Mercurial > libavcodec.hg
comparison raw.c @ 5264:810df021dbef libavcodec
split rawvideo encoder and decoder in their own files
| author | aurel |
|---|---|
| date | Mon, 09 Jul 2007 16:26:11 +0000 |
| parents | 334a964f6fc1 |
| children | 6b8daf48b82f |
comparison
equal
deleted
inserted
replaced
| 5263:5b8b6dad7197 | 5264:810df021dbef |
|---|---|
| 23 * @file raw.c | 23 * @file raw.c |
| 24 * Raw Video Codec | 24 * Raw Video Codec |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "avcodec.h" | 27 #include "avcodec.h" |
| 28 #include "raw.h" | |
| 28 | 29 |
| 29 typedef struct RawVideoContext { | 30 const PixelFormatTag ff_raw_pixelFormatTags[] = { |
| 30 unsigned char * buffer; /* block of memory for holding one frame */ | |
| 31 int length; /* number of bytes in buffer */ | |
| 32 AVFrame pic; ///< AVCodecContext.coded_frame | |
| 33 } RawVideoContext; | |
| 34 | |
| 35 typedef struct PixelFormatTag { | |
| 36 int pix_fmt; | |
| 37 unsigned int fourcc; | |
| 38 } PixelFormatTag; | |
| 39 | |
| 40 static const PixelFormatTag pixelFormatTags[] = { | |
| 41 { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ | 31 { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ |
| 42 { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') }, | 32 { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') }, |
| 43 { PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') }, | 33 { PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') }, |
| 44 { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') }, | 34 { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') }, |
| 45 { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') }, | 35 { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') }, |
| 62 { PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */ | 52 { PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */ |
| 63 | 53 |
| 64 { -1, 0 }, | 54 { -1, 0 }, |
| 65 }; | 55 }; |
| 66 | 56 |
| 67 static const PixelFormatTag pixelFormatBpsAVI[] = { | |
| 68 { PIX_FMT_PAL8, 8 }, | |
| 69 { PIX_FMT_RGB555, 15 }, | |
| 70 { PIX_FMT_RGB555, 16 }, | |
| 71 { PIX_FMT_BGR24, 24 }, | |
| 72 { PIX_FMT_RGB32, 32 }, | |
| 73 { -1, 0 }, | |
| 74 }; | |
| 75 | |
| 76 static const PixelFormatTag pixelFormatBpsMOV[] = { | |
| 77 /* FIXME fix swscaler to support those */ | |
| 78 /* http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html */ | |
| 79 { PIX_FMT_PAL8, 8 }, | |
| 80 { PIX_FMT_BGR555, 16 }, | |
| 81 { PIX_FMT_RGB24, 24 }, | |
| 82 { PIX_FMT_BGR32_1, 32 }, | |
| 83 { -1, 0 }, | |
| 84 }; | |
| 85 | |
| 86 static int findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc) | |
| 87 { | |
| 88 while (tags->pix_fmt >= 0) { | |
| 89 if (tags->fourcc == fourcc) | |
| 90 return tags->pix_fmt; | |
| 91 tags++; | |
| 92 } | |
| 93 return PIX_FMT_YUV420P; | |
| 94 } | |
| 95 | |
| 96 unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt) | 57 unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt) |
| 97 { | 58 { |
| 98 const PixelFormatTag * tags = pixelFormatTags; | 59 const PixelFormatTag * tags = ff_raw_pixelFormatTags; |
| 99 while (tags->pix_fmt >= 0) { | 60 while (tags->pix_fmt >= 0) { |
| 100 if (tags->pix_fmt == fmt) | 61 if (tags->pix_fmt == fmt) |
| 101 return tags->fourcc; | 62 return tags->fourcc; |
| 102 tags++; | 63 tags++; |
| 103 } | 64 } |
| 104 return 0; | 65 return 0; |
| 105 } | 66 } |
| 106 | |
| 107 /* RAW Decoder Implementation */ | |
| 108 | |
| 109 static int raw_init_decoder(AVCodecContext *avctx) | |
| 110 { | |
| 111 RawVideoContext *context = avctx->priv_data; | |
| 112 | |
| 113 if (avctx->codec_tag == MKTAG('r','a','w',' ')) | |
| 114 avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_sample); | |
| 115 else if (avctx->codec_tag) | |
| 116 avctx->pix_fmt = findPixelFormat(pixelFormatTags, avctx->codec_tag); | |
| 117 else if (avctx->bits_per_sample) | |
| 118 avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_sample); | |
| 119 | |
| 120 context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); | |
| 121 context->buffer = av_malloc(context->length); | |
| 122 context->pic.pict_type = FF_I_TYPE; | |
| 123 context->pic.key_frame = 1; | |
| 124 | |
| 125 avctx->coded_frame= &context->pic; | |
| 126 | |
| 127 if (!context->buffer) | |
| 128 return -1; | |
| 129 | |
| 130 return 0; | |
| 131 } | |
| 132 | |
| 133 static void flip(AVCodecContext *avctx, AVPicture * picture){ | |
| 134 if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[2]==0){ | |
| 135 picture->data[0] += picture->linesize[0] * (avctx->height-1); | |
| 136 picture->linesize[0] *= -1; | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 static int raw_decode(AVCodecContext *avctx, | |
| 141 void *data, int *data_size, | |
| 142 uint8_t *buf, int buf_size) | |
| 143 { | |
| 144 RawVideoContext *context = avctx->priv_data; | |
| 145 | |
| 146 AVFrame * frame = (AVFrame *) data; | |
| 147 AVPicture * picture = (AVPicture *) data; | |
| 148 | |
| 149 frame->interlaced_frame = avctx->coded_frame->interlaced_frame; | |
| 150 frame->top_field_first = avctx->coded_frame->top_field_first; | |
| 151 | |
| 152 if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) | |
| 153 return -1; | |
| 154 | |
| 155 avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); | |
| 156 if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){ | |
| 157 frame->data[1]= context->buffer; | |
| 158 } | |
| 159 if (avctx->palctrl && avctx->palctrl->palette_changed) { | |
| 160 memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); | |
| 161 avctx->palctrl->palette_changed = 0; | |
| 162 } | |
| 163 | |
| 164 flip(avctx, picture); | |
| 165 | |
| 166 if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2')) | |
| 167 { | |
| 168 // swap fields | |
| 169 unsigned char *tmp = picture->data[1]; | |
| 170 picture->data[1] = picture->data[2]; | |
| 171 picture->data[2] = tmp; | |
| 172 } | |
| 173 | |
| 174 *data_size = sizeof(AVPicture); | |
| 175 return buf_size; | |
| 176 } | |
| 177 | |
| 178 static int raw_close_decoder(AVCodecContext *avctx) | |
| 179 { | |
| 180 RawVideoContext *context = avctx->priv_data; | |
| 181 | |
| 182 av_freep(&context->buffer); | |
| 183 return 0; | |
| 184 } | |
| 185 | |
| 186 /* RAW Encoder Implementation */ | |
| 187 #ifdef CONFIG_RAWVIDEO_ENCODER | |
| 188 static int raw_init_encoder(AVCodecContext *avctx) | |
| 189 { | |
| 190 avctx->coded_frame = (AVFrame *)avctx->priv_data; | |
| 191 avctx->coded_frame->pict_type = FF_I_TYPE; | |
| 192 avctx->coded_frame->key_frame = 1; | |
| 193 if(!avctx->codec_tag) | |
| 194 avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); | |
| 195 return 0; | |
| 196 } | |
| 197 | |
| 198 static int raw_encode(AVCodecContext *avctx, | |
| 199 unsigned char *frame, int buf_size, void *data) | |
| 200 { | |
| 201 return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width, | |
| 202 avctx->height, frame, buf_size); | |
| 203 } | |
| 204 | |
| 205 AVCodec rawvideo_encoder = { | |
| 206 "rawvideo", | |
| 207 CODEC_TYPE_VIDEO, | |
| 208 CODEC_ID_RAWVIDEO, | |
| 209 sizeof(AVFrame), | |
| 210 raw_init_encoder, | |
| 211 raw_encode, | |
| 212 }; | |
| 213 #endif // CONFIG_RAWVIDEO_ENCODER | |
| 214 | |
| 215 #ifdef CONFIG_RAWVIDEO_DECODER | |
| 216 AVCodec rawvideo_decoder = { | |
| 217 "rawvideo", | |
| 218 CODEC_TYPE_VIDEO, | |
| 219 CODEC_ID_RAWVIDEO, | |
| 220 sizeof(RawVideoContext), | |
| 221 raw_init_decoder, | |
| 222 NULL, | |
| 223 raw_close_decoder, | |
| 224 raw_decode, | |
| 225 }; | |
| 226 #endif // CONFIG_RAWVIDEO_DECODER |
