L'octidi 18 messidor, an CCXXIII, Marton Balint a écrit : > Signed-off-by: Marton Balint <[email protected]> > --- > 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.
This looks like a step into escaping hell.
metadata foo=bar,baz=qux
metadata foo=bar
metadata baz=qux
Would the second form be ok for you?
> +
> @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;
> }
>
No other objection, but can you explain the use case? Packet metadata is not
very common.
Regards,
--
Nicolas George
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
