2 * MPEG4 Video frame extraction
3 * Copyright (c) 2003 Fabrice Bellard
4 * Copyright (c) 2003 Michael Niedermayer
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #define UNCHECKED_BITSTREAM_READER 1
27 #include "mpegvideo.h"
28 #include "mpeg4video.h"
29 #include "mpeg4video_parser.h"
31 struct Mp4vParseContext
{
33 Mpeg4DecContext dec_ctx
;
37 int ff_mpeg4_find_frame_end(ParseContext
*pc
, const uint8_t *buf
, int buf_size
)
42 vop_found
= pc
->frame_start_found
;
47 for (i
= 0; i
< buf_size
; i
++) {
48 state
= (state
<< 8) | buf
[i
];
58 /* EOF considered as end of frame */
61 for (; i
< buf_size
; i
++) {
62 state
= (state
<< 8) | buf
[i
];
63 if ((state
& 0xFFFFFF00) == 0x100) {
64 pc
->frame_start_found
= 0;
70 pc
->frame_start_found
= vop_found
;
75 /* XXX: make it use less memory */
76 static int mpeg4_decode_header(AVCodecParserContext
*s1
, AVCodecContext
*avctx
,
77 const uint8_t *buf
, int buf_size
)
79 struct Mp4vParseContext
*pc
= s1
->priv_data
;
80 Mpeg4DecContext
*dec_ctx
= &pc
->dec_ctx
;
81 MpegEncContext
*s
= &dec_ctx
->m
;
82 GetBitContext gb1
, *gb
= &gb1
;
86 s
->current_picture_ptr
= &s
->current_picture
;
88 if (avctx
->extradata_size
&& pc
->first_picture
) {
89 init_get_bits(gb
, avctx
->extradata
, avctx
->extradata_size
* 8);
90 ret
= ff_mpeg4_decode_picture_header(dec_ctx
, gb
);
92 av_log(avctx
, AV_LOG_WARNING
, "Failed to parse extradata\n");
95 init_get_bits(gb
, buf
, 8 * buf_size
);
96 ret
= ff_mpeg4_decode_picture_header(dec_ctx
, gb
);
97 if (s
->width
&& (!avctx
->width
|| !avctx
->height
||
98 !avctx
->coded_width
|| !avctx
->coded_height
)) {
99 ret
= ff_set_dimensions(avctx
, s
->width
, s
->height
);
103 if((s1
->flags
& PARSER_FLAG_USE_CODEC_TS
) && s
->avctx
->time_base
.den
>0 && ret
>=0){
104 av_assert1(s1
->pts
== AV_NOPTS_VALUE
);
105 av_assert1(s1
->dts
== AV_NOPTS_VALUE
);
107 s1
->pts
= av_rescale_q(s
->time
, (AVRational
){1, s
->avctx
->time_base
.den
}, (AVRational
){1, 1200000});
110 s1
->pict_type
= s
->pict_type
;
111 pc
->first_picture
= 0;
115 static av_cold
int mpeg4video_parse_init(AVCodecParserContext
*s
)
117 struct Mp4vParseContext
*pc
= s
->priv_data
;
119 ff_mpeg4videodec_static_init();
121 pc
->first_picture
= 1;
122 pc
->dec_ctx
.m
.quant_precision
= 5;
123 pc
->dec_ctx
.m
.slice_context_count
= 1;
124 pc
->dec_ctx
.showed_packed_warning
= 1;
128 static int mpeg4video_parse(AVCodecParserContext
*s
,
129 AVCodecContext
*avctx
,
130 const uint8_t **poutbuf
, int *poutbuf_size
,
131 const uint8_t *buf
, int buf_size
)
133 ParseContext
*pc
= s
->priv_data
;
136 if (s
->flags
& PARSER_FLAG_COMPLETE_FRAMES
) {
139 next
= ff_mpeg4_find_frame_end(pc
, buf
, buf_size
);
141 if (ff_combine_frame(pc
, next
, &buf
, &buf_size
) < 0) {
147 mpeg4_decode_header(s
, avctx
, buf
, buf_size
);
150 *poutbuf_size
= buf_size
;
154 AVCodecParser ff_mpeg4video_parser
= {
155 .codec_ids
= { AV_CODEC_ID_MPEG4
},
156 .priv_data_size
= sizeof(struct Mp4vParseContext
),
157 .parser_init
= mpeg4video_parse_init
,
158 .parser_parse
= mpeg4video_parse
,
159 .parser_close
= ff_parse_close
,
160 .split
= ff_mpeg4video_split
,