[FFmpeg-devel] [PATCH] new generic metadata API

Aurelien Jacobs aurel
Sat Sep 27 16:03:53 CEST 2008


On Tue, 23 Sep 2008 15:21:43 +0200
Michael Niedermayer <michaelni at gmx.at> wrote:

> On Mon, Sep 22, 2008 at 12:24:36AM +0200, Aurelien Jacobs wrote:
> > Hi,
> > 
> > A generic metadata API was queried several times... Now, here it is !
> >  - The first patch add the new API itself. It contains a compatibility
> >    layer so that software using the old API will still work.
> >    It also contains the appropriate #if, so that the old API and the
> >    compatibility layer will disappear after next lavf major bump.
> >  - The second patch changes all the muxers/demuxers to use the new API.
> >  - The third patch changes ffmpeg.c, ffplay.c and ffserver.c to use
> >    the new API.
> > 
> > Basically, this API allows to associate random string value to random
> > string name, for AVFormatContext, AVStream, AVChapter and AVProgram.
> > It also supports more advanced features, such as recursive metadata,
> > and multiple tags with the same name.
> > For an example usage of such features, here is what matroska can
> > contain:
> > 
> > BAND
> > - LEADPERFORMER
> > -- ADDRESS
> > --- DATE
> > --- DATEEND
> > -- ADDRESS
> > --- DATE
> > 
> > I hope this new API will fit everyone needs.
> 
> A few random comments ...
> how is the language/country code ofthe string specified?
> (german vs english titles and names ...)

It was not...
Now it is !

> Are title vs. Title vs. Name vs. name handled when things differ from
> src & dst containers?

Yes.
Demuxers store the tag name as is in AVMetadata. So it can be title, Title,
TITLE or anything.
About muxers, there are 2 cases:
 - containers supporting only a limited set of tags are using
   av_metadata_get_tag() which will return the value of a tag with
   the requested name (case insensitive) or with an equivalent name.
   eg: when querying "author", it will return the value of "artist"
   if no "author" tag is present.
 - containers supporting generic tags will store the tags as is.
   if the container as some tag naming rules, it's up to the
   muxer to enfore them. eg: matroska requires the tag name to be
   all uppercase, so it's up to them matroska muxer to convert all
   names. such a thing can't be generalized.

> What about formats that support generic user defined key-value metadata but
> do not support tree style metadata?
> I think such formats should have the whole tree stored in a flattened form,
> and where one is described in the format spec in the described format.
> 
> That is
> instead of just storing
> "BAND"="the fobar"
> it should store:
> "BAND"="the fobar"
> "BAND/ADDRESS"="foo street 123"
> if this info is available ...
> 
> It thus may make sense to have some kind of support in the API to store and
> load such flattened metadata.
> This also could come in handy for getting metadata from the commend line into
> the internal structs, which AFAICS is missing from your patches.

Indeed.

> [note, also see the nut-devel ML for some related change suggestion i just
>  posted]

Seen it.
I've added generic flattening and un-flattening support, following your
proposed nut scheme. The exact formatting could be changed latter if
a different scheme is accepted.

> [...]
> > Index: libavformat/nutenc.c
> > ===================================================================
> > --- libavformat/nutenc.c	(revision 15375)
> > +++ libavformat/nutenc.c	(working copy)
> > @@ -445,6 +445,13 @@
> >      return 1;
> >  }
> >  
> > +static int add_tag(ByteIOContext *bc, AVMetadata *metadata, const char *type){
> > +    char *value = av_metadata_get_tag(metadata, type);
> > +    if (value)  return add_info(bc, type, value);
> > +    return 0;
> > +}
> > +
> 
> > +#undef printf
> 
> huh?

Argg... Removed, along with another occurance.

> >  static int write_globalinfo(NUTContext *nut, ByteIOContext *bc){
> >      AVFormatContext *s= nut->avf;
> >      ByteIOContext *dyn_bc;
> > @@ -454,9 +461,10 @@
> >      if(ret < 0)
> >          return ret;
> >  
> > -    if(s->title    [0]) count+= add_info(dyn_bc, "Title"    , s->title);
> > -    if(s->author   [0]) count+= add_info(dyn_bc, "Author"   , s->author);
> > -    if(s->copyright[0]) count+= add_info(dyn_bc, "Copyright", s->copyright);
> > +    count += add_tag(dyn_bc, &s->metadata, "Title");
> > +    count += add_tag(dyn_bc, &s->metadata, "Author");
> > +    count += add_tag(dyn_bc, &s->metadata, "Copyright");
> > +    count += add_tag(dyn_bc, &s->metadata, "Description");
> >      if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
> >                          count+= add_info(dyn_bc, "Encoder"  , LIBAVFORMAT_IDENT);
> >  
> 
> well, thats not supporting generic metadata, it just hardcodes 4 cases

My goal was mainly to add the new API, and convert all (de)muxers
so that they don't use the old API anymore. I didn't try to implement
support for every possible kind of metadata feature in every (de)muxers.
Some (de)muxers could be further improved, but that's out of the scope of
this patch (matroska muxer don't even support muxing tags at all !).
Anyway, I've improved nut muxing, so it now really supports generic
metadata, with nested tags, and laguage code.

Attached patch is not split like in my original post (to ease testing),
but it is still intended to be applied in several steps.
You can test it with the following samples:
  http://samples.mplayerhq.hu/Matroska/nested_tags.mka
  http://samples.mplayerhq.hu/Matroska/nested_tags_lang.mka
Converting last one to nut (flattening tags) and then ffplay -stats
on the nut file (un-flattening) will show this:

BAND: Metallica
  LEAD_PERFORMER (ger): Lars Ulrich
    URL: http://www.metallica.com/Band/lars.asp
    ADDRESS: Gentofte, Denmark
      DATE: 1963-12-06
      DATEEND: 1970-12-06
    ADDRESS (eng): Whereever, US
      DATE: 1970-12-07
    INSTRUMENT: Drums
Encoder: Lavf52.23.0

(the lang values where added by me and are not supposed to be
meaningful, there are just here for testing purpose)

Aurel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: metadata.diff
Type: text/x-diff
Size: 101860 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080927/d0affe39/attachment.diff>



More information about the ffmpeg-devel mailing list