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 state = 0;
00057
00058 if(!s->frame_size){
00059 next= i;
00060 break;
00061 }
00062 }else{
00063 while(i<buf_size){
00064 int ret, sr, channels, bit_rate, frame_size;
00065
00066 state= (state<<8) + buf[i++];
00067
00068 ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
00069 if (ret < 4) {
00070 if (i > 4)
00071 s->header_count = -2;
00072 } else {
00073 if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
00074 s->header_count= -3;
00075 s->header= state;
00076 s->header_count++;
00077 s->frame_size = ret-4;
00078
00079 if (s->header_count > 1) {
00080 avctx->sample_rate= sr;
00081 avctx->channels = channels;
00082 s1->duration = frame_size;
00083 avctx->bit_rate = bit_rate;
00084 }
00085 break;
00086 }
00087 }
00088 }
00089 }
00090
00091 pc->state= state;
00092 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00093 *poutbuf = NULL;
00094 *poutbuf_size = 0;
00095 return buf_size;
00096 }
00097
00098 *poutbuf = buf;
00099 *poutbuf_size = buf_size;
00100 return next;
00101 }
00102
00103
00104 AVCodecParser ff_mpegaudio_parser = {
00105 .codec_ids = { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
00106 .priv_data_size = sizeof(MpegAudioParseContext),
00107 .parser_parse = mpegaudio_parse,
00108 .parser_close = ff_parse_close,
00109 };