/* * generic decoding-related code * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdint.h>#include <stdbool.h>#include <string.h> #include "config.h" #if CONFIG_ICONV# include <iconv.h>#endif #include "libavutil/avassert.h"#include "libavutil/channel_layout.h"#include "libavutil/common.h"#include "libavutil/emms.h"#include "libavutil/frame.h"#include "libavutil/hwcontext.h"#include "libavutil/imgutils.h"#include "libavutil/internal.h"#include "libavutil/mastering_display_metadata.h"#include "libavutil/mem.h"#include "libavutil/stereo3d.h" #include "avcodec.h"#include "avcodec_internal.h"#include "bytestream.h"#include "bsf.h"#include "codec_desc.h"#include "codec_internal.h"#include "decode.h"#include "hwaccel_internal.h"#include "hwconfig.h"#include "internal.h"#include "lcevcdec.h"#include "packet_internal.h"#include "progressframe.h"#include "libavutil/refstruct.h"#include "thread.h"#include "threadprogress.h" typedef struct DecodeContext { AVCodecInternal avci; /** * This is set to AV_FRAME_FLAG_KEY for decoders of intra-only formats * (those whose codec descriptor has AV_CODEC_PROP_INTRA_ONLY set) * to set the flag generically. */ int intra_only_flag; /** * This is set to AV_PICTURE_TYPE_I for intra only video decoders * and to AV_PICTURE_TYPE_NONE for other decoders. It is used to set * the AVFrame's pict_type before the decoder receives it. */ enum AVPictureType initial_pict_type; /* to prevent infinite loop on errors when draining */ int nb_draining_errors; /** * The caller has submitted a NULL packet on input. */ int draining_started; int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far int64_t pts_correction_last_pts; /// PTS of the last frame int64_t pts_correction_last_dts; /// DTS of the last frame /** * Bitmask indicating for which side data types we prefer user-supplied * (global or attached to packets) side data over bytestream. */ uint64_t side_data_pref_mask; FFLCEVCContext *lcevc; int lcevc_frame; int width; int height;} DecodeContext; static DecodeContext *decode_ctx(AVCodecInternal *avci){ return (DecodeContext *)avci;} static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt){ int ret; size_t size; const uint8_t *data; uint32_t flags; int64_t val; data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); if (!data) return 0; if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " "changes, but PARAM_CHANGE side data was sent to it.\n"); ret = AVERROR(EINVAL); goto fail2; } if (size < 4) goto fail; flags = bytestream_get_le32(&data); size -= 4; if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { if (size < 4) goto fail; val = bytestream_get_le32(&data); if (val <= 0 || val > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); ret = AVERROR_INVALIDDATA; goto fail2; } avctx->sample_rate = val; size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); size -= 8; ret = ff_set_dimensions(avctx, avctx->width, avctx->height); if (ret < 0) goto fail2; } return 0;fail: av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); ret = AVERROR_INVALIDDATA;fail2: if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); if (avctx->err_recognition & AV_EF_EXPLODE) return ret; } return 0;} static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt){ int ret = 0; av_packet_unref(avci->last_pkt_props); if (pkt) { ret = av_packet_copy_props(avci->last_pkt_props, pkt);#if FF_API_FRAME_PKT if (!ret) avci->last_pkt_props->stream_index = pkt->size; // Needed for ff_decode_frame_props().#endif } return ret;} static int decode_bsfs_init(AVCodecContext *avctx){ AVCodecInternal *avci = avctx->internal; const FFCodec *const codec = ffcodec(avctx->codec); int ret; if (avci->bsf) return 0; ret = av_bsf_list_parse_str(codec->bsfs, &avci->bsf); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error parsing decoder bitstream filters '%s': %s\n", codec->bsfs, av_err2str(ret)); if (ret != AVERROR(ENOMEM)) ret = AVERROR_BUG; goto fail; } /* We do not currently have an API for passing the input timebase into decoders, * but no filters used here should actually need it. * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ avci->bsf->time_base_in = (AVRational){ 1, 90000 }; ret = avcodec_parameters_from_context(avci->bsf->par_in, avctx); if (ret < 0) goto fail; ret = av_bsf_init(avci->bsf); if (ret < 0) goto fail; return 0;fail: av_bsf_free(&avci->bsf); return ret;} #if !HAVE_THREADS#define ff_thread_get_packet(avctx, pkt) (AVERROR_BUG)#define ff_thread_receive_frame(avctx, frame) (AVERROR_BUG)#endif static int decode_get_packet(AVCodecContext *avctx, AVPacket *pkt){ AVCodecInternal *avci = avctx->internal; int ret; ret = av_bsf_receive_packet(avci->bsf, pkt); if (ret < 0) return ret; if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { ret = extract_packet_props(avctx->internal, pkt); if (ret < 0) goto finish; } ret = apply_param_change(avctx, pkt); if (ret < 0) goto finish; return 0;finish: av_packet_unref(pkt); return ret;} int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt){ AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); if (avci->draining) return AVERROR_EOF; /* If we are a worker thread, get the next packet from the threading * context. Otherwise we are the main (user-facing) context, so we get the * next packet from the input filterchain. */ if (avctx->internal->is_frame_mt) return ff_thread_get_packet(avctx, pkt); while (1) { int ret = decode_get_packet(avctx, pkt); if (ret == AVERROR(EAGAIN) && (!AVPACKET_IS_EMPTY(avci->buffer_pkt) || dc->draining_started)) { ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt); if (ret >= 0) continue; av_packet_unref(avci->buffer_pkt); } if (ret == AVERROR_EOF) avci->draining = 1; return ret; }} /** * Attempt to guess proper monotonic timestamps for decoded video frames * which might have incorrect times. Input timestamps may wrap around, in * which case the output will as well. * * @param pts the pts field of the decoded AVPacket, as passed through * AVFrame.pts * @param dts the dts field of the decoded AVPacket * @return one of the input values, may be AV_NOPTS_VALUE */static int64_t guess_correct_pts(DecodeContext *dc, int64_t reordered_pts, int64_t dts){ int64_t pts = AV_NOPTS_VALUE; if (dts != AV_NOPTS_VALUE) { dc->pts_correction_num_faulty_dts += dts <= dc->pts_correction_last_dts; dc->pts_correction_last_dts = dts; } else if (reordered_pts != AV_NOPTS_VALUE) dc->pts_correction_last_dts = reordered_pts; if (reordered_pts != AV_NOPTS_VALUE) { dc->pts_correction_num_faulty_pts += reordered_pts <= dc->pts_correction_last_pts; dc->pts_correction_last_pts = reordered_pts; } else if(dts != AV_NOPTS_VALUE) dc->pts_correction_last_pts = dts; if ((dc->pts_correction_num_faulty_pts<=dc->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) && reordered_pts != AV_NOPTS_VALUE) pts = reordered_pts; else pts = dts; return pts;} static int discard_samples(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples){ AVCodecInternal *avci = avctx->internal; AVFrameSideData *side; uint32_t discard_padding = 0; uint8_t skip_reason = 0; uint8_t discard_reason = 0; side = av_frame_get_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES); if (side && side->size >= 10) { avci->skip_samples = AV_RL32(side->data); avci->skip_samples = FFMAX(0, avci->skip_samples); discard_padding = AV_RL32(side->data + 4); av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", avci->skip_samples, (int)discard_padding); skip_reason = AV_RL8(side->data + 8); discard_reason = AV_RL8(side->data + 9); } if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if (!side && (avci->skip_samples || discard_padding)) side = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); if (side && (avci->skip_samples || discard_padding)) { AV_WL32(side->data, avci->skip_samples); AV_WL32(side->data + 4, discard_padding); AV_WL8(side->data + 8, skip_reason); AV_WL8(side->data + 9, discard_reason); avci->skip_samples = 0; } return 0; } av_frame_remove_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES); if ((frame->flags & AV_FRAME_FLAG_DISCARD)) { avci->skip_samples = FFMAX(0, avci->skip_samples - frame->nb_samples); *discarded_samples += frame->nb_samples; return AVERROR(EAGAIN); } if (avci->skip_samples > 0) { if (frame->nb_samples <= avci->skip_samples){ *discarded_samples += frame->nb_samples; avci->skip_samples -= frame->nb_samples; av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", avci->skip_samples); return AVERROR(EAGAIN); } else { av_samples_copy(frame->extended_data, frame->extended_data, 0, avci->skip_samples, frame->nb_samples - avci->skip_samples, avctx->ch_layout.nb_channels, frame->format); if (avctx->pkt_timebase.num && avctx->sample_rate) { int64_t diff_ts = av_rescale_q(avci->skip_samples, (AVRational){1, avctx->sample_rate}, avctx->pkt_timebase); if (frame->pts != AV_NOPTS_VALUE) frame->pts += diff_ts; if (frame->pkt_dts != AV_NOPTS_VALUE) frame->pkt_dts += diff_ts; if (frame->duration >= diff_ts) frame->duration -= diff_ts; } else av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", avci->skip_samples, frame->nb_samples); *discarded_samples += avci->skip_samples; frame->nb_samples -= avci->skip_samples; avci->skip_samples = 0; } } if (discard_padding > 0 && discard_padding <= frame->nb_samples) { if (discard_padding == frame->nb_samples) { *discarded_samples += frame->nb_samples; return AVERROR(EAGAIN); } else { if (avctx->pkt_timebase.num && avctx->sample_rate) { int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, (AVRational){1, avctx->sample_rate}, avctx->pkt_timebase); frame->duration = diff_ts; } else av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", (int)discard_padding, frame->nb_samples); frame->nb_samples -= discard_padding; } } return 0;} /* * The core of the receive_frame_wrapper for the decoders implementing * the simple API. Certain decoders might consume partial packets without * returning any output, so this function needs to be called in a loop until it * returns EAGAIN. **/static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples){ AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); AVPacket *const pkt = avci->in_pkt; const FFCodec *const codec = ffcodec(avctx->codec); int got_frame, consumed; int ret; if (!pkt->data && !avci->draining) { av_packet_unref(pkt); ret = ff_decode_get_packet(avctx, pkt); if (ret < 0 && ret != AVERROR_EOF) return ret; } // Some codecs (at least wma lossless) will crash when feeding drain packets // after EOF was signaled. if (avci->draining_done) return AVERROR_EOF; if (!pkt->data && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return AVERROR_EOF; got_frame = 0; frame->pict_type = dc->initial_pict_type; frame->flags |= dc->intra_only_flag; consumed = codec->cb.decode(avctx, frame, &got_frame, pkt); if (!(codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) frame->pkt_dts = pkt->dts; if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) {#if FF_API_FRAME_PKTFF_DISABLE_DEPRECATION_WARNINGS if(!avctx->has_b_frames) frame->pkt_pos = pkt->pos;FF_ENABLE_DEPRECATION_WARNINGS#endif } emms_c(); if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { ret = (!got_frame || frame->flags & AV_FRAME_FLAG_DISCARD) ? AVERROR(EAGAIN) : 0; } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { ret = !got_frame ? AVERROR(EAGAIN) : discard_samples(avctx, frame, discarded_samples); } else av_assert0(0); if (ret == AVERROR(EAGAIN)) av_frame_unref(frame); // FF_CODEC_CB_TYPE_DECODE decoders must not return AVERROR EAGAIN // code later will add AVERROR(EAGAIN) to a pointer av_assert0(consumed != AVERROR(EAGAIN)); if (consumed < 0) ret = consumed; if (consumed >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) consumed = pkt->size; if (!ret) av_assert0(frame->buf[0]); if (ret == AVERROR(EAGAIN)) ret = 0; /* do not stop draining when got_frame != 0 or ret < 0 */ if (avci->draining && !got_frame) { if (ret < 0) { /* prevent infinite loop if a decoder wrongly always return error on draining */ /* reasonable nb_errors_max = maximum b frames + thread count */ int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ? avctx->thread_count : 1); if (decode_ctx(avci)->nb_draining_errors++ >= nb_errors_max) { av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. " "Stop draining and force EOF.\n"); avci->draining_done = 1; ret = AVERROR_BUG; } } else { avci->draining_done = 1; } }Lines 1–500 of 2317. Load more
/* * generic decoding-related code * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdint.h> #include <stdbool.h> #include <string.h> #include "config.h" #if CONFIG_ICONV # include <iconv.h> #endif #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/emms.h" #include "libavutil/frame.h" #include "libavutil/hwcontext.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/mem.h" #include "libavutil/stereo3d.h" #include "avcodec.h" #include "avcodec_internal.h" #include "bytestream.h" #include "bsf.h" #include "codec_desc.h" #include "codec_internal.h" #include "decode.h" #include "hwaccel_internal.h" #include "hwconfig.h" #include "internal.h" #include "lcevcdec.h" #include "packet_internal.h" #include "progressframe.h" #include "libavutil/refstruct.h" #include "thread.h" #include "threadprogress.h" typedef struct DecodeContext { AVCodecInternal avci; /** * This is set to AV_FRAME_FLAG_KEY for decoders of intra-only formats * (those whose codec descriptor has AV_CODEC_PROP_INTRA_ONLY set) * to set the flag generically. */ int intra_only_flag; /** * This is set to AV_PICTURE_TYPE_I for intra only video decoders * and to AV_PICTURE_TYPE_NONE for other decoders. It is used to set * the AVFrame's pict_type before the decoder receives it. */ enum AVPictureType initial_pict_type; /* to prevent infinite loop on errors when draining */ int nb_draining_errors; /** * The caller has submitted a NULL packet on input. */ int draining_started; int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far int64_t pts_correction_last_pts; /// PTS of the last frame int64_t pts_correction_last_dts; /// DTS of the last frame /** * Bitmask indicating for which side data types we prefer user-supplied * (global or attached to packets) side data over bytestream. */ uint64_t side_data_pref_mask; FFLCEVCContext *lcevc; int lcevc_frame; int width; int height; } DecodeContext; static DecodeContext *decode_ctx(AVCodecInternal *avci) { return (DecodeContext *)avci; } static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) { int ret; size_t size; const uint8_t *data; uint32_t flags; int64_t val; data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); if (!data) return 0; if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " "changes, but PARAM_CHANGE side data was sent to it.\n"); ret = AVERROR(EINVAL); goto fail2; } if (size < 4) goto fail; flags = bytestream_get_le32(&data); size -= 4; if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { if (size < 4) goto fail; val = bytestream_get_le32(&data); if (val <= 0 || val > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); ret = AVERROR_INVALIDDATA; goto fail2; } avctx->sample_rate = val; size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); size -= 8; ret = ff_set_dimensions(avctx, avctx->width, avctx->height); if (ret < 0) goto fail2; } return 0; fail: av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); ret = AVERROR_INVALIDDATA; fail2: if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); if (avctx->err_recognition & AV_EF_EXPLODE) return ret; } return 0; } static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) { int ret = 0; av_packet_unref(avci->last_pkt_props); if (pkt) { ret = av_packet_copy_props(avci->last_pkt_props, pkt); #if FF_API_FRAME_PKT if (!ret) avci->last_pkt_props->stream_index = pkt->size; // Needed for ff_decode_frame_props(). #endif } return ret; } static int decode_bsfs_init(AVCodecContext *avctx) { AVCodecInternal *avci = avctx->internal; const FFCodec *const codec = ffcodec(avctx->codec); int ret; if (avci->bsf) return 0; ret = av_bsf_list_parse_str(codec->bsfs, &avci->bsf); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error parsing decoder bitstream filters '%s': %s\n", codec->bsfs, av_err2str(ret)); if (ret != AVERROR(ENOMEM)) ret = AVERROR_BUG; goto fail; } /* We do not currently have an API for passing the input timebase into decoders, * but no filters used here should actually need it. * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ avci->bsf->time_base_in = (AVRational){ 1, 90000 }; ret = avcodec_parameters_from_context(avci->bsf->par_in, avctx); if (ret < 0) goto fail; ret = av_bsf_init(avci->bsf); if (ret < 0) goto fail; return 0; fail: av_bsf_free(&avci->bsf); return ret; } #if !HAVE_THREADS #define ff_thread_get_packet(avctx, pkt) (AVERROR_BUG) #define ff_thread_receive_frame(avctx, frame) (AVERROR_BUG) #endif static int decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) { AVCodecInternal *avci = avctx->internal; int ret; ret = av_bsf_receive_packet(avci->bsf, pkt); if (ret < 0) return ret; if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { ret = extract_packet_props(avctx->internal, pkt); if (ret < 0) goto finish; } ret = apply_param_change(avctx, pkt); if (ret < 0) goto finish; return 0; finish: av_packet_unref(pkt); return ret; } int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) { AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); if (avci->draining) return AVERROR_EOF; /* If we are a worker thread, get the next packet from the threading * context. Otherwise we are the main (user-facing) context, so we get the * next packet from the input filterchain. */ if (avctx->internal->is_frame_mt) return ff_thread_get_packet(avctx, pkt); while (1) { int ret = decode_get_packet(avctx, pkt); if (ret == AVERROR(EAGAIN) && (!AVPACKET_IS_EMPTY(avci->buffer_pkt) || dc->draining_started)) { ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt); if (ret >= 0) continue; av_packet_unref(avci->buffer_pkt); } if (ret == AVERROR_EOF) avci->draining = 1; return ret; } } /** * Attempt to guess proper monotonic timestamps for decoded video frames * which might have incorrect times. Input timestamps may wrap around, in * which case the output will as well. * * @param pts the pts field of the decoded AVPacket, as passed through * AVFrame.pts * @param dts the dts field of the decoded AVPacket * @return one of the input values, may be AV_NOPTS_VALUE */ static int64_t guess_correct_pts(DecodeContext *dc, int64_t reordered_pts, int64_t dts) { int64_t pts = AV_NOPTS_VALUE; if (dts != AV_NOPTS_VALUE) { dc->pts_correction_num_faulty_dts += dts <= dc->pts_correction_last_dts; dc->pts_correction_last_dts = dts; } else if (reordered_pts != AV_NOPTS_VALUE) dc->pts_correction_last_dts = reordered_pts; if (reordered_pts != AV_NOPTS_VALUE) { dc->pts_correction_num_faulty_pts += reordered_pts <= dc->pts_correction_last_pts; dc->pts_correction_last_pts = reordered_pts; } else if(dts != AV_NOPTS_VALUE) dc->pts_correction_last_pts = dts; if ((dc->pts_correction_num_faulty_pts<=dc->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) && reordered_pts != AV_NOPTS_VALUE) pts = reordered_pts; else pts = dts; return pts; } static int discard_samples(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) { AVCodecInternal *avci = avctx->internal; AVFrameSideData *side; uint32_t discard_padding = 0; uint8_t skip_reason = 0; uint8_t discard_reason = 0; side = av_frame_get_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES); if (side && side->size >= 10) { avci->skip_samples = AV_RL32(side->data); avci->skip_samples = FFMAX(0, avci->skip_samples); discard_padding = AV_RL32(side->data + 4); av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", avci->skip_samples, (int)discard_padding); skip_reason = AV_RL8(side->data + 8); discard_reason = AV_RL8(side->data + 9); } if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if (!side && (avci->skip_samples || discard_padding)) side = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); if (side && (avci->skip_samples || discard_padding)) { AV_WL32(side->data, avci->skip_samples); AV_WL32(side->data + 4, discard_padding); AV_WL8(side->data + 8, skip_reason); AV_WL8(side->data + 9, discard_reason); avci->skip_samples = 0; } return 0; } av_frame_remove_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES); if ((frame->flags & AV_FRAME_FLAG_DISCARD)) { avci->skip_samples = FFMAX(0, avci->skip_samples - frame->nb_samples); *discarded_samples += frame->nb_samples; return AVERROR(EAGAIN); } if (avci->skip_samples > 0) { if (frame->nb_samples <= avci->skip_samples){ *discarded_samples += frame->nb_samples; avci->skip_samples -= frame->nb_samples; av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", avci->skip_samples); return AVERROR(EAGAIN); } else { av_samples_copy(frame->extended_data, frame->extended_data, 0, avci->skip_samples, frame->nb_samples - avci->skip_samples, avctx->ch_layout.nb_channels, frame->format); if (avctx->pkt_timebase.num && avctx->sample_rate) { int64_t diff_ts = av_rescale_q(avci->skip_samples, (AVRational){1, avctx->sample_rate}, avctx->pkt_timebase); if (frame->pts != AV_NOPTS_VALUE) frame->pts += diff_ts; if (frame->pkt_dts != AV_NOPTS_VALUE) frame->pkt_dts += diff_ts; if (frame->duration >= diff_ts) frame->duration -= diff_ts; } else av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", avci->skip_samples, frame->nb_samples); *discarded_samples += avci->skip_samples; frame->nb_samples -= avci->skip_samples; avci->skip_samples = 0; } } if (discard_padding > 0 && discard_padding <= frame->nb_samples) { if (discard_padding == frame->nb_samples) { *discarded_samples += frame->nb_samples; return AVERROR(EAGAIN); } else { if (avctx->pkt_timebase.num && avctx->sample_rate) { int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, (AVRational){1, avctx->sample_rate}, avctx->pkt_timebase); frame->duration = diff_ts; } else av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", (int)discard_padding, frame->nb_samples); frame->nb_samples -= discard_padding; } } return 0; } /* * The core of the receive_frame_wrapper for the decoders implementing * the simple API. Certain decoders might consume partial packets without * returning any output, so this function needs to be called in a loop until it * returns EAGAIN. **/ static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) { AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); AVPacket *const pkt = avci->in_pkt; const FFCodec *const codec = ffcodec(avctx->codec); int got_frame, consumed; int ret; if (!pkt->data && !avci->draining) { av_packet_unref(pkt); ret = ff_decode_get_packet(avctx, pkt); if (ret < 0 && ret != AVERROR_EOF) return ret; } // Some codecs (at least wma lossless) will crash when feeding drain packets // after EOF was signaled. if (avci->draining_done) return AVERROR_EOF; if (!pkt->data && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return AVERROR_EOF; got_frame = 0; frame->pict_type = dc->initial_pict_type; frame->flags |= dc->intra_only_flag; consumed = codec->cb.decode(avctx, frame, &got_frame, pkt); if (!(codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) frame->pkt_dts = pkt->dts; if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { #if FF_API_FRAME_PKT FF_DISABLE_DEPRECATION_WARNINGS if(!avctx->has_b_frames) frame->pkt_pos = pkt->pos; FF_ENABLE_DEPRECATION_WARNINGS #endif } emms_c(); if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { ret = (!got_frame || frame->flags & AV_FRAME_FLAG_DISCARD) ? AVERROR(EAGAIN) : 0; } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { ret = !got_frame ? AVERROR(EAGAIN) : discard_samples(avctx, frame, discarded_samples); } else av_assert0(0); if (ret == AVERROR(EAGAIN)) av_frame_unref(frame); // FF_CODEC_CB_TYPE_DECODE decoders must not return AVERROR EAGAIN // code later will add AVERROR(EAGAIN) to a pointer av_assert0(consumed != AVERROR(EAGAIN)); if (consumed < 0) ret = consumed; if (consumed >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) consumed = pkt->size; if (!ret) av_assert0(frame->buf[0]); if (ret == AVERROR(EAGAIN)) ret = 0; /* do not stop draining when got_frame != 0 or ret < 0 */ if (avci->draining && !got_frame) { if (ret < 0) { /* prevent infinite loop if a decoder wrongly always return error on draining */ /* reasonable nb_errors_max = maximum b frames + thread count */ int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ? avctx->thread_count : 1); if (decode_ctx(avci)->nb_draining_errors++ >= nb_errors_max) { av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. " "Stop draining and force EOF.\n"); avci->draining_done = 1; ret = AVERROR_BUG; } } else { avci->draining_done = 1; } }