diff mbox

[FFmpeg-devel,1/3] aacdec: do not mutate input packet metadata

Message ID 20170308124012.27793-1-nfxjfg@googlemail.com
State Accepted
Commit fcfc78cbabb6b454aa9e39ad32ae7a766dcf33d8
Headers show

Commit Message

wm4 March 8, 2017, 12:40 p.m. UTC
Apparently the demuxer outputs the wrong padding for HE-AAC (based on
the raw sample rate, or so). aacdec contains a hack to adjust the muxer
padding accordingly before it's used to trim the decoder output. This
modified the packet side data, which in combination with the old
decoding API would change the packet the user passed to the decoder.
This is clearly not allowed, and it breaks running some gapless fate
tests with "-fflags +keepside" applied (without keepside, the packet
metadata is typically newly allocated, essentially making a copy and not
modifying the user's input packet).

This should probably be fixed in the demuxer (and consequently also the
muxer), but for now only fix the immediate problem.

Regression since 946ed78f5f8 (2012).
---
 libavcodec/aacdec_template.c | 8 ++------
 libavcodec/internal.h        | 2 ++
 libavcodec/utils.c           | 4 +++-
 3 files changed, 7 insertions(+), 7 deletions(-)

Comments

Michael Niedermayer March 8, 2017, 1:28 p.m. UTC | #1
On Wed, Mar 08, 2017 at 01:40:10PM +0100, wm4 wrote:
> Apparently the demuxer outputs the wrong padding for HE-AAC (based on
> the raw sample rate, or so). aacdec contains a hack to adjust the muxer
> padding accordingly before it's used to trim the decoder output. This
> modified the packet side data, which in combination with the old
> decoding API would change the packet the user passed to the decoder.
> This is clearly not allowed, and it breaks running some gapless fate
> tests with "-fflags +keepside" applied (without keepside, the packet
> metadata is typically newly allocated, essentially making a copy and not
> modifying the user's input packet).
> 
> This should probably be fixed in the demuxer (and consequently also the
> muxer), but for now only fix the immediate problem.
> 
> Regression since 946ed78f5f8 (2012).
> ---
>  libavcodec/aacdec_template.c | 8 ++------
>  libavcodec/internal.h        | 2 ++
>  libavcodec/utils.c           | 4 +++-
>  3 files changed, 7 insertions(+), 7 deletions(-)

this patch LGTM

thx

[...]
wm4 March 9, 2017, 9:21 a.m. UTC | #2
On Wed, 8 Mar 2017 14:28:33 +0100
Michael Niedermayer <michael@niedermayer.cc> wrote:

> On Wed, Mar 08, 2017 at 01:40:10PM +0100, wm4 wrote:
> > Apparently the demuxer outputs the wrong padding for HE-AAC (based on
> > the raw sample rate, or so). aacdec contains a hack to adjust the muxer
> > padding accordingly before it's used to trim the decoder output. This
> > modified the packet side data, which in combination with the old
> > decoding API would change the packet the user passed to the decoder.
> > This is clearly not allowed, and it breaks running some gapless fate
> > tests with "-fflags +keepside" applied (without keepside, the packet
> > metadata is typically newly allocated, essentially making a copy and not
> > modifying the user's input packet).
> > 
> > This should probably be fixed in the demuxer (and consequently also the
> > muxer), but for now only fix the immediate problem.
> > 
> > Regression since 946ed78f5f8 (2012).
> > ---
> >  libavcodec/aacdec_template.c | 8 ++------
> >  libavcodec/internal.h        | 2 ++
> >  libavcodec/utils.c           | 4 +++-
> >  3 files changed, 7 insertions(+), 7 deletions(-)  
> 
> this patch LGTM
> 

Pushed.
diff mbox

Patch

diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 4367e74cf7..98a3240597 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -3095,12 +3095,8 @@  static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
         ac->oc[1].status = OC_LOCKED;
     }
 
-    if (multiplier) {
-        int side_size;
-        const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
-        if (side && side_size>=4)
-            AV_WL32(side, 2*AV_RL32(side));
-    }
+    if (multiplier)
+        avctx->internal->skip_samples_multiplier = 2;
 
     if (!ac->frame->data[0] && samples) {
         av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index c92dba472a..e3286d2a58 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -174,6 +174,8 @@  typedef struct AVCodecInternal {
     AVFrame *buffer_frame;
     int draining_done;
     int showed_multi_packet_warning;
+
+    int skip_samples_multiplier;
 } AVCodecInternal;
 
 struct AVCodecDefault {
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index db3adb18d4..3c8a9cc13e 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1305,6 +1305,8 @@  int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         goto free_and_end;
     }
 
+    avctx->internal->skip_samples_multiplier = 1;
+
     if (codec->priv_data_size > 0) {
         if (!avctx->priv_data) {
             avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -2387,7 +2389,7 @@  int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
 
         side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
         if(side && side_size>=10) {
-            avctx->internal->skip_samples = AV_RL32(side);
+            avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier;
             discard_padding = AV_RL32(side + 4);
             av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n",
                    avctx->internal->skip_samples, (int)discard_padding);