diff --git a/libavformat/internal.h b/libavformat/internal.h index 647ad65fb2..1b44beafb3 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -490,6 +490,15 @@ int ff_generate_avci_extradata(AVStream *st); */ int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args); +/** + * Copy encoding parameters from source to destination stream + * + * @param dst pointer to destination AVStream + * @param src pointer to source AVStream + * @return >=0 on success, AVERROR code on error + */ +int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src); + /** * Wrap errno on rename() error. * diff --git a/libavformat/utils.c b/libavformat/utils.c index d2a709c9a4..f2b0e6e1e5 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3951,6 +3951,63 @@ int av_read_pause(AVFormatContext *s) return AVERROR(ENOSYS); } +int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src) +{ + int ret, i; + + dst->id = src->id; + dst->time_base = src->time_base; + dst->nb_frames = src->nb_frames; + dst->disposition = src->disposition; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->avg_frame_rate = src->avg_frame_rate; + dst->r_frame_rate = src->r_frame_rate; + + av_dict_free(&dst->metadata); + ret = av_dict_copy(&dst->metadata, src->metadata, 0); + if (ret < 0) + return ret; + + ret = avcodec_parameters_copy(dst->codecpar, src->codecpar); + if (ret < 0) + return ret; + + /* Free existing side data*/ + for (i = 0; i < dst->nb_side_data; i++) + av_free(dst->side_data[i].data); + av_freep(&dst->side_data); + dst->nb_side_data = 0; + + /* Copy side data if present */ + if (src->nb_side_data) { + dst->side_data = av_mallocz_array(src->nb_side_data, + sizeof(AVPacketSideData)); + if (!dst->side_data) + return AVERROR(ENOMEM); + dst->nb_side_data = src->nb_side_data; + + for (i = 0; i < src->nb_side_data; i++) { + uint8_t *data = av_memdup(src->side_data[i].data, + src->side_data[i].size); + if (!data) + return AVERROR(ENOMEM); + dst->side_data[i].type = src->side_data[i].type; + dst->side_data[i].size = src->side_data[i].size; + dst->side_data[i].data = data; + } + } + + av_freep(&dst->recommended_encoder_configuration); + if (src->recommended_encoder_configuration) { + const char *conf_str = src->recommended_encoder_configuration; + dst->recommended_encoder_configuration = av_strdup(conf_str); + if (!dst->recommended_encoder_configuration) + return AVERROR(ENOMEM); + } + + return 0; +} + static void free_stream(AVStream **pst) { AVStream *st = *pst;