annotate ffmpeg/libavcodec/parser.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Audio and Video frame extraction
yading@10 3 * Copyright (c) 2003 Fabrice Bellard
yading@10 4 * Copyright (c) 2003 Michael Niedermayer
yading@10 5 *
yading@10 6 * This file is part of FFmpeg.
yading@10 7 *
yading@10 8 * FFmpeg is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * FFmpeg is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with FFmpeg; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 #include <string.h>
yading@10 24
yading@10 25 #include "parser.h"
yading@10 26 #include "libavutil/mem.h"
yading@10 27
yading@10 28 static AVCodecParser *av_first_parser = NULL;
yading@10 29
yading@10 30 AVCodecParser* av_parser_next(AVCodecParser *p){
yading@10 31 if(p) return p->next;
yading@10 32 else return av_first_parser;
yading@10 33 }
yading@10 34
yading@10 35 void av_register_codec_parser(AVCodecParser *parser)
yading@10 36 {
yading@10 37 parser->next = av_first_parser;
yading@10 38 av_first_parser = parser;
yading@10 39 }
yading@10 40
yading@10 41 AVCodecParserContext *av_parser_init(int codec_id)
yading@10 42 {
yading@10 43 AVCodecParserContext *s = NULL;
yading@10 44 AVCodecParser *parser;
yading@10 45 int ret;
yading@10 46
yading@10 47 if(codec_id == AV_CODEC_ID_NONE)
yading@10 48 return NULL;
yading@10 49
yading@10 50 for(parser = av_first_parser; parser != NULL; parser = parser->next) {
yading@10 51 if (parser->codec_ids[0] == codec_id ||
yading@10 52 parser->codec_ids[1] == codec_id ||
yading@10 53 parser->codec_ids[2] == codec_id ||
yading@10 54 parser->codec_ids[3] == codec_id ||
yading@10 55 parser->codec_ids[4] == codec_id)
yading@10 56 goto found;
yading@10 57 }
yading@10 58 return NULL;
yading@10 59 found:
yading@10 60 s = av_mallocz(sizeof(AVCodecParserContext));
yading@10 61 if (!s)
yading@10 62 goto err_out;
yading@10 63 s->parser = parser;
yading@10 64 s->priv_data = av_mallocz(parser->priv_data_size);
yading@10 65 if (!s->priv_data)
yading@10 66 goto err_out;
yading@10 67 s->fetch_timestamp=1;
yading@10 68 s->pict_type = AV_PICTURE_TYPE_I;
yading@10 69 if (parser->parser_init) {
yading@10 70 ret = parser->parser_init(s);
yading@10 71 if (ret != 0)
yading@10 72 goto err_out;
yading@10 73 }
yading@10 74 s->key_frame = -1;
yading@10 75 s->convergence_duration = 0;
yading@10 76 s->dts_sync_point = INT_MIN;
yading@10 77 s->dts_ref_dts_delta = INT_MIN;
yading@10 78 s->pts_dts_delta = INT_MIN;
yading@10 79 return s;
yading@10 80
yading@10 81 err_out:
yading@10 82 if (s)
yading@10 83 av_freep(&s->priv_data);
yading@10 84 av_free(s);
yading@10 85 return NULL;
yading@10 86 }
yading@10 87
yading@10 88 void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove){
yading@10 89 int i;
yading@10 90
yading@10 91 s->dts= s->pts= AV_NOPTS_VALUE;
yading@10 92 s->pos= -1;
yading@10 93 s->offset= 0;
yading@10 94 for(i = 0; i < AV_PARSER_PTS_NB; i++) {
yading@10 95 if ( s->cur_offset + off >= s->cur_frame_offset[i]
yading@10 96 && (s->frame_offset < s->cur_frame_offset[i] ||
yading@10 97 (!s->frame_offset && !s->next_frame_offset)) // first field/frame
yading@10 98 // check disabled since MPEG-TS does not send complete PES packets
yading@10 99 && /*s->next_frame_offset + off <*/ s->cur_frame_end[i]){
yading@10 100 s->dts= s->cur_frame_dts[i];
yading@10 101 s->pts= s->cur_frame_pts[i];
yading@10 102 s->pos= s->cur_frame_pos[i];
yading@10 103 s->offset = s->next_frame_offset - s->cur_frame_offset[i];
yading@10 104 if(remove)
yading@10 105 s->cur_frame_offset[i]= INT64_MAX;
yading@10 106 if(s->cur_offset + off < s->cur_frame_end[i])
yading@10 107 break;
yading@10 108 }
yading@10 109 }
yading@10 110 }
yading@10 111
yading@10 112 int av_parser_parse2(AVCodecParserContext *s,
yading@10 113 AVCodecContext *avctx,
yading@10 114 uint8_t **poutbuf, int *poutbuf_size,
yading@10 115 const uint8_t *buf, int buf_size,
yading@10 116 int64_t pts, int64_t dts,
yading@10 117 int64_t pos)
yading@10 118 {
yading@10 119 int index, i;
yading@10 120 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
yading@10 121
yading@10 122 if(!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) {
yading@10 123 s->next_frame_offset =
yading@10 124 s->cur_offset = pos;
yading@10 125 s->flags |= PARSER_FLAG_FETCHED_OFFSET;
yading@10 126 }
yading@10 127
yading@10 128 if (buf_size == 0) {
yading@10 129 /* padding is always necessary even if EOF, so we add it here */
yading@10 130 memset(dummy_buf, 0, sizeof(dummy_buf));
yading@10 131 buf = dummy_buf;
yading@10 132 } else if (s->cur_offset + buf_size !=
yading@10 133 s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */
yading@10 134 /* add a new packet descriptor */
yading@10 135 i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
yading@10 136 s->cur_frame_start_index = i;
yading@10 137 s->cur_frame_offset[i] = s->cur_offset;
yading@10 138 s->cur_frame_end[i] = s->cur_offset + buf_size;
yading@10 139 s->cur_frame_pts[i] = pts;
yading@10 140 s->cur_frame_dts[i] = dts;
yading@10 141 s->cur_frame_pos[i] = pos;
yading@10 142 }
yading@10 143
yading@10 144 if (s->fetch_timestamp){
yading@10 145 s->fetch_timestamp=0;
yading@10 146 s->last_pts = s->pts;
yading@10 147 s->last_dts = s->dts;
yading@10 148 s->last_pos = s->pos;
yading@10 149 ff_fetch_timestamp(s, 0, 0);
yading@10 150 }
yading@10 151
yading@10 152 /* WARNING: the returned index can be negative */
yading@10 153 index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size);
yading@10 154 /* update the file pointer */
yading@10 155 if (*poutbuf_size) {
yading@10 156 /* fill the data for the current frame */
yading@10 157 s->frame_offset = s->next_frame_offset;
yading@10 158
yading@10 159 /* offset of the next frame */
yading@10 160 s->next_frame_offset = s->cur_offset + index;
yading@10 161 s->fetch_timestamp=1;
yading@10 162 }
yading@10 163 if (index < 0)
yading@10 164 index = 0;
yading@10 165 s->cur_offset += index;
yading@10 166 return index;
yading@10 167 }
yading@10 168
yading@10 169 int av_parser_change(AVCodecParserContext *s,
yading@10 170 AVCodecContext *avctx,
yading@10 171 uint8_t **poutbuf, int *poutbuf_size,
yading@10 172 const uint8_t *buf, int buf_size, int keyframe){
yading@10 173
yading@10 174 if(s && s->parser->split){
yading@10 175 if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){
yading@10 176 int i= s->parser->split(avctx, buf, buf_size);
yading@10 177 buf += i;
yading@10 178 buf_size -= i;
yading@10 179 }
yading@10 180 }
yading@10 181
yading@10 182 /* cast to avoid warning about discarding qualifiers */
yading@10 183 *poutbuf= (uint8_t *) buf;
yading@10 184 *poutbuf_size= buf_size;
yading@10 185 if(avctx->extradata){
yading@10 186 if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER))
yading@10 187 /*||(s->pict_type != AV_PICTURE_TYPE_I && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/
yading@10 188 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
yading@10 189 int size= buf_size + avctx->extradata_size;
yading@10 190 *poutbuf_size= size;
yading@10 191 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 192
yading@10 193 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
yading@10 194 memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 195 return 1;
yading@10 196 }
yading@10 197 }
yading@10 198
yading@10 199 return 0;
yading@10 200 }
yading@10 201
yading@10 202 void av_parser_close(AVCodecParserContext *s)
yading@10 203 {
yading@10 204 if(s){
yading@10 205 if (s->parser->parser_close)
yading@10 206 s->parser->parser_close(s);
yading@10 207 av_free(s->priv_data);
yading@10 208 av_free(s);
yading@10 209 }
yading@10 210 }
yading@10 211
yading@10 212 /*****************************************************/
yading@10 213
yading@10 214 int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
yading@10 215 {
yading@10 216 if(pc->overread){
yading@10 217 av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
yading@10 218 pc->overread, pc->state, next, pc->index, pc->overread_index);
yading@10 219 av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]);
yading@10 220 }
yading@10 221
yading@10 222 /* Copy overread bytes from last frame into buffer. */
yading@10 223 for(; pc->overread>0; pc->overread--){
yading@10 224 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
yading@10 225 }
yading@10 226
yading@10 227 /* flush remaining if EOF */
yading@10 228 if(!*buf_size && next == END_NOT_FOUND){
yading@10 229 next= 0;
yading@10 230 }
yading@10 231
yading@10 232 pc->last_index= pc->index;
yading@10 233
yading@10 234 /* copy into buffer end return */
yading@10 235 if(next == END_NOT_FOUND){
yading@10 236 void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 237
yading@10 238 if(!new_buffer)
yading@10 239 return AVERROR(ENOMEM);
yading@10 240 pc->buffer = new_buffer;
yading@10 241 memcpy(&pc->buffer[pc->index], *buf, *buf_size);
yading@10 242 pc->index += *buf_size;
yading@10 243 return -1;
yading@10 244 }
yading@10 245
yading@10 246 *buf_size=
yading@10 247 pc->overread_index= pc->index + next;
yading@10 248
yading@10 249 /* append to buffer */
yading@10 250 if(pc->index){
yading@10 251 void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 252
yading@10 253 if(!new_buffer)
yading@10 254 return AVERROR(ENOMEM);
yading@10 255 pc->buffer = new_buffer;
yading@10 256 if (next > -FF_INPUT_BUFFER_PADDING_SIZE)
yading@10 257 memcpy(&pc->buffer[pc->index], *buf,
yading@10 258 next + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 259 pc->index = 0;
yading@10 260 *buf= pc->buffer;
yading@10 261 }
yading@10 262
yading@10 263 /* store overread bytes */
yading@10 264 for(;next < 0; next++){
yading@10 265 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
yading@10 266 pc->state64 = (pc->state64<<8) | pc->buffer[pc->last_index + next];
yading@10 267 pc->overread++;
yading@10 268 }
yading@10 269
yading@10 270 if(pc->overread){
yading@10 271 av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n",
yading@10 272 pc->overread, pc->state, next, pc->index, pc->overread_index);
yading@10 273 av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
yading@10 274 }
yading@10 275
yading@10 276 return 0;
yading@10 277 }
yading@10 278
yading@10 279 void ff_parse_close(AVCodecParserContext *s)
yading@10 280 {
yading@10 281 ParseContext *pc = s->priv_data;
yading@10 282
yading@10 283 av_freep(&pc->buffer);
yading@10 284 }
yading@10 285
yading@10 286 /*************************/
yading@10 287
yading@10 288 int ff_mpeg4video_split(AVCodecContext *avctx,
yading@10 289 const uint8_t *buf, int buf_size)
yading@10 290 {
yading@10 291 int i;
yading@10 292 uint32_t state= -1;
yading@10 293
yading@10 294 for(i=0; i<buf_size; i++){
yading@10 295 state= (state<<8) | buf[i];
yading@10 296 if(state == 0x1B3 || state == 0x1B6)
yading@10 297 return i-3;
yading@10 298 }
yading@10 299 return 0;
yading@10 300 }