[FFmpeg-devel] [PATCH] libavformat/mxfdec.c: initial support for EssenceGroups

Mark Reid mindmark at gmail.com
Sun Nov 30 03:40:25 CET 2014


On Fri, Nov 28, 2014 at 9:26 AM, Tomas Härdin <tomas.hardin at codemill.se>
wrote:

> On Tue, 2014-11-25 at 15:14 -0800, Mark Reid wrote:
> > ---
> >  libavformat/mxf.c      |   1 +
> >  libavformat/mxf.h      |   1 +
> >  libavformat/mxfdec.c   | 148
> ++++++++++++++++++++++++++++++++++++++++---------
> >  tests/ref/lavf/mxf     |   6 +-
> >  tests/ref/lavf/mxf_d10 |   2 +-
> >  5 files changed, 127 insertions(+), 31 deletions(-)
> >
> > diff --git a/libavformat/mxf.c b/libavformat/mxf.c
> > index 4dc54d7..14d143e 100644
> > --- a/libavformat/mxf.c
> > +++ b/libavformat/mxf.c
> > @@ -94,6 +94,7 @@ static const struct {
> >      {AV_PIX_FMT_RGB565BE,{'R', 5,  'G', 6,  'B', 5
>    }},
> >      {AV_PIX_FMT_RGBA,    {'R', 8,  'G', 8,  'B', 8, 'A', 8
>    }},
> >      {AV_PIX_FMT_PAL8,    {'P', 8
>    }},
> > +    {AV_PIX_FMT_GRAY8,   {'A', 8
>    }},
>
> There's no pixel format for pure alpha?
>

I was looking for a  AV_PIX_FMT_A8 or something like that but could find
one.

http://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5

AV_PIX_FMT_GRAY8  has the right buffer size, 1 channel 8bpp.
AV_PIX_FMT_YA8 or AV_PIX_FMT_GRAY8A are 4 channels.


> >  };
> >
> >  static const int num_pixel_layouts =
> FF_ARRAY_ELEMS(ff_mxf_pixel_layouts);
> > diff --git a/libavformat/mxf.h b/libavformat/mxf.h
> > index 5b95efa..63b497a 100644
> > --- a/libavformat/mxf.h
> > +++ b/libavformat/mxf.h
> > @@ -35,6 +35,7 @@ enum MXFMetadataSetType {
> >      TimecodeComponent,
> >      PulldownComponent,
> >      Sequence,
> > +    EssenceGroup,
>
> Add this to the end of the enum? That way mxfenc output doesn't change.
>

Okay I'll do that, I just didn't because of the scary comment at the bottom
of the enum

           TypeBottom,// add metadata type before this


> >      MultipleDescriptor,
> >      Descriptor,
> >      Track,
> >  [...]
> >
> > +static int mxf_read_essence_group(void *arg, AVIOContext *pb, int tag,
> int size, UID uid, int64_t klv_offset)
> > +{
> > +    MXFEssenceGroup *essence_group = arg;
> > +    switch (tag) {
> > +    case 0x0202:
> > +        essence_group->duration = avio_rb64(pb);
> > +        break;
> > +    case 0x0501:
> > +        essence_group->structural_components_count = avio_rb32(pb);
> > +        essence_group->structural_components_refs =
> av_calloc(essence_group->structural_components_count, sizeof(UID));
> > +        if (!essence_group->structural_components_refs)
> > +            return AVERROR(ENOMEM);
> > +        avio_skip(pb, 4); /* useless size of objects, always 16
> according to specs */
> > +        avio_read(pb, (uint8_t
> *)essence_group->structural_components_refs,
> essence_group->structural_components_count * sizeof(UID));
>
> Is there any risk of this multiplication overflowing? I suspect
> av_calloc() will fail if it does, just making sure. Also not critical if
> it actually does since avio_read() just ends up reading less.
>

I copied the same code from the mxf_read_sequence func, so I assumed it was
okay.
http://ffmpeg.org/doxygen/trunk/mem_8c_source.html#l00251
av_calloc does check for a overflow and will return NULL if nmemb >=
INT_MAX / size. So it should fail before even getting to the avio_read.


> > +static MXFStructuralComponent*
> mxf_resolve_essence_group_choice(MXFContext *mxf, MXFEssenceGroup
> *essence_group)
> > +{
> > +    MXFStructuralComponent *component = NULL;
> > +    MXFPackage *package = NULL;
> > +    MXFDescriptor *descriptor = NULL;
> > +    int i;
> > +
> > +    if (!essence_group || !essence_group->structural_components_count)
> > +        return NULL;
> > +
> > +    /* essence groups contains multiple representations of the same
> media,
> > +       this return the first components with a valid Descriptor
> typically index 0 */
> > +    for (i =0; i < essence_group->structural_components_count; i++){
> > +        component = mxf_resolve_strong_ref(mxf,
> &essence_group->structural_components_refs[i], SourceClip);
> > +        if (!component)
> > +            continue;
> > +
> > +        if (!(package = mxf_resolve_source_package(mxf,
> component->source_package_uid)))
> > +            continue;
> > +
> > +        descriptor = mxf_resolve_strong_ref(mxf,
> &package->descriptor_ref, Descriptor);
> > +        if (descriptor){
> > +            /* HACK: force the duration of the component to match the
> duration of the descriptor */
> > +            if (descriptor->duration != AV_NOPTS_VALUE)
> > +                component->duration = descriptor->duration;
>
> Not a huge fan of this, but probably doesn't hurt since it's checking
> for AV_NOPTS_VALUE.
>
>
I was planing of removing this in a future patch. I was going to move the
logic into mxf_parse_structural_metadata, but need to refactor and shuffle
somethings around in there to get it to work.


> > +static int mxf_metadataset_init(MXFMetadataSet *ctx, enum
> MXFMetadataSetType type)
> > +{
> > +    switch (type){
> > +    case MultipleDescriptor:
> > +    case Descriptor:
> > +        ((MXFDescriptor*)ctx)->pix_fmt = AV_PIX_FMT_NONE;
> > +        ((MXFDescriptor*)ctx)->duration = AV_NOPTS_VALUE;
> > +        break;
> > +    default:
> > +        break;
> > +    }
> > +    return 0;
> > +}
> > +
>
> Good idea :)
>
> > diff --git a/tests/ref/lavf/mxf b/tests/ref/lavf/mxf
> > index 236661c..d237560 100644
> > --- a/tests/ref/lavf/mxf
> > +++ b/tests/ref/lavf/mxf
>
> Again, probably not needed if you stick EssenceGroup at the end of the
> enum.
>
> I like using mxf_resolve_source_package() to reduce the size of
> mxf_parse_physical_source_package() and mxf_parse_structural_metadata().
>
> Memory handling looks correct too. Did you double-check with valgrind?


> Looks pretty good overall.
>

Great, I'll double check it with valgrind, remove the changes to the tests,
put EssenceGroup at the end of the enum and send a new patch.
thanks for taking the time to review.


> /Tomas
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>


More information about the ffmpeg-devel mailing list