2 * Audio and 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
25 AVCodecParser
*av_first_parser
= NULL
;
27 AVCodecParser
* av_parser_next(AVCodecParser
*p
){
29 else return av_first_parser
;
32 void av_register_codec_parser(AVCodecParser
*parser
)
34 parser
->next
= av_first_parser
;
35 av_first_parser
= parser
;
38 AVCodecParserContext
*av_parser_init(int codec_id
)
40 AVCodecParserContext
*s
;
41 AVCodecParser
*parser
;
44 if(codec_id
== CODEC_ID_NONE
)
47 for(parser
= av_first_parser
; parser
!= NULL
; parser
= parser
->next
) {
48 if (parser
->codec_ids
[0] == codec_id
||
49 parser
->codec_ids
[1] == codec_id
||
50 parser
->codec_ids
[2] == codec_id
||
51 parser
->codec_ids
[3] == codec_id
||
52 parser
->codec_ids
[4] == codec_id
)
57 s
= av_mallocz(sizeof(AVCodecParserContext
));
61 s
->priv_data
= av_mallocz(parser
->priv_data_size
);
66 if (parser
->parser_init
) {
67 ret
= parser
->parser_init(s
);
69 av_free(s
->priv_data
);
75 s
->pict_type
= FF_I_TYPE
;
82 * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output)
83 * @param pts input presentation timestamp
84 * @param dts input decoding timestamp
85 * @param poutbuf will contain a pointer to the first byte of the output frame
86 * @param poutbuf_size will contain the length of the output frame
87 * @return the number of bytes of the input bitstream used
92 * len = av_parser_parse(myparser, AVCodecContext, &data, &size,
99 * decode_frame(data, size);
103 int av_parser_parse(AVCodecParserContext
*s
,
104 AVCodecContext
*avctx
,
105 uint8_t **poutbuf
, int *poutbuf_size
,
106 const uint8_t *buf
, int buf_size
,
107 int64_t pts
, int64_t dts
)
110 uint8_t dummy_buf
[FF_INPUT_BUFFER_PADDING_SIZE
];
113 /* padding is always necessary even if EOF, so we add it here */
114 memset(dummy_buf
, 0, sizeof(dummy_buf
));
117 /* add a new packet descriptor */
118 k
= (s
->cur_frame_start_index
+ 1) & (AV_PARSER_PTS_NB
- 1);
119 s
->cur_frame_start_index
= k
;
120 s
->cur_frame_offset
[k
] = s
->cur_offset
;
121 s
->cur_frame_pts
[k
] = pts
;
122 s
->cur_frame_dts
[k
] = dts
;
124 /* fill first PTS/DTS */
125 if (s
->fetch_timestamp
){
126 s
->fetch_timestamp
=0;
130 s
->cur_frame_pts
[k
] =
131 s
->cur_frame_dts
[k
] = AV_NOPTS_VALUE
;
135 /* WARNING: the returned index can be negative */
136 index
= s
->parser
->parser_parse(s
, avctx
, (const uint8_t **)poutbuf
, poutbuf_size
, buf
, buf_size
);
137 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id);
138 /* update the file pointer */
140 /* fill the data for the current frame */
141 s
->frame_offset
= s
->last_frame_offset
;
142 s
->pts
= s
->last_pts
;
143 s
->dts
= s
->last_dts
;
144 s
->offset
= s
->last_offset
;
146 /* offset of the next frame */
147 s
->last_frame_offset
= s
->cur_offset
+ index
;
148 /* find the packet in which the new frame starts. It
149 is tricky because of MPEG video start codes
150 which can begin in one packet and finish in
151 another packet. In the worst case, an MPEG
152 video start code could be in 4 different
154 k
= s
->cur_frame_start_index
;
155 for(i
= 0; i
< AV_PARSER_PTS_NB
; i
++) {
156 if (s
->last_frame_offset
>= s
->cur_frame_offset
[k
])
158 k
= (k
- 1) & (AV_PARSER_PTS_NB
- 1);
161 s
->last_pts
= s
->cur_frame_pts
[k
];
162 s
->last_dts
= s
->cur_frame_dts
[k
];
163 s
->last_offset
= s
->last_frame_offset
- s
->cur_frame_offset
[k
];
165 /* some parsers tell us the packet size even before seeing the first byte of the next packet,
166 so the next pts/dts is in the next chunk */
167 if(index
== buf_size
){
168 s
->fetch_timestamp
=1;
173 s
->cur_offset
+= index
;
179 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
180 * @deprecated use AVBitstreamFilter
182 int av_parser_change(AVCodecParserContext
*s
,
183 AVCodecContext
*avctx
,
184 uint8_t **poutbuf
, int *poutbuf_size
,
185 const uint8_t *buf
, int buf_size
, int keyframe
){
187 if(s
&& s
->parser
->split
){
188 if((avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) || (avctx
->flags2
& CODEC_FLAG2_LOCAL_HEADER
)){
189 int i
= s
->parser
->split(avctx
, buf
, buf_size
);
195 /* cast to avoid warning about discarding qualifiers */
196 *poutbuf
= (uint8_t *) buf
;
197 *poutbuf_size
= buf_size
;
198 if(avctx
->extradata
){
199 if( (keyframe
&& (avctx
->flags2
& CODEC_FLAG2_LOCAL_HEADER
))
200 /*||(s->pict_type != FF_I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/
201 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
202 int size
= buf_size
+ avctx
->extradata_size
;
204 *poutbuf
= av_malloc(size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
206 memcpy(*poutbuf
, avctx
->extradata
, avctx
->extradata_size
);
207 memcpy((*poutbuf
) + avctx
->extradata_size
, buf
, buf_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
215 void av_parser_close(AVCodecParserContext
*s
)
218 if (s
->parser
->parser_close
)
219 s
->parser
->parser_close(s
);
220 av_free(s
->priv_data
);
225 /*****************************************************/
228 * combines the (truncated) bitstream to a complete frame
229 * @returns -1 if no complete frame could be created, AVERROR(ENOMEM) if there was a memory allocation error
231 int ff_combine_frame(ParseContext
*pc
, int next
, const uint8_t **buf
, int *buf_size
)
235 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
236 printf("%X %X %X %X\n", (*buf
)[0], (*buf
)[1],(*buf
)[2],(*buf
)[3]);
240 /* Copy overread bytes from last frame into buffer. */
241 for(; pc
->overread
>0; pc
->overread
--){
242 pc
->buffer
[pc
->index
++]= pc
->buffer
[pc
->overread_index
++];
245 /* flush remaining if EOF */
246 if(!*buf_size
&& next
== END_NOT_FOUND
){
250 pc
->last_index
= pc
->index
;
252 /* copy into buffer end return */
253 if(next
== END_NOT_FOUND
){
254 void* new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
, (*buf_size
) + pc
->index
+ FF_INPUT_BUFFER_PADDING_SIZE
);
257 return AVERROR(ENOMEM
);
258 pc
->buffer
= new_buffer
;
259 memcpy(&pc
->buffer
[pc
->index
], *buf
, *buf_size
);
260 pc
->index
+= *buf_size
;
265 pc
->overread_index
= pc
->index
+ next
;
267 /* append to buffer */
269 void* new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
, next
+ pc
->index
+ FF_INPUT_BUFFER_PADDING_SIZE
);
272 return AVERROR(ENOMEM
);
273 pc
->buffer
= new_buffer
;
274 memcpy(&pc
->buffer
[pc
->index
], *buf
, next
+ FF_INPUT_BUFFER_PADDING_SIZE
);
279 /* store overread bytes */
280 for(;next
< 0; next
++){
281 pc
->state
= (pc
->state
<<8) | pc
->buffer
[pc
->last_index
+ next
];
287 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
288 printf("%X %X %X %X\n", (*buf
)[0], (*buf
)[1],(*buf
)[2],(*buf
)[3]);
295 void ff_parse_close(AVCodecParserContext
*s
)
297 ParseContext
*pc
= s
->priv_data
;
302 void ff_parse1_close(AVCodecParserContext
*s
)
304 ParseContext1
*pc1
= s
->priv_data
;
306 av_free(pc1
->pc
.buffer
);
310 /*************************/
312 int ff_mpeg4video_split(AVCodecContext
*avctx
,
313 const uint8_t *buf
, int buf_size
)
318 for(i
=0; i
<buf_size
; i
++){
319 state
= (state
<<8) | buf
[i
];
320 if(state
== 0x1B3 || state
== 0x1B6)