LCOV - code coverage report
Current view: top level - libavcodec - cpia.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 94 0.0 %
Date: 2017-12-13 10:57:33 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :  * CPiA video decoder.
       3             :  * Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
       4             :  *
       5             :  * This decoder is based on the LGPL code available at
       6             :  * https://v4l4j.googlecode.com/svn/v4l4j/trunk/libvideo/libv4lconvert/cpia1.c
       7             :  *
       8             :  * This file is part of FFmpeg.
       9             :  *
      10             :  * FFmpeg is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public
      12             :  * License as published by the Free Software Foundation; either
      13             :  * version 2.1 of the License, or (at your option) any later version.
      14             :  *
      15             :  * FFmpeg is distributed in the hope that it will be useful,
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU Lesser General Public
      21             :  * License along with FFmpeg; if not, write to the Free Software
      22             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      23             :  */
      24             : 
      25             : #include "avcodec.h"
      26             : #include "get_bits.h"
      27             : #include "internal.h"
      28             : 
      29             : 
      30             : #define FRAME_HEADER_SIZE 64
      31             : #define MAGIC_0         0x19    /**< First header byte */
      32             : #define MAGIC_1         0x68    /**< Second header byte */
      33             : #define SUBSAMPLE_420      0
      34             : #define SUBSAMPLE_422      1
      35             : #define YUVORDER_YUYV      0
      36             : #define YUVORDER_UYVY      1
      37             : #define NOT_COMPRESSED     0
      38             : #define COMPRESSED         1
      39             : #define NO_DECIMATION      0
      40             : #define DECIMATION_ENAB    1
      41             : #define EOL             0xfd    /**< End Of Line marker */
      42             : #define EOI             0xff    /**< End Of Image marker */
      43             : 
      44             : 
      45             : typedef struct {
      46             :     AVFrame *frame;
      47             : } CpiaContext;
      48             : 
      49             : 
      50           0 : static int cpia_decode_frame(AVCodecContext *avctx,
      51             :                              void *data, int *got_frame, AVPacket* avpkt)
      52             : {
      53           0 :     CpiaContext* const cpia = avctx->priv_data;
      54             :     int i,j,ret;
      55             : 
      56           0 :     uint8_t* const header = avpkt->data;
      57             :     uint8_t* src;
      58             :     int src_size;
      59             :     uint16_t linelength;
      60             :     uint8_t skip;
      61             : 
      62           0 :     AVFrame *frame = cpia->frame;
      63             :     uint8_t *y, *u, *v, *y_end, *u_end, *v_end;
      64             : 
      65             :     // Check header
      66           0 :     if ( avpkt->size < FRAME_HEADER_SIZE
      67           0 :       || header[0] != MAGIC_0 || header[1] != MAGIC_1
      68           0 :       || (header[17] != SUBSAMPLE_420 && header[17] != SUBSAMPLE_422)
      69           0 :       || (header[18] != YUVORDER_YUYV && header[18] != YUVORDER_UYVY)
      70           0 :       || (header[28] != NOT_COMPRESSED && header[28] != COMPRESSED)
      71           0 :       || (header[29] != NO_DECIMATION && header[29] != DECIMATION_ENAB)
      72             :     ) {
      73           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid header!\n");
      74           0 :         return AVERROR_INVALIDDATA;
      75             :     }
      76             : 
      77             :     // currently unsupported properties
      78           0 :     if (header[17] == SUBSAMPLE_422) {
      79           0 :         avpriv_report_missing_feature(avctx, "4:2:2 subsampling");
      80           0 :         return AVERROR_PATCHWELCOME;
      81             :     }
      82           0 :     if (header[18] == YUVORDER_UYVY) {
      83           0 :         avpriv_report_missing_feature(avctx, "YUV byte order UYVY");
      84           0 :         return AVERROR_PATCHWELCOME;
      85             :     }
      86           0 :     if (header[29] == DECIMATION_ENAB) {
      87           0 :         avpriv_report_missing_feature(avctx, "Decimation");
      88           0 :         return AVERROR_PATCHWELCOME;
      89             :     }
      90             : 
      91           0 :     src = header + FRAME_HEADER_SIZE;
      92           0 :     src_size = avpkt->size - FRAME_HEADER_SIZE;
      93             : 
      94           0 :     if (header[28] == NOT_COMPRESSED) {
      95           0 :         frame->pict_type = AV_PICTURE_TYPE_I;
      96           0 :         frame->key_frame = 1;
      97             :     } else {
      98           0 :         frame->pict_type = AV_PICTURE_TYPE_P;
      99           0 :         frame->key_frame = 0;
     100             :     }
     101             : 
     102             :     // Get buffer filled with previous frame
     103           0 :     if ((ret = ff_reget_buffer(avctx, frame)) < 0)
     104           0 :         return ret;
     105             : 
     106             : 
     107           0 :     for ( i = 0;
     108           0 :           i < frame->height;
     109           0 :           i++, src += linelength, src_size -= linelength
     110             :     ) {
     111             :         // Read line length, two byte little endian
     112           0 :         linelength = AV_RL16(src);
     113           0 :         src += 2;
     114             : 
     115           0 :         if (src_size < linelength) {
     116           0 :             frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
     117           0 :             av_log(avctx, AV_LOG_WARNING, "Frame ended unexpectedly!\n");
     118           0 :             break;
     119             :         }
     120           0 :         if (src[linelength - 1] != EOL) {
     121           0 :             frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
     122           0 :             av_log(avctx, AV_LOG_WARNING, "Wrong line length %d or line not terminated properly (found 0x%02x)!\n", linelength, src[linelength - 1]);
     123           0 :             break;
     124             :         }
     125             : 
     126             :         /* Update the data pointers. Y data is on every line.
     127             :          * U and V data on every second line
     128             :          */
     129           0 :         y = &frame->data[0][i * frame->linesize[0]];
     130           0 :         u = &frame->data[1][(i >> 1) * frame->linesize[1]];
     131           0 :         v = &frame->data[2][(i >> 1) * frame->linesize[2]];
     132           0 :         y_end = y + frame->linesize[0] - 1;
     133           0 :         u_end = u + frame->linesize[1] - 1;
     134           0 :         v_end = v + frame->linesize[2] - 1;
     135             : 
     136           0 :         if ((i & 1) && header[17] == SUBSAMPLE_420) {
     137             :             /* We are on an odd line and 420 subsample is used.
     138             :              * On this line only Y values are specified, one per pixel.
     139             :              */
     140           0 :             for (j = 0; j < linelength - 1; j++) {
     141           0 :                 if (y > y_end) {
     142           0 :                     frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
     143           0 :                     av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
     144           0 :                     break;
     145             :                 }
     146           0 :                 if ((src[j] & 1) && header[28] == COMPRESSED) {
     147             :                     /* It seems that odd lines are always uncompressed, but
     148             :                      * we do it according to specification anyways.
     149             :                      */
     150           0 :                     skip = src[j] >> 1;
     151           0 :                     y += skip;
     152             :                 } else {
     153           0 :                     *(y++) = src[j];
     154             :                 }
     155             :             }
     156           0 :         } else if (header[17] == SUBSAMPLE_420) {
     157             :             /* We are on an even line and 420 subsample is used.
     158             :              * On this line each pair of pixels is described by four bytes.
     159             :              */
     160           0 :             for (j = 0; j < linelength - 4; ) {
     161           0 :                 if (y + 1 > y_end || u > u_end || v > v_end) {
     162           0 :                     frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
     163           0 :                     av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
     164           0 :                     break;
     165             :                 }
     166           0 :                 if ((src[j] & 1) && header[28] == COMPRESSED) {
     167             :                     // Skip amount of pixels and move forward one byte
     168           0 :                     skip = src[j] >> 1;
     169           0 :                     y += skip;
     170           0 :                     u += skip >> 1;
     171           0 :                     v += skip >> 1;
     172           0 :                     j++;
     173             :                 } else {
     174             :                     // Set image data as specified and move forward 4 bytes
     175           0 :                     *(y++) = src[j];
     176           0 :                     *(u++) = src[j+1];
     177           0 :                     *(y++) = src[j+2];
     178           0 :                     *(v++) = src[j+3];
     179           0 :                     j += 4;
     180             :                 }
     181             :             }
     182             :         }
     183             :     }
     184             : 
     185           0 :     *got_frame = 1;
     186           0 :     if ((ret = av_frame_ref(data, cpia->frame)) < 0)
     187           0 :         return ret;
     188             : 
     189           0 :     return avpkt->size;
     190             : }
     191             : 
     192           0 : static av_cold int cpia_decode_init(AVCodecContext *avctx)
     193             : {
     194           0 :     CpiaContext *s = avctx->priv_data;
     195             : 
     196             :     // output pixel format
     197           0 :     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     198             : 
     199             :     /* The default timebase set by the v4l2 demuxer leads to probing which is buggy.
     200             :      * Set some reasonable time_base to skip this.
     201             :      */
     202           0 :     if (avctx->time_base.num == 1 && avctx->time_base.den == 1000000) {
     203           0 :         avctx->time_base.num = 1;
     204           0 :         avctx->time_base.den = 60;
     205             :     }
     206             : 
     207           0 :     s->frame = av_frame_alloc();
     208           0 :     if (!s->frame)
     209           0 :         return AVERROR(ENOMEM);
     210             : 
     211           0 :     return 0;
     212             : }
     213             : 
     214           0 : static av_cold int cpia_decode_end(AVCodecContext *avctx)
     215             : {
     216           0 :     CpiaContext *s = avctx->priv_data;
     217             : 
     218           0 :     av_frame_free(&s->frame);
     219             : 
     220           0 :     return 0;
     221             : }
     222             : 
     223             : AVCodec ff_cpia_decoder = {
     224             :     .name           = "cpia",
     225             :     .long_name      = NULL_IF_CONFIG_SMALL("CPiA video format"),
     226             :     .type           = AVMEDIA_TYPE_VIDEO,
     227             :     .id             = AV_CODEC_ID_CPIA,
     228             :     .priv_data_size = sizeof(CpiaContext),
     229             :     .init           = cpia_decode_init,
     230             :     .close          = cpia_decode_end,
     231             :     .decode         = cpia_decode_frame,
     232             :     .capabilities   = AV_CODEC_CAP_DR1,
     233             : };

Generated by: LCOV version 1.13