3 * Copyright (c) 2001 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "libavutil/avassert.h"
33 #include "libavutil/buffer.h"
34 #include "libavutil/common.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/imgutils.h"
37 #include "libavutil/opt.h"
39 typedef struct RawVideoContext
{
42 int frame_size
; /* size of the frame in bytes */
44 int is_2_4_bpp
; // 2 or 4 bpp raw in avi/mov
46 int is_lt_16bpp
; // 16bpp pixfmt and bits_per_coded_sample < 16
49 BswapDSPContext bbdsp
;
51 unsigned int bitstream_buf_size
;
54 static const AVOption options
[]={
55 {"top", "top field first", offsetof(RawVideoContext
, tff
), AV_OPT_TYPE_INT
, {.i64
= -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM
|AV_OPT_FLAG_VIDEO_PARAM
},
59 static const AVClass rawdec_class
= {
60 .class_name
= "rawdec",
62 .version
= LIBAVUTIL_VERSION_INT
,
65 static av_cold
int raw_init_decoder(AVCodecContext
*avctx
)
67 RawVideoContext
*context
= avctx
->priv_data
;
68 const AVPixFmtDescriptor
*desc
;
70 ff_bswapdsp_init(&context
->bbdsp
);
72 if ( avctx
->codec_tag
== MKTAG('r','a','w',' ')
73 || avctx
->codec_tag
== MKTAG('N','O','1','6'))
74 avctx
->pix_fmt
= avpriv_find_pix_fmt(avpriv_pix_fmt_bps_mov
,
75 avctx
->bits_per_coded_sample
);
76 else if (avctx
->codec_tag
== MKTAG('W', 'R', 'A', 'W'))
77 avctx
->pix_fmt
= avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi
,
78 avctx
->bits_per_coded_sample
);
79 else if (avctx
->codec_tag
&& (avctx
->codec_tag
& 0xFFFFFF) != MKTAG('B','I','T', 0))
80 avctx
->pix_fmt
= avpriv_find_pix_fmt(ff_raw_pix_fmt_tags
, avctx
->codec_tag
);
81 else if (avctx
->pix_fmt
== AV_PIX_FMT_NONE
&& avctx
->bits_per_coded_sample
)
82 avctx
->pix_fmt
= avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi
,
83 avctx
->bits_per_coded_sample
);
85 desc
= av_pix_fmt_desc_get(avctx
->pix_fmt
);
87 av_log(avctx
, AV_LOG_ERROR
, "Invalid pixel format.\n");
88 return AVERROR(EINVAL
);
91 if (desc
->flags
& (AV_PIX_FMT_FLAG_PAL
| AV_PIX_FMT_FLAG_PSEUDOPAL
)) {
92 context
->palette
= av_buffer_alloc(AVPALETTE_SIZE
);
93 if (!context
->palette
)
94 return AVERROR(ENOMEM
);
95 if (desc
->flags
& AV_PIX_FMT_FLAG_PSEUDOPAL
)
96 avpriv_set_systematic_pal2((uint32_t*)context
->palette
->data
, avctx
->pix_fmt
);
98 memset(context
->palette
->data
, 0, AVPALETTE_SIZE
);
101 if ((avctx
->extradata_size
>= 9 &&
102 !memcmp(avctx
->extradata
+ avctx
->extradata_size
- 9, "BottomUp", 9)) ||
103 avctx
->codec_tag
== MKTAG('c','y','u','v') ||
104 avctx
->codec_tag
== MKTAG(3, 0, 0, 0) ||
105 avctx
->codec_tag
== MKTAG('W','R','A','W'))
108 if (avctx
->codec_tag
== AV_RL32("yuv2") &&
109 avctx
->pix_fmt
== AV_PIX_FMT_YUYV422
)
110 context
->is_yuv2
= 1;
115 static void flip(AVCodecContext
*avctx
, AVPicture
*picture
)
117 picture
->data
[0] += picture
->linesize
[0] * (avctx
->height
- 1);
118 picture
->linesize
[0] *= -1;
122 * Scale sample to 16-bit resolution
124 #define SCALE16(x, bits) (((x) << (16 - (bits))) | ((x) >> (2 * (bits) - 16)))
127 * Scale buffer to 16 bits per coded sample resolution
129 #define MKSCALE16(name, r16, w16) \
130 static void name(AVCodecContext *avctx, uint8_t * dst, const uint8_t *buf, int buf_size, int packed) \
134 for (i = 0; i + 1 < buf_size; i += 2) \
135 w16(dst + i, SCALE16(r16(buf + i), avctx->bits_per_coded_sample)); \
138 init_get_bits(&gb, buf, buf_size * 8); \
139 for (i = 0; i < avctx->width * avctx->height; i++) { \
140 int sample = get_bits(&gb, avctx->bits_per_coded_sample); \
141 w16(dst + i*2, SCALE16(sample, avctx->bits_per_coded_sample)); \
146 MKSCALE16(scale16be
, AV_RB16
, AV_WB16
)
147 MKSCALE16(scale16le
, AV_RL16
, AV_WL16
)
149 static int raw_decode(AVCodecContext
*avctx
, void *data
, int *got_frame
,
152 const AVPixFmtDescriptor
*desc
= av_pix_fmt_desc_get(avctx
->pix_fmt
);
153 RawVideoContext
*context
= avctx
->priv_data
;
154 const uint8_t *buf
= avpkt
->data
;
155 int buf_size
= avpkt
->size
;
156 int linesize_align
= 4;
160 AVFrame
*frame
= data
;
161 AVPicture
*picture
= data
;
163 if ((avctx
->bits_per_coded_sample
== 4 || avctx
->bits_per_coded_sample
== 2) &&
164 avctx
->pix_fmt
== AV_PIX_FMT_PAL8
&&
165 (!avctx
->codec_tag
|| avctx
->codec_tag
== MKTAG('r','a','w',' '))) {
166 context
->is_2_4_bpp
= 1;
167 context
->frame_size
= avpicture_get_size(avctx
->pix_fmt
,
168 FFALIGN(avctx
->width
, 16),
171 context
->is_lt_16bpp
= av_get_bits_per_pixel(desc
) == 16 && avctx
->bits_per_coded_sample
&& avctx
->bits_per_coded_sample
< 16;
172 context
->frame_size
= avpicture_get_size(avctx
->pix_fmt
, avctx
->width
,
175 if (context
->frame_size
< 0)
176 return context
->frame_size
;
178 need_copy
= !avpkt
->buf
|| context
->is_2_4_bpp
|| context
->is_yuv2
|| context
->is_lt_16bpp
;
180 frame
->pict_type
= AV_PICTURE_TYPE_I
;
181 frame
->key_frame
= 1;
183 res
= ff_decode_frame_props(avctx
, frame
);
187 av_frame_set_pkt_pos (frame
, avctx
->internal
->pkt
->pos
);
188 av_frame_set_pkt_duration(frame
, avctx
->internal
->pkt
->duration
);
190 if (context
->tff
>= 0) {
191 frame
->interlaced_frame
= 1;
192 frame
->top_field_first
= context
->tff
;
195 if ((res
= av_image_check_size(avctx
->width
, avctx
->height
, 0, avctx
)) < 0)
199 frame
->buf
[0] = av_buffer_alloc(FFMAX(context
->frame_size
, buf_size
));
201 frame
->buf
[0] = av_buffer_ref(avpkt
->buf
);
203 return AVERROR(ENOMEM
);
205 //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
206 if (context
->is_2_4_bpp
) {
208 uint8_t *dst
= frame
->buf
[0]->data
;
209 buf_size
= context
->frame_size
- AVPALETTE_SIZE
;
210 if (avctx
->bits_per_coded_sample
== 4) {
211 for (i
= 0; 2 * i
+ 1 < buf_size
&& i
<avpkt
->size
; i
++) {
212 dst
[2 * i
+ 0] = buf
[i
] >> 4;
213 dst
[2 * i
+ 1] = buf
[i
] & 15;
217 av_assert0(avctx
->bits_per_coded_sample
== 2);
218 for (i
= 0; 4 * i
+ 3 < buf_size
&& i
<avpkt
->size
; i
++) {
219 dst
[4 * i
+ 0] = buf
[i
] >> 6;
220 dst
[4 * i
+ 1] = buf
[i
] >> 4 & 3;
221 dst
[4 * i
+ 2] = buf
[i
] >> 2 & 3;
222 dst
[4 * i
+ 3] = buf
[i
] & 3;
227 } else if (context
->is_lt_16bpp
) {
228 uint8_t *dst
= frame
->buf
[0]->data
;
229 int packed
= (avctx
->codec_tag
& 0xFFFFFF) == MKTAG('B','I','T', 0);
230 int swap
= avctx
->codec_tag
>> 24;
232 if (packed
&& swap
) {
233 av_fast_padded_malloc(&context
->bitstream_buf
, &context
->bitstream_buf_size
, buf_size
);
234 if (!context
->bitstream_buf
)
235 return AVERROR(ENOMEM
);
237 context
->bbdsp
.bswap16_buf(context
->bitstream_buf
, (const uint16_t*)buf
, buf_size
/ 2);
239 context
->bbdsp
.bswap_buf(context
->bitstream_buf
, (const uint32_t*)buf
, buf_size
/ 4);
241 return AVERROR_INVALIDDATA
;
242 buf
= context
->bitstream_buf
;
245 if (desc
->flags
& AV_PIX_FMT_FLAG_BE
)
246 scale16be(avctx
, dst
, buf
, buf_size
, packed
);
248 scale16le(avctx
, dst
, buf
, buf_size
, packed
);
251 } else if (need_copy
) {
252 memcpy(frame
->buf
[0]->data
, buf
, buf_size
);
253 buf
= frame
->buf
[0]->data
;
256 if (avctx
->codec_tag
== MKTAG('A', 'V', '1', 'x') ||
257 avctx
->codec_tag
== MKTAG('A', 'V', 'u', 'p'))
258 buf
+= buf_size
- context
->frame_size
;
260 len
= context
->frame_size
- (avctx
->pix_fmt
==AV_PIX_FMT_PAL8
? AVPALETTE_SIZE
: 0);
261 if (buf_size
< len
&& (avctx
->codec_tag
& 0xFFFFFF) != MKTAG('B','I','T', 0)) {
262 av_log(avctx
, AV_LOG_ERROR
, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size
, len
);
263 av_buffer_unref(&frame
->buf
[0]);
264 return AVERROR(EINVAL
);
267 if ((res
= avpicture_fill(picture
, buf
, avctx
->pix_fmt
,
268 avctx
->width
, avctx
->height
)) < 0) {
269 av_buffer_unref(&frame
->buf
[0]);
273 if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
) {
274 const uint8_t *pal
= av_packet_get_side_data(avpkt
, AV_PKT_DATA_PALETTE
,
278 av_buffer_unref(&context
->palette
);
279 context
->palette
= av_buffer_alloc(AVPALETTE_SIZE
);
280 if (!context
->palette
) {
281 av_buffer_unref(&frame
->buf
[0]);
282 return AVERROR(ENOMEM
);
284 memcpy(context
->palette
->data
, pal
, AVPALETTE_SIZE
);
285 frame
->palette_has_changed
= 1;
289 if ((avctx
->pix_fmt
==AV_PIX_FMT_BGR24
||
290 avctx
->pix_fmt
==AV_PIX_FMT_GRAY8
||
291 avctx
->pix_fmt
==AV_PIX_FMT_RGB555LE
||
292 avctx
->pix_fmt
==AV_PIX_FMT_RGB555BE
||
293 avctx
->pix_fmt
==AV_PIX_FMT_RGB565LE
||
294 avctx
->pix_fmt
==AV_PIX_FMT_MONOWHITE
||
295 avctx
->pix_fmt
==AV_PIX_FMT_PAL8
) &&
296 FFALIGN(frame
->linesize
[0], linesize_align
) * avctx
->height
<= buf_size
)
297 frame
->linesize
[0] = FFALIGN(frame
->linesize
[0], linesize_align
);
299 if (avctx
->pix_fmt
== AV_PIX_FMT_NV12
&& avctx
->codec_tag
== MKTAG('N', 'V', '1', '2') &&
300 FFALIGN(frame
->linesize
[0], linesize_align
) * avctx
->height
+
301 FFALIGN(frame
->linesize
[1], linesize_align
) * ((avctx
->height
+ 1) / 2) <= buf_size
) {
302 int la0
= FFALIGN(frame
->linesize
[0], linesize_align
);
303 frame
->data
[1] += (la0
- frame
->linesize
[0]) * avctx
->height
;
304 frame
->linesize
[0] = la0
;
305 frame
->linesize
[1] = FFALIGN(frame
->linesize
[1], linesize_align
);
308 if ((avctx
->pix_fmt
== AV_PIX_FMT_PAL8
&& buf_size
< context
->frame_size
) ||
309 (desc
->flags
& AV_PIX_FMT_FLAG_PSEUDOPAL
)) {
310 frame
->buf
[1] = av_buffer_ref(context
->palette
);
311 if (!frame
->buf
[1]) {
312 av_buffer_unref(&frame
->buf
[0]);
313 return AVERROR(ENOMEM
);
315 frame
->data
[1] = frame
->buf
[1]->data
;
318 if (avctx
->pix_fmt
== AV_PIX_FMT_BGR24
&&
319 ((frame
->linesize
[0] + 3) & ~3) * avctx
->height
<= buf_size
)
320 frame
->linesize
[0] = (frame
->linesize
[0] + 3) & ~3;
323 flip(avctx
, picture
);
325 if (avctx
->codec_tag
== MKTAG('Y', 'V', '1', '2') ||
326 avctx
->codec_tag
== MKTAG('Y', 'V', '1', '6') ||
327 avctx
->codec_tag
== MKTAG('Y', 'V', '2', '4') ||
328 avctx
->codec_tag
== MKTAG('Y', 'V', 'U', '9'))
329 FFSWAP(uint8_t *, picture
->data
[1], picture
->data
[2]);
331 if (avctx
->codec_tag
== AV_RL32("I420") && (avctx
->width
+1)*(avctx
->height
+1) * 3/2 == buf_size
) {
332 picture
->data
[1] = picture
->data
[1] + (avctx
->width
+1)*(avctx
->height
+1) -avctx
->width
*avctx
->height
;
333 picture
->data
[2] = picture
->data
[2] + ((avctx
->width
+1)*(avctx
->height
+1) -avctx
->width
*avctx
->height
)*5/4;
336 if (avctx
->codec_tag
== AV_RL32("yuv2") &&
337 avctx
->pix_fmt
== AV_PIX_FMT_YUYV422
) {
339 uint8_t *line
= picture
->data
[0];
340 for (y
= 0; y
< avctx
->height
; y
++) {
341 for (x
= 0; x
< avctx
->width
; x
++)
342 line
[2 * x
+ 1] ^= 0x80;
343 line
+= picture
->linesize
[0];
347 if (avctx
->field_order
> AV_FIELD_PROGRESSIVE
) { /* we have interlaced material flagged in container */
348 frame
->interlaced_frame
= 1;
349 if (avctx
->field_order
== AV_FIELD_TT
|| avctx
->field_order
== AV_FIELD_TB
)
350 frame
->top_field_first
= 1;
357 static av_cold
int raw_close_decoder(AVCodecContext
*avctx
)
359 RawVideoContext
*context
= avctx
->priv_data
;
361 av_buffer_unref(&context
->palette
);
365 AVCodec ff_rawvideo_decoder
= {
367 .long_name
= NULL_IF_CONFIG_SMALL("raw video"),
368 .type
= AVMEDIA_TYPE_VIDEO
,
369 .id
= AV_CODEC_ID_RAWVIDEO
,
370 .priv_data_size
= sizeof(RawVideoContext
),
371 .init
= raw_init_decoder
,
372 .close
= raw_close_decoder
,
373 .decode
= raw_decode
,
374 .priv_class
= &rawdec_class
,
375 .capabilities
= CODEC_CAP_PARAM_CHANGE
,