Commit cdd6f059 authored by wm4's avatar wm4 Committed by Michael Niedermayer

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent a9b10e15
...@@ -15,6 +15,13 @@ libavutil: 2014-08-09 ...@@ -15,6 +15,13 @@ libavutil: 2014-08-09
API changes, most recent first: 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 2014-10-02 - xxxxxxx - lavu 54.8.100 - avstring.h
Add av_match_list() Add av_match_list()
......
...@@ -768,6 +768,7 @@ typedef struct RcOverride{ ...@@ -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_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_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_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 : /* Unsupported options :
* Syntax Arithmetic coding (SAC) * Syntax Arithmetic coding (SAC)
......
...@@ -89,6 +89,7 @@ static const AVOption avcodec_options[] = { ...@@ -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"}, {"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"}, {"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"}, {"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"}, {"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" }, {"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" }, {"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
......
...@@ -2448,6 +2448,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, ...@@ -2448,6 +2448,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
uint8_t *side; uint8_t *side;
int side_size; int side_size;
uint32_t discard_padding = 0; uint32_t discard_padding = 0;
uint8_t skip_reason = 0;
uint8_t discard_reason = 0;
// copy to ensure we do not change avpkt // copy to ensure we do not change avpkt
AVPacket tmp = *avpkt; AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp); int did_split = av_packet_split_side_data(&tmp);
...@@ -2488,8 +2490,11 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, ...@@ -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", av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
avctx->internal->skip_samples); avctx->internal->skip_samples);
discard_padding = AV_RL32(side + 4); 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){ if(frame->nb_samples <= avctx->internal->skip_samples){
*got_frame_ptr = 0; *got_frame_ptr = 0;
avctx->internal->skip_samples -= frame->nb_samples; avctx->internal->skip_samples -= frame->nb_samples;
...@@ -2518,7 +2523,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, ...@@ -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) { if (discard_padding == frame->nb_samples) {
*got_frame_ptr = 0; *got_frame_ptr = 0;
} else { } else {
...@@ -2536,6 +2542,17 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, ...@@ -2536,6 +2542,17 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
frame->nb_samples -= discard_padding; 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: fail:
avctx->internal->pkt = NULL; avctx->internal->pkt = NULL;
if (did_split) { if (did_split) {
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
#include "libavutil/version.h" #include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56 #define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR 1 #define LIBAVCODEC_VERSION_MINOR 2
#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
......
...@@ -94,6 +94,18 @@ enum AVFrameSideDataType { ...@@ -94,6 +94,18 @@ enum AVFrameSideDataType {
* libavutil/motion_vector.h. * libavutil/motion_vector.h.
*/ */
AV_FRAME_DATA_MOTION_VECTORS, 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 { enum AVActiveFormatDescription {
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 54 #define LIBAVUTIL_VERSION_MAJOR 54
#define LIBAVUTIL_VERSION_MINOR 8 #define LIBAVUTIL_VERSION_MINOR 9
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment