00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #include "avcodec.h"
00026 #include "get_bits.h"
00027 
00028 
00029 #define FRAME_HEADER_SIZE 64
00030 #define MAGIC_0         0x19    
00031 #define MAGIC_1         0x68    
00032 #define SUBSAMPLE_420      0
00033 #define SUBSAMPLE_422      1
00034 #define YUVORDER_YUYV      0
00035 #define YUVORDER_UYVY      1
00036 #define NOT_COMPRESSED     0
00037 #define COMPRESSED         1
00038 #define NO_DECIMATION      0
00039 #define DECIMATION_ENAB    1
00040 #define EOL             0xfd    
00041 #define EOI             0xff    
00044 typedef struct {
00045     AVFrame frame;
00046 } CpiaContext;
00047 
00048 
00049 static int cpia_decode_frame(AVCodecContext* avctx,
00050         void* data, int* data_size, AVPacket* avpkt)
00051 {
00052     CpiaContext* const cpia = avctx->priv_data;
00053     int i,j,ret;
00054 
00055     uint8_t* const header = avpkt->data;
00056     uint8_t* src;
00057     int src_size;
00058     uint16_t linelength;
00059     uint8_t skip;
00060 
00061     AVFrame* const frame = &cpia->frame;
00062     uint8_t *y, *u, *v, *y_end, *u_end, *v_end;
00063 
00064     
00065     if ( avpkt->size < FRAME_HEADER_SIZE
00066       || header[0] != MAGIC_0 || header[1] != MAGIC_1
00067       || (header[17] != SUBSAMPLE_420 && header[17] != SUBSAMPLE_422)
00068       || (header[18] != YUVORDER_YUYV && header[18] != YUVORDER_UYVY)
00069       || (header[28] != NOT_COMPRESSED && header[28] != COMPRESSED)
00070       || (header[29] != NO_DECIMATION && header[29] != DECIMATION_ENAB)
00071     ) {
00072         av_log(avctx, AV_LOG_ERROR, "Invalid header!\n");
00073         return AVERROR_INVALIDDATA;
00074     }
00075 
00076     
00077     if (header[17] == SUBSAMPLE_422) {
00078         av_log(avctx, AV_LOG_ERROR, "Unsupported subsample!\n");
00079         return AVERROR_PATCHWELCOME;
00080     }
00081     if (header[18] == YUVORDER_UYVY) {
00082         av_log(avctx, AV_LOG_ERROR, "Unsupported YUV byte order!\n");
00083         return AVERROR_PATCHWELCOME;
00084     }
00085     if (header[29] == DECIMATION_ENAB) {
00086         av_log(avctx, AV_LOG_ERROR, "Decimation unsupported!\n");
00087         return AVERROR_PATCHWELCOME;
00088     }
00089 
00090     src = header + FRAME_HEADER_SIZE;
00091     src_size = avpkt->size - FRAME_HEADER_SIZE;
00092 
00093     if (header[28] == NOT_COMPRESSED) {
00094         frame->pict_type = AV_PICTURE_TYPE_I;
00095         frame->key_frame = 1;
00096     } else {
00097         frame->pict_type = AV_PICTURE_TYPE_P;
00098         frame->key_frame = 0;
00099     }
00100 
00101     
00102     if ((ret = avctx->reget_buffer(avctx, frame)) < 0) {
00103         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed!\n");
00104         return ret;
00105     }
00106 
00107 
00108     for ( i = 0;
00109           i < frame->height;
00110           i++, src += linelength, src_size -= linelength
00111     ) {
00112         
00113         linelength = AV_RL16(src);
00114         src += 2;
00115 
00116         if (src_size < linelength) {
00117             frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
00118             av_log(avctx, AV_LOG_WARNING, "Frame ended enexpectedly!\n");
00119             break;
00120         }
00121         if (src[linelength - 1] != EOL) {
00122             frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
00123             av_log(avctx, AV_LOG_WARNING, "Wrong line length %d or line not terminated properly (found 0x%02x)!\n", linelength, src[linelength - 1]);
00124             break;
00125         }
00126 
00127         
00128 
00129 
00130         y = &frame->data[0][i * frame->linesize[0]];
00131         u = &frame->data[1][(i >> 1) * frame->linesize[1]];
00132         v = &frame->data[2][(i >> 1) * frame->linesize[2]];
00133         y_end = y + frame->linesize[0] - 1;
00134         u_end = u + frame->linesize[1] - 1;
00135         v_end = v + frame->linesize[2] - 1;
00136 
00137         if ((i & 1) && header[17] == SUBSAMPLE_420) {
00138             
00139 
00140 
00141             for (j = 0; j < linelength - 1; j++) {
00142                 if (y > y_end) {
00143                     frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
00144                     av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
00145                     break;
00146                 }
00147                 if ((src[j] & 1) && header[28] == COMPRESSED) {
00148                     
00149 
00150 
00151                     skip = src[j] >> 1;
00152                     y += skip;
00153                 } else {
00154                     *(y++) = src[j];
00155                 }
00156             }
00157         } else if (header[17] == SUBSAMPLE_420) {
00158             
00159 
00160 
00161             for (j = 0; j < linelength - 4; ) {
00162                 if (y + 1 > y_end || u > u_end || v > v_end) {
00163                     frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
00164                     av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
00165                     break;
00166                 }
00167                 if ((src[j] & 1) && header[28] == COMPRESSED) {
00168                     
00169                     skip = src[j] >> 1;
00170                     y += skip;
00171                     u += skip >> 1;
00172                     v += skip >> 1;
00173                     j++;
00174                 } else {
00175                     
00176                     *(y++) = src[j];
00177                     *(u++) = src[j+1];
00178                     *(y++) = src[j+2];
00179                     *(v++) = src[j+3];
00180                     j += 4;
00181                 }
00182             }
00183         }
00184     }
00185 
00186     *data_size = sizeof(AVFrame);
00187     *(AVFrame*) data = *frame;
00188 
00189     return avpkt->size;
00190 }
00191 
00192 static av_cold int cpia_decode_init(AVCodecContext *avctx)
00193 {
00194     
00195     avctx->pix_fmt = PIX_FMT_YUV420P;
00196 
00197     
00198 
00199 
00200     if (avctx->time_base.num == 1 && avctx->time_base.den == 1000000) {
00201         avctx->time_base.num = 1;
00202         avctx->time_base.den = 60;
00203     }
00204 
00205     return 0;
00206 }
00207 
00208 
00209 AVCodec ff_cpia_decoder = {
00210     .name           = "cpia",
00211     .type           = AVMEDIA_TYPE_VIDEO,
00212     .id             = AV_CODEC_ID_CPIA,
00213     .priv_data_size = sizeof(CpiaContext),
00214     .init           = cpia_decode_init,
00215     .decode         = cpia_decode_frame,
00216     .capabilities   = CODEC_CAP_DR1,
00217     .long_name      = NULL_IF_CONFIG_SMALL("CPiA video format"),
00218 };