00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include "raw.h"
00029
00030 typedef struct RawVideoContext {
00031 unsigned char * buffer;
00032 int length;
00033 AVFrame pic;
00034 } RawVideoContext;
00035
00036 static const PixelFormatTag pixelFormatBpsAVI[] = {
00037 { PIX_FMT_PAL8, 4 },
00038 { PIX_FMT_PAL8, 8 },
00039 { PIX_FMT_RGB555, 15 },
00040 { PIX_FMT_RGB555, 16 },
00041 { PIX_FMT_BGR24, 24 },
00042 { PIX_FMT_RGB32, 32 },
00043 { -1, 0 },
00044 };
00045
00046 static const PixelFormatTag pixelFormatBpsMOV[] = {
00047
00048
00049 { PIX_FMT_PAL8, 8 },
00050 { PIX_FMT_BGR555, 16 },
00051 { PIX_FMT_RGB24, 24 },
00052 { PIX_FMT_BGR32_1, 32 },
00053 { -1, 0 },
00054 };
00055
00056 static int findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc)
00057 {
00058 while (tags->pix_fmt >= 0) {
00059 if (tags->fourcc == fourcc)
00060 return tags->pix_fmt;
00061 tags++;
00062 }
00063 return PIX_FMT_YUV420P;
00064 }
00065
00066 static int raw_init_decoder(AVCodecContext *avctx)
00067 {
00068 RawVideoContext *context = avctx->priv_data;
00069
00070 if (avctx->codec_tag == MKTAG('r','a','w',' '))
00071 avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_sample);
00072 else if (avctx->codec_tag)
00073 avctx->pix_fmt = findPixelFormat(ff_raw_pixelFormatTags, avctx->codec_tag);
00074 else if (avctx->bits_per_sample)
00075 avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_sample);
00076
00077 context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
00078 context->buffer = av_malloc(context->length);
00079 context->pic.pict_type = FF_I_TYPE;
00080 context->pic.key_frame = 1;
00081
00082 avctx->coded_frame= &context->pic;
00083
00084 if (!context->buffer)
00085 return -1;
00086
00087 return 0;
00088 }
00089
00090 static void flip(AVCodecContext *avctx, AVPicture * picture){
00091 if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[2]==0){
00092 picture->data[0] += picture->linesize[0] * (avctx->height-1);
00093 picture->linesize[0] *= -1;
00094 }
00095 }
00096
00097 static int raw_decode(AVCodecContext *avctx,
00098 void *data, int *data_size,
00099 const uint8_t *buf, int buf_size)
00100 {
00101 RawVideoContext *context = avctx->priv_data;
00102
00103 AVFrame * frame = (AVFrame *) data;
00104 AVPicture * picture = (AVPicture *) data;
00105
00106 frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
00107 frame->top_field_first = avctx->coded_frame->top_field_first;
00108
00109
00110 if(avctx->bits_per_sample == 4 && avctx->pix_fmt==PIX_FMT_PAL8 && !avctx->codec_tag){
00111 int i;
00112 for(i=256*2; i+1 < context->length>>1; i++){
00113 context->buffer[2*i+0]= buf[i-256*2]>>4;
00114 context->buffer[2*i+1]= buf[i-256*2]&15;
00115 }
00116 buf= context->buffer + 256*4;
00117 buf_size= context->length - 256*4;
00118 }
00119
00120 if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0))
00121 return -1;
00122
00123 avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
00124 if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){
00125 frame->data[1]= context->buffer;
00126 }
00127 if (avctx->palctrl && avctx->palctrl->palette_changed) {
00128 memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE);
00129 avctx->palctrl->palette_changed = 0;
00130 }
00131
00132 flip(avctx, picture);
00133
00134 if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2'))
00135 {
00136
00137 unsigned char *tmp = picture->data[1];
00138 picture->data[1] = picture->data[2];
00139 picture->data[2] = tmp;
00140 }
00141
00142 *data_size = sizeof(AVPicture);
00143 return buf_size;
00144 }
00145
00146 static int raw_close_decoder(AVCodecContext *avctx)
00147 {
00148 RawVideoContext *context = avctx->priv_data;
00149
00150 av_freep(&context->buffer);
00151 return 0;
00152 }
00153
00154 AVCodec rawvideo_decoder = {
00155 "rawvideo",
00156 CODEC_TYPE_VIDEO,
00157 CODEC_ID_RAWVIDEO,
00158 sizeof(RawVideoContext),
00159 raw_init_decoder,
00160 NULL,
00161 raw_close_decoder,
00162 raw_decode,
00163 };