summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-03 17:29:53 +0200
committerwm4 <wm4@nowhere>2014-10-03 23:03:22 +0200
commitcf2add4ff98c71b125ddbff041a85b8fe3b4cc5b (patch)
treef151fdfae50b374ea37be2c47a677b9ce0486dc5
parenta037313c1092e9a9a3d94085a83954c477076ab0 (diff)
downloadmpv-cf2add4ff98c71b125ddbff041a85b8fe3b4cc5b.tar.bz2
mpv-cf2add4ff98c71b125ddbff041a85b8fe3b4cc5b.tar.xz
audio: skip samples and adjust timestamps ourselves
This gets rid of this warning: Could not update timestamps for skipped samples. This required an API addition to FFmpeg (otherwise it would instead doing arithmetic on the timestamps itself), so whether it works depends on the FFmpeg version.
-rw-r--r--audio/decode/ad_lavc.c24
-rwxr-xr-xold-configure6
-rw-r--r--wscript6
3 files changed, 34 insertions, 2 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index cb65cda184..b138c5d69c 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -25,6 +25,7 @@
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/common.h>
+#include <libavutil/intreadwrite.h>
#include "talloc.h"
@@ -100,6 +101,22 @@ static void set_data_from_avframe(struct dec_audio *da)
da->decoded.samples = priv->avframe->nb_samples;
for (int n = 0; n < da->decoded.num_planes; n++)
da->decoded.planes[n] = priv->avframe->data[n];
+
+#if HAVE_AVFRAME_SKIP_SAMPLES
+ AVFrameSideData *sd =
+ av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
+ if (sd && sd->size >= 10) {
+ char *d = sd->data;
+ uint32_t skip = AV_RL32(d + 0);
+ uint32_t pad = AV_RL32(d + 4);
+ if (skip <= da->decoded.samples) {
+ mp_audio_skip_samples(&da->decoded, skip);
+ da->pts_offset += skip;
+ }
+ if (pad <= da->decoded.samples)
+ da->decoded.samples -= pad;
+ }
+#endif
}
static int init(struct dec_audio *da, const char *decoder)
@@ -139,6 +156,9 @@ static int init(struct dec_audio *da, const char *decoder)
av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc,
AV_OPT_SEARCH_CHILDREN);
+ // Let decoder add AV_FRAME_DATA_SKIP_SAMPLES.
+ av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN);
+
mp_set_avopts(da->log, lavc_context, opts->avopts);
lavc_context->codec_tag = sh->format;
@@ -258,14 +278,14 @@ static int decode_packet(struct dec_audio *da)
if (!got_frame)
return mpkt ? AD_OK : AD_EOF;
- set_data_from_avframe(da);
-
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, NULL);
if (out_pts != MP_NOPTS_VALUE) {
da->pts = out_pts;
da->pts_offset = 0;
}
+ set_data_from_avframe(da);
+
MP_DBG(da, "Decoded %d -> %d samples\n", in_len, da->decoded.samples);
return 0;
}
diff --git a/old-configure b/old-configure
index a0cd853a6d..bd31bfc1c1 100755
--- a/old-configure
+++ b/old-configure
@@ -829,6 +829,12 @@ api_statement_check \
'av_frame_get_metadata(NULL)'
api_statement_check \
+ "libavutil AVFrame skip samples metadata" \
+ HAVE_AVFRAME_SKIP_SAMPLES \
+ libavutil/frame.h \
+ 'enum AVFrameSideDataType type = AV_FRAME_DATA_SKIP_SAMPLES'
+
+api_statement_check \
"libavutil QP API" \
HAVE_AVUTIL_QP_API \
libavutil/frame.h \
diff --git a/wscript b/wscript
index a72e69a9b5..4ac0479f57 100644
--- a/wscript
+++ b/wscript
@@ -422,6 +422,12 @@ Libav libraries ({0}). Aborting.".format(" ".join(libav_pkg_config_checks))
'func': check_statement('libavutil/frame.h',
'av_frame_get_metadata(NULL)',
use='libav')
+ }, {
+ 'name': 'avframe-skip-samples',
+ 'desc': 'libavutil AVFrame skip samples metadata',
+ 'func': check_statement('libavutil/frame.h',
+ 'enum AVFrameSideDataType type = AV_FRAME_DATA_SKIP_SAMPLES',
+ use='libav')
}
]