From: Limin Wang <lance.lmw...@gmail.com> Signed-off-by: Limin Wang <lance.lmw...@gmail.com> --- libavcodec/cbs_h2645.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/cbs_h265.h | 25 ++++++++++++++ 2 files changed, 118 insertions(+)
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 5f71d80..2fc957d 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1612,3 +1612,96 @@ void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, (sei->payload_count - position) * sizeof(*sei->payload)); } } + +int ff_cbs_h265_add_sei_prefix_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + H265RawSEIPayload *payload) +{ + H265RawSEI *sei = NULL; + int err, i; + + // Find an existing SEI PREFIX NAL unit to add to. + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == HEVC_NAL_SEI_PREFIX) { + sei = au->units[i].content; + if (sei->payload_count < H265_MAX_SEI_PAYLOADS) + break; + + sei = NULL; + } + } + + if (!sei) { + // Need to make a new SEI NAL unit. Insert it before the first + // slice data NAL unit; if no slice data, add at the end. + AVBufferRef *sei_ref; + + sei = av_mallocz(sizeof(*sei)); + if (!sei) { + err = AVERROR(ENOMEM); + goto fail; + } + + sei->nal_unit_header.nal_unit_type = HEVC_NAL_SEI_PREFIX; + sei->nal_unit_header.nuh_layer_id = 0; + sei->nal_unit_header.nuh_temporal_id_plus1 = 1; + + sei_ref = av_buffer_create((uint8_t*)sei, sizeof(*sei), + &cbs_h265_free_sei, NULL, 0); + if (!sei_ref) { + av_freep(&sei); + err = AVERROR(ENOMEM); + goto fail; + } + + for (i = 0; i < au->nb_units; i++) { + if (au->units[i].type == HEVC_NAL_IDR_W_RADL || + au->units[i].type == HEVC_NAL_IDR_N_LP) + break; + } + + err = ff_cbs_insert_unit_content(ctx, au, i, HEVC_NAL_SEI_PREFIX, + sei, sei_ref); + av_buffer_unref(&sei_ref); + if (err < 0) + goto fail; + } + + memcpy(&sei->payload[sei->payload_count], payload, sizeof(*payload)); + ++sei->payload_count; + + return 0; +fail: + cbs_h265_free_sei_payload(payload); + return err; +} + +void ff_cbs_h265_delete_sei_prefix_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *au, + CodedBitstreamUnit *nal, + int position) +{ + H265RawSEI *sei = nal->content; + + av_assert0(nal->type == HEVC_NAL_SEI_PREFIX); + av_assert0(position >= 0 && position < sei->payload_count); + + if (position == 0 && sei->payload_count == 1) { + // Deleting NAL unit entirely. + int i; + + for (i = 0; i < au->nb_units; i++) { + if (&au->units[i] == nal) + break; + } + + ff_cbs_delete_unit(ctx, au, i); + } else { + cbs_h265_free_sei_payload(&sei->payload[position]); + + --sei->payload_count; + memmove(sei->payload + position, + sei->payload + position + 1, + (sei->payload_count - position) * sizeof(*sei->payload)); + } +} diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h index ad746bf..b7e7dff 100644 --- a/libavcodec/cbs_h265.h +++ b/libavcodec/cbs_h265.h @@ -22,6 +22,7 @@ #include <stddef.h> #include <stdint.h> +#include "cbs.h" #include "cbs_h2645.h" #include "hevc.h" @@ -745,5 +746,29 @@ typedef struct CodedBitstreamH265Context { const H265RawPPS *active_pps; } CodedBitstreamH265Context; +/** + * Add an SEI message to an access unit. + * + * On success, the payload will be owned by a unit in access_unit; + * on failure, the content of the payload will be freed. + */ +int ff_cbs_h265_add_sei_prefix_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *access_unit, + H265RawSEIPayload *payload); + +/** + * Delete an SEI message from an access unit. + * + * Deletes from nal_unit, which must be an SEI PREFIX NAL unit. If this is the + * last message in nal_unit, also deletes it from access_unit. + * + * Requires nal_unit to be a unit in access_unit and position to be >= 0 + * and < the payload count of the SEI nal_unit. + */ +void ff_cbs_h265_delete_sei_prefix_message(CodedBitstreamContext *ctx, + CodedBitstreamFragment *access_unit, + CodedBitstreamUnit *nal_unit, + int position); + #endif /* AVCODEC_CBS_H265_H */ -- 2.9.5 _______________________________________________ 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".