static int mp3_write_header(struct AVFormatContext *s) { MP3Context *mp3 = s->priv_data; int ret, i; if (mp3->id3v2_version && mp3->id3v2_version != 3 && mp3->id3v2_version != 4) { av_log(s, AV_LOG_ERROR, "Invalid ID3v2 version requested: %d. Only " "3, 4 or 0 (disabled) are allowed.\n", mp3->id3v2_version); return AVERROR(EINVAL); } /* check the streams -- we want exactly one audio and arbitrary number of * video (attached pictures) */ mp3->audio_stream_idx = -1; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { if (mp3->audio_stream_idx >= 0 || st->codecpar->codec_id != AV_CODEC_ID_MP3) { av_log(s, AV_LOG_ERROR, "Invalid audio stream. Exactly one MP3 " "audio stream is required.\n"); return AVERROR(EINVAL); } mp3->audio_stream_idx = i; } else if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) { av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in MP3.\n"); return AVERROR(EINVAL); } } if (mp3->audio_stream_idx < 0) { av_log(s, AV_LOG_ERROR, "No audio stream present.\n"); return AVERROR(EINVAL); } mp3->pics_to_write = s->nb_streams - 1; if (mp3->pics_to_write && !mp3->id3v2_version) { av_log(s, AV_LOG_ERROR, "Attached pictures were requested, but the " "ID3v2 header is disabled.\n"); return AVERROR(EINVAL); } if (mp3->id3v2_version) { ff_id3v2_start(&mp3->id3, s->pb, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC); ret = ff_id3v2_write_metadata(s, &mp3->id3); if (ret < 0) return ret; } if (!mp3->pics_to_write) { if (mp3->id3v2_version) ff_id3v2_finish(&mp3->id3, s->pb); mp3_write_xing(s); } return 0; }
static int mp3_queue_flush(AVFormatContext *s) { MP3Context *mp3 = s->priv_data; AVPacketList *pktl; int ret = 0, write = 1; ff_id3v2_finish(&mp3->id3, s->pb); mp3_write_xing(s); while ((pktl = mp3->queue)) { if (write && (ret = mp3_write_audio_packet(s, &pktl->pkt)) < 0) write = 0; av_free_packet(&pktl->pkt); mp3->queue = pktl->next; av_freep(&pktl); } mp3->queue_end = NULL; return ret; }