annotate aac_ac3_parser.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 3b06c3d9e72d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
1 /*
7470
1a93d3bbe3ee cosmetics: make all references to AC-3 capitalized and hyphenated
jbr
parents: 6650
diff changeset
2 * Common AAC and AC-3 parser
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 8082
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 8082
diff changeset
4 * Copyright (c) 2003 Michael Niedermayer
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
5 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
6 * This file is part of FFmpeg.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
7 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
12 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
16 * Lesser General Public License for more details.
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
17 *
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
21 */
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
22
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
23 #include "parser.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
24 #include "aac_ac3_parser.h"
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
25
4942
b42e963c8149 cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents: 4941
diff changeset
26 int ff_aac_ac3_parse(AVCodecParserContext *s1,
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
27 AVCodecContext *avctx,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
28 const uint8_t **poutbuf, int *poutbuf_size,
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
29 const uint8_t *buf, int buf_size)
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
30 {
4942
b42e963c8149 cosmetics: rename for consistency after previous aac and ac3 parsers move
aurel
parents: 4941
diff changeset
31 AACAC3ParseContext *s = s1->priv_data;
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
32 ParseContext *pc = &s->pc;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
33 int len, i;
6643
4d04fcb5e1e4 Add new_frame_start and need_next_header.
michael
parents: 6642
diff changeset
34 int new_frame_start;
5816
0168cd384df3 factorize code and add safety check to prevent memcpying negative amounts
michael
parents: 4942
diff changeset
35
6644
1d9eb7c09f98 part 1 of EAC3 support
michael
parents: 6643
diff changeset
36 get_next:
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
37 i=END_NOT_FOUND;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
38 if(s->remaining_size <= buf_size){
6644
1d9eb7c09f98 part 1 of EAC3 support
michael
parents: 6643
diff changeset
39 if(s->remaining_size && !s->need_next_header){
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
40 i= s->remaining_size;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
41 s->remaining_size = 0;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
42 }else{ //we need a header first
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
43 len=0;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
44 for(i=s->remaining_size; i<buf_size; i++){
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
45 s->state = (s->state<<8) + buf[i];
6643
4d04fcb5e1e4 Add new_frame_start and need_next_header.
michael
parents: 6642
diff changeset
46 if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
47 break;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
48 }
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
49 if(len<=0){
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
50 i=END_NOT_FOUND;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
51 }else{
8082
75d40b4b28ed Reset state after some frame header is found.
michael
parents: 7903
diff changeset
52 s->state=0;
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
53 i-= s->header_size -1;
6646
7ca428109684 100l I broke AC3 in MPEG seeking.
michael
parents: 6644
diff changeset
54 s->remaining_size = len;
7903
ad95dd08b31a Fix all the recent problems Justin had run into with the AC3 parser,
michael
parents: 7769
diff changeset
55 if(!new_frame_start || pc->index+i<=0){
6650
2d1497d25251 This fixes the code so it is correct on both sides of the if().
michael
parents: 6649
diff changeset
56 s->remaining_size += i;
6644
1d9eb7c09f98 part 1 of EAC3 support
michael
parents: 6643
diff changeset
57 goto get_next;
6650
2d1497d25251 This fixes the code so it is correct on both sides of the if().
michael
parents: 6649
diff changeset
58 }
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
59 }
6576
5e7c69ebc019 undo changes in aac_ac3_parser
bwolowiec
parents: 6572
diff changeset
60 }
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
61 }
5816
0168cd384df3 factorize code and add safety check to prevent memcpying negative amounts
michael
parents: 4942
diff changeset
62
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
63 if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
64 s->remaining_size -= FFMIN(s->remaining_size, buf_size);
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
65 *poutbuf = NULL;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
66 *poutbuf_size = 0;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
67 return buf_size;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
68 }
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
69
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
70 *poutbuf = buf;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
71 *poutbuf_size = buf_size;
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
72
6649
michael
parents: 6646
diff changeset
73 /* update codec info */
8977
82ab0b77695b Allow AC-3 parser to modify codec_id.
jbr
parents: 8629
diff changeset
74 if(s->codec_id)
82ab0b77695b Allow AC-3 parser to modify codec_id.
jbr
parents: 8629
diff changeset
75 avctx->codec_id = s->codec_id;
82ab0b77695b Allow AC-3 parser to modify codec_id.
jbr
parents: 8629
diff changeset
76
11356
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
77 /* Due to backwards compatible HE-AAC the sample rate, channel count,
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
78 and total number of samples found in an AAC ADTS header are not
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
79 reliable. Bit rate is still accurate because the total frame duration in
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
80 seconds is still correct (as is the number of bits in the frame). */
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
81 if (avctx->codec_id != CODEC_ID_AAC) {
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
82 avctx->sample_rate = s->sample_rate;
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
83
11357
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
84 /* allow downmixing to stereo (or mono for AC-3) */
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
85 if(avctx->request_channels > 0 &&
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
86 avctx->request_channels < s->channels &&
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
87 (avctx->request_channels <= 2 ||
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
88 (avctx->request_channels == 1 &&
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
89 (avctx->codec_id == CODEC_ID_AC3 ||
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
90 avctx->codec_id == CODEC_ID_EAC3)))) {
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
91 avctx->channels = avctx->request_channels;
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
92 } else {
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
93 avctx->channels = s->channels;
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
94 avctx->channel_layout = s->channel_layout;
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
95 }
3b06c3d9e72d Cosmetics: Re-indent after last commit.
alexc
parents: 11356
diff changeset
96 avctx->frame_size = s->samples;
11356
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
97 }
9056fd765255 AAC parser: Don't write channels, sample rate, and frame size each frame.
alexc
parents: 9635
diff changeset
98
6649
michael
parents: 6646
diff changeset
99 avctx->bit_rate = s->bit_rate;
6642
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
100
866b9ade048c Change aac and ac3 parsers to use ff_combine_frame().
michael
parents: 6639
diff changeset
101 return i;
4941
c3ee5c30c297 move aac and ac3 parsers in their own files
aurel
parents:
diff changeset
102 }