2 * MPEG4 Video frame extraction
3 * Copyright (c) 2003 Fabrice Bellard
4 * Copyright (c) 2003 Michael Niedermayer
6 * This file is part of Libav.
8 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "mpegvideo.h"
26 #include "mpeg4video.h"
27 #include "mpeg4video_parser.h"
29 struct Mp4vParseContext
{
31 struct MpegEncContext enc
;
35 int ff_mpeg4_find_frame_end(ParseContext
*pc
, const uint8_t *buf
, int buf_size
){
39 vop_found
= pc
->frame_start_found
;
44 for(i
=0; i
<buf_size
; i
++){
45 state
= (state
<<8) | buf
[i
];
55 /* EOF considered as end of frame */
58 for(; i
<buf_size
; i
++){
59 state
= (state
<<8) | buf
[i
];
60 if((state
&0xFFFFFF00) == 0x100){
61 pc
->frame_start_found
=0;
67 pc
->frame_start_found
= vop_found
;
72 /* XXX: make it use less memory */
73 static int av_mpeg4_decode_header(AVCodecParserContext
*s1
,
74 AVCodecContext
*avctx
,
75 const uint8_t *buf
, int buf_size
)
77 struct Mp4vParseContext
*pc
= s1
->priv_data
;
78 MpegEncContext
*s
= &pc
->enc
;
79 GetBitContext gb1
, *gb
= &gb1
;
83 s
->current_picture_ptr
= &s
->current_picture
;
85 if (avctx
->extradata_size
&& pc
->first_picture
){
86 init_get_bits(gb
, avctx
->extradata
, avctx
->extradata_size
*8);
87 ret
= ff_mpeg4_decode_picture_header(s
, gb
);
90 init_get_bits(gb
, buf
, 8 * buf_size
);
91 ret
= ff_mpeg4_decode_picture_header(s
, gb
);
92 if (s
->width
&& (!avctx
->width
|| !avctx
->height
|| !avctx
->coded_width
|| !avctx
->coded_height
)) {
93 ret
= ff_set_dimensions(avctx
, s
->width
, s
->height
);
97 s1
->pict_type
= s
->pict_type
;
98 pc
->first_picture
= 0;
102 static av_cold
int mpeg4video_parse_init(AVCodecParserContext
*s
)
104 struct Mp4vParseContext
*pc
= s
->priv_data
;
106 pc
->first_picture
= 1;
107 pc
->enc
.slice_context_count
= 1;
111 static int mpeg4video_parse(AVCodecParserContext
*s
,
112 AVCodecContext
*avctx
,
113 const uint8_t **poutbuf
, int *poutbuf_size
,
114 const uint8_t *buf
, int buf_size
)
116 ParseContext
*pc
= s
->priv_data
;
119 if(s
->flags
& PARSER_FLAG_COMPLETE_FRAMES
){
122 next
= ff_mpeg4_find_frame_end(pc
, buf
, buf_size
);
124 if (ff_combine_frame(pc
, next
, &buf
, &buf_size
) < 0) {
130 av_mpeg4_decode_header(s
, avctx
, buf
, buf_size
);
133 *poutbuf_size
= buf_size
;
138 AVCodecParser ff_mpeg4video_parser
= {
139 .codec_ids
= { AV_CODEC_ID_MPEG4
},
140 .priv_data_size
= sizeof(struct Mp4vParseContext
),
141 .parser_init
= mpeg4video_parse_init
,
142 .parser_parse
= mpeg4video_parse
,
143 .parser_close
= ff_parse_close
,
144 .split
= ff_mpeg4video_split
,