#include "parser.h"
#include "mpegaudio.h"
+#include "mpegaudiodecheader.h"
typedef struct MpegAudioParseContext {
#define SAME_HEADER_MASK \
(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
+/* useful helper to get mpeg audio stream infos. Return -1 if error in
+ header, otherwise the coded frame size in bytes */
+int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate)
+{
+ MPADecodeContext s1, *s = &s1;
+ s1.avctx = avctx;
+
+ if (ff_mpa_check_header(head) != 0)
+ return -1;
+
+ if (ff_mpegaudio_decode_header(s, head) != 0) {
+ return -1;
+ }
+
+ switch(s->layer) {
+ case 1:
+ avctx->frame_size = 384;
+ break;
+ case 2:
+ avctx->frame_size = 1152;
+ break;
+ default:
+ case 3:
+ if (s->lsf)
+ avctx->frame_size = 576;
+ else
+ avctx->frame_size = 1152;
+ break;
+ }
+
+ *sample_rate = s->sample_rate;
+ avctx->channels = s->nb_channels;
+ avctx->bit_rate = s->bit_rate;
+ avctx->sub_id = s->layer;
+ return s->frame_size;
+}
+
static int mpegaudio_parse_init(AVCodecParserContext *s1)
{
MpegAudioParseContext *s = s1->priv_data;
/* special case for next header for first frame in free
format case (XXX: find a simpler method) */
if (s->free_format_next_header != 0) {
- s->inbuf[0] = s->free_format_next_header >> 24;
- s->inbuf[1] = s->free_format_next_header >> 16;
- s->inbuf[2] = s->free_format_next_header >> 8;
- s->inbuf[3] = s->free_format_next_header;
+ AV_WB32(s->inbuf, s->free_format_next_header);
s->inbuf_ptr = s->inbuf + 4;
s->free_format_next_header = 0;
goto got_header;
}
if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
got_header:
- header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
- (s->inbuf[2] << 8) | s->inbuf[3];
+ header = AV_RB32(s->inbuf);
- ret = mpa_decode_header(avctx, header, &sr);
+ ret = ff_mpa_decode_header(avctx, header, &sr);
if (ret < 0) {
s->header_count= -2;
/* no sync found : move by one byte (inefficient, but simple!) */
#if 0
/* free format: prepare to compute frame size */
- if (decode_header(s, header) == 1) {
+ if (ff_mpegaudio_decode_header(s, header) == 1) {
s->frame_size = -1;
}
#endif
+ if(s->header_count > 1)
+ avctx->sample_rate= sr;
}
- if(s->header_count > 1)
- avctx->sample_rate= sr;
}
} else
#if 0
p = s->inbuf_ptr - 3;
pend = s->inbuf_ptr + len - 4;
while (p <= pend) {
- header = (p[0] << 24) | (p[1] << 16) |
- (p[2] << 8) | p[3];
- header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
- (s->inbuf[2] << 8) | s->inbuf[3];
+ header = AV_RB32(p);
+ header1 = AV_RB32(s->inbuf);
/* check with high probability that we have a
valid header */
if ((header & SAME_HEADER_MASK) ==
s->free_format_frame_size -= padding;
dprintf(avctx, "free frame size=%d padding=%d\n",
s->free_format_frame_size, padding);
- decode_header(s, header1);
+ ff_mpegaudio_decode_header(s, header1);
goto next_data;
}
p++;