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 <string.h>
24 
25 #include "parser.h"
26 #include "libavutil/mem.h"
27 
29 
31  if(p) return p->next;
32  else return av_first_parser;
33 }
34 
36 {
37  parser->next = av_first_parser;
38  av_first_parser = parser;
39 }
40 
42 {
44  AVCodecParser *parser;
45  int ret;
46 
47  if(codec_id == AV_CODEC_ID_NONE)
48  return NULL;
49 
50  for(parser = av_first_parser; parser != NULL; parser = parser->next) {
51  if (parser->codec_ids[0] == codec_id ||
52  parser->codec_ids[1] == codec_id ||
53  parser->codec_ids[2] == codec_id ||
54  parser->codec_ids[3] == codec_id ||
55  parser->codec_ids[4] == codec_id)
56  goto found;
57  }
58  return NULL;
59  found:
60  s = av_mallocz(sizeof(AVCodecParserContext));
61  if (!s)
62  goto err_out;
63  s->parser = parser;
64  s->priv_data = av_mallocz(parser->priv_data_size);
65  if (!s->priv_data)
66  goto err_out;
67  s->fetch_timestamp=1;
69  if (parser->parser_init) {
70  ret = parser->parser_init(s);
71  if (ret != 0)
72  goto err_out;
73  }
74  s->key_frame = -1;
75  s->convergence_duration = 0;
76  s->dts_sync_point = INT_MIN;
77  s->dts_ref_dts_delta = INT_MIN;
78  s->pts_dts_delta = INT_MIN;
79  return s;
80 
81 err_out:
82  if (s)
83  av_freep(&s->priv_data);
84  av_free(s);
85  return NULL;
86 }
87 
88 void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove){
89  int i;
90 
91  s->dts= s->pts= AV_NOPTS_VALUE;
92  s->pos= -1;
93  s->offset= 0;
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]){
100  s->dts= s->cur_frame_dts[i];
101  s->pts= s->cur_frame_pts[i];
102  s->pos= s->cur_frame_pos[i];
104  if(remove)
105  s->cur_frame_offset[i]= INT64_MAX;
106  if(s->cur_offset + off < s->cur_frame_end[i])
107  break;
108  }
109  }
110 }
111 
113  AVCodecContext *avctx,
114  uint8_t **poutbuf, int *poutbuf_size,
115  const uint8_t *buf, int buf_size,
116  int64_t pts, int64_t dts,
117  int64_t pos)
118 {
119  int index, i;
121 
122  if(!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) {
123  s->next_frame_offset =
124  s->cur_offset = pos;
126  }
127 
128  if (buf_size == 0) {
129  /* padding is always necessary even if EOF, so we add it here */
130  memset(dummy_buf, 0, sizeof(dummy_buf));
131  buf = dummy_buf;
132  } else if (s->cur_offset + buf_size !=
133  s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */
134  /* add a new packet descriptor */
135  i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
137  s->cur_frame_offset[i] = s->cur_offset;
138  s->cur_frame_end[i] = s->cur_offset + buf_size;
139  s->cur_frame_pts[i] = pts;
140  s->cur_frame_dts[i] = dts;
141  s->cur_frame_pos[i] = pos;
142  }
143 
144  if (s->fetch_timestamp){
145  s->fetch_timestamp=0;
146  s->last_pts = s->pts;
147  s->last_dts = s->dts;
148  s->last_pos = s->pos;
149  ff_fetch_timestamp(s, 0, 0);
150  }
151 
152  /* WARNING: the returned index can be negative */
153  index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size);
154  /* update the file pointer */
155  if (*poutbuf_size) {
156  /* fill the data for the current frame */
158 
159  /* offset of the next frame */
161  s->fetch_timestamp=1;
162  }
163  if (index < 0)
164  index = 0;
165  s->cur_offset += index;
166  return index;
167 }
168 
170  AVCodecContext *avctx,
171  uint8_t **poutbuf, int *poutbuf_size,
172  const uint8_t *buf, int buf_size, int keyframe){
173 
174  if(s && s->parser->split){
175  if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){
176  int i= s->parser->split(avctx, buf, buf_size);
177  buf += i;
178  buf_size -= i;
179  }
180  }
181 
182  /* cast to avoid warning about discarding qualifiers */
183  *poutbuf= (uint8_t *) buf;
184  *poutbuf_size= buf_size;
185  if(avctx->extradata){
186  if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER))
187  /*||(s->pict_type != AV_PICTURE_TYPE_I && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/
188  /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
189  int size= buf_size + avctx->extradata_size;
190  *poutbuf_size= size;
191  *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
192 
193  memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
194  memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
195  return 1;
196  }
197  }
198 
199  return 0;
200 }
201 
203 {
204  if(s){
205  if (s->parser->parser_close)
206  s->parser->parser_close(s);
207  av_free(s->priv_data);
208  av_free(s);
209  }
210 }
211 
212 /*****************************************************/
213 
214 int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
215 {
216  if(pc->overread){
217  av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
218  pc->overread, pc->state, next, pc->index, pc->overread_index);
219  av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
220  }
221 
222  /* Copy overread bytes from last frame into buffer. */
223  for(; pc->overread>0; pc->overread--){
224  pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
225  }
226 
227  /* flush remaining if EOF */
228  if(!*buf_size && next == END_NOT_FOUND){
229  next= 0;
230  }
231 
232  pc->last_index= pc->index;
233 
234  /* copy into buffer end return */
235  if(next == END_NOT_FOUND){
236  void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
237 
238  if(!new_buffer)
239  return AVERROR(ENOMEM);
240  pc->buffer = new_buffer;
241  memcpy(&pc->buffer[pc->index], *buf, *buf_size);
242  pc->index += *buf_size;
243  return -1;
244  }
245 
246  *buf_size=
247  pc->overread_index= pc->index + next;
248 
249  /* append to buffer */
250  if(pc->index){
251  void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
252 
253  if(!new_buffer)
254  return AVERROR(ENOMEM);
255  pc->buffer = new_buffer;
256  if (next > -FF_INPUT_BUFFER_PADDING_SIZE)
257  memcpy(&pc->buffer[pc->index], *buf,
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->state64 = (pc->state64<<8) | pc->buffer[pc->last_index + next];
267  pc->overread++;
268  }
269 
270  if(pc->overread){
271  av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
272  pc->overread, pc->state, next, pc->index, pc->overread_index);
273  av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
274  }
275 
276  return 0;
277 }
278 
280 {
281  ParseContext *pc = s->priv_data;
282 
283  av_freep(&pc->buffer);
284 }
285 
286 /*************************/
287 
289  const uint8_t *buf, int buf_size)
290 {
291  int i;
292  uint32_t state= -1;
293 
294  for(i=0; i<buf_size; i++){
295  state= (state<<8) | buf[i];
296  if(state == 0x1B3 || state == 0x1B6)
297  return i-3;
298  }
299  return 0;
300 }
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:205
const char * s
Definition: avisynth_c.h:668
void(* parser_close)(AVCodecParserContext *s)
memory handling functions
int(* split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
int64_t cur_frame_pos[AV_PARSER_PTS_NB]
Position of the packet in file.
int dts_ref_dts_delta
Offset of the current timestamp against last timestamp sync point in units of AVCodecContext.time_base.
int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: parser.c:288
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:198
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:169
#define CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
struct AVCodecParser * next
void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove)
Fetch timestamps for a specific byte within the current access unit.
Definition: parser.c:88
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:183
int64_t pos
Byte position of currently parsed frame in stream.
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.
struct AVCodecParser * parser
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:214
int flags
CODEC_FLAG_*.
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]
int(* parser_parse)(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
#define AV_PARSER_PTS_NB
enum AVCodecID codec_id
Definition: mov_chan.c:433
AVCodecParser * av_parser_next(AVCodecParser *p)
Definition: parser.c:30
int size
void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:279
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
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:112
ret
Definition: avfilter.c:821
int64_t offset
byte offset from starting packet start
int64_t convergence_duration
Time difference in stream time base units from the pts of this packet to the point at which the outpu...
void av_parser_close(AVCodecParserContext *s)
Definition: parser.c:202
int64_t cur_frame_end[AV_PARSER_PTS_NB]
int64_t cur_frame_pts[AV_PARSER_PTS_NB]
int64_t last_pos
Previous frame byte position.
int pts_dts_delta
Presentation delay of current frame in units of AVCodecContext.time_base.
NULL
Definition: eval.c:55
AVCodecParserContext * av_parser_init(int codec_id)
Definition: parser.c:41
uint8_t * buffer
Definition: parser.h:29
main external API structure.
#define CODEC_FLAG2_LOCAL_HEADER
Place global headers at every keyframe instead of in extradata.
void * buf
Definition: avisynth_c.h:594
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
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:73
int index
Definition: gxfenc.c:89
uint64_t state64
contains the last 8 bytes in MSB order
Definition: parser.h:37
synthesis window for stochastic i
void av_register_codec_parser(AVCodecParser *parser)
Definition: parser.c:35
static AVCodecParser * av_first_parser
Definition: parser.c:28
#define END_NOT_FOUND
Definition: parser.h:40
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
int(* parser_init)(AVCodecParserContext *s)
static uint32_t state
Definition: trasher.c:27
#define PARSER_FLAG_FETCHED_OFFSET
Set if the parser has a valid file offset.
int index
Definition: parser.h:30
int64_t cur_frame_offset[AV_PARSER_PTS_NB]
int flags2
CODEC_FLAG2_*.
int key_frame
Set by parser to 1 for key frames and 0 for non-key frames.
int dts_sync_point
Synchronization point for start of timestamp generation.
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190