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 };