Signed-off-by: Marton Balint <c...@passwd.hu> --- doc/demuxers.texi | 4 ++++ libavformat/concatdec.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 4ba797e..28244f3 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -142,6 +142,10 @@ before the specified Out point. The duration of the files (if not specified by the @code{duration} directive) will be reduced based on their specified Out point. +@item @code{metadata @var{string}} +Metadata of the file. The specified metadata (which consists of +@code{key=value} pairs seperated by commas) will be set for each file packet. + @item @code{stream} Introduce a stream in the virtual file. All subsequent stream-related directives apply to the last introduced diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index eaf34b0..66e81c8 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -45,6 +45,8 @@ typedef struct { ConcatStream *streams; int64_t inpoint; int64_t outpoint; + char *metadata; + int metadata_len; int nb_streams; } ConcatFile; @@ -329,6 +331,7 @@ static int concat_read_close(AVFormatContext *avf) avformat_close_input(&cat->avf); for (i = 0; i < cat->nb_files; i++) { av_freep(&cat->files[i].url); + av_freep(&cat->files[i].metadata); av_freep(&cat->files[i].streams); } av_freep(&cat->files); @@ -381,6 +384,27 @@ static int concat_read_header(AVFormatContext *avf) file->inpoint = dur; else if (!strcmp(keyword, "out")) file->outpoint = dur; + } else if (!strcmp(keyword, "metadata")) { + AVDictionary *opts = NULL; + char *metadata; + if (file->metadata) { + av_log(avf, AV_LOG_ERROR, "Line %d: metadata is already provided\n", line); + FAIL(AVERROR_INVALIDDATA); + } + metadata = av_get_token((const char **)&cursor, SPACE_CHARS); + if (!metadata) { + av_log(avf, AV_LOG_ERROR, "Line %d: metadata required\n", line); + FAIL(AVERROR_INVALIDDATA); + } + if ((ret = av_dict_parse_string(&opts, metadata, "=", ",", 0)) < 0) { + av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line); + av_freep(&metadata); + av_dict_free(&opts); + FAIL(AVERROR_INVALIDDATA); + } + file->metadata = av_packet_pack_dictionary(opts, &file->metadata_len); + av_freep(&metadata); + av_dict_free(&opts); } else if (!strcmp(keyword, "stream")) { if (!avformat_new_stream(avf, NULL)) FAIL(AVERROR(ENOMEM)); @@ -576,6 +600,12 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n", av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base)); + if (cat->cur_file->metadata) { + uint8_t* metadata; + if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, cat->cur_file->metadata_len))) + return AVERROR(ENOMEM); + memcpy(metadata, cat->cur_file->metadata, cat->cur_file->metadata_len); + } return ret; } -- 2.1.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel