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
26 #include "libavutil/atomic.h"
27 #include "libavutil/mem.h"
31 static AVCodecParser
*av_first_parser
= NULL
;
33 AVCodecParser
*av_parser_next(const AVCodecParser
*p
)
38 return av_first_parser
;
41 void av_register_codec_parser(AVCodecParser
*parser
)
44 parser
->next
= av_first_parser
;
45 } while (parser
->next
!= avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser
, parser
->next
, parser
));
48 AVCodecParserContext
*av_parser_init(int codec_id
)
50 AVCodecParserContext
*s
= NULL
;
51 AVCodecParser
*parser
;
54 if (codec_id
== AV_CODEC_ID_NONE
)
57 for (parser
= av_first_parser
; parser
; parser
= parser
->next
) {
58 if (parser
->codec_ids
[0] == codec_id
||
59 parser
->codec_ids
[1] == codec_id
||
60 parser
->codec_ids
[2] == codec_id
||
61 parser
->codec_ids
[3] == codec_id
||
62 parser
->codec_ids
[4] == codec_id
)
68 s
= av_mallocz(sizeof(AVCodecParserContext
));
72 s
->priv_data
= av_mallocz(parser
->priv_data_size
);
76 s
->pict_type
= AV_PICTURE_TYPE_I
;
77 if (parser
->parser_init
) {
78 ret
= parser
->parser_init(s
);
83 s
->convergence_duration
= 0;
84 s
->dts_sync_point
= INT_MIN
;
85 s
->dts_ref_dts_delta
= INT_MIN
;
86 s
->pts_dts_delta
= INT_MIN
;
91 av_freep(&s
->priv_data
);
96 void ff_fetch_timestamp(AVCodecParserContext
*s
, int off
, int remove
)
101 s
->pts
= AV_NOPTS_VALUE
;
104 for (i
= 0; i
< AV_PARSER_PTS_NB
; i
++) {
105 if (s
->cur_offset
+ off
>= s
->cur_frame_offset
[i
] &&
106 (s
->frame_offset
< s
->cur_frame_offset
[i
] ||
107 (!s
->frame_offset
&& !s
->next_frame_offset
)) && // first field/frame
108 // check disabled since MPEG-TS does not send complete PES packets
109 /*s->next_frame_offset + off <*/ s
->cur_frame_end
[i
]){
111 s
->dts
= s
->cur_frame_dts
[i
];
112 s
->pts
= s
->cur_frame_pts
[i
];
113 s
->pos
= s
->cur_frame_pos
[i
];
114 s
->offset
= s
->next_frame_offset
- s
->cur_frame_offset
[i
];
116 s
->cur_frame_offset
[i
] = INT64_MAX
;
117 if (s
->cur_offset
+ off
< s
->cur_frame_end
[i
])
123 int av_parser_parse2(AVCodecParserContext
*s
, AVCodecContext
*avctx
,
124 uint8_t **poutbuf
, int *poutbuf_size
,
125 const uint8_t *buf
, int buf_size
,
126 int64_t pts
, int64_t dts
, int64_t pos
)
129 uint8_t dummy_buf
[FF_INPUT_BUFFER_PADDING_SIZE
];
131 if (!(s
->flags
& PARSER_FLAG_FETCHED_OFFSET
)) {
132 s
->next_frame_offset
=
134 s
->flags
|= PARSER_FLAG_FETCHED_OFFSET
;
138 /* padding is always necessary even if EOF, so we add it here */
139 memset(dummy_buf
, 0, sizeof(dummy_buf
));
141 } else if (s
->cur_offset
+ buf_size
!= s
->cur_frame_end
[s
->cur_frame_start_index
]) { /* skip remainder packets */
142 /* add a new packet descriptor */
143 i
= (s
->cur_frame_start_index
+ 1) & (AV_PARSER_PTS_NB
- 1);
144 s
->cur_frame_start_index
= i
;
145 s
->cur_frame_offset
[i
] = s
->cur_offset
;
146 s
->cur_frame_end
[i
] = s
->cur_offset
+ buf_size
;
147 s
->cur_frame_pts
[i
] = pts
;
148 s
->cur_frame_dts
[i
] = dts
;
149 s
->cur_frame_pos
[i
] = pos
;
152 if (s
->fetch_timestamp
) {
153 s
->fetch_timestamp
= 0;
154 s
->last_pts
= s
->pts
;
155 s
->last_dts
= s
->dts
;
156 s
->last_pos
= s
->pos
;
157 ff_fetch_timestamp(s
, 0, 0);
159 /* WARNING: the returned index can be negative */
160 index
= s
->parser
->parser_parse(s
, avctx
, (const uint8_t **) poutbuf
,
161 poutbuf_size
, buf
, buf_size
);
162 /* update the file pointer */
164 /* fill the data for the current frame */
165 s
->frame_offset
= s
->next_frame_offset
;
167 /* offset of the next frame */
168 s
->next_frame_offset
= s
->cur_offset
+ index
;
169 s
->fetch_timestamp
= 1;
173 s
->cur_offset
+= index
;
177 int av_parser_change(AVCodecParserContext
*s
, AVCodecContext
*avctx
,
178 uint8_t **poutbuf
, int *poutbuf_size
,
179 const uint8_t *buf
, int buf_size
, int keyframe
)
181 if (s
&& s
->parser
->split
) {
182 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
||
183 avctx
->flags2
& CODEC_FLAG2_LOCAL_HEADER
) {
184 int i
= s
->parser
->split(avctx
, buf
, buf_size
);
190 /* cast to avoid warning about discarding qualifiers */
191 *poutbuf
= (uint8_t *) buf
;
192 *poutbuf_size
= buf_size
;
193 if (avctx
->extradata
) {
194 if (keyframe
&& (avctx
->flags2
& CODEC_FLAG2_LOCAL_HEADER
)) {
195 int size
= buf_size
+ avctx
->extradata_size
;
197 *poutbuf_size
= size
;
198 *poutbuf
= av_malloc(size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
200 memcpy(*poutbuf
, avctx
->extradata
, avctx
->extradata_size
);
201 memcpy(*poutbuf
+ avctx
->extradata_size
, buf
,
202 buf_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
210 void av_parser_close(AVCodecParserContext
*s
)
213 if (s
->parser
->parser_close
)
214 s
->parser
->parser_close(s
);
215 av_freep(&s
->priv_data
);
220 int ff_combine_frame(ParseContext
*pc
, int next
,
221 const uint8_t **buf
, int *buf_size
)
224 av_dlog(NULL
, "overread %d, state:%X next:%d index:%d o_index:%d\n",
225 pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
226 av_dlog(NULL
, "%X %X %X %X\n",
227 (*buf
)[0], (*buf
)[1], (*buf
)[2], (*buf
)[3]);
230 /* Copy overread bytes from last frame into buffer. */
231 for (; pc
->overread
> 0; pc
->overread
--)
232 pc
->buffer
[pc
->index
++] = pc
->buffer
[pc
->overread_index
++];
234 /* flush remaining if EOF */
235 if (!*buf_size
&& next
== END_NOT_FOUND
)
238 pc
->last_index
= pc
->index
;
240 /* copy into buffer end return */
241 if (next
== END_NOT_FOUND
) {
242 void *new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
,
243 *buf_size
+ pc
->index
+
244 FF_INPUT_BUFFER_PADDING_SIZE
);
248 return AVERROR(ENOMEM
);
250 pc
->buffer
= new_buffer
;
251 memcpy(&pc
->buffer
[pc
->index
], *buf
, *buf_size
);
252 pc
->index
+= *buf_size
;
257 pc
->overread_index
= pc
->index
+ next
;
259 /* append to buffer */
261 void *new_buffer
= av_fast_realloc(pc
->buffer
, &pc
->buffer_size
,
263 FF_INPUT_BUFFER_PADDING_SIZE
);
267 return AVERROR(ENOMEM
);
269 pc
->buffer
= new_buffer
;
270 if (next
> -FF_INPUT_BUFFER_PADDING_SIZE
)
271 memcpy(&pc
->buffer
[pc
->index
], *buf
,
272 next
+ FF_INPUT_BUFFER_PADDING_SIZE
);
277 /* store overread bytes */
278 for (; next
< 0; next
++) {
279 pc
->state
= pc
->state
<< 8 | pc
->buffer
[pc
->last_index
+ next
];
280 pc
->state64
= pc
->state64
<< 8 | pc
->buffer
[pc
->last_index
+ next
];
285 av_dlog(NULL
, "overread %d, state:%X next:%d index:%d o_index:%d\n",
286 pc
->overread
, pc
->state
, next
, pc
->index
, pc
->overread_index
);
287 av_dlog(NULL
, "%X %X %X %X\n",
288 (*buf
)[0], (*buf
)[1], (*buf
)[2], (*buf
)[3]);
294 void ff_parse_close(AVCodecParserContext
*s
)
296 ParseContext
*pc
= s
->priv_data
;
298 av_freep(&pc
->buffer
);
301 int ff_mpeg4video_split(AVCodecContext
*avctx
, const uint8_t *buf
, int buf_size
)
306 for (i
= 0; i
< buf_size
; i
++) {
307 state
= state
<< 8 | buf
[i
];
308 if (state
== 0x1B3 || state
== 0x1B6)