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
00026
00027 typedef struct MpegAudioParseContext {
00028 ParseContext pc;
00029 int frame_size;
00030 uint32_t header;
00031 int header_count;
00032 } MpegAudioParseContext;
00033
00034 #define MPA_HEADER_SIZE 4
00035
00036
00037 #define SAME_HEADER_MASK \
00038 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
00039
00040 static int mpegaudio_parse(AVCodecParserContext *s1,
00041 AVCodecContext *avctx,
00042 const uint8_t **poutbuf, int *poutbuf_size,
00043 const uint8_t *buf, int buf_size)
00044 {
00045 MpegAudioParseContext *s = s1->priv_data;
00046 ParseContext *pc = &s->pc;
00047 uint32_t state= pc->state;
00048 int i;
00049 int next= END_NOT_FOUND;
00050
00051 for(i=0; i<buf_size; ){
00052 if(s->frame_size){
00053 int inc= FFMIN(buf_size - i, s->frame_size);
00054 i += inc;
00055 s->frame_size -= inc;
00056
00057 if(!s->frame_size){
00058 next= i;
00059 break;
00060 }
00061 }else{
00062 while(i<buf_size){
00063 int ret, sr, channels, bit_rate, frame_size;
00064
00065 state= (state<<8) + buf[i++];
00066
00067 ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
00068 if (ret < 4) {
00069 if(i > 4)
00070 s->header_count= -2;
00071 } else {
00072 if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
00073 s->header_count= -3;
00074 s->header= state;
00075 s->header_count++;
00076 s->frame_size = ret-4;
00077
00078 if(s->header_count > 1){
00079 avctx->sample_rate= sr;
00080 avctx->channels = channels;
00081 avctx->frame_size = frame_size;
00082 avctx->bit_rate = bit_rate;
00083 }
00084 break;
00085 }
00086 }
00087 }
00088 }
00089
00090 pc->state= state;
00091 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00092 *poutbuf = NULL;
00093 *poutbuf_size = 0;
00094 return buf_size;
00095 }
00096
00097 *poutbuf = buf;
00098 *poutbuf_size = buf_size;
00099 return next;
00100 }
00101
00102
00103 AVCodecParser ff_mpegaudio_parser = {
00104 { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
00105 sizeof(MpegAudioParseContext),
00106 NULL,
00107 mpegaudio_parse,
00108 ff_parse_close,
00109 };