Commit | Line | Data |
---|---|---|
8424cf50 FB |
1 | /* |
2 | * Audio and Video frame extraction | |
3 | * Copyright (c) 2003 Fabrice Bellard. | |
4 | * Copyright (c) 2003 Michael Niedermayer. | |
5 | * | |
b78e7197 DB |
6 | * This file is part of FFmpeg. |
7 | * | |
8 | * FFmpeg is free software; you can redistribute it and/or | |
8424cf50 FB |
9 | * modify it under the terms of the GNU Lesser General Public |
10 | * License as published by the Free Software Foundation; either | |
b78e7197 | 11 | * version 2.1 of the License, or (at your option) any later version. |
8424cf50 | 12 | * |
b78e7197 | 13 | * FFmpeg is distributed in the hope that it will be useful, |
8424cf50 FB |
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. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
b78e7197 | 19 | * License along with FFmpeg; if not, write to the Free Software |
5509bffa | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
8424cf50 | 21 | */ |
1fddeecd | 22 | |
4067d81b | 23 | #include "parser.h" |
8424cf50 FB |
24 | |
25 | AVCodecParser *av_first_parser = NULL; | |
26 | ||
55b9e69a MN |
27 | AVCodecParser* av_parser_next(AVCodecParser *p){ |
28 | if(p) return p->next; | |
29 | else return av_first_parser; | |
30 | } | |
31 | ||
8424cf50 FB |
32 | void av_register_codec_parser(AVCodecParser *parser) |
33 | { | |
34 | parser->next = av_first_parser; | |
35 | av_first_parser = parser; | |
36 | } | |
37 | ||
38 | AVCodecParserContext *av_parser_init(int codec_id) | |
39 | { | |
40 | AVCodecParserContext *s; | |
41 | AVCodecParser *parser; | |
42 | int ret; | |
115329f1 | 43 | |
8845e427 MN |
44 | if(codec_id == CODEC_ID_NONE) |
45 | return NULL; | |
8424cf50 FB |
46 | |
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 || | |
99f06236 MN |
50 | parser->codec_ids[2] == codec_id || |
51 | parser->codec_ids[3] == codec_id || | |
52 | parser->codec_ids[4] == codec_id) | |
8424cf50 FB |
53 | goto found; |
54 | } | |
55 | return NULL; | |
56 | found: | |
57 | s = av_mallocz(sizeof(AVCodecParserContext)); | |
58 | if (!s) | |
59 | return NULL; | |
60 | s->parser = parser; | |
61 | s->priv_data = av_mallocz(parser->priv_data_size); | |
62 | if (!s->priv_data) { | |
63 | av_free(s); | |
64 | return NULL; | |
65 | } | |
66 | if (parser->parser_init) { | |
67 | ret = parser->parser_init(s); | |
68 | if (ret != 0) { | |
69 | av_free(s->priv_data); | |
70 | av_free(s); | |
71 | return NULL; | |
72 | } | |
73 | } | |
a62aecce | 74 | s->fetch_timestamp=1; |
adcb72b5 | 75 | s->pict_type = FF_I_TYPE; |
8424cf50 FB |
76 | return s; |
77 | } | |
78 | ||
6ab312da MN |
79 | /** |
80 | * | |
81 | * @param buf input | |
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 | |
88 | * | |
89 | * Example: | |
90 | * @code | |
91 | * while(in_len){ | |
92 | * len = av_parser_parse(myparser, AVCodecContext, &data, &size, | |
93 | * in_data, in_len, | |
94 | * pts, dts); | |
95 | * in_data += len; | |
96 | * in_len -= len; | |
97 | * | |
832a7b63 MN |
98 | * if(size) |
99 | * decode_frame(data, size); | |
6ab312da MN |
100 | * } |
101 | * @endcode | |
102 | */ | |
115329f1 | 103 | int av_parser_parse(AVCodecParserContext *s, |
8424cf50 | 104 | AVCodecContext *avctx, |
115329f1 | 105 | uint8_t **poutbuf, int *poutbuf_size, |
b84f2a35 FB |
106 | const uint8_t *buf, int buf_size, |
107 | int64_t pts, int64_t dts) | |
8424cf50 | 108 | { |
b84f2a35 | 109 | int index, i, k; |
6e45e928 | 110 | uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
115329f1 | 111 | |
6e45e928 FB |
112 | if (buf_size == 0) { |
113 | /* padding is always necessary even if EOF, so we add it here */ | |
114 | memset(dummy_buf, 0, sizeof(dummy_buf)); | |
115 | buf = dummy_buf; | |
b84f2a35 FB |
116 | } else { |
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; | |
cb63a4b3 | 121 | s->cur_frame_end[k] = s->cur_offset + buf_size; |
b84f2a35 FB |
122 | s->cur_frame_pts[k] = pts; |
123 | s->cur_frame_dts[k] = dts; | |
cb63a4b3 | 124 | } |
b84f2a35 | 125 | |
591569b5 MN |
126 | if (s->fetch_timestamp){ |
127 | s->fetch_timestamp=0; | |
cb63a4b3 MN |
128 | s->last_pts = s->pts; |
129 | s->last_dts = s->dts; | |
130 | s->dts= s->pts= AV_NOPTS_VALUE; | |
131 | s->offset= 0; | |
132 | for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
26f23725 | 133 | if ( s->next_frame_offset >= s->cur_frame_offset[i] |
cb63a4b3 | 134 | &&(s-> frame_offset < s->cur_frame_offset[i] || !s->frame_offset) |
26f23725 | 135 | && s->next_frame_offset < s->cur_frame_end[i]){ |
cb63a4b3 MN |
136 | s->dts= s->cur_frame_dts[i]; |
137 | s->pts= s->cur_frame_pts[i]; | |
26f23725 | 138 | s->offset = s->next_frame_offset - s->cur_frame_offset[i]; |
cb63a4b3 | 139 | } |
b84f2a35 | 140 | } |
6e45e928 FB |
141 | } |
142 | ||
8424cf50 | 143 | /* WARNING: the returned index can be negative */ |
c53d2d90 | 144 | index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size); |
949b1a13 | 145 | //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); |
8424cf50 FB |
146 | /* update the file pointer */ |
147 | if (*poutbuf_size) { | |
b84f2a35 | 148 | /* fill the data for the current frame */ |
26f23725 | 149 | s->frame_offset = s->next_frame_offset; |
115329f1 | 150 | |
b84f2a35 | 151 | /* offset of the next frame */ |
26f23725 | 152 | s->next_frame_offset = s->cur_offset + index; |
591569b5 | 153 | s->fetch_timestamp=1; |
8424cf50 FB |
154 | } |
155 | if (index < 0) | |
156 | index = 0; | |
157 | s->cur_offset += index; | |
158 | return index; | |
159 | } | |
160 | ||
73480a15 MN |
161 | /** |
162 | * | |
163 | * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed | |
748c2fca | 164 | * @deprecated use AVBitstreamFilter |
73480a15 | 165 | */ |
90ad92b3 MN |
166 | int av_parser_change(AVCodecParserContext *s, |
167 | AVCodecContext *avctx, | |
115329f1 | 168 | uint8_t **poutbuf, int *poutbuf_size, |
90ad92b3 | 169 | const uint8_t *buf, int buf_size, int keyframe){ |
115329f1 | 170 | |
90ad92b3 | 171 | if(s && s->parser->split){ |
73480a15 | 172 | if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){ |
90ad92b3 MN |
173 | int i= s->parser->split(avctx, buf, buf_size); |
174 | buf += i; | |
175 | buf_size -= i; | |
176 | } | |
177 | } | |
178 | ||
79396ac6 MR |
179 | /* cast to avoid warning about discarding qualifiers */ |
180 | *poutbuf= (uint8_t *) buf; | |
90ad92b3 MN |
181 | *poutbuf_size= buf_size; |
182 | if(avctx->extradata){ | |
183 | if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) | |
9701840b | 184 | /*||(s->pict_type != FF_I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/ |
90ad92b3 MN |
185 | /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ |
186 | int size= buf_size + avctx->extradata_size; | |
187 | *poutbuf_size= size; | |
188 | *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); | |
115329f1 | 189 | |
90ad92b3 | 190 | memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); |
73480a15 | 191 | memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
90ad92b3 MN |
192 | return 1; |
193 | } | |
194 | } | |
195 | ||
196 | return 0; | |
197 | } | |
198 | ||
8424cf50 FB |
199 | void av_parser_close(AVCodecParserContext *s) |
200 | { | |
99c1c388 | 201 | if(s){ |
87b6ea84 MN |
202 | if (s->parser->parser_close) |
203 | s->parser->parser_close(s); | |
204 | av_free(s->priv_data); | |
205 | av_free(s); | |
99c1c388 | 206 | } |
8424cf50 FB |
207 | } |
208 | ||
209 | /*****************************************************/ | |
210 | ||
8424cf50 FB |
211 | /** |
212 | * combines the (truncated) bitstream to a complete frame | |
1f96bafb | 213 | * @returns -1 if no complete frame could be created, AVERROR(ENOMEM) if there was a memory allocation error |
8424cf50 | 214 | */ |
c53d2d90 | 215 | int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) |
8424cf50 FB |
216 | { |
217 | #if 0 | |
218 | if(pc->overread){ | |
219 | printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
220 | printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
221 | } | |
222 | #endif | |
223 | ||
e42dba48 | 224 | /* Copy overread bytes from last frame into buffer. */ |
8424cf50 FB |
225 | for(; pc->overread>0; pc->overread--){ |
226 | pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
227 | } | |
f48c0551 MN |
228 | |
229 | /* flush remaining if EOF */ | |
230 | if(!*buf_size && next == END_NOT_FOUND){ | |
231 | next= 0; | |
232 | } | |
233 | ||
8424cf50 FB |
234 | pc->last_index= pc->index; |
235 | ||
236 | /* copy into buffer end return */ | |
237 | if(next == END_NOT_FOUND){ | |
1f96bafb | 238 | void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); |
8424cf50 | 239 | |
1f96bafb AG |
240 | if(!new_buffer) |
241 | return AVERROR(ENOMEM); | |
242 | pc->buffer = new_buffer; | |
8424cf50 FB |
243 | memcpy(&pc->buffer[pc->index], *buf, *buf_size); |
244 | pc->index += *buf_size; | |
245 | return -1; | |
246 | } | |
247 | ||
248 | *buf_size= | |
249 | pc->overread_index= pc->index + next; | |
115329f1 | 250 | |
8424cf50 FB |
251 | /* append to buffer */ |
252 | if(pc->index){ | |
1f96bafb | 253 | void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); |
8424cf50 | 254 | |
1f96bafb AG |
255 | if(!new_buffer) |
256 | return AVERROR(ENOMEM); | |
257 | pc->buffer = new_buffer; | |
8424cf50 FB |
258 | memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); |
259 | pc->index = 0; | |
260 | *buf= pc->buffer; | |
261 | } | |
262 | ||
263 | /* store overread bytes */ | |
264 | for(;next < 0; next++){ | |
265 | pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
266 | pc->overread++; | |
267 | } | |
268 | ||
269 | #if 0 | |
270 | if(pc->overread){ | |
271 | printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
272 | printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
273 | } | |
274 | #endif | |
275 | ||
276 | return 0; | |
277 | } | |
278 | ||
e4cb187d | 279 | void ff_parse_close(AVCodecParserContext *s) |
8424cf50 | 280 | { |
e4cb187d | 281 | ParseContext *pc = s->priv_data; |
8424cf50 FB |
282 | |
283 | av_free(pc->buffer); | |
8424cf50 FB |
284 | } |
285 | ||
4067d81b | 286 | void ff_parse1_close(AVCodecParserContext *s) |
8424cf50 | 287 | { |
e4cb187d | 288 | ParseContext1 *pc1 = s->priv_data; |
8424cf50 | 289 | |
e4cb187d MN |
290 | av_free(pc1->pc.buffer); |
291 | av_free(pc1->enc); | |
8424cf50 FB |
292 | } |
293 | ||
e4cb187d MN |
294 | /*************************/ |
295 | ||
d136d2fc | 296 | int ff_mpeg4video_split(AVCodecContext *avctx, |
90ad92b3 MN |
297 | const uint8_t *buf, int buf_size) |
298 | { | |
299 | int i; | |
300 | uint32_t state= -1; | |
115329f1 | 301 | |
90ad92b3 MN |
302 | for(i=0; i<buf_size; i++){ |
303 | state= (state<<8) | buf[i]; | |
304 | if(state == 0x1B3 || state == 0x1B6) | |
73480a15 | 305 | return i-3; |
90ad92b3 MN |
306 | } |
307 | return 0; | |
308 | } |