[FFmpeg-devel] lavc/opus: Create extradata if it is missing

Submitted by Carl Eugen Hoyos on Sept. 19, 2019, 10:32 p.m.

Details

Message ID CAB0OVGqiFSF001jQeuBALTMUN61NO23gjGrza-RNPM9uQdq1gw@mail.gmail.com
State New
Headers show

Commit Message

Carl Eugen Hoyos Sept. 19, 2019, 10:32 p.m.
Hi!

Attached patch fixes remuxing opus from sdp, reported by Juan Navarro.

Please comment, Carl Eugen

Comments

Juan Navarro Oct. 1, 2019, 2:57 p.m.
This patch fixes the remuxing of OPUS audio into MP4 container, as per the
issue described here:
http://ffmpeg.org/pipermail/ffmpeg-user/2019-September/045274.html
but introduces a regression for WEBM recordings.

(Originally posted here, with attachments:
http://ffmpeg.org/pipermail/ffmpeg-user/2019-September/045475.html)

I'm afraid some further testing shows that the patch did actually fix
the case of missing extradata when recording OPUS with MP4, but it in
turn breaks the case of WEBM. Didn't try other formats, yet, but there
is a clear regression for the WEBM format.

Report logs attached for both before and after applying the patch. No
meaningful differences in the log, though. The only visible effect of
the regression is when trying to open up the WEBM file in VLC. ffplay is
able to play it, though.

VLC says this when trying to play the WEBM file:
[00007f8978053e20] opus decoder error: cannot read Opus header
[00007f8978053e20] opus decoder error: initial Opus header is corrupted

Patch hide | download patch | download mbox

From 957e568e7dd1c2acc0ea29dad122919c8c9e05ce Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Fri, 20 Sep 2019 00:29:16 +0200
Subject: [PATCH] lavc/opus: Create extradata if it is missing.

Fixes streamcopying from sdp.
Reported-by: Juan Navarro, juan dot navarro at gmx dot es
---
 libavcodec/opus.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/libavcodec/opus.c b/libavcodec/opus.c
index f74278a7e3..2f1045facb 100644
--- a/libavcodec/opus.c
+++ b/libavcodec/opus.c
@@ -307,12 +307,16 @@  av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
                    "Multichannel configuration without extradata.\n");
             return AVERROR(EINVAL);
         }
-        extradata      = opus_default_extradata;
-        extradata_size = sizeof(opus_default_extradata);
-    } else {
-        extradata = avctx->extradata;
-        extradata_size = avctx->extradata_size;
+        avctx->extradata = av_malloc(sizeof(opus_default_extradata) + AV_INPUT_BUFFER_PADDING_SIZE);
+        if (!avctx->extradata)
+            return AVERROR(ENOMEM);
+        memcpy(avctx->extradata, opus_default_extradata, sizeof(opus_default_extradata));
+        memset(avctx->extradata + sizeof(opus_default_extradata), 0, AV_INPUT_BUFFER_PADDING_SIZE);
+        avctx->extradata_size = sizeof(opus_default_extradata);
+        avctx->extradata[9] = avctx->channels;
     }
+    extradata = avctx->extradata;
+    extradata_size = avctx->extradata_size;
 
     if (extradata_size < 19) {
         av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
@@ -330,7 +334,7 @@  av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
     if (avctx->internal)
         avctx->internal->skip_samples = avctx->delay;
 
-    channels = avctx->extradata ? extradata[9] : (avctx->channels == 1) ? 1 : 2;
+    channels = extradata[9];
     if (!channels) {
         av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n");
         return AVERROR_INVALIDDATA;
-- 
2.23.0