00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "mjpeg.h"
00024 #include "mjpegdec.h"
00025
00026 typedef struct {
00027 MJpegDecodeContext mjpeg_ctx;
00028 AVFrame frame;
00029 int is_mjpeg;
00030 int interlace;
00031 int tff;
00032 } AVRnContext;
00033
00034 static av_cold int init(AVCodecContext *avctx)
00035 {
00036 AVRnContext *a = avctx->priv_data;
00037
00038
00039 a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
00040
00041 if(a->is_mjpeg)
00042 return ff_mjpeg_decode_init(avctx);
00043
00044 if(avctx->width <= 0 || avctx->height <= 0)
00045 return -1;
00046
00047 avcodec_get_frame_defaults(&a->frame);
00048 avctx->pix_fmt = PIX_FMT_UYVY422;
00049
00050 if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
00051 int ndx = avctx->extradata[4] + 4;
00052 a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
00053 if(a->interlace) {
00054 a->tff = avctx->extradata[ndx + 24] == 1;
00055 }
00056 }
00057
00058 return 0;
00059 }
00060
00061 static av_cold int end(AVCodecContext *avctx)
00062 {
00063 AVRnContext *a = avctx->priv_data;
00064 AVFrame *p = &a->frame;
00065
00066 if(p->data[0])
00067 avctx->release_buffer(avctx, p);
00068
00069 if(a->is_mjpeg)
00070 ff_mjpeg_decode_end(avctx);
00071
00072 return 0;
00073 }
00074
00075 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
00076 {
00077 AVRnContext *a = avctx->priv_data;
00078 AVFrame *p = &a->frame;
00079 const uint8_t *buf = avpkt->data;
00080 int buf_size = avpkt->size;
00081 int true_height = buf_size / (2*avctx->width);
00082 int y;
00083
00084 if(a->is_mjpeg)
00085 return ff_mjpeg_decode_frame(avctx, data, data_size, avpkt);
00086
00087 if(p->data[0])
00088 avctx->release_buffer(avctx, p);
00089
00090 if(buf_size < 2*avctx->width * avctx->height) {
00091 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
00092 return AVERROR_INVALIDDATA;
00093 }
00094
00095 if(avctx->get_buffer(avctx, p) < 0){
00096 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00097 return -1;
00098 }
00099 p->pict_type= AV_PICTURE_TYPE_I;
00100 p->key_frame= 1;
00101
00102 if(a->interlace) {
00103 buf += (true_height - avctx->height)*avctx->width;
00104 for(y = 0; y < avctx->height-1; y+=2) {
00105 memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf , 2*avctx->width);
00106 memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
00107 buf += 2*avctx->width;
00108 }
00109 } else {
00110 buf += (true_height - avctx->height)*avctx->width*2;
00111 for(y = 0; y < avctx->height; y++) {
00112 memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
00113 buf += 2*avctx->width;
00114 }
00115 }
00116
00117 *(AVFrame*)data = a->frame;
00118 *data_size = sizeof(AVFrame);
00119 return buf_size;
00120 }
00121
00122 AVCodec ff_avrn_decoder = {
00123 .name = "avrn",
00124 .type = AVMEDIA_TYPE_VIDEO,
00125 .id = AV_CODEC_ID_AVRN,
00126 .priv_data_size = sizeof(AVRnContext),
00127 .init = init,
00128 .close = end,
00129 .decode = decode_frame,
00130 .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
00131 .capabilities = CODEC_CAP_DR1,
00132 };
00133