libavcodec/aac_ac3_parser.c
99ff31dc
 /*
14b70628
  * Common AAC and AC-3 parser
406792e7
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
99ff31dc
  *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
b5328546
 #include "libavutil/channel_layout.h"
1d9c2dc8
 #include "libavutil/common.h"
99ff31dc
 #include "parser.h"
 #include "aac_ac3_parser.h"
 
679c2294
 int ff_aac_ac3_parse(AVCodecParserContext *s1,
99ff31dc
                      AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
 {
679c2294
     AACAC3ParseContext *s = s1->priv_data;
454064ad
     ParseContext *pc = &s->pc;
     int len, i;
133ac890
     int new_frame_start;
9f5baf90
     int got_frame = 0;
99ff31dc
 
8629e756
 get_next:
454064ad
     i=END_NOT_FOUND;
     if(s->remaining_size <= buf_size){
8629e756
         if(s->remaining_size && !s->need_next_header){
454064ad
             i= s->remaining_size;
             s->remaining_size = 0;
         }else{ //we need a header first
             len=0;
             for(i=s->remaining_size; i<buf_size; i++){
                 s->state = (s->state<<8) + buf[i];
133ac890
                 if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
454064ad
                     break;
             }
             if(len<=0){
                 i=END_NOT_FOUND;
             }else{
9f5baf90
                 got_frame = 1;
bf2cdefc
                 s->state=0;
454064ad
                 i-= s->header_size -1;
e4d5a185
                 s->remaining_size = len;
8dbd9cb6
                 if(!new_frame_start || pc->index+i<=0){
8870cf82
                     s->remaining_size += i;
8629e756
                     goto get_next;
8870cf82
                 }
454064ad
             }
         }
     }
99ff31dc
 
454064ad
     if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
         s->remaining_size -= FFMIN(s->remaining_size, buf_size);
         *poutbuf = NULL;
         *poutbuf_size = 0;
         return buf_size;
     }
469d8816
 
454064ad
     *poutbuf = buf;
     *poutbuf_size = buf_size;
211dd1e8
 
7bc5f6e5
     /* update codec info */
4cff8dc8
     if(s->codec_id)
         avctx->codec_id = s->codec_id;
 
9f5baf90
     if (got_frame) {
f0ea536c
         /* Due to backwards compatible HE-AAC the sample rate, channel count,
            and total number of samples found in an AAC ADTS header are not
            reliable. Bit rate is still accurate because the total frame
            duration in seconds is still correct (as is the number of bits in
            the frame). */
         if (avctx->codec_id != AV_CODEC_ID_AAC) {
             avctx->sample_rate = s->sample_rate;
9484b9f4
             avctx->channels = s->channels;
             avctx->channel_layout = s->channel_layout;
f0ea536c
             s1->duration = s->samples;
             avctx->audio_service_type = s->service_type;
65bec42e
         }
ca1fa414
 
f0ea536c
         avctx->bit_rate = s->bit_rate;
9f5baf90
     }
454064ad
 
     return i;
99ff31dc
 }