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 };