00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include "parser.h"
00024 #include "mpegaudiodecheader.h"
00025 #include "libavutil/common.h"
00026 
00027 
00028 typedef struct MpegAudioParseContext {
00029     ParseContext pc;
00030     int frame_size;
00031     uint32_t header;
00032     int header_count;
00033 } MpegAudioParseContext;
00034 
00035 #define MPA_HEADER_SIZE 4
00036 
00037 
00038 #define SAME_HEADER_MASK \
00039    (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
00040 
00041 static int mpegaudio_parse(AVCodecParserContext *s1,
00042                            AVCodecContext *avctx,
00043                            const uint8_t **poutbuf, int *poutbuf_size,
00044                            const uint8_t *buf, int buf_size)
00045 {
00046     MpegAudioParseContext *s = s1->priv_data;
00047     ParseContext *pc = &s->pc;
00048     uint32_t state= pc->state;
00049     int i;
00050     int next= END_NOT_FOUND;
00051 
00052     for(i=0; i<buf_size; ){
00053         if(s->frame_size){
00054             int inc= FFMIN(buf_size - i, s->frame_size);
00055             i += inc;
00056             s->frame_size -= inc;
00057             state = 0;
00058 
00059             if(!s->frame_size){
00060                 next= i;
00061                 break;
00062             }
00063         }else{
00064             while(i<buf_size){
00065                 int ret, sr, channels, bit_rate, frame_size;
00066 
00067                 state= (state<<8) + buf[i++];
00068 
00069                 ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
00070                 if (ret < 4) {
00071                     if (i > 4)
00072                         s->header_count = -2;
00073                 } else {
00074                     if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
00075                         s->header_count= -3;
00076                     s->header= state;
00077                     s->header_count++;
00078                     s->frame_size = ret-4;
00079 
00080                     if (s->header_count > 1) {
00081                         avctx->sample_rate= sr;
00082                         avctx->channels   = channels;
00083                         s1->duration      = frame_size;
00084                         avctx->bit_rate   = bit_rate;
00085                     }
00086                     break;
00087                 }
00088             }
00089         }
00090     }
00091 
00092     pc->state= state;
00093     if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00094         *poutbuf = NULL;
00095         *poutbuf_size = 0;
00096         return buf_size;
00097     }
00098 
00099     *poutbuf = buf;
00100     *poutbuf_size = buf_size;
00101     return next;
00102 }
00103 
00104 
00105 AVCodecParser ff_mpegaudio_parser = {
00106     .codec_ids      = { AV_CODEC_ID_MP1, AV_CODEC_ID_MP2, AV_CODEC_ID_MP3 },
00107     .priv_data_size = sizeof(MpegAudioParseContext),
00108     .parser_parse   = mpegaudio_parse,
00109     .parser_close   = ff_parse_close,
00110 };