From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH v9 6/6] lavc/hevcdec: Parse DOVI RPU NALs Date: Sun, 2 Jan 2022 05:31:30 +0100 Message-ID: <AM7PR03MB666056476872B8B25916CEEF8F489@AM7PR03MB6660.eurprd03.prod.outlook.com> (raw) In-Reply-To: <20211222151447.57681-6-ffmpeg@haasn.xyz> Niklas Haas: > From: Niklas Haas <git@haasn.dev> > > And expose the parsed values as frame side data. Update FATE results to > match. > > It's worth documenting that this relies on the dovi configuration record > being present on the first AVPacket fed to the decoder, which in > practice is the case if if the API user has called something like > av_format_inject_global_side_data, which is unfortunately not the > default. > > This commit is not the time and place to change that behavior, though. > > Signed-off-by: Niklas Haas <git@haasn.dev> > --- > configure | 2 +- > libavcodec/hevcdec.c | 63 +++++++++-- > libavcodec/hevcdec.h | 3 + > tests/ref/fate/hevc-dv-rpu | 224 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 283 insertions(+), 9 deletions(-) > > diff --git a/configure b/configure > index 68658a847f..7803aa47af 100755 > --- a/configure > +++ b/configure > @@ -2826,7 +2826,7 @@ h264_decoder_suggest="error_resilience" > hap_decoder_select="snappy texturedsp" > hap_encoder_deps="libsnappy" > hap_encoder_select="texturedspenc" > -hevc_decoder_select="atsc_a53 bswapdsp cabac golomb hevcparse videodsp" > +hevc_decoder_select="atsc_a53 bswapdsp cabac dovi_rpu golomb hevcparse videodsp" > huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp" > huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp" > hymt_decoder_select="huffyuv_decoder" > diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c > index 46d9edf8eb..298d89fea6 100644 > --- a/libavcodec/hevcdec.c > +++ b/libavcodec/hevcdec.c > @@ -2723,6 +2723,7 @@ error: > static int set_side_data(HEVCContext *s) > { > AVFrame *out = s->ref->frame; > + int ret; > > if (s->sei.frame_packing.present && > s->sei.frame_packing.arrangement_type >= 3 && > @@ -2967,6 +2968,9 @@ static int set_side_data(HEVCContext *s) > s->rpu_buf = NULL; > } > > + if ((ret = ff_dovi_attach_side_data(&s->dovi_ctx, out)) < 0) > + return ret; > + > return 0; > } > > @@ -3298,16 +3302,24 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) > if (s->pkt.nb_nals > 1 && s->pkt.nals[s->pkt.nb_nals - 1].type == HEVC_NAL_UNSPEC62 && > s->pkt.nals[s->pkt.nb_nals - 1].size > 2 && !s->pkt.nals[s->pkt.nb_nals - 1].nuh_layer_id > && !s->pkt.nals[s->pkt.nb_nals - 1].temporal_id) { > + H2645NAL *nal = &s->pkt.nals[s->pkt.nb_nals - 1]; > if (s->rpu_buf) { > av_buffer_unref(&s->rpu_buf); > av_log(s->avctx, AV_LOG_WARNING, "Multiple Dolby Vision RPUs found in one AU. Skipping previous.\n"); > } > > - s->rpu_buf = av_buffer_alloc(s->pkt.nals[s->pkt.nb_nals - 1].raw_size - 2); > + s->rpu_buf = av_buffer_alloc(nal->raw_size - 2); > if (!s->rpu_buf) > return AVERROR(ENOMEM); > + memcpy(s->rpu_buf->data, nal->raw_data + 2, nal->raw_size - 2); > > - memcpy(s->rpu_buf->data, s->pkt.nals[s->pkt.nb_nals - 1].raw_data + 2, s->pkt.nals[s->pkt.nb_nals - 1].raw_size - 2); > + s->dovi_ctx.config = s->dovi_cfg ? (void *) s->dovi_cfg->data : NULL; > + ret = ff_dovi_rpu_parse(&s->dovi_ctx, nal->data + 2, nal->size - 2); > + if (ret < 0) { > + av_buffer_unref(&s->rpu_buf); > + av_log(s->avctx, AV_LOG_WARNING, "Error parsing DOVI NAL unit.\n"); > + /* ignore */ > + } > } > > /* decode the NAL units */ > @@ -3440,8 +3452,8 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, > AVPacket *avpkt) > { > int ret; > - size_t new_extradata_size; > - uint8_t *new_extradata; > + uint8_t *sd; > + size_t sd_size; > HEVCContext *s = avctx->priv_data; > > if (!avpkt->size) { > @@ -3453,14 +3465,37 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, > return 0; > } > > - new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, > - &new_extradata_size); > - if (new_extradata && new_extradata_size > 0) { > - ret = hevc_decode_extradata(s, new_extradata, new_extradata_size, 0); > + sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &sd_size); > + if (sd && sd_size > 0) { > + ret = hevc_decode_extradata(s, sd, sd_size, 0); > if (ret < 0) > return ret; > } > > + sd = av_packet_get_side_data(avpkt, AV_PKT_DATA_DOVI_CONF, &sd_size); > + if (sd && sd_size > 0) { > + if (s->dovi_cfg) { > + /* Reuse existing buffer */ > + if ((ret = av_buffer_make_writable(&s->dovi_cfg)) < 0) > + return ret; > + } else { > + /* Allocate new buffer */ > + AVDOVIDecoderConfigurationRecord *cfg; > + size_t cfg_size; > + cfg = av_dovi_alloc(&cfg_size); > + if (!cfg) > + return AVERROR(ENOMEM); > + s->dovi_cfg = av_buffer_create((uint8_t *) cfg, cfg_size, NULL, NULL, 0); > + if (!s->dovi_cfg) { > + av_free(cfg); > + return AVERROR(ENOMEM); > + } > + } > + > + av_assert0(sd_size >= s->dovi_cfg->size); > + memcpy(s->dovi_cfg->data, sd, s->dovi_cfg->size); dovi_cfg is only used for exactly one thing: To read its dv_profile in ff_dovi_rpu_parse() later. This is quite a lot of effort to get this bit of data. Why not add a ff_dovi_parse_config() that just copies the needed field(s) from the user-supplied AVDOVIDecoderConfigurationRecord to the DOVIContext instead? (Furthermore, said config is explicitly intended to survive an unref as happens in a flush, leading to a dangling pointer in case the user unrefs dovi_cfg in flush. (Yes, the hevc decoder ensures that config is always set correctly before every ff_dovi_rpu_parse() call, but it is nevertheless nowhere stated that the profile is intended to be persistent.)) > + } > + > s->ref = NULL; > ret = decode_nal_units(s, avpkt->data, avpkt->size); > if (ret < 0) > @@ -3553,6 +3588,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) > > pic_arrays_free(s); > > + ff_dovi_ctx_unref(&s->dovi_ctx); > + av_buffer_unref(&s->dovi_cfg); > av_buffer_unref(&s->rpu_buf); > > av_freep(&s->md5_ctx); > @@ -3637,6 +3674,7 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) > > ff_bswapdsp_init(&s->bdsp); > > + s->dovi_ctx.logctx = avctx; > s->context_initialized = 1; > s->eos = 0; > > @@ -3745,6 +3783,14 @@ static int hevc_update_thread_context(AVCodecContext *dst, > if (ret < 0) > return ret; > > + ret = av_buffer_replace(&s->dovi_cfg, s0->dovi_cfg); > + if (ret < 0) > + return ret; > + > + ret = ff_dovi_ctx_replace(&s->dovi_ctx, &s0->dovi_ctx); > + if (ret < 0) > + return ret; > + > s->sei.frame_packing = s0->sei.frame_packing; > s->sei.display_orientation = s0->sei.display_orientation; > s->sei.mastering_display = s0->sei.mastering_display; > @@ -3801,6 +3847,7 @@ static void hevc_decode_flush(AVCodecContext *avctx) > HEVCContext *s = avctx->priv_data; > ff_hevc_flush_dpb(s); > ff_hevc_reset_sei(&s->sei); > + ff_dovi_ctx_unref(&s->dovi_ctx); > av_buffer_unref(&s->rpu_buf); > s->max_ra = INT_MAX; > s->eos = 1; > diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h > index 870ff178d4..c8dde6fd17 100644 > --- a/libavcodec/hevcdec.h > +++ b/libavcodec/hevcdec.h > @@ -32,6 +32,7 @@ > #include "avcodec.h" > #include "bswapdsp.h" > #include "cabac.h" > +#include "dovi_rpu.h" > #include "get_bits.h" > #include "hevcpred.h" > #include "h2645_parse.h" > @@ -574,6 +575,8 @@ typedef struct HEVCContext { > int nuh_layer_id; > > AVBufferRef *rpu_buf; ///< 0 or 1 Dolby Vision RPUs. > + AVBufferRef *dovi_cfg; ///< contains AVDOVIDecoderConfigurationRecord > + DOVIContext dovi_ctx; ///< Dolby Vision decoding context > } HEVCContext; > > /** _______________________________________________ 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".
prev parent reply other threads:[~2022-01-02 4:31 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-12-22 15:14 [FFmpeg-devel] [PATCH v9 1/6] lavu/frame: Add Dolby Vision metadata side data type Niklas Haas 2021-12-22 15:14 ` [FFmpeg-devel] [PATCH v9 2/6] lavfi/showinfo: Support AV_FRAME_DATA_DOVI_METADATA Niklas Haas 2021-12-22 15:14 ` [FFmpeg-devel] [PATCH v9 3/6] ffprobe: " Niklas Haas 2021-12-22 15:14 ` [FFmpeg-devel] [PATCH v9 4/6] lavc: Implement Dolby Vision RPU parsing Niklas Haas 2022-01-02 4:18 ` Andreas Rheinhardt 2022-01-02 12:45 ` James Almer 2022-01-02 18:55 ` Hendrik Leppkes 2022-01-02 19:01 ` Hendrik Leppkes 2022-01-03 5:42 ` Andreas Rheinhardt 2021-12-22 15:14 ` [FFmpeg-devel] [PATCH v9 5/6] fate: Limit Dolby Vision RPU test frame count Niklas Haas 2021-12-22 15:14 ` [FFmpeg-devel] [PATCH v9 6/6] lavc/hevcdec: Parse DOVI RPU NALs Niklas Haas 2021-12-22 19:55 ` Andreas Rheinhardt 2022-01-02 4:31 ` Andreas Rheinhardt [this message]
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=AM7PR03MB666056476872B8B25916CEEF8F489@AM7PR03MB6660.eurprd03.prod.outlook.com \ --to=andreas.rheinhardt@outlook.com \ --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