diff mbox series

[FFmpeg-devel] avformat/mxf: Establish register of local tags

Message ID 8a8cec0acd192d7e638a7e3d0266591d5e523049.camel@acc.umu.se
State Accepted
Headers show
Series [FFmpeg-devel] avformat/mxf: Establish register of local tags | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Tomas Härdin Jan. 27, 2021, 2:04 p.m. UTC
Hi

Ticket #9079 brought this about. This should prevent accidentally
adding local tags that are not registered in the primer. It also allows
us to omit tags that we know won't be used, in a manner that is more
elegant than the old code.

The actual meat of this patch is mxf_mark_tag_unused(),
mxf_write_primer_pack(), mxf_write_local_tag() and
ff_mxf_lookup_local_tag()

fate-mxf passes of course, since this doesn't actually change the
output of the muxer.

/Tomas
Subject: [PATCH] avformat/mxf: Establish register of local tags

Tags can be marked "not used" upfront, saving some space in the primer.
av_asserts0() is used to enforce that only tags that are in the primer can actually be written.
---
 libavformat/mxf.c    | 144 +++++++++++-
 libavformat/mxf.h    |   3 +-
 libavformat/mxfdec.c |   8 +-
 libavformat/mxfenc.c | 517 +++++++++++++++++--------------------------
 4 files changed, 349 insertions(+), 323 deletions(-)

Comments

Marton Balint Jan. 27, 2021, 8:38 p.m. UTC | #1
On Wed, 27 Jan 2021, Tomas Härdin wrote:

> Hi
>
> Ticket #9079 brought this about. This should prevent accidentally
> adding local tags that are not registered in the primer. It also allows
> us to omit tags that we know won't be used, in a manner that is more
> elegant than the old code.
>
> The actual meat of this patch is mxf_mark_tag_unused(),
> mxf_write_primer_pack(), mxf_write_local_tag() and
> ff_mxf_lookup_local_tag()

IMHO you should not move the local tags to mxf.c, because only encoding 
uses them.

The only exception where sharing made sense is 
ff_mxf_mastering_display_local_tags, but that is super ugly that you 
now lookup them in mxfdec.c based on local tags we assign them for 
encoding. Not to mention the linear search you use for each lookup...

So I suggest you simply duplicate the 4 UL-s to the single local tags 
array you make and keep them in mxfenc.c, that way you also don't have to 
specify the array size manually...

Regards,
Marton
Tomas Härdin Jan. 27, 2021, 9:24 p.m. UTC | #2
ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
> 
> On Wed, 27 Jan 2021, Tomas Härdin wrote:
> 
> > Hi
> > 
> > Ticket #9079 brought this about. This should prevent accidentally
> > adding local tags that are not registered in the primer. It also allows
> > us to omit tags that we know won't be used, in a manner that is more
> > elegant than the old code.
> > 
> > The actual meat of this patch is mxf_mark_tag_unused(),
> > mxf_write_primer_pack(), mxf_write_local_tag() and
> > ff_mxf_lookup_local_tag()
> 
> IMHO you should not move the local tags to mxf.c, because only encoding 
> uses them.
> 
> The only exception where sharing made sense is 
> ff_mxf_mastering_display_local_tags, but that is super ugly that you 
> now lookup them in mxfdec.c based on local tags we assign them for 
> encoding. Not to mention the linear search you use for each lookup...

We could sort them and use a binary search, but I wanted some feedback
on this idea before going further. There's not terribly many of them

I'd like to avoid having the full ULs twice in the code. The only way I
can see how to do that is with #defines

> So I suggest you simply duplicate the 4 UL-s to the single local tags 
> array you make and keep them in mxfenc.c, that way you also don't have to 
> specify the array size manually...

That might conflict with Andreas' deduplication efforts. But yeah, the
thought did occur to me

/Tomas
Tomas Härdin Jan. 27, 2021, 9:50 p.m. UTC | #3
ons 2021-01-27 klockan 22:24 +0100 skrev Tomas Härdin:
> ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
> > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > 
> > > Hi
> > > 
> > > Ticket #9079 brought this about. This should prevent accidentally
> > > adding local tags that are not registered in the primer. It also allows
> > > us to omit tags that we know won't be used, in a manner that is more
> > > elegant than the old code.
> > > 
> > > The actual meat of this patch is mxf_mark_tag_unused(),
> > > mxf_write_primer_pack(), mxf_write_local_tag() and
> > > ff_mxf_lookup_local_tag()
> > 
> > IMHO you should not move the local tags to mxf.c, because only encoding 
> > uses them.
> > 
> > The only exception where sharing made sense is 
> > ff_mxf_mastering_display_local_tags, but that is super ugly that you 
> > now lookup them in mxfdec.c based on local tags we assign them for 
> > encoding. Not to mention the linear search you use for each lookup...
> 
> We could sort them and use a binary search, but I wanted some feedback
> on this idea before going further. There's not terribly many of them
> 
> I'd like to avoid having the full ULs twice in the code. The only way I
> can see how to do that is with #defines
> 
> > So I suggest you simply duplicate the 4 UL-s to the single local tags 
> > array you make and keep them in mxfenc.c, that way you also don't have to 
> > specify the array size manually...
> 
> That might conflict with Andreas' deduplication efforts. But yeah, the
> thought did occur to me

Here's an updated patch. Feedback welcome.

/Tomas
Marton Balint Jan. 27, 2021, 10:50 p.m. UTC | #4
On Wed, 27 Jan 2021, Tomas Härdin wrote:

> ons 2021-01-27 klockan 22:24 +0100 skrev Tomas Härdin:
>> ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
>>> On Wed, 27 Jan 2021, Tomas Härdin wrote:
>>>
>>>> Hi
>>>>
>>>> Ticket #9079 brought this about. This should prevent accidentally
>>>> adding local tags that are not registered in the primer. It also allows
>>>> us to omit tags that we know won't be used, in a manner that is more
>>>> elegant than the old code.
>>>>
>>>> The actual meat of this patch is mxf_mark_tag_unused(),
>>>> mxf_write_primer_pack(), mxf_write_local_tag() and
>>>> ff_mxf_lookup_local_tag()
>>>
>>> IMHO you should not move the local tags to mxf.c, because only encoding
>>> uses them.
>>>
>>> The only exception where sharing made sense is
>>> ff_mxf_mastering_display_local_tags, but that is super ugly that you
>>> now lookup them in mxfdec.c based on local tags we assign them for
>>> encoding. Not to mention the linear search you use for each lookup...
>>
>> We could sort them and use a binary search, but I wanted some feedback
>> on this idea before going further. There's not terribly many of them
>>
>> I'd like to avoid having the full ULs twice in the code. The only way I
>> can see how to do that is with #defines
>>
>>> So I suggest you simply duplicate the 4 UL-s to the single local tags
>>> array you make and keep them in mxfenc.c, that way you also don't have to
>>> specify the array size manually...
>>
>> That might conflict with Andreas' deduplication efforts. But yeah, the
>> thought did occur to me
>
> Here's an updated patch. Feedback welcome.

Thanks, I like this version much more. One comment is that I'd put an 
assert right into mxf_lookup_local_tag instead of returning NULL if a tag 
is not found, this way you can remove NULL-check asserts from individual 
places where mxf_lookup_local_tag is called. Otherwise seems all fine.

Regards,
Marton
Tomas Härdin Jan. 27, 2021, 11:09 p.m. UTC | #5
ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> 
> On Wed, 27 Jan 2021, Tomas Härdin wrote:
> 
> > ons 2021-01-27 klockan 22:24 +0100 skrev Tomas Härdin:
> > > ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
> > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > > 
> > > > > Hi
> > > > > 
> > > > > Ticket #9079 brought this about. This should prevent accidentally
> > > > > adding local tags that are not registered in the primer. It also allows
> > > > > us to omit tags that we know won't be used, in a manner that is more
> > > > > elegant than the old code.
> > > > > 
> > > > > The actual meat of this patch is mxf_mark_tag_unused(),
> > > > > mxf_write_primer_pack(), mxf_write_local_tag() and
> > > > > ff_mxf_lookup_local_tag()
> > > > 
> > > > IMHO you should not move the local tags to mxf.c, because only encoding
> > > > uses them.
> > > > 
> > > > The only exception where sharing made sense is
> > > > ff_mxf_mastering_display_local_tags, but that is super ugly that you
> > > > now lookup them in mxfdec.c based on local tags we assign them for
> > > > encoding. Not to mention the linear search you use for each lookup...
> > > 
> > > We could sort them and use a binary search, but I wanted some feedback
> > > on this idea before going further. There's not terribly many of them
> > > 
> > > I'd like to avoid having the full ULs twice in the code. The only way I
> > > can see how to do that is with #defines
> > > 
> > > > So I suggest you simply duplicate the 4 UL-s to the single local tags
> > > > array you make and keep them in mxfenc.c, that way you also don't have to
> > > > specify the array size manually...
> > > 
> > > That might conflict with Andreas' deduplication efforts. But yeah, the
> > > thought did occur to me
> > 
> > Here's an updated patch. Feedback welcome.
> 
> Thanks, I like this version much more. One comment is that I'd put an 
> assert right into mxf_lookup_local_tag instead of returning NULL if a tag 
> is not found, this way you can remove NULL-check asserts from individual 
> places where mxf_lookup_local_tag is called. Otherwise seems all fine.

There's not really anything to av_assert0() on in
mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
NULL with either

    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
0x%04x\n", tag);
    abort();

or

    av_assert0(0 && "Tried to use unregistered local tag");

or maybe

    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
0x%04x\n", tag);
    av_assert0(0);

to avoid explicitly calling abort()

/Tomas
Marton Balint Jan. 28, 2021, 7:56 a.m. UTC | #6
On Thu, 28 Jan 2021, Tomas Härdin wrote:

> ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
>> 
>> On Wed, 27 Jan 2021, Tomas Härdin wrote:
>> 
>> > ons 2021-01-27 klockan 22:24 +0100 skrev Tomas Härdin:
>> > > ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
>> > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
>> > > > 
>> > > > > Hi
>> > > > > 
>> > > > > Ticket #9079 brought this about. This should prevent accidentally
>> > > > > adding local tags that are not registered in the primer. It also allows
>> > > > > us to omit tags that we know won't be used, in a manner that is more
>> > > > > elegant than the old code.
>> > > > > 
>> > > > > The actual meat of this patch is mxf_mark_tag_unused(),
>> > > > > mxf_write_primer_pack(), mxf_write_local_tag() and
>> > > > > ff_mxf_lookup_local_tag()
>> > > > 
>> > > > IMHO you should not move the local tags to mxf.c, because only encoding
>> > > > uses them.
>> > > > 
>> > > > The only exception where sharing made sense is
>> > > > ff_mxf_mastering_display_local_tags, but that is super ugly that you
>> > > > now lookup them in mxfdec.c based on local tags we assign them for
>> > > > encoding. Not to mention the linear search you use for each lookup...
>> > > 
>> > > We could sort them and use a binary search, but I wanted some feedback
>> > > on this idea before going further. There's not terribly many of them
>> > > 
>> > > I'd like to avoid having the full ULs twice in the code. The only way I
>> > > can see how to do that is with #defines
>> > > 
>> > > > So I suggest you simply duplicate the 4 UL-s to the single local tags
>> > > > array you make and keep them in mxfenc.c, that way you also don't have to
>> > > > specify the array size manually...
>> > > 
>> > > That might conflict with Andreas' deduplication efforts. But yeah, the
>> > > thought did occur to me
>> > 
>> > Here's an updated patch. Feedback welcome.
>> 
>> Thanks, I like this version much more. One comment is that I'd put an 
>> assert right into mxf_lookup_local_tag instead of returning NULL if a tag 
>> is not found, this way you can remove NULL-check asserts from individual 
>> places where mxf_lookup_local_tag is called. Otherwise seems all fine.
>
> There's not really anything to av_assert0() on in
> mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
> NULL with either
>
>    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> 0x%04x\n", tag);
>    abort();
>
> or
>
>    av_assert0(0 && "Tried to use unregistered local tag");
>
> or maybe
>
>    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> 0x%04x\n", tag);
>    av_assert0(0);
>
> to avoid explicitly calling abort()

I think we usually do av_assert0(0) in this case. I am not sure if the 
error message is particularly useful, afterall who sees it should be a 
programmer and file/line is printed by assert anyway, so a comment in the 
source code before the assert makes more sense to me.

Regards,
Marton
Tomas Härdin Jan. 28, 2021, 1:48 p.m. UTC | #7
tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
> 
> On Thu, 28 Jan 2021, Tomas Härdin wrote:
> 
> > ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > 
> > > > ons 2021-01-27 klockan 22:24 +0100 skrev Tomas Härdin:
> > > > > ons 2021-01-27 klockan 21:38 +0100 skrev Marton Balint:
> > > > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > > > > 
> > > > > > > Hi
> > > > > > > 
> > > > > > > Ticket #9079 brought this about. This should prevent accidentally
> > > > > > > adding local tags that are not registered in the primer. It also allows
> > > > > > > us to omit tags that we know won't be used, in a manner that is more
> > > > > > > elegant than the old code.
> > > > > > > 
> > > > > > > The actual meat of this patch is mxf_mark_tag_unused(),
> > > > > > > mxf_write_primer_pack(), mxf_write_local_tag() and
> > > > > > > ff_mxf_lookup_local_tag()
> > > > > > 
> > > > > > IMHO you should not move the local tags to mxf.c, because only encoding
> > > > > > uses them.
> > > > > > 
> > > > > > The only exception where sharing made sense is
> > > > > > ff_mxf_mastering_display_local_tags, but that is super ugly that you
> > > > > > now lookup them in mxfdec.c based on local tags we assign them for
> > > > > > encoding. Not to mention the linear search you use for each lookup...
> > > > > 
> > > > > We could sort them and use a binary search, but I wanted some feedback
> > > > > on this idea before going further. There's not terribly many of them
> > > > > 
> > > > > I'd like to avoid having the full ULs twice in the code. The only way I
> > > > > can see how to do that is with #defines
> > > > > 
> > > > > > So I suggest you simply duplicate the 4 UL-s to the single local tags
> > > > > > array you make and keep them in mxfenc.c, that way you also don't have to
> > > > > > specify the array size manually...
> > > > > 
> > > > > That might conflict with Andreas' deduplication efforts. But yeah, the
> > > > > thought did occur to me
> > > > 
> > > > Here's an updated patch. Feedback welcome.
> > > 
> > > Thanks, I like this version much more. One comment is that I'd put an 
> > > assert right into mxf_lookup_local_tag instead of returning NULL if a tag 
> > > is not found, this way you can remove NULL-check asserts from individual 
> > > places where mxf_lookup_local_tag is called. Otherwise seems all fine.
> > 
> > There's not really anything to av_assert0() on in
> > mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
> > NULL with either
> > 
> >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > 0x%04x\n", tag);
> >    abort();
> > 
> > or
> > 
> >    av_assert0(0 && "Tried to use unregistered local tag");
> > 
> > or maybe
> > 
> >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > 0x%04x\n", tag);
> >    av_assert0(0);
> > 
> > to avoid explicitly calling abort()
> 
> I think we usually do av_assert0(0) in this case. I am not sure if the 
> error message is particularly useful, afterall who sees it should be a 
> programmer and file/line is printed by assert anyway, so a comment in the 
> source code before the assert makes more sense to me.

Maybe av_assert0(0 && "you forgot to add a local tag to the registry")?

/Tomas
Tomas Härdin Jan. 28, 2021, 3:36 p.m. UTC | #8
tor 2021-01-28 klockan 14:48 +0100 skrev Tomas Härdin:
> tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
> > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > > ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > There's not really anything to av_assert0() on in
> > > mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
> > > NULL with either
> > > 
> > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > 0x%04x\n", tag);
> > >    abort();
> > > 
> > > or
> > > 
> > >    av_assert0(0 && "Tried to use unregistered local tag");
> > > 
> > > or maybe
> > > 
> > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > 0x%04x\n", tag);
> > >    av_assert0(0);
> > > 
> > > to avoid explicitly calling abort()
> > 
> > I think we usually do av_assert0(0) in this case. I am not sure if the 
> > error message is particularly useful, afterall who sees it should be a 
> > programmer and file/line is printed by assert anyway, so a comment in the 
> > source code before the assert makes more sense to me.
> 
> Maybe av_assert0(0 && "you forgot to add a local tag to the registry")?

Here's a rebased patch that does this, with a little comment also

/Tomas
Marton Balint Jan. 29, 2021, 9:06 p.m. UTC | #9
On Thu, 28 Jan 2021, Tomas Härdin wrote:

> tor 2021-01-28 klockan 14:48 +0100 skrev Tomas Härdin:
>> tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
>>> On Thu, 28 Jan 2021, Tomas Härdin wrote:
>>>> ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
>>>>> On Wed, 27 Jan 2021, Tomas Härdin wrote:
>>>> There's not really anything to av_assert0() on in
>>>> mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
>>>> NULL with either
>>>>
>>>>    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
>>>> 0x%04x\n", tag);
>>>>    abort();
>>>>
>>>> or
>>>>
>>>>    av_assert0(0 && "Tried to use unregistered local tag");
>>>>
>>>> or maybe
>>>>
>>>>    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
>>>> 0x%04x\n", tag);
>>>>    av_assert0(0);
>>>>
>>>> to avoid explicitly calling abort()
>>>
>>> I think we usually do av_assert0(0) in this case. I am not sure if the
>>> error message is particularly useful, afterall who sees it should be a
>>> programmer and file/line is printed by assert anyway, so a comment in the
>>> source code before the assert makes more sense to me.
>>
>> Maybe av_assert0(0 && "you forgot to add a local tag to the registry")?
>
> Here's a rebased patch that does this, with a little comment also

LGTM, thanks.

Marton
Tomas Härdin Feb. 1, 2021, 10:37 a.m. UTC | #10
fre 2021-01-29 klockan 22:06 +0100 skrev Marton Balint:
> 
> On Thu, 28 Jan 2021, Tomas Härdin wrote:
> 
> > tor 2021-01-28 klockan 14:48 +0100 skrev Tomas Härdin:
> > > tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
> > > > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > > > > ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> > > > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > > > There's not really anything to av_assert0() on in
> > > > > mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
> > > > > NULL with either
> > > > > 
> > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > > > 0x%04x\n", tag);
> > > > >    abort();
> > > > > 
> > > > > or
> > > > > 
> > > > >    av_assert0(0 && "Tried to use unregistered local tag");
> > > > > 
> > > > > or maybe
> > > > > 
> > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > > > 0x%04x\n", tag);
> > > > >    av_assert0(0);
> > > > > 
> > > > > to avoid explicitly calling abort()
> > > > 
> > > > I think we usually do av_assert0(0) in this case. I am not sure if the
> > > > error message is particularly useful, afterall who sees it should be a
> > > > programmer and file/line is printed by assert anyway, so a comment in the
> > > > source code before the assert makes more sense to me.
> > > 
> > > Maybe av_assert0(0 && "you forgot to add a local tag to the registry")?
> > 
> > Here's a rebased patch that does this, with a little comment also
> 
> LGTM, thanks.

Will push later today

/Tomas
Tomas Härdin Feb. 1, 2021, 11:11 p.m. UTC | #11
mån 2021-02-01 klockan 11:37 +0100 skrev Tomas Härdin:
> fre 2021-01-29 klockan 22:06 +0100 skrev Marton Balint:
> > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > 
> > > tor 2021-01-28 klockan 14:48 +0100 skrev Tomas Härdin:
> > > > tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
> > > > > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > > > > > ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> > > > > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > > > > There's not really anything to av_assert0() on in
> > > > > > mxf_lookup_local_tag(). Either way, I'm thinking replacing the return
> > > > > > NULL with either
> > > > > > 
> > > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > > > > 0x%04x\n", tag);
> > > > > >    abort();
> > > > > > 
> > > > > > or
> > > > > > 
> > > > > >    av_assert0(0 && "Tried to use unregistered local tag");
> > > > > > 
> > > > > > or maybe
> > > > > > 
> > > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local tag
> > > > > > 0x%04x\n", tag);
> > > > > >    av_assert0(0);
> > > > > > 
> > > > > > to avoid explicitly calling abort()
> > > > > 
> > > > > I think we usually do av_assert0(0) in this case. I am not sure if the
> > > > > error message is particularly useful, afterall who sees it should be a
> > > > > programmer and file/line is printed by assert anyway, so a comment in the
> > > > > source code before the assert makes more sense to me.
> > > > 
> > > > Maybe av_assert0(0 && "you forgot to add a local tag to the registry")?
> > > 
> > > Here's a rebased patch that does this, with a little comment also
> > 
> > LGTM, thanks.
> 
> Will push later today

Pushed

/Tomas
Paul B Mahol Feb. 2, 2021, 11:58 a.m. UTC | #12
I think you should make tables that never change const.

On Tue, Feb 2, 2021 at 12:11 AM Tomas Härdin <tjoppen@acc.umu.se> wrote:

> mån 2021-02-01 klockan 11:37 +0100 skrev Tomas Härdin:
> > fre 2021-01-29 klockan 22:06 +0100 skrev Marton Balint:
> > > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > >
> > > > tor 2021-01-28 klockan 14:48 +0100 skrev Tomas Härdin:
> > > > > tor 2021-01-28 klockan 08:56 +0100 skrev Marton Balint:
> > > > > > On Thu, 28 Jan 2021, Tomas Härdin wrote:
> > > > > > > ons 2021-01-27 klockan 23:50 +0100 skrev Marton Balint:
> > > > > > > > On Wed, 27 Jan 2021, Tomas Härdin wrote:
> > > > > > > There's not really anything to av_assert0() on in
> > > > > > > mxf_lookup_local_tag(). Either way, I'm thinking replacing the
> return
> > > > > > > NULL with either
> > > > > > >
> > > > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local
> tag
> > > > > > > 0x%04x\n", tag);
> > > > > > >    abort();
> > > > > > >
> > > > > > > or
> > > > > > >
> > > > > > >    av_assert0(0 && "Tried to use unregistered local tag");
> > > > > > >
> > > > > > > or maybe
> > > > > > >
> > > > > > >    av_log(NULL, AV_LOG_PANIC, "Tried to use unregistered local
> tag
> > > > > > > 0x%04x\n", tag);
> > > > > > >    av_assert0(0);
> > > > > > >
> > > > > > > to avoid explicitly calling abort()
> > > > > >
> > > > > > I think we usually do av_assert0(0) in this case. I am not sure
> if the
> > > > > > error message is particularly useful, afterall who sees it
> should be a
> > > > > > programmer and file/line is printed by assert anyway, so a
> comment in the
> > > > > > source code before the assert makes more sense to me.
> > > > >
> > > > > Maybe av_assert0(0 && "you forgot to add a local tag to the
> registry")?
> > > >
> > > > Here's a rebased patch that does this, with a little comment also
> > >
> > > LGTM, thanks.
> >
> > Will push later today
>
> Pushed
>
> /Tomas
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Tomas Härdin Feb. 3, 2021, 5:07 p.m. UTC | #13
tis 2021-02-02 klockan 12:58 +0100 skrev Paul B Mahol:
> I think you should make tables that never change const.

Fixed.

/Tomas
diff mbox series

Patch

diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index 1901b24c68..4bc92a95fe 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -26,13 +26,140 @@  const uint8_t ff_mxf_mastering_display_prefix[13]           = { 0x06,0x0e,0x2b,0
 
 const uint8_t ff_mxf_random_index_pack_key[16] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
 
-/* be careful to update references to this array if reordering */
-/* local tags are dynamic and must not clash with others in mxfenc.c */
-const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4] = {
+/**
+ * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
+ *             https://smpte-ra.org/sites/default/files/Labels.xml
+ */
+const MXFLocalTagPair ff_mxf_local_tags[109] = {
+    // preface set
+    { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
+    { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
+    { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
+    { 0x3B07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x04,0x00,0x00,0x00}}, /* Object Model Version */
+    { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
+    { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
+    { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
+    { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
+    { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
+    // Identification
+    { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
+    { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
+    { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
+    { 0x3C03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x04,0x00,0x00,0x00}}, /* Product Version */
+    { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
+    { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
+    { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
+    { 0x3C07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x0A,0x00,0x00,0x00}}, /* Toolkit Version */
+    { 0x3C08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x06,0x01,0x00,0x00}}, /* Platform */
+    // Content Storage
+    { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
+    { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
+    // Essence Container Data
+    { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
+    { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
+    // Package
+    { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
+    { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
+    { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
+    { 0x4402, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Package Name */
+    { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
+    { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
+    // Track
+    { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
+    { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */
+    { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
+    { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
+    { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
+    // Sequence
+    { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
+    { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
+    { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
+    // Source Clip
+    { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
+    { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
+    { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
+    // Timecode Component
+    { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */
+    { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */
+    { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */
+    // File Descriptor
+    { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
+    { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
+    { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
+    { 0x3002, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x02,0x00,0x00,0x00,0x00}}, /* ContainerDuration */
+    { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
+    // Generic Picture Essence Descriptor
+    { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */
+    { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */
+    { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
+    { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
+    { 0x3216, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x08,0x00,0x00,0x00}}, /* Stored F2 Offset */
+    { 0x3205, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x08,0x00,0x00,0x00}}, /* Sampled Width */
+    { 0x3204, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x07,0x00,0x00,0x00}}, /* Sampled Height */
+    { 0x3206, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x09,0x00,0x00,0x00}}, /* Sampled X Offset */
+    { 0x3207, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0A,0x00,0x00,0x00}}, /* Sampled Y Offset */
+    { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
+    { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
+    { 0x320A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0D,0x00,0x00,0x00}}, /* Display X offset */
+    { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */
+    { 0x3217, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x07,0x00,0x00,0x00}}, /* Display F2 offset */
+    { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
+    { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer characteristic */
+    { 0x3213, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x02,0x00,0x00,0x00,0x00}}, /* Image Start Offset */
+    { 0x3214, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Image End Offset */
+    { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
+    { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
+    { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */
+    // CDCI Picture Essence Descriptor
+    { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
+    { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
+    { 0x3308, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x01,0x10,0x00,0x00,0x00}}, /* Vertical Subsampling */
+    { 0x3303, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x06,0x00,0x00,0x00}}, /* Color Siting */
+    { 0x3307, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x04,0x00,0x00,0x00,0x00}}, /* Padding Bits */
+    { 0x3304, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x03,0x00,0x00,0x00}}, /* Black Ref level */
+    { 0x3305, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x04,0x00,0x00,0x00}}, /* White Ref level */
+    { 0x3306, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x05,0x00,0x00,0x00}}, /* Color Range */
+    // Generic Sound Essence Descriptor
+    { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */
+    { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
+    { 0x3D04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x02,0x01,0x01,0x03,0x00,0x00,0x00}}, /* Audio Ref Level */
+    { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
+    { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
+    { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
+    // Index Table Segment
+    { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */
+    { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */
+    { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */
+    { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */
+    { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */
+    { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */
+    { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */
+    { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
+    // MPEG video Descriptor
+    { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
+    { 0x8003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x05,0x00,0x00}}, /* LowDelay */
+    { 0x8004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x06,0x00,0x00}}, /* ClosedGOP */
+    { 0x8006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x08,0x00,0x00}}, /* MaxGOP */
+    { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
+    { 0x8008, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x09,0x00,0x00}}, /* BPictureCount */
+    // Wave Audio Essence Descriptor
+    { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
+    { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
+    // mxf_user_comments_local_tag
+    { 0x4406, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0C,0x00,0x00,0x00}}, /* User Comments */
+    { 0x5001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x09,0x01,0x00,0x00}}, /* Name */
+    { 0x5003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0A,0x01,0x00,0x00}}, /* Value */
+    // mxf_avc_subdescriptor_local_tags
+    { 0x8100, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00}}, /* SubDescriptors */
+    { 0x8200, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0E,0x00,0x00}}, /* AVC Decoding Delay */
+    { 0x8201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0A,0x00,0x00}}, /* AVC Profile */
+    { 0x8202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0D,0x00,0x00}}, /* AVC Level */
+    // ff_mxf_mastering_display_local_tags
     { 0x8301, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x01,0x00,0x00 }}, /* Mastering Display Primaries */
     { 0x8302, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x02,0x00,0x00 }}, /* Mastering Display White Point Chromaticity */
     { 0x8303, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x03,0x00,0x00 }}, /* Mastering Display Maximum Luminance */
     { 0x8304, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x04,0x00,0x00 }}  /* Mastering Display Minimum Luminance */
+    // remember to increase the size of this array here and in mxf.h when adding new entries
 };
 
 /**
@@ -228,3 +355,14 @@  int ff_mxf_get_content_package_rate(AVRational time_base)
             return mxf_content_package_rates[i].rate;
     return 0;
 }
+
+const MXFLocalTagPair* ff_mxf_lookup_local_tag(int tag)
+{
+    for (int i = 0; i < FF_ARRAY_ELEMS(ff_mxf_local_tags); i++) {
+        if (ff_mxf_local_tags[i].local_tag == tag) {
+            return &ff_mxf_local_tags[i];
+        }
+    }
+
+    return NULL;
+}
\ No newline at end of file
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index 5219abc767..0f24b5385e 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -85,7 +85,7 @@  typedef struct MXFLocalTagPair {
 
 extern const uint8_t ff_mxf_mastering_display_prefix[13];
 extern const uint8_t ff_mxf_random_index_pack_key[16];
-extern const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4];
+extern const MXFLocalTagPair ff_mxf_local_tags[109];
 
 #define FF_MXF_MASTERING_CHROMA_DEN 50000
 #define FF_MXF_MASTERING_LUMA_DEN   10000
@@ -109,6 +109,7 @@  extern const MXFCodecUL ff_mxf_color_space_uls[];
 
 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
 int ff_mxf_get_content_package_rate(AVRational time_base);
+const MXFLocalTagPair* ff_mxf_lookup_local_tag(int tag);
 
 
 #define PRIxUID                             \
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index afff20402d..a71b60bb73 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -1286,7 +1286,7 @@  static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
                 if (!descriptor->mastering)
                     return AVERROR(ENOMEM);
             }
-            if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[0].uid)) {
+            if (IS_KLV_KEY(uid, ff_mxf_lookup_local_tag(0x8301)->uid)) {
                 for (int i = 0; i < 3; i++) {
                     /* Order: large x, large y, other (i.e. RGB) */
                     descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
@@ -1296,20 +1296,20 @@  static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
                 if (descriptor->mastering->white_point[0].den != 0)
                     descriptor->mastering->has_primaries = 1;
             }
-            if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[1].uid)) {
+            if (IS_KLV_KEY(uid, ff_mxf_lookup_local_tag(0x8302)->uid)) {
                 descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
                 descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
                 /* Check we have seen mxf_mastering_display_primaries */
                 if (descriptor->mastering->display_primaries[0][0].den != 0)
                     descriptor->mastering->has_primaries = 1;
             }
-            if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[2].uid)) {
+            if (IS_KLV_KEY(uid, ff_mxf_lookup_local_tag(0x8303)->uid)) {
                 descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
                 /* Check we have seen mxf_mastering_display_minimum_luminance */
                 if (descriptor->mastering->min_luminance.den != 0)
                     descriptor->mastering->has_luminance = 1;
             }
-            if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[3].uid)) {
+            if (IS_KLV_KEY(uid, ff_mxf_lookup_local_tag(0x8304)->uid)) {
                 descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
                 /* Check we have seen mxf_mastering_display_maximum_luminance */
                 if (descriptor->mastering->max_luminance.den != 0)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 6c5331ad62..1fece29cd5 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -228,6 +228,30 @@  static const UID mxf_d10_container_uls[] = {
     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, // D-10 525/50 NTSC 30mb/s
 };
 
+static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
+static const uint8_t umid_ul[]              = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
+
+/**
+ * complete key for operation pattern, partitions, and primer pack
+ */
+static const uint8_t op1a_ul[]                     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
+static const uint8_t opatom_ul[]                   = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x02,0x01,0x10,0x03,0x00,0x00 };
+static const uint8_t footer_partition_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
+static const uint8_t primer_pack_key[]             = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
+static const uint8_t index_table_segment_key[]     = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
+static const uint8_t header_open_partition_key[]   = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete
+static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
+static const uint8_t klv_fill_key[]                = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
+static const uint8_t body_partition_key[]          = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete
+
+/**
+ * partial key for header metadata
+ */
+static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
+static const uint8_t multiple_desc_ul[]     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
+
+#define MXF_NUM_TAGS FF_ARRAY_ELEMS(ff_mxf_local_tags)
+
 typedef struct MXFContext {
     AVClass *av_class;
     int64_t footer_partition_offset;
@@ -258,164 +282,9 @@  typedef struct MXFContext {
     int store_user_comments;
     int track_instance_count; // used to generate MXFTrack uuids
     int cbr_index;           ///< use a constant bitrate index
+    uint8_t unused_tags[MXF_NUM_TAGS];  ///< local tags that we know will not be used
 } MXFContext;
 
-static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
-static const uint8_t umid_ul[]              = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
-
-/**
- * complete key for operation pattern, partitions, and primer pack
- */
-static const uint8_t op1a_ul[]                     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
-static const uint8_t opatom_ul[]                   = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x02,0x01,0x10,0x03,0x00,0x00 };
-static const uint8_t footer_partition_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
-static const uint8_t primer_pack_key[]             = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
-static const uint8_t index_table_segment_key[]     = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
-static const uint8_t header_open_partition_key[]   = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete
-static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
-static const uint8_t klv_fill_key[]                = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
-static const uint8_t body_partition_key[]          = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete
-
-/**
- * partial key for header metadata
- */
-static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
-static const uint8_t multiple_desc_ul[]     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
-
-/**
- * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
- *             https://smpte-ra.org/sites/default/files/Labels.xml
- */
-static const MXFLocalTagPair mxf_local_tag_batch[] = {
-    // preface set
-    { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
-    { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
-    { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
-    { 0x3B07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x04,0x00,0x00,0x00}}, /* Object Model Version */
-    { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
-    { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
-    { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
-    { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
-    { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
-    // Identification
-    { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
-    { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
-    { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
-    { 0x3C03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x04,0x00,0x00,0x00}}, /* Product Version */
-    { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
-    { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
-    { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
-    { 0x3C07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x0A,0x00,0x00,0x00}}, /* Toolkit Version */
-    { 0x3C08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x06,0x01,0x00,0x00}}, /* Platform */
-    // Content Storage
-    { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
-    { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
-    // Essence Container Data
-    { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
-    { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
-    // Package
-    { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
-    { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
-    { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
-    { 0x4402, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x03,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Package Name */
-    { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
-    { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
-    // Track
-    { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
-    { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */
-    { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
-    { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
-    { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
-    // Sequence
-    { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
-    { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
-    { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
-    // Source Clip
-    { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
-    { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
-    { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
-    // Timecode Component
-    { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */
-    { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */
-    { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */
-    // File Descriptor
-    { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
-    { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
-    { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
-    { 0x3002, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x02,0x00,0x00,0x00,0x00}}, /* ContainerDuration */
-    { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
-    // Generic Picture Essence Descriptor
-    { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */
-    { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */
-    { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
-    { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
-    { 0x3216, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x08,0x00,0x00,0x00}}, /* Stored F2 Offset */
-    { 0x3205, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x08,0x00,0x00,0x00}}, /* Sampled Width */
-    { 0x3204, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x07,0x00,0x00,0x00}}, /* Sampled Height */
-    { 0x3206, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x09,0x00,0x00,0x00}}, /* Sampled X Offset */
-    { 0x3207, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0A,0x00,0x00,0x00}}, /* Sampled Y Offset */
-    { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
-    { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
-    { 0x320A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0D,0x00,0x00,0x00}}, /* Display X offset */
-    { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */
-    { 0x3217, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x07,0x00,0x00,0x00}}, /* Display F2 offset */
-    { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
-    { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer characteristic */
-    { 0x3213, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x02,0x00,0x00,0x00,0x00}}, /* Image Start Offset */
-    { 0x3214, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Image End Offset */
-    { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
-    { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
-    { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */
-    // CDCI Picture Essence Descriptor
-    { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
-    { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
-    { 0x3308, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x01,0x10,0x00,0x00,0x00}}, /* Vertical Subsampling */
-    { 0x3303, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x06,0x00,0x00,0x00}}, /* Color Siting */
-    { 0x3307, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x04,0x00,0x00,0x00,0x00}}, /* Padding Bits */
-    { 0x3304, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x03,0x00,0x00,0x00}}, /* Black Ref level */
-    { 0x3305, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x04,0x00,0x00,0x00}}, /* White Ref level */
-    { 0x3306, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x05,0x00,0x00,0x00}}, /* Color Range */
-    // Generic Sound Essence Descriptor
-    { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */
-    { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
-    { 0x3D04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x02,0x01,0x01,0x03,0x00,0x00,0x00}}, /* Audio Ref Level */
-    { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
-    { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
-    { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
-    // Index Table Segment
-    { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */
-    { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */
-    { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */
-    { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */
-    { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */
-    { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */
-    { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */
-    { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
-    // MPEG video Descriptor
-    { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
-    { 0x8003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x05,0x00,0x00}}, /* LowDelay */
-    { 0x8004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x06,0x00,0x00}}, /* ClosedGOP */
-    { 0x8006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x08,0x00,0x00}}, /* MaxGOP */
-    { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
-    { 0x8008, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x09,0x00,0x00}}, /* BPictureCount */
-    // Wave Audio Essence Descriptor
-    { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
-    { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
-};
-
-static const MXFLocalTagPair mxf_avc_subdescriptor_local_tags[] = {
-    { 0x8100, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00}}, /* SubDescriptors */
-    { 0x8200, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0E,0x00,0x00}}, /* AVC Decoding Delay */
-    { 0x8201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0A,0x00,0x00}}, /* AVC Profile */
-    { 0x8202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x0E,0x04,0x01,0x06,0x06,0x01,0x0D,0x00,0x00}}, /* AVC Level */
-};
-
-static const MXFLocalTagPair mxf_user_comments_local_tag[] = {
-    { 0x4406, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0C,0x00,0x00,0x00}}, /* User Comments */
-    { 0x5001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x09,0x01,0x00,0x00}}, /* Name */
-    { 0x5003, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x02,0x01,0x02,0x0A,0x01,0x00,0x00}}, /* Value */
-};
-
 static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value)
 {
     avio_write(pb, uuid_base, 12);
@@ -490,38 +359,54 @@  static int mxf_get_essence_container_ul_index(enum AVCodecID id)
     return -1;
 }
 
-static void mxf_write_local_tags(AVIOContext *pb, const MXFLocalTagPair *local_tags, int count)
+static void mxf_mark_tag_unused(MXFContext *mxf, int tag)
 {
-    int i;
-    for (i = 0; i < count; i++) {
-        avio_wb16(pb, local_tags[i].local_tag);
-        avio_write(pb, local_tags[i].uid, 16);
-    }
+    const MXFLocalTagPair *pair = ff_mxf_lookup_local_tag(tag);
+    mxf->unused_tags[pair - ff_mxf_local_tags] = 1;
 }
 
 static void mxf_write_primer_pack(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
     AVIOContext *pb = s->pb;
-    int local_tag_number, i = 0;
-    int avc_tags_count = 0;
-    int mastering_tags_count = 0;
-
-    local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
-    local_tag_number += mxf->store_user_comments * FF_ARRAY_ELEMS(mxf_user_comments_local_tag);
+    int local_tag_number = MXF_NUM_TAGS, i;
+    int will_have_avc_tags = 0, will_have_mastering_tags = 0;
 
     for (i = 0; i < s->nb_streams; i++) {
         MXFStreamContext *sc = s->streams[i]->priv_data;
         if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_H264 && !sc->avc_intra) {
-            avc_tags_count = FF_ARRAY_ELEMS(mxf_avc_subdescriptor_local_tags);
+            will_have_avc_tags = 1;
         }
         if (av_stream_get_side_data(s->streams[i], AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL)) {
-            mastering_tags_count = FF_ARRAY_ELEMS(ff_mxf_mastering_display_local_tags);
+            will_have_mastering_tags = 1;
         }
     }
 
-    local_tag_number += avc_tags_count;
-    local_tag_number += mastering_tags_count;
+    if (!mxf->store_user_comments) {
+        mxf_mark_tag_unused(mxf, 0x4406);
+        mxf_mark_tag_unused(mxf, 0x5001);
+        mxf_mark_tag_unused(mxf, 0x5003);
+    }
+
+    if (!will_have_avc_tags) {
+        mxf_mark_tag_unused(mxf, 0x8100);
+        mxf_mark_tag_unused(mxf, 0x8200);
+        mxf_mark_tag_unused(mxf, 0x8201);
+        mxf_mark_tag_unused(mxf, 0x8202);
+    }
+
+    if (!will_have_mastering_tags) {
+        mxf_mark_tag_unused(mxf, 0x8301);
+        mxf_mark_tag_unused(mxf, 0x8302);
+        mxf_mark_tag_unused(mxf, 0x8303);
+        mxf_mark_tag_unused(mxf, 0x8304);
+    }
+
+    for (i = 0; i < MXF_NUM_TAGS; i++) {
+        if (mxf->unused_tags[i]) {
+            local_tag_number--;
+        }
+    }
 
     avio_write(pb, primer_pack_key, 16);
     klv_encode_ber_length(pb, local_tag_number * 18 + 8);
@@ -529,23 +414,24 @@  static void mxf_write_primer_pack(AVFormatContext *s)
     avio_wb32(pb, local_tag_number); // local_tag num
     avio_wb32(pb, 18); // item size, always 18 according to the specs
 
-    for (i = 0; i < FF_ARRAY_ELEMS(mxf_local_tag_batch); i++) {
-        avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
-        avio_write(pb, mxf_local_tag_batch[i].uid, 16);
-    }
-    if (mxf->store_user_comments)
-        for (i = 0; i < FF_ARRAY_ELEMS(mxf_user_comments_local_tag); i++) {
-            avio_wb16(pb, mxf_user_comments_local_tag[i].local_tag);
-            avio_write(pb, mxf_user_comments_local_tag[i].uid, 16);
+    for (i = 0; i < MXF_NUM_TAGS; i++) {
+        if (mxf->unused_tags[i] == 0) {
+            avio_wb16(pb, ff_mxf_local_tags[i].local_tag);
+            avio_write(pb, ff_mxf_local_tags[i].uid, 16);
         }
-    if (avc_tags_count > 0)
-        mxf_write_local_tags(pb, mxf_avc_subdescriptor_local_tags, avc_tags_count);
-    if (mastering_tags_count > 0)
-        mxf_write_local_tags(pb, ff_mxf_mastering_display_local_tags, mastering_tags_count);
+    }
 }
 
-static void mxf_write_local_tag(AVIOContext *pb, int size, int tag)
+static void mxf_write_local_tag(AVFormatContext *s, int size, int tag)
 {
+    MXFContext *mxf = s->priv_data;
+    AVIOContext *pb = s->pb;
+    const MXFLocalTagPair *pair = ff_mxf_lookup_local_tag(tag);
+
+    // make sure the tag is registered and not declared unnecessary upfront
+    av_assert0(pair != NULL);
+    av_assert0(mxf->unused_tags[pair - ff_mxf_local_tags] == 0);
+
     avio_wb16(pb, tag);
     avio_wb16(pb, size);
 }
@@ -602,44 +488,44 @@  static void mxf_write_preface(AVFormatContext *s)
     klv_encode_ber_length(pb, 138 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
 
     // write preface set uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, Preface, 0);
     PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
 
     // last modified date
-    mxf_write_local_tag(pb, 8, 0x3B02);
+    mxf_write_local_tag(s, 8, 0x3B02);
     avio_wb64(pb, mxf->timestamp);
 
     // write version
-    mxf_write_local_tag(pb, 2, 0x3B05);
+    mxf_write_local_tag(s, 2, 0x3B05);
     avio_wb16(pb, 259); // v1.3
 
     // Object Model Version
-    mxf_write_local_tag(pb, 4, 0x3B07);
+    mxf_write_local_tag(s, 4, 0x3B07);
     avio_wb32(pb, 1);
 
     // write identification_refs
-    mxf_write_local_tag(pb, 16 + 8, 0x3B06);
+    mxf_write_local_tag(s, 16 + 8, 0x3B06);
     mxf_write_refs_count(pb, 1);
     mxf_write_uuid(pb, Identification, 0);
 
     // write content_storage_refs
-    mxf_write_local_tag(pb, 16, 0x3B03);
+    mxf_write_local_tag(s, 16, 0x3B03);
     mxf_write_uuid(pb, ContentStorage, 0);
 
     // operational pattern
-    mxf_write_local_tag(pb, 16, 0x3B09);
+    mxf_write_local_tag(s, 16, 0x3B09);
     if (s->oformat == &ff_mxf_opatom_muxer)
         avio_write(pb, opatom_ul, 16);
     else
         avio_write(pb, op1a_ul, 16);
 
     // write essence_container_refs
-    mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A);
+    mxf_write_local_tag(s, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A);
     mxf_write_essence_container_refs(s);
 
     // write dm_scheme_refs
-    mxf_write_local_tag(pb, 8, 0x3B0B);
+    mxf_write_local_tag(s, 8, 0x3B0B);
     avio_wb64(pb, 0);
 }
 
@@ -688,8 +574,9 @@  static int mxf_utf16_local_tag_length(const char *utf8_str)
 /*
  * Write a local tag containing an utf-8 string as utf-16
  */
-static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
+static void mxf_write_local_tag_utf16(AVFormatContext *s, int tag, const char *value)
 {
+    AVIOContext *pb = s->pb;
     uint64_t size = mxf_utf16len(value);
 
     if (size >= UINT16_MAX/2) {
@@ -697,7 +584,7 @@  static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *valu
         return;
     }
 
-    mxf_write_local_tag(pb, size*2, tag);
+    mxf_write_local_tag(s, size*2, tag);
     avio_put_str16be(pb, value);
 }
 
@@ -737,30 +624,30 @@  static void mxf_write_identification(AVFormatContext *s)
     klv_encode_ber_length(pb, length);
 
     // write uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, Identification, 0);
     PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
 
     // write generation uid
-    mxf_write_local_tag(pb, 16, 0x3C09);
+    mxf_write_local_tag(s, 16, 0x3C09);
     mxf_write_uuid(pb, Identification, 1);
-    mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name
-    mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name
+    mxf_write_local_tag_utf16(s, 0x3C01, company); // Company Name
+    mxf_write_local_tag_utf16(s, 0x3C02, product); // Product Name
 
-    mxf_write_local_tag(pb, 10, 0x3C03); // Product Version
+    mxf_write_local_tag(s, 10, 0x3C03); // Product Version
     store_version(s);
 
-    mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String
+    mxf_write_local_tag_utf16(s, 0x3C04, version); // Version String
 
     // write product uid
-    mxf_write_local_tag(pb, 16, 0x3C05);
+    mxf_write_local_tag(s, 16, 0x3C05);
     mxf_write_uuid(pb, Identification, 2);
 
     // modification date
-    mxf_write_local_tag(pb, 8, 0x3C06);
+    mxf_write_local_tag(s, 8, 0x3C06);
     avio_wb64(pb, mxf->timestamp);
 
-    mxf_write_local_tag(pb, 10, 0x3C07); // Toolkit Version
+    mxf_write_local_tag(s, 10, 0x3C07); // Toolkit Version
     store_version(s);
 }
 
@@ -774,19 +661,19 @@  static void mxf_write_content_storage(AVFormatContext *s, MXFPackage *packages,
     klv_encode_ber_length(pb, 60 + (16 * package_count));
 
     // write uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, ContentStorage, 0);
     PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
 
     // write package reference
-    mxf_write_local_tag(pb, 16 * package_count + 8, 0x1901);
+    mxf_write_local_tag(s, 16 * package_count + 8, 0x1901);
     mxf_write_refs_count(pb, package_count);
     for (i = 0; i < package_count; i++) {
         mxf_write_uuid(pb, packages[i].type, packages[i].instance);
     }
 
     // write essence container data
-    mxf_write_local_tag(pb, 8 + 16, 0x1902);
+    mxf_write_local_tag(s, 8 + 16, 0x1902);
     mxf_write_refs_count(pb, 1);
     mxf_write_uuid(pb, EssenceContainerData, 0);
 }
@@ -802,23 +689,23 @@  static void mxf_write_track(AVFormatContext *s, AVStream *st, MXFPackage *packag
     klv_encode_ber_length(pb, 80);
 
     // write track uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, Track, mxf->track_instance_count);
     PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
 
     // write track id
-    mxf_write_local_tag(pb, 4, 0x4801);
+    mxf_write_local_tag(s, 4, 0x4801);
     avio_wb32(pb, st->index+2);
 
     // write track number
-    mxf_write_local_tag(pb, 4, 0x4804);
+    mxf_write_local_tag(s, 4, 0x4804);
     if (package->type == MaterialPackage)
         avio_wb32(pb, 0); // track number of material package is 0
     else
         avio_write(pb, sc->track_essence_element_key + 12, 4);
 
     // write edit rate
-    mxf_write_local_tag(pb, 8, 0x4B01);
+    mxf_write_local_tag(s, 8, 0x4B01);
 
     if (st == mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer) {
         avio_wb32(pb, mxf->tc.rate.num);
@@ -829,11 +716,11 @@  static void mxf_write_track(AVFormatContext *s, AVStream *st, MXFPackage *packag
     }
 
     // write origin
-    mxf_write_local_tag(pb, 8, 0x4B02);
+    mxf_write_local_tag(s, 8, 0x4B02);
     avio_wb64(pb, 0);
 
     // write sequence refs
-    mxf_write_local_tag(pb, 16, 0x4803);
+    mxf_write_local_tag(s, 16, 0x4803);
     mxf_write_uuid(pb, Sequence, mxf->track_instance_count);
 }
 
@@ -845,7 +732,7 @@  static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
     AVIOContext *pb = s->pb;
 
     // find data define uls
-    mxf_write_local_tag(pb, 16, 0x0201);
+    mxf_write_local_tag(s, 16, 0x0201);
     if (st == mxf->timecode_track)
         avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
     else {
@@ -854,7 +741,7 @@  static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
     }
 
     // write duration
-    mxf_write_local_tag(pb, 8, 0x0202);
+    mxf_write_local_tag(s, 8, 0x0202);
 
     if (st != mxf->timecode_track && s->oformat == &ff_mxf_opatom_muxer && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
         avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count);
@@ -873,14 +760,14 @@  static void mxf_write_sequence(AVFormatContext *s, AVStream *st, MXFPackage *pac
     PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
     klv_encode_ber_length(pb, 80);
 
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, Sequence, mxf->track_instance_count);
 
     PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
     mxf_write_common_fields(s, st);
 
     // write structural component
-    mxf_write_local_tag(pb, 16 + 8, 0x1001);
+    mxf_write_local_tag(s, 16 + 8, 0x1001);
     mxf_write_refs_count(pb, 1);
     if (st == mxf->timecode_track)
         component = TimecodeComponent;
@@ -899,21 +786,21 @@  static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, MXFPa
     klv_encode_ber_length(pb, 75);
 
     // UID
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, TimecodeComponent, mxf->track_instance_count);
 
     mxf_write_common_fields(s, st);
 
     // Start Time Code
-    mxf_write_local_tag(pb, 8, 0x1501);
+    mxf_write_local_tag(s, 8, 0x1501);
     avio_wb64(pb, mxf->tc.start);
 
     // Rounded Time Code Base
-    mxf_write_local_tag(pb, 2, 0x1502);
+    mxf_write_local_tag(s, 2, 0x1502);
     avio_wb16(pb, mxf->timecode_base);
 
     // Drop Frame
-    mxf_write_local_tag(pb, 1, 0x1503);
+    mxf_write_local_tag(s, 1, 0x1503);
     avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
 }
 
@@ -928,18 +815,18 @@  static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXF
     klv_encode_ber_length(pb, 108);
 
     // write uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, SourceClip, mxf->track_instance_count);
 
     PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
     mxf_write_common_fields(s, st);
 
     // write start_position
-    mxf_write_local_tag(pb, 8, 0x1201);
+    mxf_write_local_tag(s, 8, 0x1201);
     avio_wb64(pb, 0);
 
     // write source package uid, end of the reference
-    mxf_write_local_tag(pb, 32, 0x1101);
+    mxf_write_local_tag(s, 32, 0x1101);
     if (!package->ref) {
         for (i = 0; i < 4; i++)
             avio_wb64(pb, 0);
@@ -947,7 +834,7 @@  static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXF
         mxf_write_umid(s, package->ref->instance);
 
     // write source track id
-    mxf_write_local_tag(pb, 4, 0x1102);
+    mxf_write_local_tag(s, 4, 0x1102);
     if (package->type == SourcePackage && !package->ref)
         avio_wb32(pb, 0);
     else
@@ -961,7 +848,7 @@  static void mxf_write_tape_descriptor(AVFormatContext *s)
     mxf_write_metadata_key(pb, 0x012e00);
     PRINT_KEY(s, "tape descriptor key", pb->buf_ptr - 16);
     klv_encode_ber_length(pb, 20);
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, TapeDescriptor, 0);
     PRINT_KEY(s, "tape_desc uid", pb->buf_ptr - 16);
 }
@@ -978,17 +865,17 @@  static void mxf_write_multi_descriptor(AVFormatContext *s)
     PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
     klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams);
 
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, MultipleDescriptor, 0);
     PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
 
     // write sample rate
-    mxf_write_local_tag(pb, 8, 0x3001);
+    mxf_write_local_tag(s, 8, 0x3001);
     avio_wb32(pb, mxf->time_base.den);
     avio_wb32(pb, mxf->time_base.num);
 
     // write essence container ul
-    mxf_write_local_tag(pb, 16, 0x3004);
+    mxf_write_local_tag(s, 16, 0x3004);
     if (mxf->essence_container_count > 1)
         ul = multiple_desc_ul;
     else {
@@ -998,7 +885,7 @@  static void mxf_write_multi_descriptor(AVFormatContext *s)
     avio_write(pb, ul, 16);
 
     // write sub descriptor refs
-    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
+    mxf_write_local_tag(s, s->nb_streams * 16 + 8, 0x3F01);
     mxf_write_refs_count(pb, s->nb_streams);
     for (i = 0; i < s->nb_streams; i++)
         mxf_write_uuid(pb, SubDescriptor, i);
@@ -1015,13 +902,13 @@  static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI
     klv_encode_ber4_length(pb, 0);
     pos = avio_tell(pb);
 
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, SubDescriptor, st->index);
 
-    mxf_write_local_tag(pb, 4, 0x3006);
+    mxf_write_local_tag(s, 4, 0x3006);
     avio_wb32(pb, st->index+2);
 
-    mxf_write_local_tag(pb, 8, 0x3001);
+    mxf_write_local_tag(s, 8, 0x3001);
     if (s->oformat == &ff_mxf_d10_muxer) {
         avio_wb32(pb, mxf->time_base.den);
         avio_wb32(pb, mxf->time_base.num);
@@ -1036,7 +923,7 @@  static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI
         }
     }
 
-    mxf_write_local_tag(pb, 16, 0x3004);
+    mxf_write_local_tag(s, 16, 0x3004);
     avio_write(pb, *sc->container_ul, 16);
 
     return pos;
@@ -1088,43 +975,43 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     if (!stored_width)
         stored_width = (st->codecpar->width+15)/16*16;
 
-    mxf_write_local_tag(pb, 4, 0x3203);
+    mxf_write_local_tag(s, 4, 0x3203);
     avio_wb32(pb, stored_width);
 
-    mxf_write_local_tag(pb, 4, 0x3202);
+    mxf_write_local_tag(s, 4, 0x3202);
     avio_wb32(pb, stored_height>>sc->interlaced);
 
     if (s->oformat == &ff_mxf_d10_muxer) {
         //Stored F2 Offset
-        mxf_write_local_tag(pb, 4, 0x3216);
+        mxf_write_local_tag(s, 4, 0x3216);
         avio_wb32(pb, 0);
 
         //Image Start Offset
-        mxf_write_local_tag(pb, 4, 0x3213);
+        mxf_write_local_tag(s, 4, 0x3213);
         avio_wb32(pb, 0);
 
         //Image End Offset
-        mxf_write_local_tag(pb, 4, 0x3214);
+        mxf_write_local_tag(s, 4, 0x3214);
         avio_wb32(pb, 0);
     }
 
     //Sampled width
-    mxf_write_local_tag(pb, 4, 0x3205);
+    mxf_write_local_tag(s, 4, 0x3205);
     avio_wb32(pb, stored_width);
 
     //Samples height
-    mxf_write_local_tag(pb, 4, 0x3204);
+    mxf_write_local_tag(s, 4, 0x3204);
     avio_wb32(pb, st->codecpar->height>>sc->interlaced);
 
     //Sampled X Offset
-    mxf_write_local_tag(pb, 4, 0x3206);
+    mxf_write_local_tag(s, 4, 0x3206);
     avio_wb32(pb, 0);
 
     //Sampled Y Offset
-    mxf_write_local_tag(pb, 4, 0x3207);
+    mxf_write_local_tag(s, 4, 0x3207);
     avio_wb32(pb, 0);
 
-    mxf_write_local_tag(pb, 4, 0x3209);
+    mxf_write_local_tag(s, 4, 0x3209);
     avio_wb32(pb, stored_width);
 
     if (st->codecpar->height == 608) // PAL + VBI
@@ -1134,41 +1021,41 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     else
         display_height = st->codecpar->height;
 
-    mxf_write_local_tag(pb, 4, 0x3208);
+    mxf_write_local_tag(s, 4, 0x3208);
     avio_wb32(pb, display_height>>sc->interlaced);
 
     // display X offset
-    mxf_write_local_tag(pb, 4, 0x320A);
+    mxf_write_local_tag(s, 4, 0x320A);
     avio_wb32(pb, 0);
 
     // display Y offset
-    mxf_write_local_tag(pb, 4, 0x320B);
+    mxf_write_local_tag(s, 4, 0x320B);
     avio_wb32(pb, (st->codecpar->height - display_height)>>sc->interlaced);
 
     if (sc->interlaced) {
         //Display F2 Offset
-        mxf_write_local_tag(pb, 4, 0x3217);
+        mxf_write_local_tag(s, 4, 0x3217);
         avio_wb32(pb, -((st->codecpar->height - display_height)&1));
     }
 
     // component depth
-    mxf_write_local_tag(pb, 4, 0x3301);
+    mxf_write_local_tag(s, 4, 0x3301);
     avio_wb32(pb, sc->component_depth);
 
     // horizontal subsampling
-    mxf_write_local_tag(pb, 4, 0x3302);
+    mxf_write_local_tag(s, 4, 0x3302);
     avio_wb32(pb, sc->h_chroma_sub_sample);
 
     // vertical subsampling
-    mxf_write_local_tag(pb, 4, 0x3308);
+    mxf_write_local_tag(s, 4, 0x3308);
     avio_wb32(pb, sc->v_chroma_sub_sample);
 
     // color siting
-    mxf_write_local_tag(pb, 1, 0x3303);
+    mxf_write_local_tag(s, 1, 0x3303);
     avio_w8(pb, sc->color_siting);
 
     // Padding Bits
-    mxf_write_local_tag(pb, 2, 0x3307);
+    mxf_write_local_tag(s, 2, 0x3307);
     avio_wb16(pb, 0);
 
     if (st->codecpar->color_range != AVCOL_RANGE_UNSPECIFIED) {
@@ -1180,21 +1067,21 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
             white = 235 << (sc->component_depth - 8);
             color = (14 << (sc->component_depth - 4)) + 1;
         }
-        mxf_write_local_tag(pb, 4, 0x3304);
+        mxf_write_local_tag(s, 4, 0x3304);
         avio_wb32(pb, black);
-        mxf_write_local_tag(pb, 4, 0x3305);
+        mxf_write_local_tag(s, 4, 0x3305);
         avio_wb32(pb, white);
-        mxf_write_local_tag(pb, 4, 0x3306);
+        mxf_write_local_tag(s, 4, 0x3306);
         avio_wb32(pb, color);
     }
 
     if (sc->signal_standard) {
-        mxf_write_local_tag(pb, 1, 0x3215);
+        mxf_write_local_tag(s, 1, 0x3215);
         avio_w8(pb, sc->signal_standard);
     }
 
     // frame layout
-    mxf_write_local_tag(pb, 1, 0x320C);
+    mxf_write_local_tag(s, 1, 0x320C);
     avio_w8(pb, sc->interlaced);
 
     // video line map
@@ -1214,32 +1101,32 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     }
 
 
-    mxf_write_local_tag(pb, 16, 0x320D);
+    mxf_write_local_tag(s, 16, 0x320D);
     avio_wb32(pb, 2);
     avio_wb32(pb, 4);
     avio_wb32(pb, f1);
     avio_wb32(pb, f2);
 
-    mxf_write_local_tag(pb, 8, 0x320E);
+    mxf_write_local_tag(s, 8, 0x320E);
     avio_wb32(pb, sc->aspect_ratio.num);
     avio_wb32(pb, sc->aspect_ratio.den);
 
     if (color_primaries_ul->uid[0]) {
-        mxf_write_local_tag(pb, 16, 0x3219);
+        mxf_write_local_tag(s, 16, 0x3219);
         avio_write(pb, color_primaries_ul->uid, 16);
     };
 
     if (color_trc_ul->uid[0]) {
-        mxf_write_local_tag(pb, 16, 0x3210);
+        mxf_write_local_tag(s, 16, 0x3210);
         avio_write(pb, color_trc_ul->uid, 16);
     };
 
     if (color_space_ul->uid[0]) {
-        mxf_write_local_tag(pb, 16, 0x321A);
+        mxf_write_local_tag(s, 16, 0x321A);
         avio_write(pb, color_space_ul->uid, 16);
     };
 
-    mxf_write_local_tag(pb, 16, 0x3201);
+    mxf_write_local_tag(s, 16, 0x3201);
     avio_write(pb, *sc->codec_ul, 16);
 
     // Mastering Display metadata
@@ -1247,23 +1134,23 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     if (side_data) {
         const AVMasteringDisplayMetadata *metadata = (const AVMasteringDisplayMetadata*)side_data;
         if (metadata->has_primaries) {
-            mxf_write_local_tag(pb, 12, ff_mxf_mastering_display_local_tags[0].local_tag);
+            mxf_write_local_tag(s, 12, 0x8301);
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][0]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][1]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][0]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][1]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][0]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][1]));
-            mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[1].local_tag);
+            mxf_write_local_tag(s, 4, 0x8302);
             avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[0]));
             avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[1]));
         } else {
             av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display primaries. Missing data.\n");
         }
         if (metadata->has_luminance) {
-            mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[2].local_tag);
+            mxf_write_local_tag(s, 4, 0x8303);
             avio_wb32(pb, rescale_mastering_luma(metadata->max_luminance));
-            mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[3].local_tag);
+            mxf_write_local_tag(s, 4, 0x8304);
             avio_wb32(pb, rescale_mastering_luma(metadata->min_luminance));
         } else {
             av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display luminances. Missing data.\n");
@@ -1271,13 +1158,13 @@  static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID
     }
 
     if (sc->interlaced && sc->field_dominance) {
-        mxf_write_local_tag(pb, 1, 0x3212);
+        mxf_write_local_tag(s, 1, 0x3212);
         avio_w8(pb, sc->field_dominance);
     }
 
     if (st->codecpar->codec_id == AV_CODEC_ID_H264 && !sc->avc_intra) {
         // write avc sub descriptor ref
-        mxf_write_local_tag(pb, 8 + 16, 0x8100);
+        mxf_write_local_tag(s, 8 + 16, 0x8100);
         mxf_write_refs_count(pb, 1);
         mxf_write_uuid(pb, AVCSubDescriptor, 0);
     }
@@ -1303,16 +1190,16 @@  static void mxf_write_avc_subdesc(AVFormatContext *s, AVStream *st)
     klv_encode_ber4_length(pb, 0);
     pos = avio_tell(pb);
 
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, AVCSubDescriptor, 0);
 
-    mxf_write_local_tag(pb, 1, 0x8200);
+    mxf_write_local_tag(s, 1, 0x8200);
     avio_w8(pb, 0xFF); // AVC Decoding Delay, unknown
 
-    mxf_write_local_tag(pb, 1, 0x8201);
+    mxf_write_local_tag(s, 1, 0x8201);
     avio_w8(pb, st->codecpar->profile); // AVC Profile
 
-    mxf_write_local_tag(pb, 1, 0x8202);
+    mxf_write_local_tag(s, 1, 0x8202);
     avio_w8(pb, st->codecpar->level); // AVC Level
 
     mxf_update_klv_size(s->pb, pos);
@@ -1355,29 +1242,29 @@  static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
 
     if (st->codecpar->codec_id != AV_CODEC_ID_H264) {
         // bit rate
-        mxf_write_local_tag(pb, 4, 0x8000);
+        mxf_write_local_tag(s, 4, 0x8000);
         avio_wb32(pb, sc->video_bit_rate);
 
         // profile and level
-        mxf_write_local_tag(pb, 1, 0x8007);
+        mxf_write_local_tag(s, 1, 0x8007);
         if (!st->codecpar->profile)
             profile_and_level |= 0x80; // escape bit
         avio_w8(pb, profile_and_level);
 
         // low delay
-        mxf_write_local_tag(pb, 1, 0x8003);
+        mxf_write_local_tag(s, 1, 0x8003);
         avio_w8(pb, sc->low_delay);
 
         // closed gop
-        mxf_write_local_tag(pb, 1, 0x8004);
+        mxf_write_local_tag(s, 1, 0x8004);
         avio_w8(pb, sc->seq_closed_gop);
 
         // max gop
-        mxf_write_local_tag(pb, 2, 0x8006);
+        mxf_write_local_tag(s, 2, 0x8006);
         avio_wb16(pb, sc->max_gop);
 
         // b picture count
-        mxf_write_local_tag(pb, 2, 0x8008);
+        mxf_write_local_tag(s, 2, 0x8008);
         avio_wb16(pb, sc->b_picture_count);
     }
 
@@ -1392,25 +1279,25 @@  static int64_t mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st,
     int64_t pos = mxf_write_generic_desc(s, st, key);
 
     if (s->oformat == &ff_mxf_opatom_muxer) {
-        mxf_write_local_tag(pb, 8, 0x3002);
+        mxf_write_local_tag(s, 8, 0x3002);
         avio_wb64(pb, mxf->body_offset / mxf->edit_unit_byte_count);
     }
 
     // audio locked
-    mxf_write_local_tag(pb, 1, 0x3D02);
+    mxf_write_local_tag(s, 1, 0x3D02);
     avio_w8(pb, 1);
 
     // write audio sampling rate
-    mxf_write_local_tag(pb, 8, 0x3D03);
+    mxf_write_local_tag(s, 8, 0x3D03);
     avio_wb32(pb, st->codecpar->sample_rate);
     avio_wb32(pb, 1);
 
     if (s->oformat == &ff_mxf_d10_muxer) {
-        mxf_write_local_tag(pb, 1, 0x3D04);
+        mxf_write_local_tag(s, 1, 0x3D04);
         avio_w8(pb, 0);
     }
 
-    mxf_write_local_tag(pb, 4, 0x3D07);
+    mxf_write_local_tag(s, 4, 0x3D07);
     if (mxf->channel_count == -1) {
         if (show_warnings && (s->oformat == &ff_mxf_d10_muxer) && (st->codecpar->channels != 4) && (st->codecpar->channels != 8))
             av_log(s, AV_LOG_WARNING, "the number of audio channels shall be 4 or 8 : the output will not comply to MXF D-10 specs, use -d10_channelcount to fix this\n");
@@ -1425,7 +1312,7 @@  static int64_t mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st,
         avio_wb32(pb, st->codecpar->channels);
     }
 
-    mxf_write_local_tag(pb, 4, 0x3D01);
+    mxf_write_local_tag(s, 4, 0x3D01);
     avio_wb32(pb, av_get_bits_per_sample(st->codecpar->codec_id));
 
     return pos;
@@ -1436,11 +1323,11 @@  static int64_t mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID
     AVIOContext *pb = s->pb;
     int64_t pos = mxf_write_generic_sound_common(s, st, key);
 
-    mxf_write_local_tag(pb, 2, 0x3D0A);
+    mxf_write_local_tag(s, 2, 0x3D0A);
     avio_wb16(pb, st->codecpar->block_align);
 
     // avg bytes per sec
-    mxf_write_local_tag(pb, 4, 0x3D09);
+    mxf_write_local_tag(s, 4, 0x3D09);
     avio_wb32(pb, st->codecpar->block_align*st->codecpar->sample_rate);
 
     return pos;
@@ -1480,14 +1367,14 @@  static int mxf_write_tagged_value(AVFormatContext *s, const char* name, const ch
     klv_encode_ber_length(pb, 24 + name_size + indirect_value_size);
 
     // write instance UID
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count);
 
     // write name
-    mxf_write_local_tag_utf16(pb, 0x5001, name); // Name
+    mxf_write_local_tag_utf16(s, 0x5001, name); // Name
 
     // write indirect value
-    mxf_write_local_tag(pb, indirect_value_size, 0x5003);
+    mxf_write_local_tag(s, indirect_value_size, 0x5003);
     avio_write(pb, mxf_indirect_value_utf16le, 17);
     avio_put_str16le(pb, value);
 
@@ -1534,30 +1421,30 @@  static void mxf_write_package(AVFormatContext *s, MXFPackage *package)
     }
 
     // write uid
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, package->type, package->instance);
     av_log(s, AV_LOG_DEBUG, "package type:%d\n", package->type);
     PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
 
     // write package umid
-    mxf_write_local_tag(pb, 32, 0x4401);
+    mxf_write_local_tag(s, 32, 0x4401);
     mxf_write_umid(s, package->instance);
     PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
 
     // package name
     if (name_size)
-        mxf_write_local_tag_utf16(pb, 0x4402, package->name);
+        mxf_write_local_tag_utf16(s, 0x4402, package->name);
 
     // package creation date
-    mxf_write_local_tag(pb, 8, 0x4405);
+    mxf_write_local_tag(s, 8, 0x4405);
     avio_wb64(pb, mxf->timestamp);
 
     // package modified date
-    mxf_write_local_tag(pb, 8, 0x4404);
+    mxf_write_local_tag(s, 8, 0x4404);
     avio_wb64(pb, mxf->timestamp);
 
     // write track refs
-    mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
+    mxf_write_local_tag(s, track_count*16 + 8, 0x4403);
     mxf_write_refs_count(pb, track_count);
     // these are the uuids of the tracks the will be written in mxf_write_track
     for (i = 0; i < track_count; i++)
@@ -1565,7 +1452,7 @@  static void mxf_write_package(AVFormatContext *s, MXFPackage *package)
 
     // write user comment refs
     if (mxf->store_user_comments) {
-        mxf_write_local_tag(pb, user_comment_count*16 + 8, 0x4406);
+        mxf_write_local_tag(s, user_comment_count*16 + 8, 0x4406);
         mxf_write_refs_count(pb, user_comment_count);
         for (i = 0; i < user_comment_count; i++)
             mxf_write_uuid(pb, TaggedValue, mxf->tagged_value_count - user_comment_count + i);
@@ -1573,14 +1460,14 @@  static void mxf_write_package(AVFormatContext *s, MXFPackage *package)
 
     // write multiple descriptor reference
     if (package->type == SourcePackage && package->instance == 1) {
-        mxf_write_local_tag(pb, 16, 0x4701);
+        mxf_write_local_tag(s, 16, 0x4701);
         if (s->nb_streams > 1) {
             mxf_write_uuid(pb, MultipleDescriptor, 0);
             mxf_write_multi_descriptor(s);
         } else
             mxf_write_uuid(pb, SubDescriptor, 0);
     } else if (package->type == SourcePackage && package->instance == 2) {
-        mxf_write_local_tag(pb, 16, 0x4701);
+        mxf_write_local_tag(s, 16, 0x4701);
         mxf_write_uuid(pb, TapeDescriptor, 0);
         mxf_write_tape_descriptor(s);
     }
@@ -1620,16 +1507,16 @@  static int mxf_write_essence_container_data(AVFormatContext *s)
     mxf_write_metadata_key(pb, 0x012300);
     klv_encode_ber_length(pb, 72);
 
-    mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID
+    mxf_write_local_tag(s, 16, 0x3C0A); // Instance UID
     mxf_write_uuid(pb, EssenceContainerData, 0);
 
-    mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID
+    mxf_write_local_tag(s, 32, 0x2701); // Linked Package UID
     mxf_write_umid(s, 1);
 
-    mxf_write_local_tag(pb, 4, 0x3F07); // BodySID
+    mxf_write_local_tag(s, 4, 0x3F07); // BodySID
     avio_wb32(pb, 1);
 
-    mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID
+    mxf_write_local_tag(s, 4, 0x3F06); // IndexSID
     avio_wb32(pb, 2);
 
     return 0;
@@ -1714,43 +1601,43 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
     pos = avio_tell(pb);
 
     // instance id
-    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_local_tag(s, 16, 0x3C0A);
     mxf_write_uuid(pb, IndexTableSegment, 0);
 
     // index edit rate
-    mxf_write_local_tag(pb, 8, 0x3F0B);
+    mxf_write_local_tag(s, 8, 0x3F0B);
     avio_wb32(pb, mxf->time_base.den);
     avio_wb32(pb, mxf->time_base.num);
 
     // index start position
-    mxf_write_local_tag(pb, 8, 0x3F0C);
+    mxf_write_local_tag(s, 8, 0x3F0C);
     avio_wb64(pb, mxf->last_indexed_edit_unit);
 
     // index duration
-    mxf_write_local_tag(pb, 8, 0x3F0D);
+    mxf_write_local_tag(s, 8, 0x3F0D);
     if (mxf->edit_unit_byte_count)
         avio_wb64(pb, 0); // index table covers whole container
     else
         avio_wb64(pb, mxf->edit_units_count);
 
     // edit unit byte count
-    mxf_write_local_tag(pb, 4, 0x3F05);
+    mxf_write_local_tag(s, 4, 0x3F05);
     avio_wb32(pb, mxf->edit_unit_byte_count);
 
     // index sid
-    mxf_write_local_tag(pb, 4, 0x3F06);
+    mxf_write_local_tag(s, 4, 0x3F06);
     avio_wb32(pb, 2);
 
     // body sid
-    mxf_write_local_tag(pb, 4, 0x3F07);
+    mxf_write_local_tag(s, 4, 0x3F07);
     avio_wb32(pb, 1);
 
     // real slice count - 1
-    mxf_write_local_tag(pb, 1, 0x3F08);
+    mxf_write_local_tag(s, 1, 0x3F08);
     avio_w8(pb, !mxf->edit_unit_byte_count); // only one slice for CBR
 
     // delta entry array
-    mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
+    mxf_write_local_tag(s, 8 + (s->nb_streams+1)*6, 0x3F09);
     avio_wb32(pb, s->nb_streams+1); // num of entries
     avio_wb32(pb, 6);               // size of one entry
     // write system item delta entry
@@ -1782,7 +1669,7 @@  static void mxf_write_index_table_segment(AVFormatContext *s)
 
     if (!mxf->edit_unit_byte_count) {
         MXFStreamContext *sc = s->streams[0]->priv_data;
-        mxf_write_local_tag(pb, 8 + mxf->edit_units_count*15, 0x3F0A);
+        mxf_write_local_tag(s, 8 + mxf->edit_units_count*15, 0x3F0A);
         avio_wb32(pb, mxf->edit_units_count);  // num of entries
         avio_wb32(pb, 15);  // size of one entry