From patchwork Fri Oct 9 13:04:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 22794 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id B83EE44AB2F for ; Fri, 9 Oct 2020 16:09:59 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5426968BA11; Fri, 9 Oct 2020 16:06:52 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C692E68B9D5 for ; Fri, 9 Oct 2020 16:06:38 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 40674296254 for ; Fri, 9 Oct 2020 15:06:34 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id Aa1Mf0JfGMyn for ; Fri, 9 Oct 2020 15:06:33 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.daenerys.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 3699B2961F9 for ; Fri, 9 Oct 2020 15:06:30 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 3135A20E00BE; Fri, 9 Oct 2020 15:06:25 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 9 Oct 2020 15:04:13 +0200 Message-Id: <20201009130430.602-1-anton@khirnov.net> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 01/18] lavf: move AVStream.info to AVStreamInternal X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This struct is for internal use of avformat_find_stream_info(), so it should not be exposed in public headers. Keep a stub pointer in its place to avoid changing AVStream layout, since e.g. ffmpeg.c accesses some fields located after it (even though they are marked as private). --- libavformat/avformat.h | 36 +------ libavformat/internal.h | 33 ++++++ libavformat/utils.c | 228 ++++++++++++++++++++--------------------- 3 files changed, 151 insertions(+), 146 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index c8c0b6c08d..8eff5b8eaa 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1023,38 +1023,10 @@ typedef struct AVStream { ***************************************************************** */ -#define MAX_STD_TIMEBASES (30*12+30+3+6) - /** - * Stream information used internally by avformat_find_stream_info() - */ - struct { - int64_t last_dts; - int64_t duration_gcd; - int duration_count; - int64_t rfps_duration_sum; - double (*duration_error)[2][MAX_STD_TIMEBASES]; - int64_t codec_info_duration; - int64_t codec_info_duration_fields; - int frame_delay_evidence; - - /** - * 0 -> decoder has not been searched for yet. - * >0 -> decoder found - * <0 -> decoder with codec_id == -found_decoder has not been found - */ - int found_decoder; - - int64_t last_duration; - - /** - * Those are used for average framerate estimation. - */ - int64_t fps_first_dts; - int fps_first_dts_idx; - int64_t fps_last_dts; - int fps_last_dts_idx; - - } *info; +#if LIBAVFORMAT_VERSION_MAJOR < 59 + // kept for ABI compatibility only, do not access in any way + void *unused; +#endif int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ diff --git a/libavformat/internal.h b/libavformat/internal.h index f4174628e0..30b4df9181 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -191,6 +191,39 @@ struct AVStreamInternal { int is_intra_only; FFFrac *priv_pts; + +#define MAX_STD_TIMEBASES (30*12+30+3+6) + /** + * Stream information used internally by avformat_find_stream_info() + */ + struct { + int64_t last_dts; + int64_t duration_gcd; + int duration_count; + int64_t rfps_duration_sum; + double (*duration_error)[2][MAX_STD_TIMEBASES]; + int64_t codec_info_duration; + int64_t codec_info_duration_fields; + int frame_delay_evidence; + + /** + * 0 -> decoder has not been searched for yet. + * >0 -> decoder found + * <0 -> decoder with codec_id == -found_decoder has not been found + */ + int found_decoder; + + int64_t last_duration; + + /** + * Those are used for average framerate estimation. + */ + int64_t fps_first_dts; + int fps_first_dts_idx; + int64_t fps_last_dts; + int fps_last_dts_idx; + + } *info; }; #ifdef __GNUC__ diff --git a/libavformat/utils.c b/libavformat/utils.c index a2e701ea1a..a13f31dccf 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -992,7 +992,7 @@ int ff_is_intra_only(enum AVCodecID id) static int has_decode_delay_been_guessed(AVStream *st) { if (st->codecpar->codec_id != AV_CODEC_ID_H264) return 1; - if (!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy + if (!st->internal->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy return 1; #if CONFIG_H264_DECODER if (st->internal->avctx->has_b_frames && @@ -1539,7 +1539,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (avcodec_is_open(st->internal->avctx)) { av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); avcodec_close(st->internal->avctx); - st->info->found_decoder = 0; + st->internal->info->found_decoder = 0; } /* close parser, because it depends on the codec */ @@ -2812,10 +2812,10 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) else duration -= st->first_dts; if (duration > 0) { - if (st->duration == AV_NOPTS_VALUE || st->info->last_duration<= 0 || - (st->duration < duration && FFABS(duration - st->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) + if (st->duration == AV_NOPTS_VALUE || st->internal->info->last_duration<= 0 || + (st->duration < duration && FFABS(duration - st->internal->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) st->duration = duration; - st->info->last_duration = duration; + st->internal->info->last_duration = duration; } } av_packet_unref(pkt); @@ -2952,20 +2952,20 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) case AVMEDIA_TYPE_AUDIO: if (!avctx->frame_size && determinable_frame_size(avctx)) FAIL("unspecified frame size"); - if (st->info->found_decoder >= 0 && + if (st->internal->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE) FAIL("unspecified sample format"); if (!avctx->sample_rate) FAIL("unspecified sample rate"); if (!avctx->channels) FAIL("unspecified number of channels"); - if (st->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) + if (st->internal->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS) FAIL("no decodable DTS frames"); break; case AVMEDIA_TYPE_VIDEO: if (!avctx->width) FAIL("unspecified size"); - if (st->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) + if (st->internal->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE) FAIL("unspecified pixel format"); if (st->codecpar->codec_id == AV_CODEC_ID_RV30 || st->codecpar->codec_id == AV_CODEC_ID_RV40) if (!st->sample_aspect_ratio.num && !st->codecpar->sample_aspect_ratio.num && !st->codec_info_nb_frames) @@ -2999,14 +2999,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, return AVERROR(ENOMEM); if (!avcodec_is_open(avctx) && - st->info->found_decoder <= 0 && - (st->codecpar->codec_id != -st->info->found_decoder || !st->codecpar->codec_id)) { + st->internal->info->found_decoder <= 0 && + (st->codecpar->codec_id != -st->internal->info->found_decoder || !st->codecpar->codec_id)) { AVDictionary *thread_opt = NULL; codec = find_probe_decoder(s, st, st->codecpar->codec_id); if (!codec) { - st->info->found_decoder = -st->codecpar->codec_id; + st->internal->info->found_decoder = -st->codecpar->codec_id; ret = -1; goto fail; } @@ -3020,14 +3020,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, if (!options) av_dict_free(&thread_opt); if (ret < 0) { - st->info->found_decoder = -avctx->codec_id; + st->internal->info->found_decoder = -avctx->codec_id; goto fail; } - st->info->found_decoder = 1; - } else if (!st->info->found_decoder) - st->info->found_decoder = 1; + st->internal->info->found_decoder = 1; + } else if (!st->internal->info->found_decoder) + st->internal->info->found_decoder = 1; - if (st->info->found_decoder < 0) { + if (st->internal->info->found_decoder < 0) { ret = -1; goto fail; } @@ -3293,59 +3293,59 @@ int ff_get_extradata(AVFormatContext *s, AVCodecParameters *par, AVIOContext *pb int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts) { int i, j; - int64_t last = st->info->last_dts; + int64_t last = st->internal->info->last_dts; if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last && ts - (uint64_t)last < INT64_MAX) { double dts = (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base); int64_t duration = ts - last; - if (!st->info->duration_error) - st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2); - if (!st->info->duration_error) + if (!st->internal->info->duration_error) + st->internal->info->duration_error = av_mallocz(sizeof(st->internal->info->duration_error[0])*2); + if (!st->internal->info->duration_error) return AVERROR(ENOMEM); // if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) // av_log(NULL, AV_LOG_ERROR, "%f\n", dts); for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { + if (st->internal->info->duration_error[0][1][i] < 1e10) { int framerate = get_std_framerate(i); double sdts = dts*framerate/(1001*12); for (j= 0; j<2; j++) { int64_t ticks = llrint(sdts+j*0.5); double error= sdts - ticks + j*0.5; - st->info->duration_error[j][0][i] += error; - st->info->duration_error[j][1][i] += error*error; + st->internal->info->duration_error[j][0][i] += error; + st->internal->info->duration_error[j][1][i] += error*error; } } } - if (st->info->rfps_duration_sum <= INT64_MAX - duration) { - st->info->duration_count++; - st->info->rfps_duration_sum += duration; + if (st->internal->info->rfps_duration_sum <= INT64_MAX - duration) { + st->internal->info->duration_count++; + st->internal->info->rfps_duration_sum += duration; } - if (st->info->duration_count % 10 == 0) { - int n = st->info->duration_count; + if (st->internal->info->duration_count % 10 == 0) { + int n = st->internal->info->duration_count; for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { - double a0 = st->info->duration_error[0][0][i] / n; - double error0 = st->info->duration_error[0][1][i] / n - a0*a0; - double a1 = st->info->duration_error[1][0][i] / n; - double error1 = st->info->duration_error[1][1][i] / n - a1*a1; + if (st->internal->info->duration_error[0][1][i] < 1e10) { + double a0 = st->internal->info->duration_error[0][0][i] / n; + double error0 = st->internal->info->duration_error[0][1][i] / n - a0*a0; + double a1 = st->internal->info->duration_error[1][0][i] / n; + double error1 = st->internal->info->duration_error[1][1][i] / n - a1*a1; if (error0 > 0.04 && error1 > 0.04) { - st->info->duration_error[0][1][i] = 2e10; - st->info->duration_error[1][1][i] = 2e10; + st->internal->info->duration_error[0][1][i] = 2e10; + st->internal->info->duration_error[1][1][i] = 2e10; } } } } // ignore the first 4 values, they might have some random jitter - if (st->info->duration_count > 3 && is_relative(ts) == is_relative(last)) - st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration); + if (st->internal->info->duration_count > 3 && is_relative(ts) == is_relative(last)) + st->internal->info->duration_gcd = av_gcd(st->internal->info->duration_gcd, duration); } if (ts != AV_NOPTS_VALUE) - st->info->last_dts = ts; + st->internal->info->last_dts = ts; return 0; } @@ -3362,9 +3362,9 @@ void ff_rfps_calculate(AVFormatContext *ic) // the check for tb_unreliable() is not completely correct, since this is not about handling // an unreliable/inexact time base, but a time base that is finer than necessary, as e.g. // ipmovie.c produces. - if (tb_unreliable(st->internal->avctx) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX); - if (st->info->duration_count>1 && !st->r_frame_rate.num + if (tb_unreliable(st->internal->avctx) && st->internal->info->duration_count > 15 && st->internal->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->internal->info->duration_gcd, INT_MAX); + if (st->internal->info->duration_count>1 && !st->r_frame_rate.num && tb_unreliable(st->internal->avctx)) { int num = 0; double best_error= 0.01; @@ -3373,19 +3373,19 @@ void ff_rfps_calculate(AVFormatContext *ic) for (j= 0; jinfo->codec_info_duration && - st->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) + if (st->internal->info->codec_info_duration && + st->internal->info->codec_info_duration*av_q2d(st->time_base) < (1001*11.5)/get_std_framerate(j)) continue; - if (!st->info->codec_info_duration && get_std_framerate(j) < 1001*12) + if (!st->internal->info->codec_info_duration && get_std_framerate(j) < 1001*12) continue; - if (av_q2d(st->time_base) * st->info->rfps_duration_sum / st->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) + if (av_q2d(st->time_base) * st->internal->info->rfps_duration_sum / st->internal->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) continue; for (k= 0; k<2; k++) { - int n = st->info->duration_count; - double a= st->info->duration_error[k][0][j] / n; - double error= st->info->duration_error[k][1][j]/n - a*a; + int n = st->internal->info->duration_count; + double a= st->internal->info->duration_error[k][0][j] / n; + double error= st->internal->info->duration_error[k][1][j]/n - a*a; if (error < best_error && best_error> 0.000000001) { best_error= error; @@ -3400,19 +3400,19 @@ void ff_rfps_calculate(AVFormatContext *ic) av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); } if ( !st->avg_frame_rate.num - && st->r_frame_rate.num && st->info->rfps_duration_sum - && st->info->codec_info_duration <= 0 - && st->info->duration_count > 2 - && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->info->rfps_duration_sum / (double)st->info->duration_count) <= 1.0 + && st->r_frame_rate.num && st->internal->info->rfps_duration_sum + && st->internal->info->codec_info_duration <= 0 + && st->internal->info->duration_count > 2 + && fabs(1.0 / (av_q2d(st->r_frame_rate) * av_q2d(st->time_base)) - st->internal->info->rfps_duration_sum / (double)st->internal->info->duration_count) <= 1.0 ) { av_log(ic, AV_LOG_DEBUG, "Setting avg frame rate based on r frame rate\n"); st->avg_frame_rate = st->r_frame_rate; } - av_freep(&st->info->duration_error); - st->info->last_dts = AV_NOPTS_VALUE; - st->info->duration_count = 0; - st->info->rfps_duration_sum = 0; + av_freep(&st->internal->info->duration_error); + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->duration_count = 0; + st->internal->info->rfps_duration_sum = 0; } } @@ -3660,10 +3660,10 @@ FF_ENABLE_DEPRECATION_WARNINGS for (i = 0; i < ic->nb_streams; i++) { #if FF_API_R_FRAME_RATE - ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->last_dts = AV_NOPTS_VALUE; #endif - ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE; - ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_first_dts = AV_NOPTS_VALUE; + ic->streams[i]->internal->info->fps_last_dts = AV_NOPTS_VALUE; } read_size = 0; @@ -3697,8 +3697,8 @@ FF_ENABLE_DEPRECATION_WARNINGS fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ? - st->info->codec_info_duration_fields/2 : - st->info->duration_count; + st->internal->info->codec_info_duration_fields/2 : + st->internal->info->duration_count; if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (count < fps_analyze_framecount) @@ -3706,7 +3706,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } // Look at the first 3 frames if there is evidence of frame delay // but the decoder delay is not set. - if (st->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) + if (st->internal->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) break; if (!st->internal->avctx->extradata && (!st->internal->extract_extradata.inited || @@ -3741,7 +3741,7 @@ FF_ENABLE_DEPRECATION_WARNINGS "Probe buffer size limit of %"PRId64" bytes reached\n", probesize); for (i = 0; i < ic->nb_streams; i++) if (!ic->streams[i]->r_frame_rate.num && - ic->streams[i]->info->duration_count <= 1 && + ic->streams[i]->internal->info->duration_count <= 1 && ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && strcmp(ic->iformat->name, "image2")) av_log(ic, AV_LOG_WARNING, @@ -3788,57 +3788,57 @@ FF_ENABLE_DEPRECATION_WARNINGS if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts >= pkt->dts) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts >= pkt->dts) { av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* Check for a discontinuity in dts. If the difference in dts * is more than 1000 times the average packet duration in the * sequence, we treat it as a discontinuity. */ - if (st->info->fps_last_dts != AV_NOPTS_VALUE && - st->info->fps_last_dts_idx > st->info->fps_first_dts_idx && - (pkt->dts - (uint64_t)st->info->fps_last_dts) / 1000 > - (st->info->fps_last_dts - (uint64_t)st->info->fps_first_dts) / - (st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) { + if (st->internal->info->fps_last_dts != AV_NOPTS_VALUE && + st->internal->info->fps_last_dts_idx > st->internal->info->fps_first_dts_idx && + (pkt->dts - (uint64_t)st->internal->info->fps_last_dts) / 1000 > + (st->internal->info->fps_last_dts - (uint64_t)st->internal->info->fps_first_dts) / + (st->internal->info->fps_last_dts_idx - st->internal->info->fps_first_dts_idx)) { av_log(ic, AV_LOG_WARNING, "DTS discontinuity in stream %d: packet %d with DTS " "%"PRId64", packet %d with DTS %"PRId64"\n", - st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, + st->index, st->internal->info->fps_last_dts_idx, + st->internal->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; } /* update stored dts values */ - if (st->info->fps_first_dts == AV_NOPTS_VALUE) { - st->info->fps_first_dts = pkt->dts; - st->info->fps_first_dts_idx = st->codec_info_nb_frames; + if (st->internal->info->fps_first_dts == AV_NOPTS_VALUE) { + st->internal->info->fps_first_dts = pkt->dts; + st->internal->info->fps_first_dts_idx = st->codec_info_nb_frames; } - st->info->fps_last_dts = pkt->dts; - st->info->fps_last_dts_idx = st->codec_info_nb_frames; + st->internal->info->fps_last_dts = pkt->dts; + st->internal->info->fps_last_dts_idx = st->codec_info_nb_frames; } if (st->codec_info_nb_frames>1) { int64_t t = 0; int64_t limit; if (st->time_base.den > 0) - t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); + t = av_rescale_q(st->internal->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); if (st->avg_frame_rate.num > 0) t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q)); if ( t == 0 && st->codec_info_nb_frames>30 - && st->info->fps_first_dts != AV_NOPTS_VALUE - && st->info->fps_last_dts != AV_NOPTS_VALUE) - t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q)); + && st->internal->info->fps_first_dts != AV_NOPTS_VALUE + && st->internal->info->fps_last_dts != AV_NOPTS_VALUE) + t = FFMAX(t, av_rescale_q(st->internal->info->fps_last_dts - st->internal->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q)); if (analyzed_all_streams) limit = max_analyze_duration; else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration; @@ -3854,10 +3854,10 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (pkt->duration) { if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { - st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration); + st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration); } else - st->info->codec_info_duration += pkt->duration; - st->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; + st->internal->info->codec_info_duration += pkt->duration; + st->internal->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -3865,7 +3865,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_rfps_add_frame(ic, st, pkt->dts); #endif if (pkt->dts != pkt->pts && pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE) - st->info->frame_delay_evidence = 1; + st->internal->info->frame_delay_evidence = 1; } if (!st->internal->avctx->extradata) { ret = extract_extradata(st, pkt); @@ -3928,7 +3928,7 @@ FF_ENABLE_DEPRECATION_WARNINGS st = ic->streams[i]; /* flush the decoders */ - if (st->info->found_decoder == 1) { + if (st->internal->info->found_decoder == 1) { do { err = try_decode_frame(ic, st, &empty_pkt, (options && i < orig_nb_streams) @@ -3956,20 +3956,20 @@ FF_ENABLE_DEPRECATION_WARNINGS } /* estimate average framerate if not set by demuxer */ - if (st->info->codec_info_duration_fields && + if (st->internal->info->codec_info_duration_fields && !st->avg_frame_rate.num && - st->info->codec_info_duration) { + st->internal->info->codec_info_duration) { int best_fps = 0; double best_error = 0.01; AVRational codec_frame_rate = avctx->framerate; - if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| - st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || - st->info->codec_info_duration < 0) + if (st->internal->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| + st->internal->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || + st->internal->info->codec_info_duration < 0) continue; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - st->info->codec_info_duration_fields * (int64_t) st->time_base.den, - st->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); + st->internal->info->codec_info_duration_fields * (int64_t) st->time_base.den, + st->internal->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); /* Round guessed framerate to a "standard" framerate if it's * within 1% of the original estimate. */ @@ -4138,10 +4138,10 @@ FF_ENABLE_DEPRECATION_WARNINGS find_stream_info_err: for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (st->info) - av_freep(&st->info->duration_error); + if (st->internal->info) + av_freep(&st->internal->info->duration_error); avcodec_close(ic->streams[i]->internal->avctx); - av_freep(&ic->streams[i]->info); + av_freep(&ic->streams[i]->internal->info); av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf); av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt); } @@ -4343,6 +4343,10 @@ static void free_stream(AVStream **pst) av_freep(&st->internal->priv_pts); av_bsf_free(&st->internal->extract_extradata.bsf); av_packet_free(&st->internal->extract_extradata.pkt); + + if (st->internal->info) + av_freep(&st->internal->info->duration_error); + av_freep(&st->internal->info); } av_freep(&st->internal); @@ -4356,9 +4360,6 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif av_freep(&st->priv_data); - if (st->info) - av_freep(&st->info->duration_error); - av_freep(&st->info); #if FF_API_LAVF_FFSERVER FF_DISABLE_DEPRECATION_WARNINGS av_freep(&st->recommended_encoder_configuration); @@ -4466,17 +4467,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st = av_mallocz(sizeof(AVStream)); if (!st) return NULL; - if (!(st->info = av_mallocz(sizeof(*st->info)))) { - av_free(st); - return NULL; - } - st->info->last_dts = AV_NOPTS_VALUE; #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS st->codec = avcodec_alloc_context3(c); if (!st->codec) { - av_free(st->info); av_free(st); return NULL; } @@ -4487,6 +4482,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!st->internal) goto fail; + st->internal->info = av_mallocz(sizeof(*st->internal->info)); + if (!st->internal->info) + goto fail; + st->internal->info->last_dts = AV_NOPTS_VALUE; + st->codecpar = avcodec_parameters_alloc(); if (!st->codecpar) goto fail; @@ -4530,10 +4530,10 @@ FF_ENABLE_DEPRECATION_WARNINGS st->sample_aspect_ratio = (AVRational) { 0, 1 }; #if FF_API_R_FRAME_RATE - st->info->last_dts = AV_NOPTS_VALUE; + st->internal->info->last_dts = AV_NOPTS_VALUE; #endif - st->info->fps_first_dts = AV_NOPTS_VALUE; - st->info->fps_last_dts = AV_NOPTS_VALUE; + st->internal->info->fps_first_dts = AV_NOPTS_VALUE; + st->internal->info->fps_last_dts = AV_NOPTS_VALUE; st->inject_global_side_data = s->internal->inject_global_side_data;