Libav
parser.c
Go to the documentation of this file.
1 /*
2  * Audio and Video frame extraction
3  * Copyright (c) 2003 Fabrice Bellard
4  * Copyright (c) 2003 Michael Niedermayer
5  *
6  * This file is part of Libav.
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 #include <stdint.h>
24 #include <string.h>
25 
26 #include "libavutil/internal.h"
27 #include "libavutil/mem.h"
28 
29 #include "internal.h"
30 #include "parser.h"
31 
33 
35 {
36  if (p)
37  return p->next;
38  else
39  return av_first_parser;
40 }
41 
43 {
44  parser->next = av_first_parser;
45  av_first_parser = parser;
46 }
47 
49 {
51  AVCodecParser *parser;
52  int ret;
53 
54  if (codec_id == AV_CODEC_ID_NONE)
55  return NULL;
56 
57  for (parser = av_first_parser; parser != NULL; 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)
63  goto found;
64  }
65  return NULL;
66 
67 found:
68  s = av_mallocz(sizeof(AVCodecParserContext));
69  if (!s)
70  return NULL;
71  s->parser = parser;
72  if (parser->priv_data_size) {
73  s->priv_data = av_mallocz(parser->priv_data_size);
74  if (!s->priv_data) {
75  av_free(s);
76  return NULL;
77  }
78  }
79  if (parser->parser_init) {
80  ret = parser->parser_init(s);
81  if (ret != 0) {
82  av_free(s->priv_data);
83  av_free(s);
84  return NULL;
85  }
86  }
87  s->fetch_timestamp = 1;
89  s->key_frame = -1;
90 #if FF_API_CONVERGENCE_DURATION
92  s->convergence_duration = 0;
94 #endif
95  s->dts_sync_point = INT_MIN;
96  s->dts_ref_dts_delta = INT_MIN;
97  s->pts_dts_delta = INT_MIN;
98  s->format = -1;
99 
100  return s;
101 }
102 
103 void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove)
104 {
105  int i;
106 
107  s->dts =
108  s->pts = AV_NOPTS_VALUE;
109  s->pos = -1;
110  s->offset = 0;
111  for (i = 0; i < AV_PARSER_PTS_NB; i++) {
112  if (s->cur_offset + off >= s->cur_frame_offset[i] &&
113  (s->frame_offset < s->cur_frame_offset[i] ||
114  (!s->frame_offset && !s->next_frame_offset)) &&
115  s->cur_frame_end[i]) {
116  s->dts = s->cur_frame_dts[i];
117  s->pts = s->cur_frame_pts[i];
118  s->pos = s->cur_frame_pos[i];
119  s->offset = s->next_frame_offset - s->cur_frame_offset[i];
120  if (remove)
121  s->cur_frame_offset[i] = INT64_MAX;
122  if (s->cur_offset + off < s->cur_frame_end[i])
123  break;
124  }
125  }
126 }
127 
129  uint8_t **poutbuf, int *poutbuf_size,
130  const uint8_t *buf, int buf_size,
131  int64_t pts, int64_t dts, int64_t pos)
132 {
133  int index, i;
135 
136  if (!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) {
137  s->next_frame_offset =
138  s->cur_offset = pos;
140  }
141 
142  if (buf_size == 0) {
143  /* padding is always necessary even if EOF, so we add it here */
144  memset(dummy_buf, 0, sizeof(dummy_buf));
145  buf = dummy_buf;
146  } else if (s->cur_offset + buf_size != s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */
147  /* add a new packet descriptor */
148  i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
149  s->cur_frame_start_index = i;
150  s->cur_frame_offset[i] = s->cur_offset;
151  s->cur_frame_end[i] = s->cur_offset + buf_size;
152  s->cur_frame_pts[i] = pts;
153  s->cur_frame_dts[i] = dts;
154  s->cur_frame_pos[i] = pos;
155  }
156 
157  if (s->fetch_timestamp) {
158  s->fetch_timestamp = 0;
159  s->last_pts = s->pts;
160  s->last_dts = s->dts;
161  s->last_pos = s->pos;
162  ff_fetch_timestamp(s, 0, 0);
163  }
164  /* WARNING: the returned index can be negative */
165  index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf,
166  poutbuf_size, buf, buf_size);
167  /* update the file pointer */
168  if (*poutbuf_size) {
169  /* fill the data for the current frame */
171 
172  /* offset of the next frame */
174  s->fetch_timestamp = 1;
175  }
176  if (index < 0)
177  index = 0;
178  s->cur_offset += index;
179  return index;
180 }
181 
183  uint8_t **poutbuf, int *poutbuf_size,
184  const uint8_t *buf, int buf_size, int keyframe)
185 {
186  if (s && s->parser->split) {
187  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER ||
189  int i = s->parser->split(avctx, buf, buf_size);
190  buf += i;
191  buf_size -= i;
192  }
193  }
194 
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 & AV_CODEC_FLAG2_LOCAL_HEADER)) {
200  int size = buf_size + avctx->extradata_size;
201 
202  *poutbuf_size = size;
203  *poutbuf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
204  if (!*poutbuf)
205  return AVERROR(ENOMEM);
206 
207  memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
208  memcpy(*poutbuf + avctx->extradata_size, buf,
209  buf_size + AV_INPUT_BUFFER_PADDING_SIZE);
210  return 1;
211  }
212  }
213 
214  return 0;
215 }
216 
218 {
219  if (s) {
220  if (s->parser->parser_close)
221  s->parser->parser_close(s);
222  av_free(s->priv_data);
223  av_free(s);
224  }
225 }
226 
227 int ff_combine_frame(ParseContext *pc, int next,
228  const uint8_t **buf, int *buf_size)
229 {
230  if (pc->overread) {
231  ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
232  pc->overread, pc->state, next, pc->index, pc->overread_index);
233  ff_dlog(NULL, "%X %X %X %X\n",
234  (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
235  }
236 
237  /* Copy overread bytes from last frame into buffer. */
238  for (; pc->overread > 0; pc->overread--)
239  pc->buffer[pc->index++] = pc->buffer[pc->overread_index++];
240 
241  /* flush remaining if EOF */
242  if (!*buf_size && next == END_NOT_FOUND)
243  next = 0;
244 
245  pc->last_index = pc->index;
246 
247  /* copy into buffer end return */
248  if (next == END_NOT_FOUND) {
249  void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
250  *buf_size + pc->index +
252 
253  if (!new_buffer)
254  return AVERROR(ENOMEM);
255  pc->buffer = new_buffer;
256  memcpy(&pc->buffer[pc->index], *buf, *buf_size);
257  pc->index += *buf_size;
258  return -1;
259  }
260 
261  *buf_size =
262  pc->overread_index = pc->index + next;
263 
264  /* append to buffer */
265  if (pc->index) {
266  void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
267  next + pc->index +
269 
270  if (!new_buffer)
271  return AVERROR(ENOMEM);
272  pc->buffer = new_buffer;
273  if (next > -AV_INPUT_BUFFER_PADDING_SIZE)
274  memcpy(&pc->buffer[pc->index], *buf,
276  pc->index = 0;
277  *buf = pc->buffer;
278  }
279 
280  /* store overread bytes */
281  for (; next < 0; next++) {
282  pc->state = pc->state << 8 | pc->buffer[pc->last_index + next];
283  pc->state64 = pc->state64 << 8 | pc->buffer[pc->last_index + next];
284  pc->overread++;
285  }
286 
287  if (pc->overread) {
288  ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
289  pc->overread, pc->state, next, pc->index, pc->overread_index);
290  ff_dlog(NULL, "%X %X %X %X\n",
291  (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
292  }
293 
294  return 0;
295 }
296 
298 {
299  ParseContext *pc = s->priv_data;
300 
301  av_freep(&pc->buffer);
302 }
303 
304 int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
305 {
306  int i;
307  uint32_t state = -1;
308 
309  for (i = 0; i < buf_size; i++) {
310  state = state << 8 | buf[i];
311  if (state == 0x1B3 || state == 0x1B6)
312  return i - 3;
313  }
314  return 0;
315 }
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
int size
void(* parser_close)(AVCodecParserContext *s)
Definition: avcodec.h:4538
memory handling functions
int64_t next_frame_offset
Definition: avcodec.h:4368
int codec_ids[5]
Definition: avcodec.h:4529
int(* split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: avcodec.h:4539
int64_t cur_frame_pos[AV_PARSER_PTS_NB]
Position of the packet in file.
Definition: avcodec.h:4466
int dts_ref_dts_delta
Offset of the current timestamp against last timestamp sync point in units of AVCodecContext.time_base.
Definition: avcodec.h:4445
int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: parser.c:304
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:202
uint8_t
int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe)
Definition: parser.c:182
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1523
struct AVCodecParser * next
Definition: avcodec.h:4540
void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove)
Fetch timestamps for a specific byte within the current access unit.
Definition: parser.c:103
unsigned int buffer_size
Definition: parser.h:32
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:190
int64_t pos
Byte position of currently parsed frame in stream.
Definition: avcodec.h:4471
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
Definition: mem.c:375
int priv_data_size
Definition: avcodec.h:4530
struct AVCodecParser * parser
Definition: avcodec.h:4364
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
Combine the (truncated) bitstream to a complete frame.
Definition: parser.c:227
#define AVERROR(e)
Definition: error.h:43
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1503
int overread_index
the index into ParseContext.buffer of the overread bytes
Definition: parser.h:36
int64_t cur_frame_dts[AV_PARSER_PTS_NB]
Definition: avcodec.h:4393
int(* parser_parse)(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: avcodec.h:4534
AVCodecParser * av_parser_next(const AVCodecParser *p)
Definition: parser.c:34
void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:297
common internal API header
int overread
the number of bytes which where irreversibly read from the next frame
Definition: parser.h:35
int last_index
Definition: parser.h:31
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos)
Parse a packet.
Definition: parser.c:128
enum AVCodecID codec_id
Definition: avconv_vaapi.c:149
int64_t offset
byte offset from starting packet start
Definition: avcodec.h:4401
void av_parser_close(AVCodecParserContext *s)
Definition: parser.c:217
int64_t cur_frame_end[AV_PARSER_PTS_NB]
Definition: avcodec.h:4402
int64_t cur_frame_pts[AV_PARSER_PTS_NB]
Definition: avcodec.h:4392
int64_t last_pos
Previous frame byte position.
Definition: avcodec.h:4476
if(ac->has_optimized_func)
int pts_dts_delta
Presentation delay of current frame in units of AVCodecContext.time_base.
Definition: avcodec.h:4459
NULL
Definition: eval.c:55
AVCodecParserContext * av_parser_init(int codec_id)
Definition: parser.c:48
uint8_t * buffer
Definition: parser.h:29
#define ff_dlog(ctx,...)
Definition: internal.h:60
main external API structure.
Definition: avcodec.h:1409
#define AV_CODEC_FLAG2_LOCAL_HEADER
Place global headers at every keyframe instead of in extradata.
Definition: avcodec.h:811
#define PARSER_FLAG_FETCHED_OFFSET
Set if the parser has a valid file offset.
Definition: avcodec.h:4399
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
int extradata_size
Definition: avcodec.h:1524
int index
Definition: gxfenc.c:72
uint64_t state64
contains the last 8 bytes in MSB order
Definition: parser.h:37
void av_register_codec_parser(AVCodecParser *parser)
Definition: parser.c:42
static AVCodecParser * av_first_parser
Definition: parser.c:32
#define END_NOT_FOUND
Definition: parser.h:40
#define AV_PARSER_PTS_NB
Definition: avcodec.h:4389
int(* parser_init)(AVCodecParserContext *s)
Definition: avcodec.h:4531
attribute_deprecated int64_t convergence_duration
Definition: avcodec.h:4417
static int64_t pts
Global timestamp for the audio frames.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:784
static struct @174 state
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:77
common internal api header.
int index
Definition: parser.h:30
int64_t cur_frame_offset[AV_PARSER_PTS_NB]
Definition: avcodec.h:4391
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:638
int64_t frame_offset
Definition: avcodec.h:4365
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:78
int format
The format of the coded data, corresponds to enum AVPixelFormat for video and for enum AVSampleFormat...
Definition: avcodec.h:4525
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:1510
int key_frame
Set by parser to 1 for key frames and 0 for non-key frames.
Definition: avcodec.h:4410
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:211
int dts_sync_point
Synchronization point for start of timestamp generation.
Definition: avcodec.h:4430
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:235