summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2015-07-02 23:20:09 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-07-17 00:12:04 +0200
commit5117b5e9aaa0372b023dcdf8353173715da37246 (patch)
treec1abc7c5397ad6414b446e707d482e3f9dccf03d
parent25a6711c2548c759554933f18841c3cacbf83497 (diff)
concatdec: add support for injecting packet metadata
Reviewed-by: Nicolas George <george@nsup.org> Signed-off-by: Marton Balint <cus@passwd.hu>
-rw-r--r--doc/demuxers.texi5
-rw-r--r--libavformat/concatdec.c28
2 files changed, 33 insertions, 0 deletions
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 50b5688388..e45e1afd9f 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -148,6 +148,11 @@ stream until 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{file_packet_metadata @var{key=value}}
+Metadata of the packets of the file. The specified metadata will be set for
+each file packet. You can specify this directive multiple times to add multiple
+metadata entries.
+
@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 81404a0c21..1fe294be19 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -47,6 +47,7 @@ typedef struct {
ConcatStream *streams;
int64_t inpoint;
int64_t outpoint;
+ AVDictionary *metadata;
int nb_streams;
} ConcatFile;
@@ -334,6 +335,7 @@ static int concat_read_close(AVFormatContext *avf)
for (i = 0; i < cat->nb_files; i++) {
av_freep(&cat->files[i].url);
av_freep(&cat->files[i].streams);
+ av_dict_free(&cat->files[i].metadata);
}
av_freep(&cat->files);
return 0;
@@ -385,6 +387,19 @@ static int concat_read_header(AVFormatContext *avf)
file->inpoint = dur;
else if (!strcmp(keyword, "outpoint"))
file->outpoint = dur;
+ } else if (!strcmp(keyword, "file_packet_metadata")) {
+ char *metadata;
+ metadata = av_get_token((const char **)&cursor, SPACE_CHARS);
+ if (!metadata) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: packet metadata required\n", line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if ((ret = av_dict_parse_string(&file->metadata, metadata, "=", "", 0)) < 0) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
+ av_freep(&metadata);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ av_freep(&metadata);
} else if (!strcmp(keyword, "stream")) {
if (!avformat_new_stream(avf, NULL))
FAIL(AVERROR(ENOMEM));
@@ -570,6 +585,19 @@ 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;
+ int metadata_len;
+ char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
+ if (!packed_metadata)
+ return AVERROR(ENOMEM);
+ if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
+ av_freep(&packed_metadata);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(metadata, packed_metadata, metadata_len);
+ av_freep(&packed_metadata);
+ }
return ret;
}