[FFmpeg-devel] [PATCH 4/4] concatdec: add support for injecting packet metadata
Marton Balint
cus at passwd.hu
Mon Jul 6 02:28:51 CEST 2015
Signed-off-by: Marton Balint <cus at 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.
+ at item @code{metadata @var{string}}
+Metadata of the file. The specified metadata (which consists of
+ at 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
More information about the ffmpeg-devel
mailing list