FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 FFmpeg.
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 #include <stdint.h>
24 #include <string.h>
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/atomic.h"
28 #include "libavutil/mem.h"
29 
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  do {
45  parser->next = av_first_parser;
46  } while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));
47 }
48 
50 {
51  AVCodecParserContext *s = NULL;
52  AVCodecParser *parser;
53  int ret;
54 
55  if (codec_id == AV_CODEC_ID_NONE)
56  return NULL;
57 
58  for (parser = av_first_parser; parser; parser = parser->next) {
59  if (parser->codec_ids[0] == codec_id ||
60  parser->codec_ids[1] == codec_id ||
61  parser->codec_ids[2] == codec_id ||
62  parser->codec_ids[3] == codec_id ||
63  parser->codec_ids[4] == codec_id)
64  goto found;
65  }
66  return NULL;
67 
68 found:
69  s = av_mallocz(sizeof(AVCodecParserContext));
70  if (!s)
71  goto err_out;
72  s->parser = parser;
73  s->priv_data = av_mallocz(parser->priv_data_size);
74  if (!s->priv_data)
75  goto err_out;
76  s->fetch_timestamp=1;
78  if (parser->parser_init) {
79  ret = parser->parser_init(s);
80  if (ret != 0)
81  goto err_out;
82  }
83  s->key_frame = -1;
84  s->convergence_duration = 0;
85  s->dts_sync_point = INT_MIN;
86  s->dts_ref_dts_delta = INT_MIN;
87  s->pts_dts_delta = INT_MIN;
88  return s;
89 
90 err_out:
91  if (s)
92  av_freep(&s->priv_data);
93  av_free(s);
94  return NULL;
95 }
96 
97 void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove, int fuzzy)
98 {
99  int i;
100 
101  if (!fuzzy) {
102  s->dts =
103  s->pts = AV_NOPTS_VALUE;
104  s->pos = -1;
105  s->offset = 0;
106  }
107  for (i = 0; i < AV_PARSER_PTS_NB; i++) {
108  if (s->cur_offset + off >= s->cur_frame_offset[i] &&
109  (s->frame_offset < s->cur_frame_offset[i] ||
110  (!s->frame_offset && !s->next_frame_offset)) && // first field/frame
111  // check disabled since MPEG-TS does not send complete PES packets
112  /*s->next_frame_offset + off <*/ s->cur_frame_end[i]){
113 
114  if (!fuzzy || s->cur_frame_dts[i] != AV_NOPTS_VALUE) {
115  s->dts = s->cur_frame_dts[i];
116  s->pts = s->cur_frame_pts[i];
117  s->pos = s->cur_frame_pos[i];
118  s->offset = s->next_frame_offset - s->cur_frame_offset[i];
119  }
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, 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  av_assert0(index > -0x20000000); // The API does not allow returning AVERROR codes
168  /* update the file pointer */
169  if (*poutbuf_size) {
170  /* fill the data for the current frame */
172 
173  /* offset of the next frame */
175  s->fetch_timestamp = 1;
176  }
177  if (index < 0)
178  index = 0;
179  s->cur_offset += index;
180  return index;
181 }
182 
184  uint8_t **poutbuf, int *poutbuf_size,
185  const uint8_t *buf, int buf_size, int keyframe)
186 {
187  if (s && s->parser->split) {
188  if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER ||
189  avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) {
190  int i = s->parser->split(avctx, buf, buf_size);
191  buf += i;
192  buf_size -= i;
193  }
194  }
195 
196  /* cast to avoid warning about discarding qualifiers */
197  *poutbuf = (uint8_t *) buf;
198  *poutbuf_size = buf_size;
199  if (avctx->extradata) {
200  if (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) {
201  int size = buf_size + avctx->extradata_size;
202 
203  *poutbuf_size = size;
204  *poutbuf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
205  if (!*poutbuf)
206  return AVERROR(ENOMEM);
207 
208  memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
209  memcpy(*poutbuf + avctx->extradata_size, buf,
210  buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
211  return 1;
212  }
213  }
214 
215  return 0;
216 }
217 
219 {
220  if (s) {
221  if (s->parser->parser_close)
222  s->parser->parser_close(s);
223  av_freep(&s->priv_data);
224  av_free(s);
225  }
226 }
227 
228 int ff_combine_frame(ParseContext *pc, int next,
229  const uint8_t **buf, int *buf_size)
230 {
231  if (pc->overread) {
232  av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
233  pc->overread, pc->state, next, pc->index, pc->overread_index);
234  av_dlog(NULL, "%X %X %X %X\n",
235  (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
236  }
237 
238  /* Copy overread bytes from last frame into buffer. */
239  for (; pc->overread > 0; pc->overread--)
240  pc->buffer[pc->index++] = pc->buffer[pc->overread_index++];
241 
242  /* flush remaining if EOF */
243  if (!*buf_size && next == END_NOT_FOUND)
244  next = 0;
245 
246  pc->last_index = pc->index;
247 
248  /* copy into buffer end return */
249  if (next == END_NOT_FOUND) {
250  void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
251  *buf_size + pc->index +
253 
254  if (!new_buffer) {
255  pc->index = 0;
256  return AVERROR(ENOMEM);
257  }
258  pc->buffer = new_buffer;
259  memcpy(&pc->buffer[pc->index], *buf, *buf_size);
260  pc->index += *buf_size;
261  return -1;
262  }
263 
264  *buf_size =
265  pc->overread_index = pc->index + next;
266 
267  /* append to buffer */
268  if (pc->index) {
269  void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
270  next + pc->index +
272  if (!new_buffer) {
273  pc->overread_index =
274  pc->index = 0;
275  return AVERROR(ENOMEM);
276  }
277  pc->buffer = new_buffer;
278  if (next > -FF_INPUT_BUFFER_PADDING_SIZE)
279  memcpy(&pc->buffer[pc->index], *buf,
281  pc->index = 0;
282  *buf = pc->buffer;
283  }
284 
285  /* store overread bytes */
286  for (; next < 0; next++) {
287  pc->state = pc->state << 8 | pc->buffer[pc->last_index + next];
288  pc->state64 = pc->state64 << 8 | pc->buffer[pc->last_index + next];
289  pc->overread++;
290  }
291 
292  if (pc->overread) {
293  av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
294  pc->overread, pc->state, next, pc->index, pc->overread_index);
295  av_dlog(NULL, "%X %X %X %X\n",
296  (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
297  }
298 
299  return 0;
300 }
301 
303 {
304  ParseContext *pc = s->priv_data;
305 
306  av_freep(&pc->buffer);
307 }
308 
309 int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
310 {
311  int i;
312  uint32_t state = -1;
313 
314  for (i = 0; i < buf_size; i++) {
315  state = state << 8 | buf[i];
316  if (state == 0x1B3 || state == 0x1B6)
317  return i - 3;
318  }
319  return 0;
320 }