@@ -665,3 +665,24 @@ int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
return 0;
}
+
+int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit,
+ void** content)
+{
+ if (unit->content && (!unit->content_ref ||
+ !av_buffer_is_writable(unit->content_ref))) {
+ int err;
+ if (!ctx->codec->make_writable)
+ return AVERROR_PATCHWELCOME;
+
+ err = ctx->codec->make_writable(ctx, unit);
+ if (err < 0)
+ return err;
+
+ if (content)
+ *content = unit->content;
+ }
+
+ return 0;
+}
@@ -352,5 +352,14 @@ int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int position);
+/**
+ * Make the content of a unit writable.
+ *
+ * If content is supplied, *content will point to the unit's content on success.
+ */
+int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit,
+ void **content);
+
#endif /* AVCODEC_CBS_H */
@@ -1305,6 +1305,7 @@ const CodedBitstreamType ff_cbs_type_av1 = {
.split_fragment = &cbs_av1_split_fragment,
.read_unit = &cbs_av1_read_unit,
+ .make_writable = NULL,
.write_unit = &cbs_av1_write_unit,
.assemble_fragment = &cbs_av1_assemble_fragment,
@@ -1545,6 +1545,7 @@ const CodedBitstreamType ff_cbs_type_h264 = {
.split_fragment = &cbs_h2645_split_fragment,
.read_unit = &cbs_h264_read_nal_unit,
+ .make_writable = NULL,
.write_unit = &cbs_h2645_write_nal_unit,
.assemble_fragment = &cbs_h2645_assemble_fragment,
@@ -1558,6 +1559,7 @@ const CodedBitstreamType ff_cbs_type_h265 = {
.split_fragment = &cbs_h2645_split_fragment,
.read_unit = &cbs_h265_read_nal_unit,
+ .make_writable = NULL,
.write_unit = &cbs_h2645_write_nal_unit,
.assemble_fragment = &cbs_h2645_assemble_fragment,
@@ -44,6 +44,10 @@ typedef struct CodedBitstreamType {
int (*read_unit)(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit);
+ // Make a unit's content writable.
+ int (*make_writable)(CodedBitstreamContext *ctx,
+ CodedBitstreamUnit *unit);
+
// Write the unit->data bitstream from unit->content.
int (*write_unit)(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit);
@@ -513,6 +513,7 @@ const CodedBitstreamType ff_cbs_type_jpeg = {
.split_fragment = &cbs_jpeg_split_fragment,
.read_unit = &cbs_jpeg_read_unit,
+ .make_writable = NULL,
.write_unit = &cbs_jpeg_write_unit,
.assemble_fragment = &cbs_jpeg_assemble_fragment,
@@ -414,6 +414,7 @@ const CodedBitstreamType ff_cbs_type_mpeg2 = {
.split_fragment = &cbs_mpeg2_split_fragment,
.read_unit = &cbs_mpeg2_read_unit,
+ .make_writable = NULL,
.write_unit = &cbs_mpeg2_write_unit,
.assemble_fragment = &cbs_mpeg2_assemble_fragment,
@@ -685,6 +685,7 @@ const CodedBitstreamType ff_cbs_type_vp9 = {
.split_fragment = &cbs_vp9_split_fragment,
.read_unit = &cbs_vp9_read_unit,
+ .make_writable = NULL,
.write_unit = &cbs_vp9_write_unit,
.assemble_fragment = &cbs_vp9_assemble_fragment,
This will enable us to change e.g. the parameter sets of H.2645 in ways that would change the parsing process of future units. An example of this is the h264_redundant_pps bsf. The actual implementation of the underlying codec-dependent make_writable functions is not contained in this commit. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com> --- This is a slight extension to my previous patch. In lots of cases where this function will be applied, the user will already have a pointer to the unit's content and this addition updates the pointer automatically. libavcodec/cbs.c | 21 +++++++++++++++++++++ libavcodec/cbs.h | 9 +++++++++ libavcodec/cbs_av1.c | 1 + libavcodec/cbs_h2645.c | 2 ++ libavcodec/cbs_internal.h | 4 ++++ libavcodec/cbs_jpeg.c | 1 + libavcodec/cbs_mpeg2.c | 1 + libavcodec/cbs_vp9.c | 1 + 8 files changed, 40 insertions(+)