From cdd6f059a65f28ff7a18ccf1194e9554adad1a1b Mon Sep 17 00:00:00 2001 From: wm4 <nfxjfg@googlemail.com> Date: Sat, 27 Sep 2014 16:47:09 +0200 Subject: [PATCH] avcodec, avutil: allow more control about how samples are skipped 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. Signed-off-by: Michael Niedermayer <michaelni@gmx.at> --- doc/APIchanges | 7 +++++++ libavcodec/avcodec.h | 1 + libavcodec/options_table.h | 1 + libavcodec/utils.c | 21 +++++++++++++++++++-- libavcodec/version.h | 4 ++-- libavutil/frame.h | 12 ++++++++++++ libavutil/version.h | 2 +- 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index e3ae4e87e1b..7757227d8bc 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,13 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-10-02 - xxxxxxx - lavc 56.2.100 - avcodec.h +2014-10-02 - xxxxxxx - lavu 54.9.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-10-02 - xxxxxxx - lavu 54.8.100 - avstring.h Add av_match_list() diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 94e82f73f97..75987482506 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 ad3d52ecdf6..b9b79f927ed 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 778bdc6c2d1..ee9e24805bf 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/libavcodec/version.h b/libavcodec/version.h index 022e27b3ce3..3bd9e6a6cf2 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,8 +29,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 56 -#define LIBAVCODEC_VERSION_MINOR 1 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MINOR 2 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavutil/frame.h b/libavutil/frame.h index ee24628ae83..d335bee831d 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 { diff --git a/libavutil/version.h b/libavutil/version.h index 9e138b5fabe..f73f33441c6 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 54 -#define LIBAVUTIL_VERSION_MINOR 8 +#define LIBAVUTIL_VERSION_MINOR 9 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- GitLab