LCOV - code coverage report
Current view: top level - libavcodec - cljrenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 29 34 85.3 %
Date: 2017-12-15 18:13:28 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Cirrus Logic AccuPak (CLJR) encoder
       3             :  * Copyright (c) 2003 Alex Beregszaszi
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Cirrus Logic AccuPak encoder.
      25             :  */
      26             : 
      27             : #include "libavutil/common.h"
      28             : #include "libavutil/opt.h"
      29             : 
      30             : #include "avcodec.h"
      31             : #include "internal.h"
      32             : #include "put_bits.h"
      33             : 
      34             : typedef struct CLJRContext {
      35             :     AVClass        *avclass;
      36             :     int             dither_type;
      37             : } CLJRContext;
      38             : 
      39         200 : static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
      40             :                         const AVFrame *p, int *got_packet)
      41             : {
      42         200 :     CLJRContext *a = avctx->priv_data;
      43             :     PutBitContext pb;
      44             :     int x, y, ret;
      45         200 :     uint32_t dither= avctx->frame_number;
      46             :     static const uint32_t ordered_dither[2][2] =
      47             :     {
      48             :         { 0x10400000, 0x104F0000 },
      49             :         { 0xCB2A0000, 0xCB250000 },
      50             :     };
      51             : 
      52         200 :     if (avctx->width%4 && avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
      53           0 :          av_log(avctx, AV_LOG_ERROR,
      54             :                 "Widths which are not a multiple of 4 might fail with some decoders, "
      55             :                 "use vstrict=-1 / -strict -1 to use %d anyway.\n", avctx->width);
      56           0 :          return AVERROR_EXPERIMENTAL;
      57             :     }
      58             : 
      59         200 :     if ((ret = ff_alloc_packet2(avctx, pkt, 32*avctx->height*avctx->width/4, 0)) < 0)
      60           0 :         return ret;
      61             : 
      62         200 :     init_put_bits(&pb, pkt->data, pkt->size);
      63             : 
      64       45100 :     for (y = 0; y < avctx->height; y++) {
      65       44900 :         uint8_t *luma = &p->data[0][y * p->linesize[0]];
      66       44900 :         uint8_t *cb   = &p->data[1][y * p->linesize[1]];
      67       44900 :         uint8_t *cr   = &p->data[2][y * p->linesize[2]];
      68             :         uint8_t luma_tmp[4];
      69     3861800 :         for (x = 0; x < avctx->width; x += 4) {
      70     3816900 :             switch (a->dither_type) {
      71           0 :             case 0: dither = 0x492A0000;                       break;
      72     3816900 :             case 1: dither = dither * 1664525 + 1013904223;    break;
      73           0 :             case 2: dither = ordered_dither[ y&1 ][ (x>>2)&1 ];break;
      74             :             }
      75     3816900 :             if (x+3 >= avctx->width) {
      76        1700 :                 memset(luma_tmp, 0, sizeof(luma_tmp));
      77        1700 :                 memcpy(luma_tmp, luma, avctx->width - x);
      78        1700 :                 luma = luma_tmp;
      79             :             }
      80     3816900 :             put_bits(&pb, 5, (249*(luma[3] +  (dither>>29)   )) >> 11);
      81     3816900 :             put_bits(&pb, 5, (249*(luma[2] + ((dither>>26)&7))) >> 11);
      82     3816900 :             put_bits(&pb, 5, (249*(luma[1] + ((dither>>23)&7))) >> 11);
      83     3816900 :             put_bits(&pb, 5, (249*(luma[0] + ((dither>>20)&7))) >> 11);
      84     3816900 :             luma += 4;
      85     3816900 :             put_bits(&pb, 6, (253*(*(cb++) + ((dither>>18)&3))) >> 10);
      86     3816900 :             put_bits(&pb, 6, (253*(*(cr++) + ((dither>>16)&3))) >> 10);
      87             :         }
      88             :     }
      89             : 
      90         200 :     flush_put_bits(&pb);
      91             : 
      92         200 :     pkt->size   = put_bits_count(&pb) / 8;
      93         200 :     pkt->flags |= AV_PKT_FLAG_KEY;
      94         200 :     *got_packet = 1;
      95         200 :     return 0;
      96             : }
      97             : 
      98             : #define OFFSET(x) offsetof(CLJRContext, x)
      99             : #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
     100             : static const AVOption options[] = {
     101             :     { "dither_type",   "Dither type",   OFFSET(dither_type),        AV_OPT_TYPE_INT, { .i64=1 }, 0, 2, VE},
     102             :     { NULL },
     103             : };
     104             : 
     105             : static const AVClass cljr_class = {
     106             :     .class_name = "cljr encoder",
     107             :     .item_name  = av_default_item_name,
     108             :     .option     = options,
     109             :     .version    = LIBAVUTIL_VERSION_INT,
     110             : };
     111             : 
     112             : AVCodec ff_cljr_encoder = {
     113             :     .name           = "cljr",
     114             :     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
     115             :     .type           = AVMEDIA_TYPE_VIDEO,
     116             :     .id             = AV_CODEC_ID_CLJR,
     117             :     .priv_data_size = sizeof(CLJRContext),
     118             :     .encode2        = encode_frame,
     119             :     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
     120             :                                                    AV_PIX_FMT_NONE },
     121             :     .priv_class     = &cljr_class,
     122             : };

Generated by: LCOV version 1.13