static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) { MP3Context *mp3 = s->priv_data; if (mp3->xing_offset && pkt->size >= 4) { MPADecodeHeader c; uint32_t h; h = AV_RB32(pkt->data); if (ff_mpa_check_header(h) == 0) { avpriv_mpegaudio_decode_header(&c, h); if (!mp3->initial_bitrate) mp3->initial_bitrate = c.bit_rate; if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate)) mp3->has_variable_bitrate = 1; } mp3_xing_add_frame(mp3, pkt); if (mp3->xing_offset) { mp3->audio_size += pkt->size; mp3->audio_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), mp3->audio_crc, pkt->data, pkt->size); } } return ff_raw_write_packet(s, pkt); }
static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { MP3DecContext *mp3 = s->priv_data; AVIndexEntry *ie; AVStream *st = s->streams[0]; int64_t ret = av_index_search_timestamp(st, timestamp, flags); uint32_t header = 0; if (!mp3->xing_toc) return AVERROR(ENOSYS); if (ret < 0) return ret; ie = &st->index_entries[ret]; ret = avio_seek(s->pb, ie->pos, SEEK_SET); if (ret < 0) return ret; while (!s->pb->eof_reached) { header = (header << 8) + avio_r8(s->pb); if (ff_mpa_check_header(header) >= 0) { ff_update_cur_dts(s, st, ie->timestamp); ret = avio_seek(s->pb, -4, SEEK_CUR); return (ret >= 0) ? 0 : ret; } } return AVERROR_EOF; }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (avpriv_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = avio_rb32(s->pb); if(v & 0x1) frames = avio_rb32(s->pb); if(v & 0x2) size = avio_rb32(s->pb); } /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ avio_seek(s->pb, base + 4 + 32, SEEK_SET); v = avio_rb32(s->pb); if(v == MKBETAG('V', 'B', 'R', 'I')) { /* Check tag version */ if(avio_rb16(s->pb) == 1) { /* skip delay and quality */ avio_skip(s->pb, 4); size = avio_rb32(s->pb); frames = avio_rb32(s->pb); } } if(!frames && !size) return -1; /* Skip the vbr tag frame */ avio_seek(s->pb, base + vbrtag_size, SEEK_SET); spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ if(frames) st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->time_base); if(size && frames) st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf); return 0; }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { uint32_t v, spf; int frames = -1; /* Total number of frames in file */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeContext c; int vbrtag_size = 0; v = get_be32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (ff_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; /* Check for Xing / Info tag */ url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); v = get_be32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = get_be32(s->pb); if(v & 0x1) frames = get_be32(s->pb); } /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ url_fseek(s->pb, base + 4 + 32, SEEK_SET); v = get_be32(s->pb); if(v == MKBETAG('V', 'B', 'R', 'I')) { /* Check tag version */ if(get_be16(s->pb) == 1) { /* skip delay, quality and total bytes */ url_fseek(s->pb, 8, SEEK_CUR); frames = get_be32(s->pb); } } if(frames < 0) return -1; /* Skip the vbr tag frame */ url_fseek(s->pb, base + vbrtag_size, SEEK_SET); spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->time_base); return 0; }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { MP3Context *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; int is_cbr; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (avpriv_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) { v = avio_rb32(s->pb); if(v & XING_FLAG_FRAMES) frames = avio_rb32(s->pb); if(v & XING_FLAG_SIZE) size = avio_rb32(s->pb); if (v & XING_FLAG_TOC && frames) read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->time_base)); if(v & 8) avio_skip(s->pb, 4); v = avio_rb32(s->pb); if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { avio_skip(s->pb, 21-4); v= avio_rb24(s->pb); mp3->start_pad = v>>12; mp3-> end_pad = v&4095; st->skip_samples = mp3->start_pad + 528 + 1; av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { MP3Context *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (avpriv_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = avio_rb32(s->pb); if(v & 0x1) frames = avio_rb32(s->pb); if(v & 0x2) size = avio_rb32(s->pb); if(v & 4) avio_skip(s->pb, 100); if(v & 8) avio_skip(s->pb, 4); v = avio_rb32(s->pb); if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { avio_skip(s->pb, 21-4); v= avio_rb24(s->pb); mp3->start_pad = v>>12; mp3-> end_pad = v&4095; st->skip_samples = mp3->start_pad + 528 + 1; av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); }
/* 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, int *channels, int *frame_size, int *bit_rate) { MPADecodeHeader s1, *s = &s1; 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->codec_id = CODEC_ID_MP1; *frame_size = 384; break; case 2: avctx->codec_id = CODEC_ID_MP2; *frame_size = 1152; break; default: case 3: avctx->codec_id = CODEC_ID_MP3; if (s->lsf) *frame_size = 576; else *frame_size = 1152; break; } *sample_rate = s->sample_rate; *channels = s->nb_channels; *bit_rate = s->bit_rate; avctx->sub_id = s->layer; return s->frame_size; }