diff --git a/libavformat/internal.h b/libavformat/internal.h index 89251b2460..b3a0a0c2d5 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -700,4 +700,17 @@ int ff_parse_opts_from_query_string(void *obj, const char *str, int allow_unkown int ff_make_codec_str(void *logctx, const AVCodecParameters *par, const AVRational *frame_rate, struct AVBPrint *out); +/** + * Allocate copy of a structure and copy contents of an AVBPrint buffer to the + * flexible array member of the copied struct. AVBPrint buffer is freed. + * + * @param bp pointer to an AVBprint struct + * @param struct_ptr pointer to the struct to be copied + * @param struct_size must be sizeof(*struct_ptr) + * @param flex_member must be struct_ptr->flexible_array_member + * @return pointer to the newly allocated struct, NULL on allocation error or + * if the AVBPrint buffer is not complete + */ +void *ff_bprint_finalize_as_fam(struct AVBPrint *bp, const void *struct_ptr, size_t struct_size, void *flex_member); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/utils.c b/libavformat/utils.c index 7a74e63d68..0192dba97f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -684,3 +684,22 @@ int ff_parse_opts_from_query_string(void *obj, const char *str, int allow_unknow } return 0; } + +void *ff_bprint_finalize_as_fam(struct AVBPrint *bp, const void *struct_ptr, size_t struct_size, void *flex_member) +{ + if (!av_bprint_is_complete(bp)) { + av_bprint_finalize(bp, NULL); + return NULL; + } + + void *p = av_malloc(struct_size + bp->len); + if (!p) { + av_bprint_finalize(bp, NULL); + return NULL; + } + memcpy(p, struct_ptr, struct_size); + memcpy(p + (flex_member - struct_ptr), bp->str, bp->len); + av_bprint_finalize(bp, NULL); + + return p; +}