1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

matroskaenc: write updated STREAMINFO metadata for FLAC streams if available

FLAC streams originating from the FLAC encoder send updated and more
complete STREAMINFO metadata as part of the last packet, so write that
to CodecPrivate instead of the incomplete one available in extradata
during init.

Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
James Almer 2016-11-09 18:38:24 -03:00 committed by Anton Khirnov
parent f4bf236338
commit 98cae966c7

View File

@ -83,6 +83,7 @@ typedef struct mkv_track {
int write_dts; int write_dts;
int sample_rate; int sample_rate;
int64_t sample_rate_offset; int64_t sample_rate_offset;
int64_t codecpriv_offset;
int64_t ts_offset; int64_t ts_offset;
} mkv_track; } mkv_track;
@ -931,6 +932,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
break; break;
} }
mkv->tracks[i].codecpriv_offset = avio_tell(pb);
ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id); ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1586,6 +1588,31 @@ static int mkv_check_new_extra_data(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
break; break;
case AV_CODEC_ID_FLAC:
if (side_data_size && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
AVCodecParameters *codecpriv_par;
int64_t curpos;
if (side_data_size != par->extradata_size) {
av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n",
pkt->stream_index);
return AVERROR(EINVAL);
}
codecpriv_par = avcodec_parameters_alloc();
if (!codecpriv_par)
return AVERROR(ENOMEM);
ret = avcodec_parameters_copy(codecpriv_par, par);
if (ret < 0) {
avcodec_parameters_free(&codecpriv_par);
return ret;
}
memcpy(codecpriv_par->extradata, side_data, side_data_size);
curpos = avio_tell(s->pb);
avio_seek(s->pb, track->codecpriv_offset, SEEK_SET);
mkv_write_codecprivate(s, s->pb, codecpriv_par, 1, 0);
avio_seek(s->pb, curpos, SEEK_SET);
avcodec_parameters_free(&codecpriv_par);
}
break;
default: default:
if (side_data_size) if (side_data_size)
av_log(s, AV_LOG_DEBUG, "Ignoring new extradata in a packet for stream %d.\n", pkt->stream_index); av_log(s, AV_LOG_DEBUG, "Ignoring new extradata in a packet for stream %d.\n", pkt->stream_index);