[FFmpeg-soc] MXF muxer version 0.0.2
Michael Niedermayer
michaelni at gmx.at
Sun Aug 17 15:52:56 CEST 2008
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 ?
>
>
> >
> >
> > [...]
> >
> > > + 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.
>
>
> >
> > [...]
> >
> > > @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^
"
>
> "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
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The worst form of inequality is to try to make unequal things equal.
-- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20080817/10e954aa/attachment.pgp>
More information about the FFmpeg-soc
mailing list