[FFmpeg-soc] MXF muxer version 0.0.2

zhentan feng spyfeng at gmail.com
Sun Aug 17 18:32:12 CEST 2008


Hi

2008/8/17 Michael Niedermayer <michaelni at gmx.at>

> On Sun, Aug 17, 2008 at 11:27:41AM +0800, zhentan feng wrote:
> > Hi
> >
> > 2008/8/17 Michael Niedermayer <michaelni at gmx.at>
> >
> > > On Sat, Aug 16, 2008 at 10:50:12PM +0800, zhentan feng wrote:
> [...]
> > > > +static int mxf_write_track(AVFormatContext *s, KLVPacket *klv, int
> > > stream_index, enum MXFMetadataSetType type)
> > > > +{
> > > > +    ByteIOContext *pb = s->pb;
> > > > +    AVStream *st;
> > > > +    MXFStreamContext *sc;
> > > > +    const MXFCodecUL *element;
> > > > +    int i = 0;
> > > > +    int
> > > track_number_sign[sizeof(mxf_essence_element_key)/sizeof(MXFCodecUL)] =
> { 0
> > > };
> > > > +
> > > > +    AV_WB24(klv->key + 13, 0x013b00);
> > > > +
> > > > +    put_buffer(pb, klv->key, 16);
> > > > +    klv_encode_ber_length(pb, 80);
> > > > +
> > > > +    st = s->streams[stream_index];
> > > > +    sc = st->priv_data;
> > > > +
> > > > +    // write track uid
> > > > +    mxf_write_local_tag(pb, 16, 0x3C0A);
> > > > +    mxf_write_uuid(pb, Track * type, stream_index);
> > > > +#ifdef DEBUG
> > > > +    PRINT_KEY(s, "track key", klv->key);
> > > > +    PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
> > > > +#endif
> > > > +    // write track id
> > > > +    mxf_write_local_tag(pb, 4, 0x4801);
> > > > +    put_be32(pb, stream_index);
> > > > +
> > > > +    mxf_write_local_tag(pb, 4, 0x4804);
> > > > +    if (type != MaterialPackage) {
> > > > +        for (element = mxf_essence_element_key; element->id !=
> > > CODEC_ID_NONE; element++) {
> > > > +            if (st->codec->codec_id== element->id) {
> > > > +                // write track number
> > > > +                put_buffer(pb, element->uid + 12, 3);
> > > > +                put_byte(pb, element->uid[15] +
> track_number_sign[i]);
> > >
> > > track_number_sign will always be 0 here, i suspect this is not intended
> ...
> > >
> >
> > in material package, the track number is always 0 .
> > but in source package,
> > according to specs, track number should increment for same essence
> element
> > key.
> > we use track_number_sign[] in order to record the times of same present
> of
> > the essence element key.
>
> and does it work? That is is it for source package ever non 0 ?
>
no.
because the test.mpg is just 2 streams, which have not same essence element
keyin all streams.
so the track_number_sign[] won't increment.
Do you mean remvoe it for now?

>
>
> >
> >
> > >
> > >
> > > [...]
> > >
> > > > +    if (type == SourcePackage) {
> > > > +        // write source package uid, end of the reference
> > > > +        mxf_write_local_tag(pb, 32, 0x1101);
> > > [...]
> > > > +    } else {
> > > > +        mxf_write_local_tag(pb, 32, 0x1101);
> > >
> > > can be factored out
> > >
> > > [...]
> > >
> > > > +static int mxf_write_mpeg_video_desc(AVFormatContext *s, const
> > > MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
> > > > +{
> > > > +    ByteIOContext *pb = s->pb;
> > > > +    AVStream *st;
> > > > +
> > > > +    st = s->streams[stream_index];
> > > > +
> > > > +    put_buffer(pb, desc_tbl->key, 16);
> > > > +    klv_encode_ber_length(pb, 96);
> > > > +
> > > > +    mxf_write_local_tag(pb, 16, 0x3C0A);
> > > > +    mxf_write_uuid(pb, SubDescriptor, stream_index);
> > > > +
> > > > +    mxf_write_local_tag(pb, 4, 0x3006);
> > > > +    put_be32(pb, stream_index);
> > > [...]
> > > > +static int mxf_write_wav_desc(AVFormatContext *s, const
> > > MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
> > > > +{
> > > > +    ByteIOContext *pb = s->pb;
> > > > +    AVStream *st;
> > > > +
> > > > +    st = s->streams[stream_index];
> > > > +
> > > > +    put_buffer(pb, desc_tbl->key, 16);
> > > > +    klv_encode_ber_length(pb, 96);
> > > > +
> > > > +    mxf_write_local_tag(pb, 16, 0x3C0A);
> > > > +    mxf_write_uuid(pb, SubDescriptor, stream_index);
> > > > +
> > > > +    mxf_write_local_tag(pb, 4, 0x3006);
> > > > +    put_be32(pb, stream_index);
> > >
> > > duplicate
> > >
> > >
> > > [...]
> > >
> > > > +    for (i = 0; i < s->nb_streams; i++) {
> > > > +        sc = s->streams[i]->priv_data;
> > > > +    }
> > > > +    return ret;
> > >
> > > the loop does nothing
> > >
> > >
> > > [...]
> > >
> > > > +static int mxf_add_essence_container_ul(MXFContext *mxf, const
> > > MXFCodecUL *codec_ul)
> > > > +{
> > > > +    mxf->essence_container_uls =
> av_realloc(mxf->essence_container_uls,
> > > (mxf->essence_container_count + 1) * 16);
> > > > +    if (!mxf->essence_container_uls)
> > > > +        return AVERROR(ENOMEM);
> > > > +    memcpy(mxf->essence_container_uls[mxf->essence_container_count],
> > > codec_ul->uid, 16);
> > > > +    mxf->essence_container_count++;
> > > > +    return mxf->essence_container_count;
> > > > +}
> > > > +
> > > > +static int mxf_build_essence_container_refs(AVFormatContext *s)
> > > > +{
> > > > +    MXFContext *mxf = s->priv_data;
> > > > +    AVStream *st;
> > > > +    int i;
> > > > +    const MXFCodecUL *codec_ul = NULL;
> > > > +
> > > > +    for (codec_ul = ff_mxf_essence_container_uls; codec_ul->id;
> > > codec_ul++) {
> > > > +        for (i = 0; i < s->nb_streams; i++) {
> > > > +            st = s->streams[i];
> > > > +            if (st->codec->codec_id == codec_ul->id) {
> > >
> > > > +                if (mxf_add_essence_container_ul(mxf, codec_ul) < 0
> )
> > > > +                    return -1;
> > >
> > > this should be put_buffer() and
> > > mxf_build_essence_container_refs should be called when the list needs
> > > to be stored.
> > >
> >
> > hmm, this issue we have disscussed in ver 0.0.1.
> >
> > I said : "
> > there are at least three times to write the references in
> > mxf_write_preface_set(), mxf_write_header/footer_partition().
> >   so, if do not stroed in mem, we should check it for each time.
> > "
> >
> > and you said :
> > "yes"
> >
> > do you mean my suggestion is ok or I should modify the code?
>
> i meant
> yes it is done 3 times ...
> my awnser was not clear iam aware of that :(
>
>
> > Becasue several palce will use it, can't we prepared them in advace?
>
> I think its simpler to just call the function and build and store
> 3 times than build once and store 3 times because this avoids the
> realloc() + add to table + free table stuff.
> Its not a problem speedwise if this code is run 3 times per file.
>
>
ok , I agree with you :)


> >
> >
> > >
> > > [...]
> > >
> > > > @@ -87,6 +930,41 @@
> > > >      return 0;
> > > >  }
> > > >
> > > > +static int mxf_update_header_partition(AVFormatContext *s, int64_t
> > > footer_partition_offset)
> > > > +{
> > > > +    MXFContext *mxf = s->priv_data;
> > > > +    ByteIOContext *pb = s->pb;
> > > > +
> > > > +    if (!url_is_streamed(s->pb)) {
> > > > +        url_fseek(pb, mxf->header_byte_count_offset, SEEK_SET);
> > > > +        put_be64(pb, mxf->header_byte_count);
> > > > +        put_flush_packet(pb);
> > > > +
> > > > +        url_fseek(pb, mxf->header_footer_partition_offset,
> SEEK_SET);
> > > > +        put_be64(pb, footer_partition_offset);
> > > > +        put_flush_packet(pb);
> > >
> > > > +    } else {
> > > > +        av_log(s, AV_LOG_ERROR, "update header partition failed, non
> > > streamble out put\n");
> > > > +        return -1;
> > > > +    }
> > >
> > > we should support streamed files, not fail for them. I belive the
> footer
> > > partition is optional and when there is none also no pointer needs to
> point
> > > to one.
> >
> >
> > 1)I understand like this:
> > when files is not streamed, we can seek by offset freely,
> > and when files is streamed, we can not seek.
> >
> > But if cannot, when wrting the header partition, we can not get the
> correct
> > value until end of the file, so how to update the correct field in header
> > partition?
> >
>
> > 2) according to s377m, footer partition is not optional.
>
> s377m says:
> "An MXF File shall be divided into a number of partitions:
>      one Header Partition which shall be followed by
>      zero or more Body Partitions, the last of which shall be followed by
>
>      zero or one Footer Partition
>      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> "
>
>
It's my fault, I missed this improtant rule.
should we remove footer partition?
btw: it will be very helpful to hear some suggestion from Baptiste.


>
> >
> > "Where present, a Footer Partition shall be located at the end of the
> file.
> > It shall comprise a Footer Partition Pack
> > followed optionally by the Header Metadata, and optionally by Index Table
> > segments. The Footer Partition may
> > optionally be followed by a Random Index Pack. "
>
> "where present" means "if there is" so it says
> "if there is a footer partition then it should be at the end of the file"
>
> baptiste probably can say more about all this, but i think he isnt here
> ATM?
>
>
> >
> > 3) I run ./ffmpeg -i test.mpg test.mxf
> > it generate unstreamed files, and how to generated streamed files?
>
> ./ffmpeg -i test.mpg -f mxf - >test.mxf
>
> I mention again the former issue which you seems missed here:

when files is not streamed, we can seek by offset freely,
 and when files is streamed, we can not seek.

 But if cannot, when wrting the header partition, we can not get the correct
 value until end of the file, so we will write a default value and mark the
position then update later.

so, if streamed file muxed , any solution about this?

thanks very much.
-- 
Best wishes~



More information about the FFmpeg-soc mailing list