aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/utils.c
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2014-09-27 16:47:09 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-10-02 20:21:00 +0200
commitcdd6f059a65f28ff7a18ccf1194e9554adad1a1b (patch)
treef85077e1a32a10003a595e46d403e75e4797bd9e /libavcodec/utils.c
parenta9b10e1510ddfcae5119e616e0cc60350c99467c (diff)
downloadffmpeg-cdd6f059a65f28ff7a18ccf1194e9554adad1a1b.tar.gz
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>
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r--libavcodec/utils.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 778bdc6c2d..ee9e24805b 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) {