Mercurial > libavcodec.hg
annotate parser.c @ 5319:40af705cef7e libavcodec
AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9
Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.
2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.
| author | jbr |
|---|---|
| date | Sat, 14 Jul 2007 16:03:14 +0000 |
| parents | 25cd2084129a |
| children | b1fe945d73f9 |
| rev | line source |
|---|---|
| 1613 | 1 /* |
| 2 * Audio and Video frame extraction | |
| 3 * Copyright (c) 2003 Fabrice Bellard. | |
| 4 * Copyright (c) 2003 Michael Niedermayer. | |
| 5 * | |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * This file is part of FFmpeg. |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
| 1613 | 9 * modify it under the terms of the GNU Lesser General Public |
| 10 * License as published by the Free Software Foundation; either | |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
| 1613 | 12 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
| 1613 | 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 | |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
|
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 1613 | 21 */ |
| 4943 | 22 |
|
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
23 #include "parser.h" |
| 1613 | 24 |
| 25 AVCodecParser *av_first_parser = NULL; | |
| 26 | |
| 27 void av_register_codec_parser(AVCodecParser *parser) | |
| 28 { | |
| 29 parser->next = av_first_parser; | |
| 30 av_first_parser = parser; | |
| 31 } | |
| 32 | |
| 33 AVCodecParserContext *av_parser_init(int codec_id) | |
| 34 { | |
| 35 AVCodecParserContext *s; | |
| 36 AVCodecParser *parser; | |
| 37 int ret; | |
| 2967 | 38 |
|
2486
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
39 if(codec_id == CODEC_ID_NONE) |
|
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
40 return NULL; |
| 1613 | 41 |
| 42 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
| 43 if (parser->codec_ids[0] == codec_id || | |
| 44 parser->codec_ids[1] == codec_id || | |
| 2348 | 45 parser->codec_ids[2] == codec_id || |
| 46 parser->codec_ids[3] == codec_id || | |
| 47 parser->codec_ids[4] == codec_id) | |
| 1613 | 48 goto found; |
| 49 } | |
| 50 return NULL; | |
| 51 found: | |
| 52 s = av_mallocz(sizeof(AVCodecParserContext)); | |
| 53 if (!s) | |
| 54 return NULL; | |
| 55 s->parser = parser; | |
| 56 s->priv_data = av_mallocz(parser->priv_data_size); | |
| 57 if (!s->priv_data) { | |
| 58 av_free(s); | |
| 59 return NULL; | |
| 60 } | |
| 61 if (parser->parser_init) { | |
| 62 ret = parser->parser_init(s); | |
| 63 if (ret != 0) { | |
| 64 av_free(s->priv_data); | |
| 65 av_free(s); | |
| 66 return NULL; | |
| 67 } | |
| 68 } | |
| 2030 | 69 s->fetch_timestamp=1; |
|
4739
9b4c5d2fb8ce
set pict_type to I type during init so parsers which dont set it get all i frames, fixes mp3 seeking
michael
parents:
4679
diff
changeset
|
70 s->pict_type = FF_I_TYPE; |
| 1613 | 71 return s; |
| 72 } | |
| 73 | |
| 3989 | 74 /** |
| 75 * | |
| 76 * @param buf input | |
| 77 * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output) | |
| 78 * @param pts input presentation timestamp | |
| 79 * @param dts input decoding timestamp | |
| 80 * @param poutbuf will contain a pointer to the first byte of the output frame | |
| 81 * @param poutbuf_size will contain the length of the output frame | |
| 82 * @return the number of bytes of the input bitstream used | |
| 83 * | |
| 84 * Example: | |
| 85 * @code | |
| 86 * while(in_len){ | |
| 87 * len = av_parser_parse(myparser, AVCodecContext, &data, &size, | |
| 88 * in_data, in_len, | |
| 89 * pts, dts); | |
| 90 * in_data += len; | |
| 91 * in_len -= len; | |
| 92 * | |
| 4310 | 93 * if(size) |
| 94 * decode_frame(data, size); | |
| 3989 | 95 * } |
| 96 * @endcode | |
| 97 */ | |
| 2967 | 98 int av_parser_parse(AVCodecParserContext *s, |
| 1613 | 99 AVCodecContext *avctx, |
| 2967 | 100 uint8_t **poutbuf, int *poutbuf_size, |
| 1696 | 101 const uint8_t *buf, int buf_size, |
| 102 int64_t pts, int64_t dts) | |
| 1613 | 103 { |
| 1696 | 104 int index, i, k; |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
105 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
| 2967 | 106 |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
107 if (buf_size == 0) { |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
108 /* padding is always necessary even if EOF, so we add it here */ |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
109 memset(dummy_buf, 0, sizeof(dummy_buf)); |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
110 buf = dummy_buf; |
| 1696 | 111 } else { |
| 112 /* add a new packet descriptor */ | |
| 113 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
| 114 s->cur_frame_start_index = k; | |
| 115 s->cur_frame_offset[k] = s->cur_offset; | |
| 116 s->cur_frame_pts[k] = pts; | |
| 117 s->cur_frame_dts[k] = dts; | |
| 118 | |
| 119 /* fill first PTS/DTS */ | |
| 2030 | 120 if (s->fetch_timestamp){ |
| 121 s->fetch_timestamp=0; | |
| 1696 | 122 s->last_pts = pts; |
| 123 s->last_dts = dts; | |
| 4846 | 124 s->last_offset = 0; |
| 2107 | 125 s->cur_frame_pts[k] = |
| 126 s->cur_frame_dts[k] = AV_NOPTS_VALUE; | |
| 1696 | 127 } |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
128 } |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
129 |
| 1613 | 130 /* WARNING: the returned index can be negative */ |
|
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4913
diff
changeset
|
131 index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size); |
|
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
4104
diff
changeset
|
132 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); |
| 1613 | 133 /* update the file pointer */ |
| 134 if (*poutbuf_size) { | |
| 1696 | 135 /* fill the data for the current frame */ |
| 1613 | 136 s->frame_offset = s->last_frame_offset; |
| 1696 | 137 s->pts = s->last_pts; |
| 138 s->dts = s->last_dts; | |
| 4846 | 139 s->offset = s->last_offset; |
| 2967 | 140 |
| 1696 | 141 /* offset of the next frame */ |
| 1613 | 142 s->last_frame_offset = s->cur_offset + index; |
| 1696 | 143 /* find the packet in which the new frame starts. It |
| 144 is tricky because of MPEG video start codes | |
| 145 which can begin in one packet and finish in | |
| 146 another packet. In the worst case, an MPEG | |
| 147 video start code could be in 4 different | |
| 148 packets. */ | |
| 149 k = s->cur_frame_start_index; | |
| 150 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
| 151 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
| 152 break; | |
| 153 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
| 154 } | |
| 2030 | 155 |
| 1696 | 156 s->last_pts = s->cur_frame_pts[k]; |
| 157 s->last_dts = s->cur_frame_dts[k]; | |
| 4846 | 158 s->last_offset = s->last_frame_offset - s->cur_frame_offset[k]; |
| 2967 | 159 |
| 2030 | 160 /* some parsers tell us the packet size even before seeing the first byte of the next packet, |
| 161 so the next pts/dts is in the next chunk */ | |
| 162 if(index == buf_size){ | |
| 163 s->fetch_timestamp=1; | |
| 164 } | |
| 1613 | 165 } |
| 166 if (index < 0) | |
| 167 index = 0; | |
| 168 s->cur_offset += index; | |
| 169 return index; | |
| 170 } | |
| 171 | |
| 2777 | 172 /** |
| 173 * | |
| 174 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed | |
|
3421
b7826511f7b6
AVBitStreamFilter (some thingy which can modify the bitstream like add or remove global headers or change the headers or ...)
michael
parents:
3395
diff
changeset
|
175 * @deprecated use AVBitstreamFilter |
| 2777 | 176 */ |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
177 int av_parser_change(AVCodecParserContext *s, |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
178 AVCodecContext *avctx, |
| 2967 | 179 uint8_t **poutbuf, int *poutbuf_size, |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
180 const uint8_t *buf, int buf_size, int keyframe){ |
| 2967 | 181 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
182 if(s && s->parser->split){ |
| 2777 | 183 if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){ |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
184 int i= s->parser->split(avctx, buf, buf_size); |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
185 buf += i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
186 buf_size -= i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
187 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
188 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
189 |
|
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
190 /* cast to avoid warning about discarding qualifiers */ |
|
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
191 *poutbuf= (uint8_t *) buf; |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
192 *poutbuf_size= buf_size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
193 if(avctx->extradata){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
194 if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
195 /*||(s->pict_type != I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
196 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
197 int size= buf_size + avctx->extradata_size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
198 *poutbuf_size= size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
199 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); |
| 2967 | 200 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
201 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); |
| 2777 | 202 memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
203 return 1; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
204 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
205 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
206 |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
207 return 0; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
208 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
209 |
| 1613 | 210 void av_parser_close(AVCodecParserContext *s) |
| 211 { | |
| 212 if (s->parser->parser_close) | |
| 213 s->parser->parser_close(s); | |
| 214 av_free(s->priv_data); | |
| 215 av_free(s); | |
| 216 } | |
| 217 | |
| 218 /*****************************************************/ | |
| 219 | |
| 220 /** | |
| 221 * combines the (truncated) bitstream to a complete frame | |
| 222 * @returns -1 if no complete frame could be created | |
| 223 */ | |
|
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4913
diff
changeset
|
224 int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) |
| 1613 | 225 { |
| 226 #if 0 | |
| 227 if(pc->overread){ | |
| 228 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 229 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 230 } | |
| 231 #endif | |
| 232 | |
| 4795 | 233 /* Copy overread bytes from last frame into buffer. */ |
| 1613 | 234 for(; pc->overread>0; pc->overread--){ |
| 235 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
| 236 } | |
| 2386 | 237 |
| 238 /* flush remaining if EOF */ | |
| 239 if(!*buf_size && next == END_NOT_FOUND){ | |
| 240 next= 0; | |
| 241 } | |
| 242 | |
| 1613 | 243 pc->last_index= pc->index; |
| 244 | |
| 245 /* copy into buffer end return */ | |
| 246 if(next == END_NOT_FOUND){ | |
| 247 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 248 | |
| 249 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
| 250 pc->index += *buf_size; | |
| 251 return -1; | |
| 252 } | |
| 253 | |
| 254 *buf_size= | |
| 255 pc->overread_index= pc->index + next; | |
| 2967 | 256 |
| 1613 | 257 /* append to buffer */ |
| 258 if(pc->index){ | |
| 259 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 260 | |
| 261 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
| 262 pc->index = 0; | |
| 263 *buf= pc->buffer; | |
| 264 } | |
| 265 | |
| 266 /* store overread bytes */ | |
| 267 for(;next < 0; next++){ | |
| 268 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
| 269 pc->overread++; | |
| 270 } | |
| 271 | |
| 272 #if 0 | |
| 273 if(pc->overread){ | |
| 274 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 275 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 276 } | |
| 277 #endif | |
| 278 | |
| 279 return 0; | |
| 280 } | |
| 281 | |
| 1988 | 282 void ff_parse_close(AVCodecParserContext *s) |
| 1613 | 283 { |
| 1988 | 284 ParseContext *pc = s->priv_data; |
| 1613 | 285 |
| 286 av_free(pc->buffer); | |
| 1988 | 287 } |
| 288 | |
|
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
289 void ff_parse1_close(AVCodecParserContext *s) |
| 1988 | 290 { |
| 291 ParseContext1 *pc1 = s->priv_data; | |
| 292 | |
| 293 av_free(pc1->pc.buffer); | |
| 294 av_free(pc1->enc); | |
| 1613 | 295 } |
| 296 | |
| 297 /*************************/ | |
| 298 | |
|
4175
b3328ed50a5e
make mpeg4video_split public as ff_mpeg4video_split
stefang
parents:
4150
diff
changeset
|
299 int ff_mpeg4video_split(AVCodecContext *avctx, |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
300 const uint8_t *buf, int buf_size) |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
301 { |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
302 int i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
303 uint32_t state= -1; |
| 2967 | 304 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
305 for(i=0; i<buf_size; i++){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
306 state= (state<<8) | buf[i]; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
307 if(state == 0x1B3 || state == 0x1B6) |
| 2777 | 308 return i-3; |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
309 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
310 return 0; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
311 } |
