Mercurial > libavcodec.hg
comparison mpegaudio_parser.c @ 9894:78b2fc137c27 libavcodec
Rewrite mp3 parser. New code is much simpler and does not drop
stuff at random.
| author | michael |
|---|---|
| date | Tue, 30 Jun 2009 03:12:50 +0000 |
| parents | 6409c6ba8040 |
| children | 30dad2d5e7fe |
comparison
equal
deleted
inserted
replaced
| 9893:1d10ec092b64 | 9894:78b2fc137c27 |
|---|---|
| 24 #include "mpegaudio.h" | 24 #include "mpegaudio.h" |
| 25 #include "mpegaudiodecheader.h" | 25 #include "mpegaudiodecheader.h" |
| 26 | 26 |
| 27 | 27 |
| 28 typedef struct MpegAudioParseContext { | 28 typedef struct MpegAudioParseContext { |
| 29 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ | 29 ParseContext pc; |
| 30 uint8_t *inbuf_ptr; | |
| 31 int frame_size; | 30 int frame_size; |
| 32 int free_format_frame_size; | |
| 33 int free_format_next_header; | |
| 34 uint32_t header; | 31 uint32_t header; |
| 35 int header_count; | 32 int header_count; |
| 36 } MpegAudioParseContext; | 33 } MpegAudioParseContext; |
| 37 | 34 |
| 38 #define MPA_HEADER_SIZE 4 | 35 #define MPA_HEADER_SIZE 4 |
| 79 *bit_rate = s->bit_rate; | 76 *bit_rate = s->bit_rate; |
| 80 avctx->sub_id = s->layer; | 77 avctx->sub_id = s->layer; |
| 81 return s->frame_size; | 78 return s->frame_size; |
| 82 } | 79 } |
| 83 | 80 |
| 84 static av_cold int mpegaudio_parse_init(AVCodecParserContext *s1) | |
| 85 { | |
| 86 MpegAudioParseContext *s = s1->priv_data; | |
| 87 s->inbuf_ptr = s->inbuf; | |
| 88 return 0; | |
| 89 } | |
| 90 | |
| 91 static int mpegaudio_parse(AVCodecParserContext *s1, | 81 static int mpegaudio_parse(AVCodecParserContext *s1, |
| 92 AVCodecContext *avctx, | 82 AVCodecContext *avctx, |
| 93 const uint8_t **poutbuf, int *poutbuf_size, | 83 const uint8_t **poutbuf, int *poutbuf_size, |
| 94 const uint8_t *buf, int buf_size) | 84 const uint8_t *buf, int buf_size) |
| 95 { | 85 { |
| 96 MpegAudioParseContext *s = s1->priv_data; | 86 MpegAudioParseContext *s = s1->priv_data; |
| 97 int len, ret, sr, channels, bit_rate, frame_size; | 87 ParseContext *pc = &s->pc; |
| 98 uint32_t header; | 88 uint32_t state= pc->state; |
| 99 const uint8_t *buf_ptr; | 89 int i; |
| 90 int next= END_NOT_FOUND; | |
| 100 | 91 |
| 101 *poutbuf = NULL; | 92 for(i=0; i<buf_size; ){ |
| 102 *poutbuf_size = 0; | 93 if(s->frame_size){ |
| 103 buf_ptr = buf; | 94 int inc= FFMIN(buf_size - i, s->frame_size); |
| 104 while (buf_size > 0) { | 95 i += inc; |
| 105 len = s->inbuf_ptr - s->inbuf; | 96 s->frame_size -= inc; |
| 106 if (s->frame_size == 0) { | 97 |
| 107 /* special case for next header for first frame in free | 98 if(!s->frame_size){ |
| 108 format case (XXX: find a simpler method) */ | 99 next= i; |
| 109 if (s->free_format_next_header != 0) { | 100 break; |
| 110 AV_WB32(s->inbuf, s->free_format_next_header); | |
| 111 s->inbuf_ptr = s->inbuf + 4; | |
| 112 s->free_format_next_header = 0; | |
| 113 goto got_header; | |
| 114 } | 101 } |
| 115 /* no header seen : find one. We need at least MPA_HEADER_SIZE | 102 }else{ |
| 116 bytes to parse it */ | 103 while(i<buf_size){ |
| 117 len = FFMIN(MPA_HEADER_SIZE - len, buf_size); | 104 int ret, sr, channels, bit_rate, frame_size; |
| 118 if (len > 0) { | |
| 119 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 120 buf_ptr += len; | |
| 121 buf_size -= len; | |
| 122 s->inbuf_ptr += len; | |
| 123 } | |
| 124 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
| 125 got_header: | |
| 126 header = AV_RB32(s->inbuf); | |
| 127 | 105 |
| 128 ret = ff_mpa_decode_header(avctx, header, &sr, &channels, &frame_size, &bit_rate); | 106 state= (state<<8) + buf[i++]; |
| 129 if (ret < 0) { | 107 |
| 108 ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate); | |
| 109 if (ret < 4) { | |
| 130 s->header_count= -2; | 110 s->header_count= -2; |
| 131 /* no sync found : move by one byte (inefficient, but simple!) */ | |
| 132 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
| 133 s->inbuf_ptr--; | |
| 134 dprintf(avctx, "skip %x\n", header); | |
| 135 /* reset free format frame size to give a chance | |
| 136 to get a new bitrate */ | |
| 137 s->free_format_frame_size = 0; | |
| 138 } else { | 111 } else { |
| 139 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) | 112 if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) |
| 140 s->header_count= -3; | 113 s->header_count= -3; |
| 141 s->header= header; | 114 s->header= state; |
| 142 s->header_count++; | 115 s->header_count++; |
| 143 s->frame_size = ret; | 116 s->frame_size = ret-4; |
| 144 | 117 |
| 145 #if 0 | |
| 146 /* free format: prepare to compute frame size */ | |
| 147 if (ff_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) { | |
| 148 s->frame_size = -1; | |
| 149 } | |
| 150 #endif | |
| 151 if(s->header_count > 1){ | 118 if(s->header_count > 1){ |
| 152 avctx->sample_rate= sr; | 119 avctx->sample_rate= sr; |
| 153 avctx->channels = channels; | 120 avctx->channels = channels; |
| 154 avctx->frame_size = frame_size; | 121 avctx->frame_size = frame_size; |
| 155 avctx->bit_rate = bit_rate; | 122 avctx->bit_rate = bit_rate; |
| 156 } | 123 } |
| 124 break; | |
| 157 } | 125 } |
| 158 } | 126 } |
| 159 } else | |
| 160 #if 0 | |
| 161 if (s->frame_size == -1) { | |
| 162 /* free format : find next sync to compute frame size */ | |
| 163 len = MPA_MAX_CODED_FRAME_SIZE - len; | |
| 164 if (len > buf_size) | |
| 165 len = buf_size; | |
| 166 if (len == 0) { | |
| 167 /* frame too long: resync */ | |
| 168 s->frame_size = 0; | |
| 169 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
| 170 s->inbuf_ptr--; | |
| 171 } else { | |
| 172 uint8_t *p, *pend; | |
| 173 uint32_t header1; | |
| 174 int padding; | |
| 175 | |
| 176 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 177 /* check for header */ | |
| 178 p = s->inbuf_ptr - 3; | |
| 179 pend = s->inbuf_ptr + len - 4; | |
| 180 while (p <= pend) { | |
| 181 header = AV_RB32(p); | |
| 182 header1 = AV_RB32(s->inbuf); | |
| 183 /* check with high probability that we have a | |
| 184 valid header */ | |
| 185 if ((header & SAME_HEADER_MASK) == | |
| 186 (header1 & SAME_HEADER_MASK)) { | |
| 187 /* header found: update pointers */ | |
| 188 len = (p + 4) - s->inbuf_ptr; | |
| 189 buf_ptr += len; | |
| 190 buf_size -= len; | |
| 191 s->inbuf_ptr = p; | |
| 192 /* compute frame size */ | |
| 193 s->free_format_next_header = header; | |
| 194 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
| 195 padding = (header1 >> 9) & 1; | |
| 196 if (s->layer == 1) | |
| 197 s->free_format_frame_size -= padding * 4; | |
| 198 else | |
| 199 s->free_format_frame_size -= padding; | |
| 200 dprintf(avctx, "free frame size=%d padding=%d\n", | |
| 201 s->free_format_frame_size, padding); | |
| 202 ff_mpegaudio_decode_header((MPADecodeHeader *)s, header1); | |
| 203 goto next_data; | |
| 204 } | |
| 205 p++; | |
| 206 } | |
| 207 /* not found: simply increase pointers */ | |
| 208 buf_ptr += len; | |
| 209 s->inbuf_ptr += len; | |
| 210 buf_size -= len; | |
| 211 } | |
| 212 } else | |
| 213 #endif | |
| 214 if (len < s->frame_size) { | |
| 215 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
| 216 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
| 217 len = FFMIN(s->frame_size - len, buf_size); | |
| 218 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 219 buf_ptr += len; | |
| 220 s->inbuf_ptr += len; | |
| 221 buf_size -= len; | |
| 222 } | |
| 223 | |
| 224 if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf | |
| 225 && buf_size + buf_ptr - buf >= s->frame_size){ | |
| 226 *poutbuf = buf; | |
| 227 *poutbuf_size = s->frame_size; | |
| 228 buf_ptr = buf + s->frame_size; | |
| 229 s->inbuf_ptr = s->inbuf; | |
| 230 s->frame_size = 0; | |
| 231 break; | |
| 232 } | |
| 233 | |
| 234 // next_data: | |
| 235 if (s->frame_size > 0 && | |
| 236 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { | |
| 237 *poutbuf = s->inbuf; | |
| 238 *poutbuf_size = s->inbuf_ptr - s->inbuf; | |
| 239 s->inbuf_ptr = s->inbuf; | |
| 240 s->frame_size = 0; | |
| 241 break; | |
| 242 } | 127 } |
| 243 } | 128 } |
| 244 return buf_ptr - buf; | 129 |
| 130 pc->state= state; | |
| 131 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { | |
| 132 *poutbuf = NULL; | |
| 133 *poutbuf_size = 0; | |
| 134 return buf_size; | |
| 135 } | |
| 136 | |
| 137 *poutbuf = buf; | |
| 138 *poutbuf_size = buf_size; | |
| 139 return next; | |
| 245 } | 140 } |
| 246 | 141 |
| 247 | 142 |
| 248 AVCodecParser mpegaudio_parser = { | 143 AVCodecParser mpegaudio_parser = { |
| 249 { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 }, | 144 { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 }, |
| 250 sizeof(MpegAudioParseContext), | 145 sizeof(MpegAudioParseContext), |
| 251 mpegaudio_parse_init, | 146 NULL, |
| 252 mpegaudio_parse, | 147 mpegaudio_parse, |
| 253 NULL, | 148 NULL, |
| 254 }; | 149 }; |
