summaryrefslogtreecommitdiff
path: root/libavcodec/hevcdec.c
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2021-07-22 22:44:42 +0100
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2021-11-17 14:12:51 +0000
commitbc68fd1050bd82e59d8ce7da909a0bcaf2b61197 (patch)
tree2abe090b637fa06dbd501223b921f0832e42fa35 /libavcodec/hevcdec.c
parent54e65aa38abb37d6af92551b7e3adf6785f631ec (diff)
avcodec/hevcdec: Export Dolby Vision RPUs as side data
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
Diffstat (limited to 'libavcodec/hevcdec.c')
-rw-r--r--libavcodec/hevcdec.c39
1 files changed, 39 insertions, 0 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;
}