[FFmpeg-devel] [PATCH] avcodec, avutil: allow more control about how samples are skipped
wm4
nfxjfg at googlemail.com
Sat Sep 27 16:47:09 CEST 2014
Add CODEC_FLAG2_SKIP_MANUAL (exposed as "skip_manual"), which makes
the decoder export sample skip information via side data, instead
of applying it automatically. The format of the side data is the
same as AV_PKT_DATA_SKIP_SAMPLES, but since AVPacket and AVFrame
side data constants overlap, AV_FRAME_DATA_SKIP_SAMPLES needs to
be introduced.
This is useful for applications which want to do the timestamp
calculations manually, or which actually want to retrieve the
padding.
---
I'm doing this because my timestamps are doubles, and can't be
expressed in integer timebases. I also think libavcodec shouldn't
mess with timestamps at all, just pass them through.
---
doc/APIchanges | 7 +++++++
libavcodec/avcodec.h | 1 +
libavcodec/options_table.h | 1 +
libavcodec/utils.c | 21 +++++++++++++++++++--
libavutil/frame.h | 12 ++++++++++++
5 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index 7fadab3..c0f34c9 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,13 @@ libavutil: 2014-08-09
API changes, most recent first:
+2014-08-03 - xxxxxxx - lavc 56.x.100 - avcodec.h
+2014-08-03 - xxxxxxx - lavu 54.x.100 - frame.h
+ Add AV_FRAME_DATA_SKIP_SAMPLES. Add lavc CODEC_FLAG2_SKIP_MANUAL and
+ AVOption "skip_manual", which makes lavc export skip information via
+ AV_FRAME_DATA_SKIP_SAMPLES AVFrame side data, instead of skipping and
+ discarding samples automatically.
+
2014-09-24 - xxxxxxx - libpostproc 53.1.100
Add visualization support
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 94e82f7..7598748 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -768,6 +768,7 @@ typedef struct RcOverride{
#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
#define CODEC_FLAG2_SHOW_ALL 0x00400000 ///< Show all frames before the first keyframe
#define CODEC_FLAG2_EXPORT_MVS 0x10000000 ///< Export motion vectors through frame side data
+#define CODEC_FLAG2_SKIP_MANUAL 0x20000000 ///< Do not skip samples and export skip information as frame side data
/* Unsupported options :
* Syntax Arithmetic coding (SAC)
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index ad3d52e..b9b79f9 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -89,6 +89,7 @@ static const AVOption avcodec_options[] = {
{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"},
+{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"},
{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index b27f918..ce0d943 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -2448,6 +2448,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
uint8_t *side;
int side_size;
uint32_t discard_padding = 0;
+ uint8_t skip_reason = 0;
+ uint8_t discard_reason = 0;
// copy to ensure we do not change avpkt
AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp);
@@ -2488,8 +2490,11 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
avctx->internal->skip_samples);
discard_padding = AV_RL32(side + 4);
+ skip_reason = AV_RL8(side + 8);
+ discard_reason = AV_RL8(side + 9);
}
- if (avctx->internal->skip_samples && *got_frame_ptr) {
+ if (avctx->internal->skip_samples && *got_frame_ptr &&
+ !(avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL)) {
if(frame->nb_samples <= avctx->internal->skip_samples){
*got_frame_ptr = 0;
avctx->internal->skip_samples -= frame->nb_samples;
@@ -2518,7 +2523,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
}
}
- if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr) {
+ if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr &&
+ !(avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL)) {
if (discard_padding == frame->nb_samples) {
*got_frame_ptr = 0;
} else {
@@ -2536,6 +2542,17 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
frame->nb_samples -= discard_padding;
}
}
+
+ if ((avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL) && *got_frame_ptr) {
+ AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10);
+ if (fside) {
+ AV_WL32(fside->data, avctx->internal->skip_samples);
+ AV_WL32(fside->data + 4, discard_padding);
+ AV_WL8(fside->data + 8, skip_reason);
+ AV_WL8(fside->data + 9, discard_reason);
+ avctx->internal->skip_samples = 0;
+ }
+ }
fail:
avctx->internal->pkt = NULL;
if (did_split) {
diff --git a/libavutil/frame.h b/libavutil/frame.h
index ee24628..d335bee 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -94,6 +94,18 @@ enum AVFrameSideDataType {
* libavutil/motion_vector.h.
*/
AV_FRAME_DATA_MOTION_VECTORS,
+ /**
+ * Recommmends skipping the specified number of samples. This is exported
+ * only if the "skip_manual" AVOption is set in libavcodec.
+ * This has the same format as AV_PKT_DATA_SKIP_SAMPLES.
+ * @code
+ * u32le number of samples to skip from start of this packet
+ * u32le number of samples to skip from end of this packet
+ * u8 reason for start skip
+ * u8 reason for end skip (0=padding silence, 1=convergence)
+ * @endcode
+ */
+ AV_FRAME_DATA_SKIP_SAMPLES,
};
enum AVActiveFormatDescription {
--
2.1.0
More information about the ffmpeg-devel
mailing list