From: Anton Khirnov <anton@khirnov.net> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 16/31] fftools/ffmpeg_dec: pass hwaccel options to the decoder in a separate struct Date: Wed, 24 Jan 2024 09:16:46 +0100 Message-ID: <20240124081702.4759-16-anton@khirnov.net> (raw) In-Reply-To: <20240124081702.4759-1-anton@khirnov.net> Stop reading them from InputStream. This is a step towards decoupling Decoder and InputStream. --- fftools/ffmpeg.h | 16 +++++----- fftools/ffmpeg_dec.c | 67 +++++++++++++++++++++++------------------- fftools/ffmpeg_demux.c | 36 ++++++++++++----------- 3 files changed, 65 insertions(+), 54 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 80c09d1662..abf95f106b 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -286,6 +286,14 @@ enum DecoderFlags { DECODER_FLAG_TS_UNRELIABLE = (1 << 1), }; +typedef struct DecoderOpts { + /* hwaccel options */ + enum HWAccelID hwaccel_id; + enum AVHWDeviceType hwaccel_device_type; + char *hwaccel_device; + enum AVPixelFormat hwaccel_output_format; +} DecoderOpts; + typedef struct Decoder { const AVClass *class; @@ -351,12 +359,6 @@ typedef struct InputStream { int nb_outputs; int reinit_filters; - - /* hwaccel options */ - enum HWAccelID hwaccel_id; - enum AVHWDeviceType hwaccel_device_type; - char *hwaccel_device; - enum AVPixelFormat hwaccel_output_format; } InputStream; typedef struct InputFile { @@ -736,7 +738,7 @@ AVBufferRef *hw_device_for_filter(void); * is transferred to the decoder. */ int dec_open(InputStream *ist, Scheduler *sch, unsigned sch_idx, - AVDictionary **dec_opts, int flags); + AVDictionary **dec_opts, int flags, const DecoderOpts *o); void dec_free(Decoder **pdec); int dec_add_filter(Decoder *dec, InputFilter *ifilter); diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index f65857bea3..0cbe16ea5f 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -48,7 +48,10 @@ typedef struct DecoderPriv { // a combination of DECODER_FLAG_*, provided to dec_open() int flags; - enum AVPixelFormat hwaccel_pix_fmt; + enum AVPixelFormat hwaccel_pix_fmt; + enum HWAccelID hwaccel_id; + enum AVHWDeviceType hwaccel_device_type; + enum AVPixelFormat hwaccel_output_format; // pts/estimated duration of the last decoded frame // * in decoder timebase for video, @@ -267,9 +270,9 @@ static int64_t video_duration_estimate(const InputStream *ist, const AVFrame *fr static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input) { - InputStream *ist = avctx->opaque; + DecoderPriv *dp = avctx->opaque; AVFrame *output = NULL; - enum AVPixelFormat output_format = ist->hwaccel_output_format; + enum AVPixelFormat output_format = dp->hwaccel_output_format; int err; if (input->format == output_format) { @@ -746,8 +749,7 @@ finish: static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) { - InputStream *ist = s->opaque; - DecoderPriv *dp = dp_from_dec(ist->decoder); + DecoderPriv *dp = s->opaque; const enum AVPixelFormat *p; for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { @@ -758,8 +760,8 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) break; - if (ist->hwaccel_id == HWACCEL_GENERIC || - ist->hwaccel_id == HWACCEL_AUTO) { + if (dp->hwaccel_id == HWACCEL_GENERIC || + dp->hwaccel_id == HWACCEL_AUTO) { for (i = 0;; i++) { config = avcodec_get_hw_config(s->codec, i); if (!config) @@ -771,7 +773,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat break; } } - if (config && config->device_type == ist->hwaccel_device_type) { + if (config && config->device_type == dp->hwaccel_device_type) { dp->hwaccel_pix_fmt = *p; break; } @@ -797,21 +799,22 @@ static HWDevice *hw_device_match_by_codec(const AVCodec *codec) } } -static int hw_device_setup_for_decode(InputStream *ist, DecoderPriv *dp) +static int hw_device_setup_for_decode(InputStream *ist, DecoderPriv *dp, + const char *hwaccel_device) { const AVCodecHWConfig *config; enum AVHWDeviceType type; HWDevice *dev = NULL; int err, auto_device = 0; - if (ist->hwaccel_device) { - dev = hw_device_get_by_name(ist->hwaccel_device); + if (hwaccel_device) { + dev = hw_device_get_by_name(hwaccel_device); if (!dev) { - if (ist->hwaccel_id == HWACCEL_AUTO) { + if (dp->hwaccel_id == HWACCEL_AUTO) { auto_device = 1; - } else if (ist->hwaccel_id == HWACCEL_GENERIC) { - type = ist->hwaccel_device_type; - err = hw_device_init_from_type(type, ist->hwaccel_device, + } else if (dp->hwaccel_id == HWACCEL_GENERIC) { + type = dp->hwaccel_device_type; + err = hw_device_init_from_type(type, hwaccel_device, &dev); } else { // This will be dealt with by API-specific initialisation @@ -819,22 +822,22 @@ static int hw_device_setup_for_decode(InputStream *ist, DecoderPriv *dp) return 0; } } else { - if (ist->hwaccel_id == HWACCEL_AUTO) { - ist->hwaccel_device_type = dev->type; - } else if (ist->hwaccel_device_type != dev->type) { + if (dp->hwaccel_id == HWACCEL_AUTO) { + dp->hwaccel_device_type = dev->type; + } else if (dp->hwaccel_device_type != dev->type) { av_log(dp, AV_LOG_ERROR, "Invalid hwaccel device " "specified for decoder: device %s of type %s is not " "usable with hwaccel %s.\n", dev->name, av_hwdevice_get_type_name(dev->type), - av_hwdevice_get_type_name(ist->hwaccel_device_type)); + av_hwdevice_get_type_name(dp->hwaccel_device_type)); return AVERROR(EINVAL); } } } else { - if (ist->hwaccel_id == HWACCEL_AUTO) { + if (dp->hwaccel_id == HWACCEL_AUTO) { auto_device = 1; - } else if (ist->hwaccel_id == HWACCEL_GENERIC) { - type = ist->hwaccel_device_type; + } else if (dp->hwaccel_id == HWACCEL_GENERIC) { + type = dp->hwaccel_device_type; dev = hw_device_get_by_type(type); // When "-qsv_device device" is used, an internal QSV device named @@ -884,17 +887,17 @@ static int hw_device_setup_for_decode(InputStream *ist, DecoderPriv *dp) break; type = config->device_type; // Try to make a new device of this type. - err = hw_device_init_from_type(type, ist->hwaccel_device, + err = hw_device_init_from_type(type, hwaccel_device, &dev); if (err < 0) { // Can't make a device of this type. continue; } - if (ist->hwaccel_device) { + if (hwaccel_device) { av_log(dp, AV_LOG_INFO, "Using auto " "hwaccel type %s with new device created " "from %s.\n", av_hwdevice_get_type_name(type), - ist->hwaccel_device); + hwaccel_device); } else { av_log(dp, AV_LOG_INFO, "Using auto " "hwaccel type %s with new default device.\n", @@ -902,11 +905,11 @@ static int hw_device_setup_for_decode(InputStream *ist, DecoderPriv *dp) } } if (dev) { - ist->hwaccel_device_type = type; + dp->hwaccel_device_type = type; } else { av_log(dp, AV_LOG_INFO, "Auto hwaccel " "disabled: no device found.\n"); - ist->hwaccel_id = HWACCEL_NONE; + dp->hwaccel_id = HWACCEL_NONE; return 0; } } @@ -940,7 +943,7 @@ static const AVClass dec_class = { }; int dec_open(InputStream *ist, Scheduler *sch, unsigned sch_idx, - AVDictionary **dec_opts, int flags) + AVDictionary **dec_opts, int flags, const DecoderOpts *o) { DecoderPriv *dp; const AVCodec *codec = ist->dec; @@ -958,6 +961,10 @@ int dec_open(InputStream *ist, Scheduler *sch, unsigned sch_idx, dp->dec.class = &dec_class; dp->log_parent = ist; + dp->hwaccel_id = o->hwaccel_id; + dp->hwaccel_device_type = o->hwaccel_device_type; + dp->hwaccel_output_format = o->hwaccel_output_format; + snprintf(dp->log_name, sizeof(dp->log_name), "dec:%s", codec->name); if (codec->type == AVMEDIA_TYPE_SUBTITLE && @@ -984,7 +991,7 @@ int dec_open(InputStream *ist, Scheduler *sch, unsigned sch_idx, return ret; } - dp->dec_ctx->opaque = ist; + dp->dec_ctx->opaque = dp; dp->dec_ctx->get_format = get_format; if (dp->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && @@ -1005,7 +1012,7 @@ int dec_open(InputStream *ist, Scheduler *sch, unsigned sch_idx, av_dict_set(dec_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); - ret = hw_device_setup_for_decode(ist, dp); + ret = hw_device_setup_for_decode(ist, dp, o->hwaccel_device); if (ret < 0) { av_log(dp, AV_LOG_ERROR, "Hardware device setup failed for decoder: %s\n", diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 729d7e476b..0f426e3c2e 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -72,6 +72,8 @@ typedef struct DemuxStream { const AVCodecDescriptor *codec_desc; + DecoderOpts dec_opts; + AVBSFContext *bsf; /* number of packets successfully read for this stream */ @@ -823,7 +825,7 @@ static void ist_free(InputStream **pist) av_dict_free(&ist->decoder_opts); av_freep(&ist->filters); av_freep(&ist->outputs); - av_freep(&ist->hwaccel_device); + av_freep(&ds->dec_opts.hwaccel_device); avcodec_parameters_free(&ist->par); @@ -905,7 +907,7 @@ static int ist_use(InputStream *ist, int decoding_needed) return ret; ret = dec_open(ist, d->sch, ds->sch_idx_dec, - &ist->decoder_opts, dec_flags); + &ist->decoder_opts, dec_flags, &ds->dec_opts); if (ret < 0) return ret; @@ -1166,25 +1168,25 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) "WARNING: defaulting hwaccel_output_format to cuda for compatibility " "with old commandlines. This behaviour is DEPRECATED and will be removed " "in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n"); - ist->hwaccel_output_format = AV_PIX_FMT_CUDA; + ds->dec_opts.hwaccel_output_format = AV_PIX_FMT_CUDA; } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "qsv")) { av_log(ist, AV_LOG_WARNING, "WARNING: defaulting hwaccel_output_format to qsv for compatibility " "with old commandlines. This behaviour is DEPRECATED and will be removed " "in the future. Please explicitly set \"-hwaccel_output_format qsv\".\n"); - ist->hwaccel_output_format = AV_PIX_FMT_QSV; + ds->dec_opts.hwaccel_output_format = AV_PIX_FMT_QSV; } else if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "mediacodec")) { // There is no real AVHWFrameContext implementation. Set // hwaccel_output_format to avoid av_hwframe_transfer_data error. - ist->hwaccel_output_format = AV_PIX_FMT_MEDIACODEC; + ds->dec_opts.hwaccel_output_format = AV_PIX_FMT_MEDIACODEC; } else if (hwaccel_output_format) { - ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format); - if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) { + ds->dec_opts.hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format); + if (ds->dec_opts.hwaccel_output_format == AV_PIX_FMT_NONE) { av_log(ist, AV_LOG_FATAL, "Unrecognised hwaccel output " "format: %s", hwaccel_output_format); } } else { - ist->hwaccel_output_format = AV_PIX_FMT_NONE; + ds->dec_opts.hwaccel_output_format = AV_PIX_FMT_NONE; } if (hwaccel) { @@ -1193,17 +1195,17 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) hwaccel = "cuda"; if (!strcmp(hwaccel, "none")) - ist->hwaccel_id = HWACCEL_NONE; + ds->dec_opts.hwaccel_id = HWACCEL_NONE; else if (!strcmp(hwaccel, "auto")) - ist->hwaccel_id = HWACCEL_AUTO; + ds->dec_opts.hwaccel_id = HWACCEL_AUTO; else { enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hwaccel); if (type != AV_HWDEVICE_TYPE_NONE) { - ist->hwaccel_id = HWACCEL_GENERIC; - ist->hwaccel_device_type = type; + ds->dec_opts.hwaccel_id = HWACCEL_GENERIC; + ds->dec_opts.hwaccel_device_type = type; } - if (!ist->hwaccel_id) { + if (!ds->dec_opts.hwaccel_id) { av_log(ist, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n", hwaccel); av_log(ist, AV_LOG_FATAL, "Supported hwaccels: "); @@ -1220,14 +1222,14 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st); if (hwaccel_device) { - ist->hwaccel_device = av_strdup(hwaccel_device); - if (!ist->hwaccel_device) + ds->dec_opts.hwaccel_device = av_strdup(hwaccel_device); + if (!ds->dec_opts.hwaccel_device) return AVERROR(ENOMEM); } } - ret = choose_decoder(o, ic, st, ist->hwaccel_id, ist->hwaccel_device_type, - &ist->dec); + ret = choose_decoder(o, ic, st, ds->dec_opts.hwaccel_id, + ds->dec_opts.hwaccel_device_type, &ist->dec); if (ret < 0) return ret; -- 2.42.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2024-01-24 8:19 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-01-24 8:16 [FFmpeg-devel] [PATCH 01/31] fftools/ffmpeg_dec: split Decoder into a private and public part Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 02/31] fftools/ffmpeg_dec: export subtitle_header in Decoder Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 03/31] fftools/ffmpeg_filter: consolidate decoder/filter type checks Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 04/31] fftools/ffmpeg: make decoding AVCodecContext private to the decoder Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 05/31] fftools/ffmpeg_dec: add an AVClass to Decoder Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 06/31] fftools/ffmpeg_dec: pass decoder options as an argument to dec_open() Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 07/31] fftools/ffmpeg_dec: move decoding counters from InputStream to Decoder Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 08/31] fftools/ffmpeg_dec: drop useless and racy code Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 09/31] fftools/ffmpeg_dec: drop a useless log message Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 10/31] fftools/ffmpeg: move decoder existence check to a more appropriate place Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 11/31] fftools/ffmpeg_dec: override video SAR with AVCodecParameters value Anton Khirnov 2024-03-24 22:09 ` Michael Niedermayer 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 12/31] fftools/ffmpeg_dec: stop accesing InputStream.fix_sub_duration Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 13/31] fftools/ffmpeg: refactor disabling decoder threading for attached pictures Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 14/31] fftools/ffmpeg_dec: replace InputFile.format_nots with a decoder flag Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 15/31] fftools/ffmpeg: move hwaccel_retrieve_data() from ffmpeg_hw to ffmpeg_dec Anton Khirnov 2024-01-24 8:16 ` Anton Khirnov [this message] 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 17/31] fftools/ffmpeg_dec: move flags to DecoderOpts Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 18/31] fftools/ffmpeg_dec: pass forced/estimated framerate though DecoderOpts Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 19/31] fftools/ffmpeg_dec: move setting compute_edt to demuxer Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 20/31] fftools/ffmpeg_dec: pass input timebase through DecoderOpts Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 21/31] fftools/ffmpeg_dec: pass top_field_first " Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 22/31] fftools/ffmpeg_dec: pass decoder name " Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 23/31] fftools/ffmpeg_dec: eliminate InputStream use in hw_device_setup_for_decode() Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 24/31] fftools/ffmpeg_dec: pass AVCodec through DecoderOpts Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 25/31] fftools/ffmpeg_dec: pass AVCodecParameters " Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 26/31] fftools/ffmpeg_dec: remove unnecessary InputStream arguments Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 27/31] fftools/ffmpeg_dec: stop passing InputStream to dec_open() Anton Khirnov 2024-01-25 1:19 ` Michael Niedermayer 2024-01-28 9:40 ` [FFmpeg-devel] [PATCH v2 " Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 28/31] fftools/ffmpeg_dec: eliminate all remaining InputStream uses Anton Khirnov 2024-01-24 8:16 ` [FFmpeg-devel] [PATCH 29/31] fftools/ffmpeg: make InputStream.decoding_needed private to demuxer Anton Khirnov 2024-01-24 8:17 ` [FFmpeg-devel] [PATCH 30/31] fftools/ffmpeg: make InputStream.decoder_opts " Anton Khirnov 2024-01-24 8:17 ` [FFmpeg-devel] [PATCH 31/31] fftools/ffmpeg: cosmetics, vertically align Input{File, Stream} Anton Khirnov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240124081702.4759-16-anton@khirnov.net \ --to=anton@khirnov.net \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git