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 <jamr...@gmail.com>
---
 libavformat/matroskaenc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 68c91fa..1076a55 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -100,6 +100,7 @@ typedef struct MatroskaMuxContext {
     int64_t         duration;
     int64_t         sample_rate_offset;
     int             sample_rate;
+    int64_t         codecpriv_offset;
     mkv_seekhead    *main_seekhead;
     mkv_cues        *cues;
     mkv_track       *tracks;
@@ -930,6 +931,8 @@ static int mkv_write_track(AVFormatContext *s, 
MatroskaMuxContext *mkv,
         av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are 
supported for Matroska.\n");
         break;
     }
+
+    mkv->codecpriv_offset = avio_tell(pb);
     ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id);
     if (ret < 0)
         return ret;
@@ -1584,6 +1587,29 @@ static int mkv_check_new_extra_data(AVFormatContext *s, 
AVPacket *pkt)
             return AVERROR(EINVAL);
         }
         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)
+                return ret;
+            memcpy(codecpriv_par->extradata, side_data, side_data_size);
+            curpos = avio_tell(s->pb);
+            avio_seek(s->pb, mkv->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:
         if (side_data_size)
             av_log(s, AV_LOG_DEBUG, "Ignoring new extradata in a packet for 
stream %d.\n", pkt->stream_index);
-- 
2.10.1

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to