From patchwork Fri Mar 27 12:57:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18425 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 67A4B44B885 for ; Fri, 27 Mar 2020 14:58:29 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3BB0D68B4B2; Fri, 27 Mar 2020 14:58:29 +0200 (EET) 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 ESMTP id 4495768B405 for ; Fri, 27 Mar 2020 14:58:23 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 1106428585C for ; Fri, 27 Mar 2020 13:58:23 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id KuAW139mSTaM for ; Fri, 27 Mar 2020 13:58:22 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (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 "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 78D43285554 for ; Fri, 27 Mar 2020 13:58:22 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id C645E21223 for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id FA5LtUGNX4zN for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 8ADE121200 for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id EA49620E0209; Fri, 27 Mar 2020 13:58:19 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:35 +0100 Message-Id: <20200327125747.13460-1-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 01/14] mpeg4videodec: do not copy a range of fields at once 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 is extremely fragile against reordering and hides what is actually being copied. Copy all the fields manually instead. --- Review comments applied and branch rebased against master. 13/14 has been acked and is only included for completeness. --- libavcodec/mpeg4videodec.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index cc03486646..b57bfca943 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3460,7 +3460,33 @@ static int mpeg4_update_thread_context(AVCodecContext *dst, if (ret < 0) return ret; - memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext)); + // copy all the necessary fields explicitly + s->time_increment_bits = s1->time_increment_bits; + s->shape = s1->shape; + s->vol_sprite_usage = s1->vol_sprite_usage; + s->sprite_brightness_change = s1->sprite_brightness_change; + s->num_sprite_warping_points = s1->num_sprite_warping_points; + s->rvlc = s1->rvlc; + s->resync_marker = s1->resync_marker; + s->t_frame = s1->t_frame; + s->new_pred = s1->new_pred; + s->enhancement_type = s1->enhancement_type; + s->scalability = s1->scalability; + s->use_intra_dc_vlc = s1->use_intra_dc_vlc; + s->intra_dc_threshold = s1->intra_dc_threshold; + s->divx_version = s1->divx_version; + s->divx_build = s1->divx_build; + s->xvid_build = s1->xvid_build; + s->lavc_build = s1->lavc_build; + s->showed_packed_warning = s1->showed_packed_warning; + s->vol_control_parameters = s1->vol_control_parameters; + s->cplx_estimation_trash_i = s1->cplx_estimation_trash_i; + s->cplx_estimation_trash_p = s1->cplx_estimation_trash_p; + s->cplx_estimation_trash_b = s1->cplx_estimation_trash_b; + s->rgb = s1->rgb; + + memcpy(s->sprite_shift, s1->sprite_shift, sizeof(s1->sprite_shift)); + memcpy(s->sprite_traj, s1->sprite_traj, sizeof(s1->sprite_traj)); if (CONFIG_MPEG4_DECODER && !init && s1->xvid_build >= 0) ff_xvid_idct_init(&s->m.idsp, dst); From patchwork Fri Mar 27 12:57:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18426 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 5A04244B885 for ; Fri, 27 Mar 2020 14:58:31 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 440DF68B510; Fri, 27 Mar 2020 14:58:31 +0200 (EET) 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 ESMTP id B162568B154 for ; Fri, 27 Mar 2020 14:58:24 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 680DB28587A for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id pESJPApPNbH9 for ; Fri, 27 Mar 2020 13:58:23 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id BDFA6285554 for ; Fri, 27 Mar 2020 13:58:23 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 7317E21200 for ; Fri, 27 Mar 2020 13:58:23 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id BqX0v42zQE5F for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 8CA5A21216 for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 1DD9020E0099; Fri, 27 Mar 2020 13:58:19 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:36 +0100 Message-Id: <20200327125747.13460-2-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 02/14] lavc: replace AVCodecInternal.allocate_progress with an internal cap 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 is a constant codec property, so a capability flag is more appropriate. --- doc/multithreading.txt | 5 +++-- libavcodec/ffv1dec.c | 4 +--- libavcodec/h264dec.c | 5 ++--- libavcodec/hevcdec.c | 5 ++--- libavcodec/internal.h | 20 +++++--------------- libavcodec/mimic.c | 3 +-- libavcodec/mpeg4videodec.c | 4 ++-- libavcodec/pngdec.c | 10 ++++++---- libavcodec/pthread_frame.c | 4 ++-- libavcodec/rv30.c | 1 + libavcodec/rv34.c | 2 -- libavcodec/rv40.c | 1 + libavcodec/vp3.c | 6 +++--- libavcodec/vp8.c | 2 +- libavcodec/vp9.c | 4 ++-- libavcodec/wavpack.c | 5 ++--- 16 files changed, 34 insertions(+), 47 deletions(-) diff --git a/doc/multithreading.txt b/doc/multithreading.txt index 83849deacc..5b9dcb0bfc 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -58,9 +58,10 @@ Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very lit speed gain at this point but it should work. If there are inter-frame dependencies, so the codec calls -ff_thread_report/await_progress(), set AVCodecInternal.allocate_progress. The +ff_thread_report/await_progress(), set FF_CODEC_CAP_ALLOCATE_PROGRESS in +AVCodec.caps_internal and use ff_thread_get_buffer() to allocate frames. The frames must then be freed with ff_thread_release_buffer(). -Otherwise leave it at zero and decode directly into the user-supplied frames. +Otherwise decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn't diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index ca1286f413..2ffd3ef991 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -826,8 +826,6 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((ret = ff_ffv1_init_slice_contexts(f)) < 0) return ret; - avctx->internal->allocate_progress = 1; - return 0; } @@ -1094,5 +1092,5 @@ AVCodec ff_ffv1_decoder = { .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index fec1adfeed..defe514828 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -424,8 +424,6 @@ static av_cold int h264_decode_init(AVCodecContext *avctx) h->avctx->has_b_frames = h->ps.sps->num_reorder_frames; } - avctx->internal->allocate_progress = 1; - ff_h264_flush_change(h); if (h->enable_er < 0 && (avctx->active_thread_type & FF_THREAD_SLICE)) @@ -1080,7 +1078,8 @@ AVCodec ff_h264_decoder = { #endif NULL }, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | + FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = flush_dpb, .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 7448be482c..58689a4370 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3491,8 +3491,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; int ret; - avctx->internal->allocate_progress = 1; - ret = hevc_init_context(avctx); if (ret < 0) return ret; @@ -3582,7 +3580,8 @@ AVCodec ff_hevc_decoder = { .init_thread_copy = ONLY_IF_THREADS_ENABLED(hevc_init_thread_copy), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | + FF_CODEC_CAP_ALLOCATE_PROGRESS, .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), .hw_configs = (const AVCodecHWConfigInternal*[]) { #if CONFIG_HEVC_DXVA2_HWACCEL diff --git a/libavcodec/internal.h b/libavcodec/internal.h index bccd9222d4..700807cd75 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -68,6 +68,11 @@ * Codec initializes slice-based threading with a main function */ #define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) +/* + * The codec supports frame threading and has inter-frame dependencies, so it + * uses ff_thread_report/await_progress(). + */ +#define FF_CODEC_CAP_ALLOCATE_PROGRESS (1 << 6) /** * AVCodec.codec_tags termination value @@ -141,21 +146,6 @@ typedef struct AVCodecInternal { */ int is_copy; - /** - * Whether to allocate progress for frame threading. - * - * The codec must set it to 1 if it uses ff_thread_await/report_progress(), - * then progress will be allocated in ff_thread_get_buffer(). The frames - * then MUST be freed with ff_thread_release_buffer(). - * - * If the codec does not need to call the progress functions (there are no - * dependencies between the frames), it should leave this at 0. Then it can - * decode straight to the user-provided frames (which the user will then - * free with av_frame_unref()), there is no need to call - * ff_thread_release_buffer(). - */ - int allocate_progress; - /** * An audio frame with less than required samples has been submitted and * padded with silence. Reject all subsequent frames. diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 1d463e9962..8e3a77a334 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -139,8 +139,6 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx) MimicContext *ctx = avctx->priv_data; int ret, i; - avctx->internal->allocate_progress = 1; - ctx->prev_index = 0; ctx->cur_index = 15; @@ -481,4 +479,5 @@ AVCodec ff_mimic_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy), + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index b57bfca943..de35b330ad 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3550,7 +3550,6 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->time_increment_bits = 4; /* default value for broken headers */ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - avctx->internal->allocate_progress = 1; return 0; } @@ -3596,7 +3595,8 @@ AVCodec ff_mpeg4_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | + FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 3ce980fc15..af8608b23b 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1772,7 +1772,6 @@ static av_cold int png_dec_init(AVCodecContext *avctx) } if (!avctx->internal->is_copy) { - avctx->internal->allocate_progress = 1; ff_pngdsp_init(&s->dsp); } @@ -1812,7 +1811,8 @@ AVCodec ff_apng_decoder = { .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif @@ -1829,7 +1829,8 @@ AVCodec ff_png_decoder = { .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif @@ -1845,6 +1846,7 @@ AVCodec ff_lscr_decoder = { .decode = decode_frame_lscr, .flush = decode_flush, .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE | + FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 172731a98e..ccccabf4a6 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -201,7 +201,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) { - if (avctx->internal->allocate_progress) + if (avctx->codec->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not " "free the frame on failure. This is a bug, please report it.\n"); av_frame_unref(p->frame); @@ -903,7 +903,7 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int return -1; } - if (avctx->internal->allocate_progress) { + if (avctx->codec->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) { atomic_int *progress; f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index ddaaac651c..0a63352e6b 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -306,4 +306,5 @@ AVCodec ff_rv30_decoder = { }, .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index d171e6e1bd..f877258db6 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1526,8 +1526,6 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) if(!intra_vlcs[0].cbppattern[0].bits) rv34_init_tables(); - avctx->internal->allocate_progress = 1; - return 0; } diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index dfeebda838..ad15044ee3 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -585,4 +585,5 @@ AVCodec ff_rv40_decoder = { }, .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index d53dd87029..8e37ba5fa0 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2330,8 +2330,6 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) if (ret < 0) return ret; - avctx->internal->allocate_progress = 1; - if (avctx->codec_tag == MKTAG('V', 'P', '4', '0')) s->version = 3; else if (avctx->codec_tag == MKTAG('V', 'P', '3', '0')) @@ -3266,7 +3264,7 @@ AVCodec ff_theora_decoder = { .flush = vp3_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), - .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING, + .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif @@ -3284,6 +3282,7 @@ AVCodec ff_vp3_decoder = { .flush = vp3_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #if CONFIG_VP4_DECODER @@ -3301,5 +3300,6 @@ AVCodec ff_vp4_decoder = { .flush = vp3_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index b4deb3ed67..81da0422be 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2853,7 +2853,6 @@ int vp78_decode_init(AVCodecContext *avctx, int is_vp7) s->vp7 = avctx->codec->id == AV_CODEC_ID_VP7; s->pix_fmt = AV_PIX_FMT_NONE; avctx->pix_fmt = AV_PIX_FMT_YUV420P; - avctx->internal->allocate_progress = 1; ff_videodsp_init(&s->vdsp, 8); @@ -2988,5 +2987,6 @@ AVCodec ff_vp8_decoder = { #endif NULL }, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif /* CONFIG_VP7_DECODER */ diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 7ee375d4d0..e47ed4e04e 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1741,7 +1741,6 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) { VP9Context *s = avctx->priv_data; - avctx->internal->allocate_progress = 1; s->last_bpp = 0; s->s.h.filter.sharpness = -1; @@ -1810,7 +1809,8 @@ AVCodec ff_vp9_decoder = { .close = vp9_decode_free, .decode = vp9_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF, + .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF | + FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = vp9_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index b27262b94e..2a2a2b7690 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1020,8 +1020,6 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx) s->fdec_num = 0; - avctx->internal->allocate_progress = 1; - s->curr_frame.f = av_frame_alloc(); s->prev_frame.f = av_frame_alloc(); @@ -1661,5 +1659,6 @@ AVCodec ff_wavpack_decoder = { .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | - AV_CODEC_CAP_SLICE_THREADS + AV_CODEC_CAP_SLICE_THREADS, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; From patchwork Fri Mar 27 12:57:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18435 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 608DC44B885 for ; Fri, 27 Mar 2020 14:58:41 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4CA2B68B7B8; Fri, 27 Mar 2020 14:58:41 +0200 (EET) 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 ESMTP id 626CB68B76D for ; Fri, 27 Mar 2020 14:58:30 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 2ADAA285554 for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id ckrHBQ1kUdsF for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id F3E6428585C for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 8093621216 for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id V3ij4pPVsBRH for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 8FA2C21217 for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 4167720E01FF; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:37 +0100 Message-Id: <20200327125747.13460-3-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 03/14] pthread_frame: merge the functionality for normal decoder init and init_thread_copy 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" The current design, where - proper init is called for the first per-thread context - first thread's private data is copied into private data for all the other threads - a "fixup" function is called for all the other threads to e.g. allocate dynamically allocated data is very fragile and hard to follow, so it is abandoned. Instead, the same init function is used to init each per-thread context. Where necessary, AVCodecInternal.is_copy can be used to differentiate between the first thread and the other ones (e.g. for decoding the extradata just once). --- doc/multithreading.txt | 3 --- libavcodec/aic.c | 1 - libavcodec/alac.c | 10 --------- libavcodec/avcodec.h | 6 ----- libavcodec/cfhd.c | 6 ++--- libavcodec/cllc.c | 14 ------------ libavcodec/dnxhddec.c | 16 -------------- libavcodec/exr.c | 15 ------------- libavcodec/ffv1dec.c | 29 ------------------------ libavcodec/flacdec.c | 14 ------------ libavcodec/h264dec.c | 38 ++++++++------------------------ libavcodec/hevcdec.c | 29 ++++++------------------ libavcodec/hqx.c | 3 --- libavcodec/huffyuvdec.c | 32 --------------------------- libavcodec/lagarith.c | 11 ---------- libavcodec/lcldec.c | 9 -------- libavcodec/magicyuv.c | 16 -------------- libavcodec/mdec.c | 12 ---------- libavcodec/mimic.c | 22 +------------------ libavcodec/mpeg4videodec.c | 10 ++++----- libavcodec/pixlet.c | 16 -------------- libavcodec/pngdec.c | 6 +---- libavcodec/proresdec2.c | 12 ---------- libavcodec/pthread_frame.c | 31 +++++++++++++++----------- libavcodec/rv30.c | 1 - libavcodec/rv34.c | 28 ------------------------ libavcodec/rv34.h | 1 - libavcodec/rv40.c | 1 - libavcodec/sheervideo.c | 14 ------------ libavcodec/takdec.c | 8 ------- libavcodec/tiff.c | 1 - libavcodec/tta.c | 8 ------- libavcodec/vble.c | 1 - libavcodec/vp3.c | 45 -------------------------------------- libavcodec/vp8.c | 16 -------------- libavcodec/vp9.c | 6 ----- libavcodec/wavpack.c | 15 ------------- libavcodec/ylc.c | 19 ---------------- 38 files changed, 42 insertions(+), 483 deletions(-) diff --git a/doc/multithreading.txt b/doc/multithreading.txt index 5b9dcb0bfc..4f645dc147 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -51,9 +51,6 @@ the decode process starts. Call ff_thread_finish_setup() afterwards. If some code can't be moved, have update_thread_context() run it in the next thread. -If the codec allocates writable tables in its init(), add an init_thread_copy() -which re-allocates them for other threads. - Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. diff --git a/libavcodec/aic.c b/libavcodec/aic.c index 956d71fcff..f027fa99ef 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -504,6 +504,5 @@ AVCodec ff_aic_decoder = { .close = aic_decode_close, .decode = aic_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(aic_decode_init), .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/alac.c b/libavcodec/alac.c index ea5ab182f9..c8c04223a0 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -601,15 +601,6 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) return 0; } -#if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - ALACContext *alac = avctx->priv_data; - alac->avctx = avctx; - return allocate_buffers(alac); -} -#endif - static const AVOption options[] = { { "extra_bits_bug", "Force non-standard decoding process", offsetof(ALACContext, extra_bit_bug), AV_OPT_TYPE_BOOL, { .i64 = 0 }, @@ -633,7 +624,6 @@ AVCodec ff_alac_decoder = { .init = alac_decode_init, .close = alac_decode_close, .decode = alac_decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .priv_class = &alac_class }; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 78c483c25c..6bf49c47e2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3606,12 +3606,6 @@ typedef struct AVCodec { * @name Frame-level threading support functions * @{ */ - /** - * If defined, called on thread contexts when they are created. - * If the codec allocates writable tables in init(), re-allocate them here. - * priv_data will be set to a copy of the original. - */ - int (*init_thread_copy)(AVCodecContext *); /** * Copy necessary context variables from a previous thread context to the current one. * If not defined, the next thread will start automatically; otherwise, the codec diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index b4d6b25cbc..7956367b49 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -1039,10 +1039,8 @@ static av_cold int cfhd_close(AVCodecContext *avctx) free_buffers(s); - if (!avctx->internal->is_copy) { - ff_free_vlc(&s->vlc_9); - ff_free_vlc(&s->vlc_18); - } + ff_free_vlc(&s->vlc_9); + ff_free_vlc(&s->vlc_18); return 0; } diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index af0f6da2e9..1f2c98ef73 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -483,19 +483,6 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -#if HAVE_THREADS -static int cllc_init_thread_copy(AVCodecContext *avctx) -{ - CLLCContext *ctx = avctx->priv_data; - - ctx->avctx = avctx; - ctx->swapped_buf = NULL; - ctx->swapped_buf_size = 0; - - return 0; -} -#endif - static av_cold int cllc_decode_close(AVCodecContext *avctx) { CLLCContext *ctx = avctx->priv_data; @@ -526,7 +513,6 @@ AVCodec ff_cllc_decoder = { .id = AV_CODEC_ID_CLLC, .priv_data_size = sizeof(CLLCContext), .init = cllc_decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(cllc_init_thread_copy), .decode = cllc_decode_frame, .close = cllc_decode_close, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index f7585458b9..e5d01e2e71 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -144,21 +144,6 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) return 0; } -static av_cold int dnxhd_decode_init_thread_copy(AVCodecContext *avctx) -{ - DNXHDContext *ctx = avctx->priv_data; - - ctx->avctx = avctx; - // make sure VLC tables will be loaded when cid is parsed - ctx->cid = -1; - - ctx->rows = av_mallocz_array(avctx->thread_count, sizeof(RowContext)); - if (!ctx->rows) - return AVERROR(ENOMEM); - - return 0; -} - static int dnxhd_get_profile(int cid) { switch(cid) { @@ -740,6 +725,5 @@ AVCodec ff_dnxhd_decoder = { .decode = dnxhd_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(dnxhd_decode_init_thread_copy), .profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles), }; diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 1db30a1ae0..73419eadb1 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1863,20 +1863,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static int decode_init_thread_copy(AVCodecContext *avctx) -{ - EXRContext *s = avctx->priv_data; - - // allocate thread data, used for non EXR_RAW compression types - s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData)); - if (!s->thread_data) - return AVERROR_INVALIDDATA; - - return 0; -} -#endif - static av_cold int decode_end(AVCodecContext *avctx) { EXRContext *s = avctx->priv_data; @@ -1956,7 +1942,6 @@ AVCodec ff_exr_decoder = { .id = AV_CODEC_ID_EXR, .priv_data_size = sizeof(EXRContext), .init = decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 2ffd3ef991..c704373cfe 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -977,34 +977,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return buf_size; } -#if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - FFV1Context *f = avctx->priv_data; - int i, ret; - - f->picture.f = NULL; - f->last_picture.f = NULL; - f->sample_buffer = NULL; - f->max_slice_count = 0; - f->slice_count = 0; - - for (i = 0; i < f->quant_table_count; i++) { - av_assert0(f->version > 1); - f->initial_states[i] = av_memdup(f->initial_states[i], - f->context_count[i] * sizeof(*f->initial_states[i])); - } - - f->picture.f = av_frame_alloc(); - f->last_picture.f = av_frame_alloc(); - - if ((ret = ff_ffv1_init_slice_contexts(f)) < 0) - return ret; - - return 0; -} -#endif - static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsrc) { fsdst->version = fsrc->version; @@ -1088,7 +1060,6 @@ AVCodec ff_ffv1_decoder = { .init = decode_init, .close = ff_ffv1_close, .decode = decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index c8eb456049..fb27e8e6d4 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -639,19 +639,6 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, return bytes_read; } -#if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - FLACContext *s = avctx->priv_data; - s->decoded_buffer = NULL; - s->decoded_buffer_size = 0; - s->avctx = avctx; - if (s->flac_stream_info.max_blocksize) - return allocate_buffers(s); - return 0; -} -#endif - static av_cold int flac_decode_close(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; @@ -682,7 +669,6 @@ AVCodec ff_flac_decoder = { .init = flac_decode_init, .close = flac_decode_close, .decode = flac_decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index defe514828..b6c51ed1e2 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -409,13 +409,15 @@ static av_cold int h264_decode_init(AVCodecContext *avctx) } avctx->ticks_per_frame = 2; - if (avctx->extradata_size > 0 && avctx->extradata) { - ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, - &h->ps, &h->is_avc, &h->nal_length_size, - avctx->err_recognition, avctx); - if (ret < 0) { - h264_decode_end(avctx); - return ret; + if (!avctx->internal->is_copy) { + if (avctx->extradata_size > 0 && avctx->extradata) { + ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, + &h->ps, &h->is_avc, &h->nal_length_size, + avctx->err_recognition, avctx); + if (ret < 0) { + h264_decode_end(avctx); + return ret; + } } } @@ -438,27 +440,6 @@ static av_cold int h264_decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static int decode_init_thread_copy(AVCodecContext *avctx) -{ - H264Context *h = avctx->priv_data; - int ret; - - if (!avctx->internal->is_copy) - return 0; - - memset(h, 0, sizeof(*h)); - - ret = h264_init_context(avctx, h); - if (ret < 0) - return ret; - - h->context_initialized = 0; - - return 0; -} -#endif - /** * instantaneous decoder refresh. */ @@ -1081,7 +1062,6 @@ AVCodec ff_h264_decoder = { .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = flush_dpb, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles), .priv_class = &h264_class, diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 58689a4370..36be83948e 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -3506,11 +3506,13 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) else s->threads_number = 1; - if (avctx->extradata_size > 0 && avctx->extradata) { - ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1); - if (ret < 0) { - hevc_decode_free(avctx); - return ret; + if (!avctx->internal->is_copy) { + if (avctx->extradata_size > 0 && avctx->extradata) { + ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1); + if (ret < 0) { + hevc_decode_free(avctx); + return ret; + } } } @@ -3522,22 +3524,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static av_cold int hevc_init_thread_copy(AVCodecContext *avctx) -{ - HEVCContext *s = avctx->priv_data; - int ret; - - memset(s, 0, sizeof(*s)); - - ret = hevc_init_context(avctx); - if (ret < 0) - return ret; - - return 0; -} -#endif - static void hevc_decode_flush(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; @@ -3577,7 +3563,6 @@ AVCodec ff_hevc_decoder = { .decode = hevc_decode_frame, .flush = hevc_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(hevc_update_thread_context), - .init_thread_copy = ONLY_IF_THREADS_ENABLED(hevc_init_thread_copy), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index 39404d24e5..e2b895ac40 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -520,9 +520,6 @@ static av_cold int hqx_decode_close(AVCodecContext *avctx) int i; HQXContext *ctx = avctx->priv_data; - if (avctx->internal->is_copy) - return 0; - ff_free_vlc(&ctx->cbp_vlc); for (i = 0; i < 3; i++) { ff_free_vlc(&ctx->dc_vlc[i]); diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 46dcfa8235..0ee7ec3917 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -570,35 +570,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return ret; } -#if HAVE_THREADS -static av_cold int decode_init_thread_copy(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - int i, ret; - - s->avctx = avctx; - - if ((ret = ff_huffyuv_alloc_temp(s)) < 0) { - ff_huffyuv_common_end(s); - return ret; - } - - for (i = 0; i < 8; i++) - s->vlc[i].table = NULL; - - if (s->version >= 2) { - if ((ret = read_huffman_tables(s, avctx->extradata + 4, - avctx->extradata_size)) < 0) - return ret; - } else { - if ((ret = read_old_huffman_tables(s)) < 0) - return ret; - } - - return 0; -} -#endif - /** Subset of GET_VLC for use in hand-roller VLC code */ #define VLC_INTERN(dst, table, gb, name, bits, max_depth) \ code = table[index][0]; \ @@ -1302,7 +1273,6 @@ AVCodec ff_huffyuv_decoder = { .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), }; #if CONFIG_FFVHUFF_DECODER @@ -1317,7 +1287,6 @@ AVCodec ff_ffvhuff_decoder = { .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), }; #endif /* CONFIG_FFVHUFF_DECODER */ @@ -1333,6 +1302,5 @@ AVCodec ff_hymt_decoder = { .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), }; #endif /* CONFIG_HYMT_DECODER */ diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 0a45812bc1..d81e55cf4c 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -712,16 +712,6 @@ static av_cold int lag_decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static av_cold int lag_decode_init_thread_copy(AVCodecContext *avctx) -{ - LagarithContext *l = avctx->priv_data; - l->avctx = avctx; - - return 0; -} -#endif - AVCodec ff_lagarith_decoder = { .name = "lagarith", .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), @@ -729,7 +719,6 @@ AVCodec ff_lagarith_decoder = { .id = AV_CODEC_ID_LAGARITH, .priv_data_size = sizeof(LagarithContext), .init = lag_decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(lag_decode_init_thread_copy), .decode = lag_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, }; diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 046cdc4f8e..c51083bdf2 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -622,13 +622,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - return decode_init(avctx); -} -#endif - static av_cold int decode_end(AVCodecContext *avctx) { LclDecContext * const c = avctx->priv_data; @@ -650,7 +643,6 @@ AVCodec ff_mszh_decoder = { .id = AV_CODEC_ID_MSZH, .priv_data_size = sizeof(LclDecContext), .init = decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, @@ -666,7 +658,6 @@ AVCodec ff_zlib_decoder = { .id = AV_CODEC_ID_ZLIB, .priv_data_size = sizeof(LclDecContext), .init = decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index aacd0d4d7d..5d76274d54 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -749,21 +749,6 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } -#if HAVE_THREADS -static int magy_init_thread_copy(AVCodecContext *avctx) -{ - MagicYUVContext *s = avctx->priv_data; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) { - s->slices[i] = NULL; - s->slices_size[i] = 0; - } - - return 0; -} -#endif - static av_cold int magy_decode_init(AVCodecContext *avctx) { MagicYUVContext *s = avctx->priv_data; @@ -792,7 +777,6 @@ AVCodec ff_magicyuv_decoder = { .id = AV_CODEC_ID_MAGICYUV, .priv_data_size = sizeof(MagicYUVContext), .init = magy_decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(magy_init_thread_copy), .close = magy_decode_end, .decode = magy_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 330b761279..7e34ec568e 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -240,17 +240,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } -#if HAVE_THREADS -static av_cold int decode_init_thread_copy(AVCodecContext *avctx) -{ - MDECContext * const a = avctx->priv_data; - - a->avctx = avctx; - - return 0; -} -#endif - static av_cold int decode_end(AVCodecContext *avctx) { MDECContext * const a = avctx->priv_data; @@ -271,5 +260,4 @@ AVCodec ff_mdec_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy) }; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 8e3a77a334..2563a49d53 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -128,8 +128,7 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx) av_frame_free(&ctx->frames[i].f); } - if (!avctx->internal->is_copy) - ff_free_vlc(&ctx->vlc); + ff_free_vlc(&ctx->vlc); return 0; } @@ -449,24 +448,6 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, return buf_size; } -#if HAVE_THREADS -static av_cold int mimic_init_thread_copy(AVCodecContext *avctx) -{ - MimicContext *ctx = avctx->priv_data; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) { - ctx->frames[i].f = av_frame_alloc(); - if (!ctx->frames[i].f) { - mimic_decode_end(avctx); - return AVERROR(ENOMEM); - } - } - - return 0; -} -#endif - AVCodec ff_mimic_decoder = { .name = "mimic", .long_name = NULL_IF_CONFIG_SMALL("Mimic"), @@ -478,6 +459,5 @@ AVCodec ff_mimic_decoder = { .decode = mimic_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context), - .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy), .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index de35b330ad..bfb1f92b33 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3559,13 +3559,11 @@ static av_cold int decode_end(AVCodecContext *avctx) Mpeg4DecContext *ctx = avctx->priv_data; int i; - if (!avctx->internal->is_copy) { - for (i = 0; i < 12; i++) - ff_free_vlc(&ctx->studio_intra_tab[i]); + for (i = 0; i < 12; i++) + ff_free_vlc(&ctx->studio_intra_tab[i]); - ff_free_vlc(&ctx->studio_luma_dc); - ff_free_vlc(&ctx->studio_chroma_dc); - } + ff_free_vlc(&ctx->studio_luma_dc); + ff_free_vlc(&ctx->studio_chroma_dc); return ff_h263_decode_end(avctx); } diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 03a2cdacc8..7b068b1ce5 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -675,28 +675,12 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, return pktsize; } -#if HAVE_THREADS -static int pixlet_init_thread_copy(AVCodecContext *avctx) -{ - PixletContext *ctx = avctx->priv_data; - - ctx->filter[0] = NULL; - ctx->filter[1] = NULL; - ctx->prediction = NULL; - ctx->w = 0; - ctx->h = 0; - - return 0; -} -#endif /* HAVE_THREADS */ - AVCodec ff_pixlet_decoder = { .name = "pixlet", .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PIXLET, .init = pixlet_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(pixlet_init_thread_copy), .close = pixlet_close, .decode = pixlet_decode_frame, .priv_data_size = sizeof(PixletContext), diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index af8608b23b..7e2c19bd57 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1771,9 +1771,7 @@ static av_cold int png_dec_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - if (!avctx->internal->is_copy) { - ff_pngdsp_init(&s->dsp); - } + ff_pngdsp_init(&s->dsp); return 0; } @@ -1808,7 +1806,6 @@ AVCodec ff_apng_decoder = { .init = png_dec_init, .close = png_dec_end, .decode = decode_frame_apng, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | @@ -1826,7 +1823,6 @@ AVCodec ff_png_decoder = { .init = png_dec_init, .close = png_dec_end, .decode = decode_frame_png, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE | diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 2652a31c81..d5fbfc6711 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -807,17 +807,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return avpkt->size; } -#if HAVE_THREADS -static int decode_init_thread_copy(AVCodecContext *avctx) -{ - ProresContext *ctx = avctx->priv_data; - - ctx->slices = NULL; - - return 0; -} -#endif - static av_cold int decode_close(AVCodecContext *avctx) { ProresContext *ctx = avctx->priv_data; @@ -834,7 +823,6 @@ AVCodec ff_prores_decoder = { .id = AV_CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), .init = decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .close = decode_close, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index ccccabf4a6..183d0f84f2 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -703,7 +703,10 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&p->released_buffers); if (i && p->avctx) { + if (codec->priv_class) + av_opt_free(p->avctx->priv_data); av_freep(&p->avctx->priv_data); + av_freep(&p->avctx->slice_offset); } @@ -809,28 +812,30 @@ int ff_frame_thread_init(AVCodecContext *avctx) copy->internal->thread_ctx = p; copy->internal->last_pkt_props = &p->avpkt; - if (!i) { - src = copy; - - if (codec->init) - err = codec->init(copy); - - update_context_from_thread(avctx, copy, 1); - } else { - copy->priv_data = av_malloc(codec->priv_data_size); + if (i) { + copy->priv_data = av_mallocz(codec->priv_data_size); if (!copy->priv_data) { err = AVERROR(ENOMEM); goto error; } - memcpy(copy->priv_data, src->priv_data, codec->priv_data_size); - copy->internal->is_copy = 1; - if (codec->init_thread_copy) - err = codec->init_thread_copy(copy); + if (codec->priv_class) { + *(const AVClass **)copy->priv_data = codec->priv_class; + err = av_opt_copy(copy->priv_data, src->priv_data); + if (err < 0) + goto error; + } + copy->internal->is_copy = 1; } + if (codec->init) + err = codec->init(copy); + if (err) goto error; + if (!i) + update_context_from_thread(avctx, copy, 1); + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index 0a63352e6b..36cd5345fd 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -304,7 +304,6 @@ AVCodec ff_rv30_decoder = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index f877258db6..ec0cd27916 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1529,34 +1529,6 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) return 0; } -int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx) -{ - int err; - RV34DecContext *r = avctx->priv_data; - - r->s.avctx = avctx; - - if (avctx->internal->is_copy) { - r->tmp_b_block_base = NULL; - r->cbp_chroma = NULL; - r->cbp_luma = NULL; - r->deblock_coefs = NULL; - r->intra_types_hist = NULL; - r->mb_type = NULL; - - ff_mpv_idct_init(&r->s); - - if ((err = ff_mpv_common_init(&r->s)) < 0) - return err; - if ((err = rv34_decoder_alloc(r)) < 0) { - ff_mpv_common_end(&r->s); - return err; - } - } - - return 0; -} - int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { RV34DecContext *r = dst->priv_data, *r1 = src->priv_data; diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h index efff94a1d9..1d5522538b 100644 --- a/libavcodec/rv34.h +++ b/libavcodec/rv34.h @@ -136,7 +136,6 @@ int ff_rv34_get_start_offset(GetBitContext *gb, int blocks); int ff_rv34_decode_init(AVCodecContext *avctx); int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt); int ff_rv34_decode_end(AVCodecContext *avctx); -int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx); int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); #endif /* AVCODEC_RV34_H */ diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index ad15044ee3..462024c81e 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -583,7 +583,6 @@ AVCodec ff_rv40_decoder = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/sheervideo.c b/libavcodec/sheervideo.c index 50c3ebcee7..1a43727a30 100644 --- a/libavcodec/sheervideo.c +++ b/libavcodec/sheervideo.c @@ -2063,19 +2063,6 @@ static int decode_frame(AVCodecContext *avctx, return avpkt->size; } -#if HAVE_THREADS -static int decode_init_thread_copy(AVCodecContext *avctx) -{ - SheerVideoContext *s = avctx->priv_data; - - s->format = 0; - memset(&s->vlc[0], 0, sizeof(s->vlc[0])); - memset(&s->vlc[1], 0, sizeof(s->vlc[1])); - - return 0; -} -#endif - static av_cold int decode_end(AVCodecContext *avctx) { SheerVideoContext *s = avctx->priv_data; @@ -2092,7 +2079,6 @@ AVCodec ff_sheervideo_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_SHEERVIDEO, .priv_data_size = sizeof(SheerVideoContext), - .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 8ec87ab509..9fa1cb1f7f 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -915,13 +915,6 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } #if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - TAKDecContext *s = avctx->priv_data; - s->avctx = avctx; - return 0; -} - static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { @@ -953,7 +946,6 @@ AVCodec ff_tak_decoder = { .init = tak_decode_init, .close = tak_decode_close, .decode = tak_decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index e8357114de..3b5985ed1e 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -2165,7 +2165,6 @@ AVCodec ff_tiff_decoder = { .init = tiff_init, .close = tiff_end, .decode = decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(tiff_init), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &tiff_decoder_class, diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 3fbee06987..e68e4fbb36 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -389,13 +389,6 @@ error: return ret; } -static int init_thread_copy(AVCodecContext *avctx) -{ - TTAContext *s = avctx->priv_data; - s->avctx = avctx; - return allocate_buffers(avctx); -} - static av_cold int tta_decode_close(AVCodecContext *avctx) { TTAContext *s = avctx->priv_data; @@ -430,7 +423,6 @@ AVCodec ff_tta_decoder = { .init = tta_decode_init, .close = tta_decode_close, .decode = tta_decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, .priv_class = &tta_decoder_class, }; diff --git a/libavcodec/vble.c b/libavcodec/vble.c index c25ee98697..c48c13127a 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -214,6 +214,5 @@ AVCodec ff_vble_decoder = { .close = vble_decode_close, .decode = vble_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vble_decode_init), .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 8e37ba5fa0..81d0b9b7bb 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -347,9 +347,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) av_frame_free(&s->last_frame.f); av_frame_free(&s->golden_frame.f); - if (avctx->internal->is_copy) - return 0; - for (i = 0; i < 16; i++) { ff_free_vlc(&s->dc_vlc[i]); ff_free_vlc(&s->ac_vlc_1[i]); @@ -2601,23 +2598,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * } if (s != s1) { - if (!s->current_frame.f) - return AVERROR(ENOMEM); - // init tables if the first frame hasn't been decoded - if (!s->current_frame.f->data[0]) { - int y_fragment_count, c_fragment_count; - s->avctx = dst; - err = allocate_tables(dst); - if (err) - return err; - y_fragment_count = s->fragment_width[0] * s->fragment_height[0]; - c_fragment_count = s->fragment_width[1] * s->fragment_height[1]; - memcpy(s->motion_val[0], s1->motion_val[0], - y_fragment_count * sizeof(*s->motion_val[0])); - memcpy(s->motion_val[1], s1->motion_val[1], - c_fragment_count * sizeof(*s->motion_val[1])); - } - // copy previous frame data if ((err = ref_frames(s, s1)) < 0) return err; @@ -2927,28 +2907,6 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) return 0; } -#if HAVE_THREADS -static int vp3_init_thread_copy(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - - s->superblock_coding = NULL; - s->all_fragments = NULL; - s->coded_fragment_list[0] = NULL; - s-> kf_coded_fragment_list= NULL; - s->nkf_coded_fragment_list= NULL; - s->dct_tokens_base = NULL; - s->superblock_fragments = NULL; - s->macroblock_coding = NULL; - s->motion_val[0] = NULL; - s->motion_val[1] = NULL; - s->edge_emu_buffer = NULL; - s->dc_pred_row = NULL; - - return init_frames(s); -} -#endif - #if CONFIG_THEORA_DECODER static const enum AVPixelFormat theora_pix_fmts[4] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P @@ -3262,7 +3220,6 @@ AVCodec ff_theora_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS, }; @@ -3280,7 +3237,6 @@ AVCodec ff_vp3_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; @@ -3298,7 +3254,6 @@ AVCodec ff_vp4_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context), .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 81da0422be..1794d6d031 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2894,21 +2894,6 @@ av_cold int ff_vp8_decode_init(AVCodecContext *avctx) #if CONFIG_VP8_DECODER #if HAVE_THREADS -static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) -{ - VP8Context *s = avctx->priv_data; - int ret; - - s->avctx = avctx; - - if ((ret = vp8_init_frames(s)) < 0) { - ff_vp8_decode_free(avctx); - return ret; - } - - return 0; -} - #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL) static int vp8_decode_update_thread_context(AVCodecContext *dst, @@ -2976,7 +2961,6 @@ AVCodec ff_vp8_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, .flush = vp8_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context), .hw_configs = (const AVCodecHWConfigInternal*[]) { #if CONFIG_VP8_VAAPI_HWACCEL diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index e47ed4e04e..2a3a4555b9 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1748,11 +1748,6 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) } #if HAVE_THREADS -static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx) -{ - return init_frames(avctx); -} - static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { int i, ret; @@ -1812,7 +1807,6 @@ AVCodec ff_vp9_decoder = { .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF | FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = vp9_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), .bsfs = "vp9_superframe_split", diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 2a2a2b7690..d96ee1fa3a 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -979,20 +979,6 @@ static av_cold int wv_alloc_frame_context(WavpackContext *c) } #if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - WavpackContext *s = avctx->priv_data; - s->avctx = avctx; - - s->curr_frame.f = av_frame_alloc(); - s->prev_frame.f = av_frame_alloc(); - - if (!s->curr_frame.f || !s->prev_frame.f) - return AVERROR(ENOMEM); - - return 0; -} - static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { WavpackContext *fsrc = src->priv_data; @@ -1656,7 +1642,6 @@ AVCodec ff_wavpack_decoder = { .close = wavpack_decode_end, .decode = wavpack_decode_frame, .flush = wavpack_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c index 11333222b9..2afe3fc9d5 100644 --- a/libavcodec/ylc.c +++ b/libavcodec/ylc.c @@ -453,24 +453,6 @@ static int decode_frame(AVCodecContext *avctx, return avpkt->size; } -#if HAVE_THREADS -static int init_thread_copy(AVCodecContext *avctx) -{ - YLCContext *s = avctx->priv_data; - - memset(&s->vlc[0], 0, sizeof(VLC)); - memset(&s->vlc[1], 0, sizeof(VLC)); - memset(&s->vlc[2], 0, sizeof(VLC)); - memset(&s->vlc[3], 0, sizeof(VLC)); - s->table_bits = NULL; - s->table_bits_size = 0; - s->bitstream_bits = NULL; - s->bitstream_bits_size = 0; - - return 0; -} -#endif - static av_cold int decode_end(AVCodecContext *avctx) { YLCContext *s = avctx->priv_data; @@ -494,7 +476,6 @@ AVCodec ff_ylc_decoder = { .id = AV_CODEC_ID_YLC, .priv_data_size = sizeof(YLCContext), .init = decode_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, From patchwork Fri Mar 27 12:57:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18427 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 488E444B885 for ; Fri, 27 Mar 2020 14:58:32 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2CD9D68B697; Fri, 27 Mar 2020 14:58:32 +0200 (EET) 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 ESMTP id 18D7968B50F for ; Fri, 27 Mar 2020 14:58:25 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id D69E1285890 for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id rRmr3bfqghb8 for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 825D0285554 for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 49AFD21200 for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id F6rDNevbRTXT for ; Fri, 27 Mar 2020 13:58:23 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 9259421218 for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 62C6E20E020F; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:38 +0100 Message-Id: <20200327125747.13460-4-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 04/14] pthread_frame: do not share priv_data between multiple codec contexts 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" Specifically, between the user-facing one and the first frame thread one. This is fragile and dangerous, allocate separate private data for each per-thread context. --- libavcodec/pthread_frame.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 183d0f84f2..19073b1253 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -702,7 +702,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_packet_unref(&p->avpkt); av_freep(&p->released_buffers); - if (i && p->avctx) { + if (p->avctx) { if (codec->priv_class) av_opt_free(p->avctx->priv_data); av_freep(&p->avctx->priv_data); @@ -812,7 +812,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) copy->internal->thread_ctx = p; copy->internal->last_pkt_props = &p->avpkt; - if (i) { + if (codec->priv_data_size) { copy->priv_data = av_mallocz(codec->priv_data_size); if (!copy->priv_data) { err = AVERROR(ENOMEM); @@ -825,9 +825,11 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (err < 0) goto error; } - copy->internal->is_copy = 1; } + if (i) + copy->internal->is_copy = 1; + if (codec->init) err = codec->init(copy); From patchwork Fri Mar 27 12:57:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18429 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 26CDB44B885 for ; Fri, 27 Mar 2020 14:58:35 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0C82168B769; Fri, 27 Mar 2020 14:58:35 +0200 (EET) 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 ESMTP id 9AD0168B52F for ; Fri, 27 Mar 2020 14:58:28 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 4130128589D for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id cXWqv3cs-CUL for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id C896A285554 for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 706A221200 for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 0A8qUaDb2RVH for ; Fri, 27 Mar 2020 13:58:26 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id BDBC12121A for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id A04D720E0099; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:39 +0100 Message-Id: <20200327125747.13460-5-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 05/14] pthread_frame: do not embed full AVFrame structs into per-thread contexts 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" Use the AVFrame API to properly allocate and free frames for delayed release. --- libavcodec/pthread_frame.c | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 19073b1253..639c5ce574 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -93,9 +93,9 @@ typedef struct PerThreadContext { * Array of frames passed to ff_thread_release_buffer(). * Frames are released after all threads referencing them are finished. */ - AVFrame *released_buffers; - int num_released_buffers; - int released_buffers_allocated; + AVFrame **released_buffers; + int num_released_buffers; + int released_buffers_allocated; AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() int requested_flags; ///< flags passed to get_buffer() for requested_frame @@ -370,7 +370,7 @@ static void release_delayed_buffers(PerThreadContext *p) // fix extended data in case the caller screwed it up av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO || p->avctx->codec_type == AVMEDIA_TYPE_AUDIO); - f = &p->released_buffers[--p->num_released_buffers]; + f = p->released_buffers[--p->num_released_buffers]; f->extended_data = f->data; av_frame_unref(f); @@ -654,7 +654,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) { FrameThreadContext *fctx = avctx->internal->thread_ctx; const AVCodec *codec = avctx->codec; - int i; + int i, j; park_frame_worker_threads(fctx, thread_count); @@ -700,6 +700,9 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_cond_destroy(&p->progress_cond); pthread_cond_destroy(&p->output_cond); av_packet_unref(&p->avpkt); + + for (j = 0; j < p->released_buffers_allocated; j++) + av_frame_free(&p->released_buffers[j]); av_freep(&p->released_buffers); if (p->avctx) { @@ -988,7 +991,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) { PerThreadContext *p = avctx->internal->thread_ctx; FrameThreadContext *fctx; - AVFrame *dst, *tmp; + AVFrame *dst; int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || THREAD_SAFE_CALLBACKS(avctx); @@ -1009,16 +1012,23 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) fctx = p->parent; pthread_mutex_lock(&fctx->buffer_mutex); - if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) - goto fail; - tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, - (p->num_released_buffers + 1) * - sizeof(*p->released_buffers)); - if (!tmp) - goto fail; - p->released_buffers = tmp; + if (p->num_released_buffers == p->released_buffers_allocated) { + AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1, + sizeof(*p->released_buffers)); + if (tmp) { + tmp[p->released_buffers_allocated] = av_frame_alloc(); + p->released_buffers = tmp; + } + + if (!tmp || !tmp[p->released_buffers_allocated]) { + av_log(avctx, AV_LOG_ERROR, "Cannot queue a buffer for delayed " + "release. This will leak memory.\n"); + goto fail; + } + p->released_buffers_allocated++; + } - dst = &p->released_buffers[p->num_released_buffers]; + dst = p->released_buffers[p->num_released_buffers]; av_frame_move_ref(dst, f->f); p->num_released_buffers++; From patchwork Fri Mar 27 12:57:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18430 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 3512144B885 for ; Fri, 27 Mar 2020 14:58:37 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1DB2868B79B; Fri, 27 Mar 2020 14:58:37 +0200 (EET) 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 ESMTP id 67CEB68B75F for ; Fri, 27 Mar 2020 14:58:29 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 362FF2858A2 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id SWy2x5f_E0bz for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id C625D285554 for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 4A21D21200 for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id i8O37M8FXkTf for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id DD7F22121B for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id BC9F520E020F; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:40 +0100 Message-Id: <20200327125747.13460-6-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 06/14] pthread_frame: do not copy a range of AVCodecContext fields at once 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 is extremely fragile against reordering and hides what is actually being copied. Copy all the fields manually instead. --- libavcodec/pthread_frame.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 639c5ce574..7ebeef357a 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -322,7 +322,6 @@ FF_ENABLE_DEPRECATION_WARNINGS */ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) { -#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); dst->flags = src->flags; dst->draw_horiz_band= src->draw_horiz_band; @@ -336,7 +335,9 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->flags2 = src->flags2; dst->export_side_data = src->export_side_data; - copy_fields(skip_loop_filter, subtitle_header); + dst->skip_loop_filter = src->skip_loop_filter; + dst->skip_idct = src->skip_idct; + dst->skip_frame = src->skip_frame; dst->frame_number = src->frame_number; dst->reordered_opaque = src->reordered_opaque; @@ -354,7 +355,6 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) } dst->slice_count = src->slice_count; return 0; -#undef copy_fields } /// Releases the buffers that this decoding thread was the last user of. From patchwork Fri Mar 27 12:57:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18428 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 3474844B885 for ; Fri, 27 Mar 2020 14:58:34 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1A6D968B708; Fri, 27 Mar 2020 14:58:34 +0200 (EET) 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 ESMTP id AD40868B50F for ; Fri, 27 Mar 2020 14:58:27 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 7575A28589A for ; Fri, 27 Mar 2020 13:58:27 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id o2NH72vnnVJh for ; Fri, 27 Mar 2020 13:58:26 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 822B9285554 for ; Fri, 27 Mar 2020 13:58:26 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 4A3BE21200 for ; Fri, 27 Mar 2020 13:58:26 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id m4CTgdrbanL0 for ; Fri, 27 Mar 2020 13:58:24 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id A1A7821219 for ; Fri, 27 Mar 2020 13:58:20 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 7A14720E0215; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:41 +0100 Message-Id: <20200327125747.13460-7-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 07/14] lavc: do not implicitly share the frame pool between threads 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" Currently the frame pool used by the default get_buffer2() implementation is a single struct, allocated when opening the decoder. A pointer to it is simply copied to each frame thread and we assume that no thread attempts to modify it at an unexpected time. This is rather fragile and potentially dangerous. With this commit, the frame pool is made refcounted, with the reference being propagated across threads along with other context variables. The frame pool is now also immutable - when the stream parameters change we drop the old reference and create a new one. --- libavcodec/decode.c | 102 ++++++++++++++++++++++++++++--------- libavcodec/internal.h | 21 +------- libavcodec/pthread_frame.c | 12 +++++ libavcodec/utils.c | 13 +---- 4 files changed, 94 insertions(+), 54 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index af6bb3f952..8925ce6edc 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -45,6 +45,25 @@ #include "internal.h" #include "thread.h" +typedef struct FramePool { + /** + * Pools for each data plane. For audio all the planes have the same size, + * so only pools[0] is used. + */ + AVBufferPool *pools[4]; + + /* + * Pool parameters + */ + int format; + int width, height; + int stride_align[AV_NUM_DATA_POINTERS]; + int linesize[4]; + int planes; + int channels; + int samples; +} FramePool; + static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) { int size = 0, ret; @@ -1504,10 +1523,61 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) return ret; } +static void frame_pool_free(void *opaque, uint8_t *data) +{ + FramePool *pool = (FramePool*)data; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) + av_buffer_pool_uninit(&pool->pools[i]); + + av_freep(&data); +} + +static AVBufferRef *frame_pool_alloc(void) +{ + FramePool *pool = av_mallocz(sizeof(*pool)); + AVBufferRef *buf; + + if (!pool) + return NULL; + + buf = av_buffer_create((uint8_t*)pool, sizeof(*pool), + frame_pool_free, NULL, 0); + if (!buf) { + av_freep(&pool); + return NULL; + } + + return buf; +} + static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) { - FramePool *pool = avctx->internal->pool; - int i, ret; + FramePool *pool = avctx->internal->pool ? + (FramePool*)avctx->internal->pool->data : NULL; + AVBufferRef *pool_buf; + int i, ret, ch, planes; + + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { + int planar = av_sample_fmt_is_planar(frame->format); + ch = frame->channels; + planes = planar ? ch : 1; + } + + if (pool && pool->format == frame->format) { + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && + pool->width == frame->width && pool->height == frame->height) + return 0; + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + } + + pool_buf = frame_pool_alloc(); + if (!pool_buf) + return AVERROR(ENOMEM); + pool = (FramePool*)pool_buf->data; switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: { @@ -1518,10 +1588,6 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) int h = frame->height; int tmpsize, unaligned; - if (pool->format == frame->format && - pool->width == frame->width && pool->height == frame->height) - return 0; - avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); do { @@ -1548,7 +1614,6 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) size[i] = tmpsize - (data[i] - data[0]); for (i = 0; i < 4; i++) { - av_buffer_pool_uninit(&pool->pools[i]); pool->linesize[i] = linesize[i]; if (size[i]) { pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, @@ -1568,15 +1633,6 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) break; } case AVMEDIA_TYPE_AUDIO: { - int ch = frame->channels; //av_get_channel_layout_nb_channels(frame->channel_layout); - int planar = av_sample_fmt_is_planar(frame->format); - int planes = planar ? ch : 1; - - if (pool->format == frame->format && pool->planes == planes && - pool->channels == ch && frame->nb_samples == pool->samples) - return 0; - - av_buffer_pool_uninit(&pool->pools[0]); ret = av_samples_get_buffer_size(&pool->linesize[0], ch, frame->nb_samples, frame->format, 0); if (ret < 0) @@ -1596,19 +1652,19 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) } default: av_assert0(0); } + + av_buffer_unref(&avctx->internal->pool); + avctx->internal->pool = pool_buf; + return 0; fail: - for (i = 0; i < 4; i++) - av_buffer_pool_uninit(&pool->pools[i]); - pool->format = -1; - pool->planes = pool->channels = pool->samples = 0; - pool->width = pool->height = 0; + av_buffer_unref(&pool_buf); return ret; } static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) { - FramePool *pool = avctx->internal->pool; + FramePool *pool = (FramePool*)avctx->internal->pool->data; int planes = pool->planes; int i; @@ -1653,7 +1709,7 @@ fail: static int video_get_buffer(AVCodecContext *s, AVFrame *pic) { - FramePool *pool = s->internal->pool; + FramePool *pool = (FramePool*)s->internal->pool->data; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); int i; diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 700807cd75..721fd017d4 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -108,25 +108,6 @@ # define STRIDE_ALIGN 8 #endif -typedef struct FramePool { - /** - * Pools for each data plane. For audio all the planes have the same size, - * so only pools[0] is used. - */ - AVBufferPool *pools[4]; - - /* - * Pool parameters - */ - int format; - int width, height; - int stride_align[AV_NUM_DATA_POINTERS]; - int linesize[4]; - int planes; - int channels; - int samples; -} FramePool; - typedef struct DecodeSimpleContext { AVPacket *in_pkt; AVFrame *out_frame; @@ -154,7 +135,7 @@ typedef struct AVCodecInternal { AVFrame *to_free; - FramePool *pool; + AVBufferRef *pool; void *thread_ctx; diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 7ebeef357a..214b191021 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -296,6 +296,17 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, } dst->hwaccel_flags = src->hwaccel_flags; + + if (!!dst->internal->pool != !!src->internal->pool || + (dst->internal->pool && dst->internal->pool->data != src->internal->pool->data)) { + av_buffer_unref(&dst->internal->pool); + + if (src->internal->pool) { + dst->internal->pool = av_buffer_ref(src->internal->pool); + if (!dst->internal->pool) + return AVERROR(ENOMEM); + } + } } if (for_user) { @@ -714,6 +725,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) } if (p->avctx) { + av_buffer_unref(&p->avctx->internal->pool); av_freep(&p->avctx->internal); av_buffer_unref(&p->avctx->hw_frames_ctx); } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4ab8cff4f5..26c038dfd9 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -583,12 +583,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } avctx->internal = avci; - avci->pool = av_mallocz(sizeof(*avci->pool)); - if (!avci->pool) { - ret = AVERROR(ENOMEM); - goto free_and_end; - } - avci->to_free = av_frame_alloc(); if (!avci->to_free) { ret = AVERROR(ENOMEM); @@ -1076,7 +1070,7 @@ FF_ENABLE_DEPRECATION_WARNINGS av_packet_free(&avci->ds.in_pkt); ff_decode_bsfs_uninit(avctx); - av_freep(&avci->pool); + av_buffer_unref(&avci->pool); } av_freep(&avci); avctx->internal = NULL; @@ -1111,7 +1105,6 @@ av_cold int avcodec_close(AVCodecContext *avctx) return 0; if (avcodec_is_open(avctx)) { - FramePool *pool = avctx->internal->pool; if (CONFIG_FRAME_THREAD_ENCODER && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { ff_frame_thread_encoder_free(avctx); @@ -1130,9 +1123,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_packet_free(&avctx->internal->ds.in_pkt); - for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) - av_buffer_pool_uninit(&pool->pools[i]); - av_freep(&avctx->internal->pool); + av_buffer_unref(&avctx->internal->pool); if (avctx->hwaccel && avctx->hwaccel->uninit) avctx->hwaccel->uninit(avctx); From patchwork Fri Mar 27 12:57:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18438 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 921B444B885 for ; Fri, 27 Mar 2020 14:58:43 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7F8B568B82B; Fri, 27 Mar 2020 14:58:43 +0200 (EET) 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 ESMTP id 60C1568B6DE for ; Fri, 27 Mar 2020 14:58:31 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 29B5328587A for ; Fri, 27 Mar 2020 13:58:31 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id UROgMVpw3pMl for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 6A0F9285890 for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id D4DBE21216 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id e44_RuCFGdf6 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 35C162121E for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 20C1120E0099; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:42 +0100 Message-Id: <20200327125747.13460-8-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 08/14] decode: plug leaks on error in update_frame_pool() 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" --- libavcodec/decode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 8925ce6edc..f43dc0dd5d 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1595,7 +1595,7 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); if (ret < 0) - return ret; + goto fail; // increase alignment of w for next try (rhs gives the lowest bit set in w) w += w & ~(w - 1); @@ -1606,8 +1606,10 @@ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, NULL, linesize); - if (tmpsize < 0) - return tmpsize; + if (tmpsize < 0) { + ret = tmpsize; + goto fail; + } for (i = 0; i < 3 && data[i + 1]; i++) size[i] = data[i + 1] - data[i]; From patchwork Fri Mar 27 12:57:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18433 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 1775144B885 for ; Fri, 27 Mar 2020 14:58:40 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0AE1368B7BB; Fri, 27 Mar 2020 14:58:40 +0200 (EET) 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 ESMTP id 37C5D68B775 for ; Fri, 27 Mar 2020 14:58:30 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id EED7F2858A4 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id XnEB2_Vn9Egg for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 71B20285554 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 1675D21200 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id w4cn9EA8hlBG for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 058912121C for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id DC69E20E0215; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:43 +0100 Message-Id: <20200327125747.13460-9-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 09/14] h264dec: do not abort if decoding extradata fails 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" Such errors are not necessarily fatal and decoding might still be possible, e.g. it happens for MVC streams where we do not handle the subset SPS thus failing to parse its corresponding PPS. --- libavcodec/h264dec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index b6c51ed1e2..dba0634fa0 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -414,10 +414,14 @@ static av_cold int h264_decode_init(AVCodecContext *avctx) ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, &h->ps, &h->is_avc, &h->nal_length_size, avctx->err_recognition, avctx); - if (ret < 0) { - h264_decode_end(avctx); - return ret; - } + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "Error decoding the extradata\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) { + h264_decode_end(avctx); + return ret; + } + ret = 0; + } } } From patchwork Fri Mar 27 12:57:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18436 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 0D7B244B885 for ; Fri, 27 Mar 2020 14:58:42 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F204B68B80F; Fri, 27 Mar 2020 14:58:41 +0200 (EET) 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 ESMTP id EB6D468B77C for ; Fri, 27 Mar 2020 14:58:30 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 91F2B2858A7 for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id VEFTJjd5I48U for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id E6E852858A6 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 9BAEB21200 for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id dZx_cOj8nb_J for ; Fri, 27 Mar 2020 13:58:28 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 21CAC2121D for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 0489D20E01FF; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:44 +0100 Message-Id: <20200327125747.13460-10-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/14] h264_sei: use a separate reader for the individual SEI messages 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 tells the parsing functions the payload size and prevents them from overreading. --- libavcodec/h264_sei.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index a565feabe2..32d13985f3 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -407,9 +407,9 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, int master_ret = 0; while (get_bits_left(gb) > 16 && show_bits(gb, 16)) { + GetBitContext gb_payload; int type = 0; unsigned size = 0; - unsigned next; int ret = 0; do { @@ -429,35 +429,38 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, type, 8*size, get_bits_left(gb)); return AVERROR_INVALIDDATA; } - next = get_bits_count(gb) + 8 * size; + + ret = init_get_bits8(&gb_payload, gb->buffer + get_bits_count(gb) / 8, size); + if (ret < 0) + return ret; switch (type) { case H264_SEI_TYPE_PIC_TIMING: // Picture timing SEI - ret = decode_picture_timing(&h->picture_timing, gb, ps, logctx); + ret = decode_picture_timing(&h->picture_timing, &gb_payload, ps, logctx); break; case H264_SEI_TYPE_USER_DATA_REGISTERED: - ret = decode_registered_user_data(h, gb, logctx, size); + ret = decode_registered_user_data(h, &gb_payload, logctx, size); break; case H264_SEI_TYPE_USER_DATA_UNREGISTERED: - ret = decode_unregistered_user_data(&h->unregistered, gb, logctx, size); + ret = decode_unregistered_user_data(&h->unregistered, &gb_payload, logctx, size); break; case H264_SEI_TYPE_RECOVERY_POINT: - ret = decode_recovery_point(&h->recovery_point, gb, logctx); + ret = decode_recovery_point(&h->recovery_point, &gb_payload, logctx); break; case H264_SEI_TYPE_BUFFERING_PERIOD: - ret = decode_buffering_period(&h->buffering_period, gb, ps, logctx); + ret = decode_buffering_period(&h->buffering_period, &gb_payload, ps, logctx); break; case H264_SEI_TYPE_FRAME_PACKING: - ret = decode_frame_packing_arrangement(&h->frame_packing, gb); + ret = decode_frame_packing_arrangement(&h->frame_packing, &gb_payload); break; case H264_SEI_TYPE_DISPLAY_ORIENTATION: - ret = decode_display_orientation(&h->display_orientation, gb); + ret = decode_display_orientation(&h->display_orientation, &gb_payload); break; case H264_SEI_TYPE_GREEN_METADATA: - ret = decode_green_metadata(&h->green_metadata, gb); + ret = decode_green_metadata(&h->green_metadata, &gb_payload); break; case H264_SEI_TYPE_ALTERNATIVE_TRANSFER: - ret = decode_alternative_transfer(&h->alternative_transfer, gb); + ret = decode_alternative_transfer(&h->alternative_transfer, &gb_payload); break; default: av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); @@ -467,10 +470,12 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, if (ret < 0) master_ret = ret; - skip_bits_long(gb, next - get_bits_count(gb)); + if (get_bits_left(&gb_payload) < 0) { + av_log(logctx, AV_LOG_WARNING, "SEI type %d overread by %d bits\n", + type, -get_bits_left(&gb_payload)); + } - // FIXME check bits here - align_get_bits(gb); + skip_bits_long(gb, 8 * size); } return master_ret; From patchwork Fri Mar 27 12:57:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18431 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 2C90044B885 for ; Fri, 27 Mar 2020 14:58:38 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 144FD68B7A8; Fri, 27 Mar 2020 14:58:38 +0200 (EET) 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 ESMTP id 2BE1A68B76D for ; Fri, 27 Mar 2020 14:58:35 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id E72E128589D for ; Fri, 27 Mar 2020 13:58:34 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id B1PmSMFGs4sC for ; Fri, 27 Mar 2020 13:58:33 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id B0EE9285890 for ; Fri, 27 Mar 2020 13:58:32 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 57A3821200 for ; Fri, 27 Mar 2020 13:58:32 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id tJlKyzjtjaw0 for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 7B5D621221 for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 6701B20E0209; Fri, 27 Mar 2020 13:58:20 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:45 +0100 Message-Id: <20200327125747.13460-11-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 11/14] h264_sei: parse the picture timing SEIs correctly 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" Those SEIs refer to the currently active SPS. However, since the SEI NALUs precede the coded picture data in the bitstream, the active SPS is in general not known when we are decoding the SEI. Therefore, store the content of the picture timing SEIs and actually parse it when the active SPS is known. --- libavcodec/h264_parser.c | 9 +++++ libavcodec/h264_sei.c | 82 +++++++++++++++++++++++----------------- libavcodec/h264_sei.h | 11 ++++++ libavcodec/h264_slice.c | 10 +++++ 4 files changed, 78 insertions(+), 34 deletions(-) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 5f9a9c46ef..ec1cbc6a66 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -481,6 +481,15 @@ static inline int parse_nal_units(AVCodecParserContext *s, } } + if (p->sei.picture_timing.present) { + ret = ff_h264_sei_process_picture_timing(&p->sei.picture_timing, + sps, avctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error processing the picture timing SEI\n"); + p->sei.picture_timing.present = 0; + } + } + if (sps->pic_struct_present_flag && p->sei.picture_timing.present) { switch (p->sei.picture_timing.pic_struct) { case H264_SEI_PIC_STRUCT_TOP_FIELD: diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 32d13985f3..870dd90717 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -54,30 +54,22 @@ void ff_h264_sei_uninit(H264SEIContext *h) av_buffer_unref(&h->a53_caption.buf_ref); } -static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, - const H264ParamSets *ps, void *logctx) +int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, + void *logctx) { - int i; - const SPS *sps = ps->sps; - - for (i = 0; ilog2_max_frame_num) && ps->sps_list[i]) - sps = (const SPS *)ps->sps_list[i]->data; + GetBitContext gb; - if (!sps) { - av_log(logctx, AV_LOG_ERROR, "SPS unavailable in decode_picture_timing\n"); - return AVERROR_PS_NOT_FOUND; - } + init_get_bits(&gb, h->payload, h->payload_size_bits); if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) { - h->cpb_removal_delay = get_bits_long(gb, sps->cpb_removal_delay_length); - h->dpb_output_delay = get_bits_long(gb, sps->dpb_output_delay_length); + h->cpb_removal_delay = get_bits_long(&gb, sps->cpb_removal_delay_length); + h->dpb_output_delay = get_bits_long(&gb, sps->dpb_output_delay_length); } if (sps->pic_struct_present_flag) { unsigned int i, num_clock_ts; - h->pic_struct = get_bits(gb, 4); + h->pic_struct = get_bits(&gb, 4); h->ct_type = 0; if (h->pic_struct > H264_SEI_PIC_STRUCT_FRAME_TRIPLING) @@ -86,38 +78,38 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, num_clock_ts = sei_num_clock_ts_table[h->pic_struct]; h->timecode_cnt = 0; for (i = 0; i < num_clock_ts; i++) { - if (get_bits(gb, 1)) { /* clock_timestamp_flag */ + if (get_bits(&gb, 1)) { /* clock_timestamp_flag */ H264SEITimeCode *tc = &h->timecode[h->timecode_cnt++]; unsigned int full_timestamp_flag; unsigned int counting_type, cnt_dropped_flag; - h->ct_type |= 1 << get_bits(gb, 2); - skip_bits(gb, 1); /* nuit_field_based_flag */ - counting_type = get_bits(gb, 5); /* counting_type */ - full_timestamp_flag = get_bits(gb, 1); - skip_bits(gb, 1); /* discontinuity_flag */ - cnt_dropped_flag = get_bits(gb, 1); /* cnt_dropped_flag */ + h->ct_type |= 1 << get_bits(&gb, 2); + skip_bits(&gb, 1); /* nuit_field_based_flag */ + counting_type = get_bits(&gb, 5); /* counting_type */ + full_timestamp_flag = get_bits(&gb, 1); + skip_bits(&gb, 1); /* discontinuity_flag */ + cnt_dropped_flag = get_bits(&gb, 1); /* cnt_dropped_flag */ if (cnt_dropped_flag && counting_type > 1 && counting_type < 7) tc->dropframe = 1; - tc->frame = get_bits(gb, 8); /* n_frames */ + tc->frame = get_bits(&gb, 8); /* n_frames */ if (full_timestamp_flag) { tc->full = 1; - tc->seconds = get_bits(gb, 6); /* seconds_value 0..59 */ - tc->minutes = get_bits(gb, 6); /* minutes_value 0..59 */ - tc->hours = get_bits(gb, 5); /* hours_value 0..23 */ + tc->seconds = get_bits(&gb, 6); /* seconds_value 0..59 */ + tc->minutes = get_bits(&gb, 6); /* minutes_value 0..59 */ + tc->hours = get_bits(&gb, 5); /* hours_value 0..23 */ } else { tc->seconds = tc->minutes = tc->hours = tc->full = 0; - if (get_bits(gb, 1)) { /* seconds_flag */ - tc->seconds = get_bits(gb, 6); - if (get_bits(gb, 1)) { /* minutes_flag */ - tc->minutes = get_bits(gb, 6); - if (get_bits(gb, 1)) /* hours_flag */ - tc->hours = get_bits(gb, 5); + if (get_bits(&gb, 1)) { /* seconds_flag */ + tc->seconds = get_bits(&gb, 6); + if (get_bits(&gb, 1)) { /* minutes_flag */ + tc->minutes = get_bits(&gb, 6); + if (get_bits(&gb, 1)) /* hours_flag */ + tc->hours = get_bits(&gb, 5); } } } if (sps->time_offset_length > 0) - skip_bits(gb, + skip_bits(&gb, sps->time_offset_length); /* time_offset */ } } @@ -126,6 +118,28 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, h->ct_type, h->pic_struct); } + return 0; +} + +static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, + void *logctx) +{ + int index = get_bits_count(gb); + int size_bits = get_bits_left(gb); + int size = (size_bits + 7) / 8; + + if (index & 7) { + av_log(logctx, AV_LOG_ERROR, "Unaligned SEI payload\n"); + return AVERROR_INVALIDDATA; + } + if (size > sizeof(h->payload)) { + av_log(logctx, AV_LOG_ERROR, "Picture timing SEI payload too large\n"); + return AVERROR_INVALIDDATA; + } + memcpy(h->payload, gb->buffer + index / 8, size); + + h->payload_size_bits = size_bits; + h->present = 1; return 0; } @@ -436,7 +450,7 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, switch (type) { case H264_SEI_TYPE_PIC_TIMING: // Picture timing SEI - ret = decode_picture_timing(&h->picture_timing, &gb_payload, ps, logctx); + ret = decode_picture_timing(&h->picture_timing, &gb_payload, logctx); break; case H264_SEI_TYPE_USER_DATA_REGISTERED: ret = decode_registered_user_data(h, &gb_payload, logctx, size); diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index a75c3aa175..f07a5055c3 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -20,6 +20,7 @@ #define AVCODEC_H264_SEI_H #include "get_bits.h" +#include "h264_ps.h" /** * SEI message types @@ -79,6 +80,10 @@ typedef struct H264SEITimeCode { } H264SEITimeCode; typedef struct H264SEIPictureTiming { + // maximum size of pic_timing according to the spec should be 274 bits + uint8_t payload[40]; + int payload_size_bits; + int present; H264_SEI_PicStructType pic_struct; @@ -202,4 +207,10 @@ void ff_h264_sei_uninit(H264SEIContext *h); */ const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h); +/** + * Parse the contents of a picture timing message given an active SPS. + */ +int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, + void *logctx); + #endif /* AVCODEC_H264_SEI_H */ diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index af30f6267b..c6072738d7 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1134,6 +1134,16 @@ static int h264_export_frame_props(H264Context *h) /* Signal interlacing information externally. */ /* Prioritize picture timing SEI information over used * decoding process if it exists. */ + if (h->sei.picture_timing.present) { + int ret = ff_h264_sei_process_picture_timing(&h->sei.picture_timing, sps, + h->avctx); + if (ret < 0) { + av_log(h->avctx, AV_LOG_ERROR, "Error processing a picture timing SEI\n"); + if (h->avctx->err_recognition & AV_EF_EXPLODE) + return ret; + h->sei.picture_timing.present = 0; + } + } if (sps->pic_struct_present_flag && h->sei.picture_timing.present) { H264SEIPictureTiming *pt = &h->sei.picture_timing; From patchwork Fri Mar 27 12:57:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18432 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 4E18F44B885 for ; Fri, 27 Mar 2020 14:58:39 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3EB8968B7B1; Fri, 27 Mar 2020 14:58:39 +0200 (EET) 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 ESMTP id 2EBAB68B76F for ; Fri, 27 Mar 2020 14:58:35 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id E7FEC2858A2 for ; Fri, 27 Mar 2020 13:58:34 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id UhqFAxZtEHtP for ; Fri, 27 Mar 2020 13:58:33 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 0942D28589A for ; Fri, 27 Mar 2020 13:58:33 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id A5D3421216 for ; Fri, 27 Mar 2020 13:58:32 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id ZFvAFiadXpve for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 685C621220 for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 5663120E01FF; Fri, 27 Mar 2020 13:58:21 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:46 +0100 Message-Id: <20200327125747.13460-12-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 12/14] h264_ps: make the PPS hold a reference to its SPS 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" It represents the relationship between them more naturally and will be useful in the following commits. Allows significantly more frames in fate-h264-attachment-631 to be decoded. --- libavcodec/h264_parser.c | 16 +--- libavcodec/h264_ps.c | 30 +++++- libavcodec/h264_ps.h | 4 +- libavcodec/h264_slice.c | 27 +----- libavcodec/h264dec.c | 4 +- tests/ref/fate/h264-attachment-631 | 148 +++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+), 45 deletions(-) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index ec1cbc6a66..aacd44cf3b 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -361,26 +361,14 @@ static inline int parse_nal_units(AVCodecParserContext *s, } av_buffer_unref(&p->ps.pps_ref); - av_buffer_unref(&p->ps.sps_ref); p->ps.pps = NULL; p->ps.sps = NULL; p->ps.pps_ref = av_buffer_ref(p->ps.pps_list[pps_id]); if (!p->ps.pps_ref) goto fail; p->ps.pps = (const PPS*)p->ps.pps_ref->data; - - if (!p->ps.sps_list[p->ps.pps->sps_id]) { - av_log(avctx, AV_LOG_ERROR, - "non-existing SPS %u referenced\n", p->ps.pps->sps_id); - goto fail; - } - - p->ps.sps_ref = av_buffer_ref(p->ps.sps_list[p->ps.pps->sps_id]); - if (!p->ps.sps_ref) - goto fail; - p->ps.sps = (const SPS*)p->ps.sps_ref->data; - - sps = p->ps.sps; + p->ps.sps = p->ps.pps->sps; + sps = p->ps.sps; // heuristic to detect non marked keyframes if (p->ps.sps->ref_frame_count <= 1 && p->ps.pps->ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 8df195e0a9..e774929e21 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -324,7 +324,6 @@ void ff_h264_ps_uninit(H264ParamSets *ps) for (i = 0; i < MAX_PPS_COUNT; i++) av_buffer_unref(&ps->pps_list[i]); - av_buffer_unref(&ps->sps_ref); av_buffer_unref(&ps->pps_ref); ps->pps = NULL; @@ -738,6 +737,15 @@ static int more_rbsp_data_in_pps(const SPS *sps, void *logctx) return 1; } +static void pps_free(void *opaque, uint8_t *data) +{ + PPS *pps = (PPS*)data; + + av_buffer_unref(&pps->sps_ref); + + av_freep(&data); +} + int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx, H264ParamSets *ps, int bit_length) { @@ -754,10 +762,15 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct return AVERROR_INVALIDDATA; } - pps_buf = av_buffer_allocz(sizeof(*pps)); - if (!pps_buf) + pps = av_mallocz(sizeof(*pps)); + if (!pps) return AVERROR(ENOMEM); - pps = (PPS*)pps_buf->data; + pps_buf = av_buffer_create((uint8_t*)pps, sizeof(*pps), + pps_free, NULL, 0); + if (!pps_buf) { + av_freep(&pps); + return AVERROR(ENOMEM); + } pps->data_size = gb->buffer_end - gb->buffer; if (pps->data_size > sizeof(pps->data)) { @@ -775,7 +788,14 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct ret = AVERROR_INVALIDDATA; goto fail; } - sps = (const SPS*)ps->sps_list[pps->sps_id]->data; + pps->sps_ref = av_buffer_ref(ps->sps_list[pps->sps_id]); + if (!pps->sps_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + pps->sps = (const SPS*)pps->sps_ref->data; + sps = pps->sps; + if (sps->bit_depth_luma > 14) { av_log(avctx, AV_LOG_ERROR, "Invalid luma bit depth=%d\n", diff --git a/libavcodec/h264_ps.h b/libavcodec/h264_ps.h index d6798ca0ef..3f1ab72e38 100644 --- a/libavcodec/h264_ps.h +++ b/libavcodec/h264_ps.h @@ -135,6 +135,9 @@ typedef struct PPS { uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64]; uint32_t(*dequant4_coeff[6])[16]; uint32_t(*dequant8_coeff[6])[64]; + + AVBufferRef *sps_ref; + const SPS *sps; } PPS; typedef struct H264ParamSets { @@ -142,7 +145,6 @@ typedef struct H264ParamSets { AVBufferRef *pps_list[MAX_PPS_COUNT]; AVBufferRef *pps_ref; - AVBufferRef *sps_ref; /* currently active parameters sets */ const PPS *pps; const SPS *sps; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index c6072738d7..5a8a4a7f86 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -333,7 +333,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst, } av_buffer_unref(&h->ps.pps_ref); - av_buffer_unref(&h->ps.sps_ref); h->ps.pps = NULL; h->ps.sps = NULL; if (h1->ps.pps_ref) { @@ -341,12 +340,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, if (!h->ps.pps_ref) return AVERROR(ENOMEM); h->ps.pps = (const PPS*)h->ps.pps_ref->data; - } - if (h1->ps.sps_ref) { - h->ps.sps_ref = av_buffer_ref(h1->ps.sps_ref); - if (!h->ps.sps_ref) - return AVERROR(ENOMEM); - h->ps.sps = (const SPS*)h->ps.sps_ref->data; + h->ps.sps = h->ps.pps->sps; } if (need_reinit || !inited) { @@ -1013,13 +1007,8 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl h->ps.pps = (const PPS*)h->ps.pps_ref->data; } - if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) { - av_buffer_unref(&h->ps.sps_ref); - h->ps.sps = NULL; - h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]); - if (!h->ps.sps_ref) - return AVERROR(ENOMEM); - h->ps.sps = (const SPS*)h->ps.sps_ref->data; + if (h->ps.sps != h->ps.pps->sps) { + h->ps.sps = (const SPS*)h->ps.pps->sps; if (h->mb_width != h->ps.sps->mb_width || h->mb_height != h->ps.sps->mb_height || @@ -1779,13 +1768,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, return AVERROR_INVALIDDATA; } pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data; - - if (!h->ps.sps_list[pps->sps_id]) { - av_log(h->avctx, AV_LOG_ERROR, - "non-existing SPS %u referenced\n", pps->sps_id); - return AVERROR_INVALIDDATA; - } - sps = (const SPS*)h->ps.sps_list[pps->sps_id]->data; + sps = pps->sps; sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num); if (!first_slice) { @@ -2171,7 +2154,7 @@ int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal) av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n"); return AVERROR_INVALIDDATA; } - if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) { + if (h->ps.sps != pps->sps) { av_log(h->avctx, AV_LOG_ERROR, "SPS changed in the middle of the frame\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index dba0634fa0..67a9cb5438 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -762,9 +762,7 @@ end: * past end by one (callers fault) and resync_mb_y != 0 * causes problems for the first MB line, too. */ - if (!FIELD_PICTURE(h) && h->current_slice && - h->ps.sps == (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data && - h->enable_er) { + if (!FIELD_PICTURE(h) && h->current_slice && h->enable_er) { H264SliceContext *sl = h->slice_ctx; int use_last_pic = h->last_pic_for_ec.f->buf[0] && !sl->ref_count[0]; diff --git a/tests/ref/fate/h264-attachment-631 b/tests/ref/fate/h264-attachment-631 index ebb5eb4fcd..5ac45e70a4 100644 --- a/tests/ref/fate/h264-attachment-631 +++ b/tests/ref/fate/h264-attachment-631 @@ -3,6 +3,154 @@ #codec_id 0: rawvideo #dimensions 0: 720x480 #sar 0: 8/9 +0, 6, 6, 1, 518400, 0xd2068698 +0, 10, 10, 1, 518400, 0x2ee4865f +0, 14, 14, 1, 518400, 0x2a01b188 +0, 18, 18, 1, 518400, 0xa4bc9572 +0, 22, 22, 1, 518400, 0x4e882f72 +0, 26, 26, 1, 518400, 0xf79cfc9c +0, 30, 30, 1, 518400, 0x93afec23 +0, 34, 34, 1, 518400, 0xadf210e6 +0, 38, 38, 1, 518400, 0xb0bdd1f1 +0, 42, 42, 1, 518400, 0x4bbb4a24 +0, 46, 46, 1, 518400, 0x49db06c8 +0, 50, 50, 1, 518400, 0xf9781bfb +0, 54, 54, 1, 518400, 0xd3a373bc +0, 58, 58, 1, 518400, 0xccfb31c5 +0, 62, 62, 1, 518400, 0x276423a7 +0, 66, 66, 1, 518400, 0xb3729230 +0, 70, 70, 1, 518400, 0xeaf4586d +0, 74, 74, 1, 518400, 0x9e629b29 +0, 78, 78, 1, 518400, 0x921d6e58 +0, 82, 82, 1, 518400, 0xc988f527 +0, 86, 86, 1, 518400, 0x4e1fed4b +0, 90, 90, 1, 518400, 0xe3819724 +0, 94, 94, 1, 518400, 0xc07602ba +0, 98, 98, 1, 518400, 0xc6b1e8d0 +0, 102, 102, 1, 518400, 0x12d94755 +0, 106, 106, 1, 518400, 0x257a5264 +0, 110, 110, 1, 518400, 0x4f985461 +0, 114, 114, 1, 518400, 0x77577244 +0, 118, 118, 1, 518400, 0x81a59edf +0, 122, 122, 1, 518400, 0x9f33c0fa +0, 126, 126, 1, 518400, 0xa89cbb3f +0, 130, 130, 1, 518400, 0x6b1bcc1c +0, 134, 134, 1, 518400, 0x520acb74 +0, 138, 138, 1, 518400, 0x006dda91 +0, 142, 142, 1, 518400, 0x7377f96f +0, 146, 146, 1, 518400, 0x0b713224 +0, 150, 150, 1, 518400, 0x98943e53 +0, 154, 154, 1, 518400, 0x59f967e2 +0, 158, 158, 1, 518400, 0x976a2461 +0, 162, 162, 1, 518400, 0xcb4d3872 +0, 166, 166, 1, 518400, 0x0a174f59 +0, 170, 170, 1, 518400, 0x7cbe6c4f +0, 174, 174, 1, 518400, 0x475cbce4 +0, 178, 178, 1, 518400, 0x2c281bb9 +0, 182, 182, 1, 518400, 0xadee7826 +0, 186, 186, 1, 518400, 0x936059a6 +0, 190, 190, 1, 518400, 0xba09ae20 +0, 194, 194, 1, 518400, 0x355e94d7 +0, 198, 198, 1, 518400, 0xafc3a0b3 +0, 202, 202, 1, 518400, 0x55bd78af +0, 206, 206, 1, 518400, 0x9678c886 +0, 210, 210, 1, 518400, 0x4d69a62a +0, 214, 214, 1, 518400, 0x406e617c +0, 218, 218, 1, 518400, 0x7031ebdb +0, 222, 222, 1, 518400, 0xf862127d +0, 226, 226, 1, 518400, 0x619b8a53 +0, 230, 230, 1, 518400, 0x0fde6b72 +0, 234, 234, 1, 518400, 0xd137deff +0, 238, 238, 1, 518400, 0x9ae6ac2e +0, 242, 242, 1, 518400, 0x6cefb571 +0, 246, 246, 1, 518400, 0x7694dda2 +0, 250, 250, 1, 518400, 0x2253f6a2 +0, 254, 254, 1, 518400, 0x770db468 +0, 258, 258, 1, 518400, 0xf4c815a5 +0, 262, 262, 1, 518400, 0x0a0f38b6 +0, 266, 266, 1, 518400, 0x17490907 +0, 270, 270, 1, 518400, 0xbc362ed6 +0, 274, 274, 1, 518400, 0x24de1b5c +0, 278, 278, 1, 518400, 0x55d20b2a +0, 282, 282, 1, 518400, 0xca1af9b1 +0, 286, 286, 1, 518400, 0x7e7b7473 +0, 290, 290, 1, 518400, 0xed30dd23 +0, 294, 294, 1, 518400, 0xb694c58f +0, 298, 298, 1, 518400, 0x8270deb7 +0, 302, 302, 1, 518400, 0x91b3b4f7 +0, 306, 306, 1, 518400, 0x37fcb63c +0, 310, 310, 1, 518400, 0x7ebcafca +0, 314, 314, 1, 518400, 0x8508b6da +0, 318, 318, 1, 518400, 0xe7e0b15e +0, 322, 322, 1, 518400, 0x9618fa0e +0, 326, 326, 1, 518400, 0xd4c3b20c +0, 330, 330, 1, 518400, 0x1aad03d1 +0, 334, 334, 1, 518400, 0xb5c18e20 +0, 338, 338, 1, 518400, 0x70144034 +0, 342, 342, 1, 518400, 0x937ee203 +0, 346, 346, 1, 518400, 0x680d72ad +0, 350, 350, 1, 518400, 0x8c9647b1 +0, 354, 354, 1, 518400, 0x65fce70a +0, 358, 358, 1, 518400, 0xa3d785dd +0, 362, 362, 1, 518400, 0xaf1a54c2 +0, 366, 366, 1, 518400, 0x301c6f4c +0, 370, 370, 1, 518400, 0x0255b5ac +0, 374, 374, 1, 518400, 0x967da8de +0, 378, 378, 1, 518400, 0x1f7e6c8c +0, 382, 382, 1, 518400, 0xb41badbf +0, 386, 386, 1, 518400, 0xca853613 +0, 390, 390, 1, 518400, 0x9f8696cb +0, 394, 394, 1, 518400, 0x55ec8427 +0, 398, 398, 1, 518400, 0x08779f91 +0, 402, 402, 1, 518400, 0x171fbc34 +0, 406, 406, 1, 518400, 0x5e9c6ddd +0, 410, 410, 1, 518400, 0xd9a55786 +0, 414, 414, 1, 518400, 0xdb509948 +0, 418, 418, 1, 518400, 0x2a326178 +0, 422, 422, 1, 518400, 0x4842c411 +0, 426, 426, 1, 518400, 0x35399db4 +0, 430, 430, 1, 518400, 0xa182b9aa +0, 434, 434, 1, 518400, 0xb6df772d +0, 438, 438, 1, 518400, 0xfe61b651 +0, 442, 442, 1, 518400, 0x031cb305 +0, 446, 446, 1, 518400, 0xde553506 +0, 450, 450, 1, 518400, 0x24ab8557 +0, 454, 454, 1, 518400, 0xadf5e251 +0, 458, 458, 1, 518400, 0xb3a3c6c5 +0, 462, 462, 1, 518400, 0x9cedc6ac +0, 466, 466, 1, 518400, 0x6ddf9b26 +0, 470, 470, 1, 518400, 0x3bfaf200 +0, 474, 474, 1, 518400, 0x0337d6f1 +0, 478, 478, 1, 518400, 0x71367bc7 +0, 482, 482, 1, 518400, 0x9e1876b8 +0, 486, 486, 1, 518400, 0x37b89366 +0, 490, 490, 1, 518400, 0x6e349056 +0, 494, 494, 1, 518400, 0x718a9543 +0, 498, 498, 1, 518400, 0x48e46e57 +0, 502, 502, 1, 518400, 0xb2ae494c +0, 506, 506, 1, 518400, 0x0ec937dc +0, 510, 510, 1, 518400, 0xb1e88149 +0, 514, 514, 1, 518400, 0xedbba51d +0, 518, 518, 1, 518400, 0x8955d114 +0, 522, 522, 1, 518400, 0x951e8716 +0, 526, 526, 1, 518400, 0x119064de +0, 530, 530, 1, 518400, 0xc06bd99a +0, 534, 534, 1, 518400, 0xdfccd738 +0, 538, 538, 1, 518400, 0x6c2de0a5 +0, 542, 542, 1, 518400, 0x11c1fdf7 +0, 546, 546, 1, 518400, 0xdcd26a62 +0, 550, 550, 1, 518400, 0x0ff63f3d +0, 554, 554, 1, 518400, 0x6443382a +0, 558, 558, 1, 518400, 0x28ce5ce3 +0, 562, 562, 1, 518400, 0xe0d47fbd +0, 566, 566, 1, 518400, 0xfdc0beed +0, 570, 570, 1, 518400, 0x9adeddc4 +0, 574, 574, 1, 518400, 0x8e5669fc +0, 578, 578, 1, 518400, 0xf0beb8ae +0, 582, 582, 1, 518400, 0xbdd68806 +0, 586, 586, 1, 518400, 0xe3c6ae23 +0, 590, 590, 1, 518400, 0xeba952c1 +0, 594, 594, 1, 518400, 0x734ff153 0, 598, 598, 1, 518400, 0xc3c0f1cf 0, 603, 603, 1, 518400, 0x21a5df80 0, 607, 607, 1, 518400, 0x5b8e115b From patchwork Fri Mar 27 12:57:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18437 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 AFC7E44B885 for ; Fri, 27 Mar 2020 14:58:42 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9AB2168B818; Fri, 27 Mar 2020 14:58:42 +0200 (EET) 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 ESMTP id 6640068B741 for ; Fri, 27 Mar 2020 14:58:31 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 2904228585C for ; Fri, 27 Mar 2020 13:58:31 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id JNIwtNeVZzJF for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id B3FD12858AA for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 69F0621200 for ; Fri, 27 Mar 2020 13:58:30 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 1Hs3H7W1IzVM for ; Fri, 27 Mar 2020 13:58:29 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 576762121F for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 34C7820E0209; Fri, 27 Mar 2020 13:58:21 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:47 +0100 Message-Id: <20200327125747.13460-13-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 13/14] h264dec: rename flush_dpb() 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" The name is misleading, this function does a lot more than just flushing the DPB. --- libavcodec/h264dec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 67a9cb5438..7679567548 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -485,8 +485,7 @@ void ff_h264_flush_change(H264Context *h) h->mmco_reset = 1; } -/* forget old pics after a seek */ -static void flush_dpb(AVCodecContext *avctx) +static void h264_decode_flush(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; int i; @@ -1063,7 +1062,7 @@ AVCodec ff_h264_decoder = { }, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS, - .flush = flush_dpb, + .flush = h264_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles), .priv_class = &h264_class, From patchwork Fri Mar 27 12:57:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18434 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 AEA2544B885 for ; Fri, 27 Mar 2020 14:58:40 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9F80368B7C8; Fri, 27 Mar 2020 14:58:40 +0200 (EET) 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 ESMTP id 6C37068B775 for ; Fri, 27 Mar 2020 14:58:35 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 3D76E285890 for ; Fri, 27 Mar 2020 13:58:35 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id WzD6NMrGylGc for ; Fri, 27 Mar 2020 13:58:35 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 591602858A6 for ; Fri, 27 Mar 2020 13:58:33 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 11D3F21200 for ; Fri, 27 Mar 2020 13:58:33 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 0p5jvacmtGfj for ; Fri, 27 Mar 2020 13:58:32 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id 856D521222 for ; Fri, 27 Mar 2020 13:58:21 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 7A2E620E01FF; Fri, 27 Mar 2020 13:58:21 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Mar 2020 13:57:48 +0100 Message-Id: <20200327125747.13460-14-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327125747.13460-1-anton@khirnov.net> References: <20200327125747.13460-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 14/14] h264dec: do not set picture_structure on init 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 has been cargo culted from mpegvideo and serves no useful purpose. It will be initialize correctly in h264_field_start() --- libavcodec/h264dec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 7679567548..57f4fec3ca 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -309,7 +309,6 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->width_from_caller = avctx->width; h->height_from_caller = avctx->height; - h->picture_structure = PICT_FRAME; h->workaround_bugs = avctx->workaround_bugs; h->flags = avctx->flags; h->poc.prev_poc_msb = 1 << 16;