Implemented decoding of NAL units and handling HDR10+ sidedata by referring to hevcdec.
Signed-off-by: yoonjoo <yoonjoo....@samsung.com> --- libavcodec/cuviddec.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 3fae9c1..1b80b81 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -33,6 +33,7 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#include "libavutil/hdr_dynamic_metadata.h" #include "avcodec.h" #include "bsf.h" @@ -41,6 +42,11 @@ #include "hwconfig.h" #include "nvdec.h" #include "internal.h" +#include "h2645_parse.h" +#include "bytestream.h" +#include "hevc/hevc.h" +#include "hevc/sei.h" +#include "hevc/ps.h" #if !NVDECAPI_CHECK_VERSION(9, 0) #define cudaVideoSurfaceFormat_YUV444 2 @@ -488,6 +494,64 @@ error: return 0; } +static void decode_nal_units(AVCodecContext* avctx, const uint8_t *buf, int length, AVFrame* frame) +{ + H2645Packet hpkt = { 0 }; + int is_nalff = 1; + int nal_length_size = 4; + HEVCSEI sei = { 0 }; + HEVCParamSets ps = { 0 }; + + av_log(avctx, AV_LOG_TRACE, "decode_nal_units\n"); + ff_h2645_packet_split(&hpkt, buf, length, avctx, is_nalff, nal_length_size, avctx->codec_id, 1, 0); + + for (int i = 0; i < hpkt.nb_nals; i++) { + H2645NAL* nal = &hpkt.nals[i]; + GetBitContext gb = nal->gb; + + av_log(avctx, AV_LOG_TRACE, "[%d/%d] NAL type = %d\n", i + 1, hpkt. nb_nals, nal->type); + + switch (nal->type) { + case HEVC_NAL_SEI_PREFIX: + { + int ret = ff_hevc_decode_nal_sei(&gb, avctx, &sei, &ps, nal- >type); + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "Skipping invalid undecodable NALU: %d\n", nal->type); + return; + } + + if (sei.common.dynamic_hdr_plus.info) + av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS, sei.common.dynamic_hdr_plus.info); + break; + } + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + case HEVC_NAL_TRAIL_R: + case HEVC_NAL_TRAIL_N: + case HEVC_NAL_TSA_N: + case HEVC_NAL_TSA_R: + case HEVC_NAL_STSA_N: + case HEVC_NAL_STSA_R: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_IDR_W_RADL: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_CRA_NUT: + case HEVC_NAL_RADL_N: + case HEVC_NAL_RADL_R: + case HEVC_NAL_RASL_N: + case HEVC_NAL_RASL_R: + // these Nal types will be handled in 'cuvid_decode_packet()' + break; + default: + av_log(avctx, AV_LOG_INFO, "Skipping NAL unit %d\n", nal- >type); + break; + } + } +} + static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) { CuvidContext *ctx = avctx->priv_data; @@ -497,6 +561,8 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) CuvidParsedFrame parsed_frame; CUdeviceptr mapped_frame = 0; int ret = 0, eret = 0; + uint8_t *pkt_data = avctx->internal->buffer_pkt->data; + int pkt_size = avctx->internal->buffer_pkt->size; av_log(avctx, AV_LOG_TRACE, "cuvid_output_frame\n"); @@ -512,6 +578,9 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) if (ret < 0 && ret != AVERROR_EOF) return ret; ret = cuvid_decode_packet(avctx, pkt); + + decode_nal_units(avctx, pkt_data, pkt_size, frame); + av_packet_unref(pkt); // cuvid_is_buffer_full() should avoid this. if (ret == AVERROR(EAGAIN)) -- 2.45.1.windows.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".