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
27 #include "libavutil/avassert.h"
28 #include "libavutil/mem.h"
32 AVCodecParserContext
*av_parser_init(int codec_id
)
34 AVCodecParserContext
*s
= NULL
;
35 const AVCodecParser
*parser
;
39 if (codec_id
== AV_CODEC_ID_NONE
)
42 while ((parser
= av_parser_iterate(&i
))) {
43 if (parser
->codec_ids
[0] == codec_id
||
44 parser
->codec_ids
[1] == codec_id
||
45 parser
->codec_ids
[2] == codec_id
||
46 parser
->codec_ids
[3] == codec_id
||
47 parser
->codec_ids
[4] == codec_id
||
48 parser
->codec_ids
[5] == codec_id
||
49 parser
->codec_ids
[6] == codec_id
)
55 s
= av_mallocz(sizeof(AVCodecParserContext
));
59 s
->priv_data
= av_mallocz(parser
->priv_data_size
);
63 s
->pict_type
= AV_PICTURE_TYPE_I
;
64 if (parser
->parser_init
) {
65 ret
= parser
->parser_init(s
);
70 s
->dts_sync_point
= INT_MIN
;
71 s
->dts_ref_dts_delta
= INT_MIN
;
72 s
->pts_dts_delta
= INT_MIN
;
79 av_freep(&s
->priv_data
);
84 void ff_fetch_timestamp(AVCodecParserContext
*s
, int off
, int remove
, int fuzzy
)
90 s
->pts
= AV_NOPTS_VALUE
;
94 for (i
= 0; i
< AV_PARSER_PTS_NB
; i
++) {
95 if (s
->cur_offset
+ off
>= s
->cur_frame_offset
[i
] &&
96 (s
->frame_offset
< s
->cur_frame_offset
[i
] ||
97 (!s
->frame_offset
&& !s
->next_frame_offset
)) && // first field/frame
98 // check disabled since MPEG-TS does not send complete PES packets
99 /*s->next_frame_offset + off <*/ s
->cur_frame_end
[i
]){
101 if (!fuzzy
|| s
->cur_frame_dts
[i
] != AV_NOPTS_VALUE
) {
102 s
->dts
= s
->cur_frame_dts
[i
];
103 s
->pts
= s
->cur_frame_pts
[i
];
104 s
->pos
= s
->cur_frame_pos
[i
];
105 s
->offset
= s
->next_frame_offset
- s
->cur_frame_offset
[i
];
108 s
->cur_frame_offset
[i
] = INT64_MAX
;
109 if (s
->cur_offset
+ off
< s
->cur_frame_end
[i
])
115 int av_parser_parse2(AVCodecParserContext
*s
, AVCodecContext
*avctx
,
116 uint8_t **poutbuf
, int *poutbuf_size
,
117 const uint8_t *buf
, int buf_size
,
118 int64_t pts
, int64_t dts
, int64_t pos
)
121 uint8_t dummy_buf
[AV_INPUT_BUFFER_PADDING_SIZE
];
123 av_assert1(avctx
->codec_id
!= AV_CODEC_ID_NONE
);
125 /* Parsers only work for the specified codec ids. */
126 av_assert1(avctx
->codec_id
== s
->parser
->codec_ids
[0] ||
127 avctx
->codec_id
== s
->parser
->codec_ids
[1] ||
128 avctx
->codec_id
== s
->parser
->codec_ids
[2] ||
129 avctx
->codec_id
== s
->parser
->codec_ids
[3] ||
130 avctx
->codec_id
== s
->parser
->codec_ids
[4] ||
131 avctx
->codec_id
== s
->parser
->codec_ids
[5] ||
132 avctx
->codec_id
== s
->parser
->codec_ids
[6]);
134 if (!(s
->flags
& PARSER_FLAG_FETCHED_OFFSET
)) {
135 s
->next_frame_offset
=
137 s
->flags
|= PARSER_FLAG_FETCHED_OFFSET
;
141 /* padding is always necessary even if EOF, so we add it here */
142 memset(dummy_buf
, 0, sizeof(dummy_buf
));
144 } else if (s
->cur_offset
+ buf_size
!= s
->cur_frame_end
[s
->cur_frame_start_index
]) { /* skip remainder packets */
145 /* add a new packet descriptor */
146 i
= (s
->cur_frame_start_index
+ 1) & (AV_PARSER_PTS_NB
- 1);
147 s
->cur_frame_start_index
= i
;
148 s
->cur_frame_offset
[i
] = s
->cur_offset
;
149 s
->cur_frame_end
[i
] = s
->cur_offset
+ buf_size
;
150 s
->cur_frame_pts
[i
] = pts
;
151 s
->cur_frame_dts
[i
] = dts
;
152 s
->cur_frame_pos
[i
] = pos
;
155 if (s
->fetch_timestamp
) {
156 s
->fetch_timestamp
= 0;
157 s
->last_pts
= s
->pts
;
158 s
->last_dts
= s
->dts
;
159 s
->last_pos
= s
->pos
;
160 ff_fetch_timestamp(s
, 0, 0, 0);
162 /* WARNING: the returned index can be negative */
163 index
= s
->parser
->parser_parse(s
, avctx
, (const uint8_t **) poutbuf
,
164 poutbuf_size
, buf
, buf_size
);
165 av_assert0(index
> -0x20000000); // The API does not allow returning AVERROR codes
166 #define FILL(name) if(s->name > 0 && avctx->name <= 0) avctx->name = s->name
167 if (avctx
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
175 /* update the file pointer */
177 /* fill the data for the current frame */
178 s
->frame_offset
= s
->next_frame_offset
;
180 /* offset of the next frame */
181 s
->next_frame_offset
= s
->cur_offset
+ index
;
182 s
->fetch_timestamp
= 1;
184 /* Don't return a pointer to dummy_buf. */
189 s
->cur_offset
+= index
;
193 void av_parser_close(AVCodecParserContext
*s
)
196 if (s
->parser
->parser_close
)
197 s
->parser
->parser_close(s
);
198 av_freep(&s
->priv_data
);
203 int ff_combine_frame(ParseContext
*pc
, int next
,
204 const uint8_t **buf
, int *buf_size
)
207 ff_dlog(NULL
, "overread %d, state:%"PRIX32
" next:%d index:%d o_index:%d\n",
208 pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
209 ff_dlog(NULL
, "%X %X %X %X\n",
210 (*buf
)[0], (*buf
)[1], (*buf
)[2], (*buf
)[3]);
213 /* Copy overread bytes from last frame into buffer. */
214 for (; pc
->overread
> 0; pc
->overread
--)
215 pc
->buffer
[pc
->index
++] = pc
->buffer
[pc
->overread_index
++];
217 if (next
> *buf_size
)
218 return AVERROR(EINVAL
);
220 /* flush remaining if EOF */
221 if (!*buf_size
&& next
== END_NOT_FOUND
)
224 pc
->last_index
= pc
->index
;
226 /* copy into buffer end return */
227 if (next
== END_NOT_FOUND
) {
228 void *new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
,
229 *buf_size
+ pc
->index
+
230 AV_INPUT_BUFFER_PADDING_SIZE
);
233 av_log(NULL
, AV_LOG_ERROR
, "Failed to reallocate parser buffer to %d\n", *buf_size
+ pc
->index
+ AV_INPUT_BUFFER_PADDING_SIZE
);
235 return AVERROR(ENOMEM
);
237 pc
->buffer
= new_buffer
;
238 memcpy(&pc
->buffer
[pc
->index
], *buf
, *buf_size
);
239 memset(&pc
->buffer
[pc
->index
+ *buf_size
], 0, AV_INPUT_BUFFER_PADDING_SIZE
);
240 pc
->index
+= *buf_size
;
244 av_assert0(next
>= 0 || pc
->buffer
);
247 pc
->overread_index
= pc
->index
+ next
;
249 /* append to buffer */
251 void *new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
,
253 AV_INPUT_BUFFER_PADDING_SIZE
);
255 av_log(NULL
, AV_LOG_ERROR
, "Failed to reallocate parser buffer to %d\n", next
+ pc
->index
+ AV_INPUT_BUFFER_PADDING_SIZE
);
259 return AVERROR(ENOMEM
);
261 pc
->buffer
= new_buffer
;
262 if (next
> -AV_INPUT_BUFFER_PADDING_SIZE
)
263 memcpy(&pc
->buffer
[pc
->index
], *buf
,
264 next
+ AV_INPUT_BUFFER_PADDING_SIZE
);
270 pc
->overread
+= -8 - next
;
273 /* store overread bytes */
274 for (; next
< 0; next
++) {
275 pc
->state
= pc
->state
<< 8 | pc
->buffer
[pc
->last_index
+ next
];
276 pc
->state64
= pc
->state64
<< 8 | pc
->buffer
[pc
->last_index
+ next
];
281 ff_dlog(NULL
, "overread %d, state:%"PRIX32
" next:%d index:%d o_index:%d\n",
282 pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
283 ff_dlog(NULL
, "%X %X %X %X\n",
284 (*buf
)[0], (*buf
)[1], (*buf
)[2], (*buf
)[3]);
290 void ff_parse_close(AVCodecParserContext
*s
)
292 ParseContext
*pc
= s
->priv_data
;
294 av_freep(&pc
->buffer
);