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); }
/** * 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; }
static int libshine_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { SHINEContext *s = avctx->priv_data; MPADecodeHeader hdr; unsigned char *data; long written; int ret, len; if (frame) data = shine_encode_buffer(s->shine, (int16_t **)frame->data, &written); else data = shine_flush(s->shine, &written); if (written < 0) return -1; if (written > 0) { if (s->buffer_index + written > BUFFER_SIZE) { av_log(avctx, AV_LOG_ERROR, "internal buffer too small\n"); return AVERROR_BUG; } memcpy(s->buffer + s->buffer_index, data, written); s->buffer_index += written; } if (frame) { if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) return ret; } if (s->buffer_index < 4 || !s->afq.frame_count) return 0; if (avpriv_mpegaudio_decode_header(&hdr, AV_RB32(s->buffer))) { av_log(avctx, AV_LOG_ERROR, "free format output not supported\n"); return -1; } len = hdr.frame_size; if (len <= s->buffer_index) { if ((ret = ff_alloc_packet2(avctx, avpkt, len))) return ret; memcpy(avpkt->data, s->buffer, len); s->buffer_index -= len; memmove(s->buffer, s->buffer + len, s->buffer_index); ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, &avpkt->duration); avpkt->size = len; *got_packet_ptr = 1; } 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) { uint32_t v, spf; MPADecodeHeader c; int vbrtag_size = 0; MP3DecContext *mp3 = s->priv_data; int ret; ffio_init_checksum(s->pb, ff_crcA001_update, 0); v = avio_rb32(s->pb); ret = avpriv_mpegaudio_decode_header(&c, v); if (ret < 0) return ret; else if (ret == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ mp3->frames = 0; mp3->size = 0; mp3_parse_info_tag(s, st, &c, spf); mp3_parse_vbri_tag(s, st, base); if (!mp3->frames && !mp3->size) return -1; /* Skip the vbr tag frame */ avio_seek(s->pb, base + vbrtag_size, SEEK_SET); if (mp3->frames) st->duration = av_rescale_q(mp3->frames, (AVRational){spf, c.sample_rate}, st->time_base); if (mp3->size && mp3->frames && !mp3->is_cbr) st->codec->bit_rate = av_rescale(mp3->size, 8 * c.sample_rate, mp3->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) { 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); }
static int check(AVIOContext *pb, int64_t pos, int64_t *out_pos) { MPADecodeHeader mh = { 0 }; int i; uint32_t header; int64_t off = 0; for (i = 0; i < SEEK_PACKETS; i++) { off = avio_seek(pb, pos + mh.frame_size, SEEK_SET); if (off < 0) break; header = avio_rb32(pb); if (avpriv_mpegaudio_decode_header(&mh, header)) break; out_pos[i] = off; } return i; }
/* * Write an empty XING header and initialize respective data. */ static void mp3_write_xing(AVFormatContext *s) { MP3Context *mp3 = s->priv_data; AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec; AVDictionaryEntry *enc = av_dict_get(s->streams[mp3->audio_stream_idx]->metadata, "encoder", NULL, 0); AVIOContext *dyn_ctx; int32_t header; MPADecodeHeader mpah; int srate_idx, i, channels; int bitrate_idx; int best_bitrate_idx; int best_bitrate_error = INT_MAX; int ret; int ver = 0; int lsf, bytes_needed; if (!s->pb->seekable || !mp3->write_xing) return; for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) { const uint16_t base_freq = avpriv_mpa_freq_tab[i]; if (codec->sample_rate == base_freq) ver = 0x3; // MPEG 1 else if (codec->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2 else if (codec->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5 else continue; srate_idx = i; break; } if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) { av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing " "header.\n"); return; } switch (codec->channels) { case 1: channels = MPA_MONO; break; case 2: channels = MPA_STEREO; break; default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, " "not writing Xing header.\n"); return; } /* dummy MPEG audio header */ header = 0xff << 24; // sync header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/ header |= (srate_idx << 2) << 8; header |= channels << 6; lsf = !((header & (1 << 20) && header & (1 << 19))); mp3->xing_offset = xing_offtbl[ver != 3][channels == 1] + 4; bytes_needed = mp3->xing_offset + XING_SIZE; for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) { int bit_rate = 1000 * avpriv_mpa_bitrate_tab[lsf][3 - 1][bitrate_idx]; int error = FFABS(bit_rate - codec->bit_rate); if (error < best_bitrate_error){ best_bitrate_error = error; best_bitrate_idx = bitrate_idx; } } for (bitrate_idx = best_bitrate_idx; bitrate_idx < 15; bitrate_idx++) { int32_t mask = bitrate_idx << (4 + 8); header |= mask; avpriv_mpegaudio_decode_header(&mpah, header); if (bytes_needed <= mpah.frame_size) break; header &= ~mask; } ret = avio_open_dyn_buf(&dyn_ctx); if (ret < 0) return; avio_wb32(dyn_ctx, header); avpriv_mpegaudio_decode_header(&mpah, header); av_assert0(mpah.frame_size >= bytes_needed); ffio_fill(dyn_ctx, 0, mp3->xing_offset - 4); ffio_wfourcc(dyn_ctx, "Xing"); avio_wb32(dyn_ctx, 0x01 | 0x02 | 0x04 | 0x08); // frames / size / TOC / vbr scale mp3->size = mpah.frame_size; mp3->want = 1; avio_wb32(dyn_ctx, 0); // frames avio_wb32(dyn_ctx, 0); // size // TOC for (i = 0; i < XING_TOC_SIZE; i++) avio_w8(dyn_ctx, 255 * i / XING_TOC_SIZE); // vbr quality // we write it, because some (broken) tools always expect it to be present avio_wb32(dyn_ctx, 0); // encoder short version string if (enc) { uint8_t encoder_str[9] = { 0 }; memcpy(encoder_str, enc->value, FFMIN(strlen(enc->value), sizeof(encoder_str))); avio_write(dyn_ctx, encoder_str, sizeof(encoder_str)); } else ffio_fill(dyn_ctx, 0, 9); avio_w8(dyn_ctx, 0); // tag revision 0 / unknown vbr method avio_w8(dyn_ctx, 0); // unknown lowpass filter value ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate // encoder delay if (codec->initial_padding >= 1 << 12) { av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); avio_wb24(dyn_ctx, 0); } else { avio_wb24(dyn_ctx, codec->initial_padding << 12); } avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain avio_wb16(dyn_ctx, 0); // preset // audio length and CRCs (will be updated later) avio_wb32(dyn_ctx, 0); // music length avio_wb16(dyn_ctx, 0); // music crc avio_wb16(dyn_ctx, 0); // tag crc ffio_fill(dyn_ctx, 0, mpah.frame_size - bytes_needed); mp3->xing_frame_size = avio_close_dyn_buf(dyn_ctx, &mp3->xing_frame); mp3->xing_frame_offset = avio_tell(s->pb); avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size); mp3->audio_size = mp3->xing_frame_size; }
static int mp3_read_probe(AVProbeData *p) { int max_frames, first_frames = 0; int frames, ret; uint32_t header; uint8_t *buf, *buf0, *buf2, *end; buf0 = p->buf; end = p->buf + p->buf_size - sizeof(uint32_t); while(buf0 < end && !*buf0) buf0++; max_frames = 0; buf = buf0; for(; buf < end; buf= buf2+1) { buf2 = buf; for(frames = 0; buf2 < end; frames++) { MPADecodeHeader h; header = AV_RB32(buf2); ret = avpriv_mpegaudio_decode_header(&h, header); if (ret != 0) break; buf2 += h.frame_size; } max_frames = FFMAX(max_frames, frames); if(buf == buf0) first_frames= frames; } // keep this in sync with ac3 probe, both need to avoid // issues with MPEG-files! if (first_frames >= 10) return AVPROBE_SCORE_EXTENSION + 5; if (first_frames >= 4) return AVPROBE_SCORE_EXTENSION + 1; if (max_frames) { int pes = 0, i; unsigned int code = -1; #define VIDEO_ID 0x000001e0 #define AUDIO_ID 0x000001c0 /* do a search for mpegps headers to be able to properly bias * towards mpegps if we detect this stream as both. */ for (i = 0; i<p->buf_size; i++) { code = (code << 8) + p->buf[i]; if ((code & 0xffffff00) == 0x100) { if ((code & 0x1f0) == VIDEO_ID) pes++; else if((code & 0x1e0) == AUDIO_ID) pes++; } } if (pes) max_frames = (max_frames + pes - 1) / pes; } if (max_frames > 500) return AVPROBE_SCORE_EXTENSION; else if (max_frames >= 4) return AVPROBE_SCORE_EXTENSION / 2; else if (max_frames >= 1) return 1; else return 0; //mpegps_mp3_unrecognized_format.mpg has max_frames=3 }