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