L'octidi 18 messidor, an CCXXIII, Marton Balint a écrit : > 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.
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 ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel