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 |