diff options
author | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2021-07-22 22:44:42 +0100 |
---|---|---|
committer | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2021-11-17 14:12:51 +0000 |
commit | bc68fd1050bd82e59d8ce7da909a0bcaf2b61197 (patch) | |
tree | 2abe090b637fa06dbd501223b921f0832e42fa35 | |
parent | 54e65aa38abb37d6af92551b7e3adf6785f631ec (diff) | |
download | ffmpeg-bc68fd1050bd82e59d8ce7da909a0bcaf2b61197.tar.gz |
avcodec/hevcdec: Export Dolby Vision RPUs as side data
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
-rw-r--r-- | libavcodec/hevcdec.c | 39 | ||||
-rw-r--r-- | libavcodec/hevcdec.h | 2 | ||||
-rw-r--r-- | libavcodec/version.h | 2 |
3 files changed, 42 insertions, 1 deletions
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 246ffd7d80..3e19f4ebed 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2950,6 +2950,14 @@ static int set_side_data(HEVCContext *s) } } + if (s->rpu_buf) { + AVFrameSideData *rpu = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_DOVI_RPU_BUFFER, s->rpu_buf); + if (!rpu) + return AVERROR(ENOMEM); + + s->rpu_buf = NULL; + } + return 0; } @@ -3223,6 +3231,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) break; case HEVC_NAL_AUD: case HEVC_NAL_FD_NUT: + case HEVC_NAL_UNSPEC62: break; default: av_log(s->avctx, AV_LOG_INFO, @@ -3269,6 +3278,29 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) } } + /* + * Check for RPU delimiter. + * + * Dolby Vision RPUs masquerade as unregistered NALs of type 62. + * + * We have to do this check here an create the rpu buffer, since RPUs are appended + * to the end of an AU; they are the last non-EOB/EOS NAL in the AU. + */ + 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) { + 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); + if (!s->rpu_buf) + return AVERROR(ENOMEM); + + 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); + } + /* decode the NAL units */ for (i = 0; i < s->pkt.nb_nals; i++) { H2645NAL *nal = &s->pkt.nals[i]; @@ -3512,6 +3544,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) pic_arrays_free(s); + av_buffer_unref(&s->rpu_buf); + av_freep(&s->md5_ctx); av_freep(&s->cabac_state); @@ -3698,6 +3732,10 @@ static int hevc_update_thread_context(AVCodecContext *dst, if (ret < 0) return ret; + ret = av_buffer_replace(&s->rpu_buf, s0->rpu_buf); + 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; @@ -3754,6 +3792,7 @@ static void hevc_decode_flush(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; ff_hevc_flush_dpb(s); ff_hevc_reset_sei(&s->sei); + 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 77fdf90da1..870ff178d4 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -572,6 +572,8 @@ typedef struct HEVCContext { int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) int nuh_layer_id; + + AVBufferRef *rpu_buf; ///< 0 or 1 Dolby Vision RPUs. } HEVCContext; /** diff --git a/libavcodec/version.h b/libavcodec/version.h index 7d4cfa3f11..4d3000364a 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 59 -#define LIBAVCODEC_VERSION_MINOR 12 +#define LIBAVCODEC_VERSION_MINOR 13 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |