On 11/1/2016 8:21 PM, Matthew Gregan wrote: > At 2016-11-01T00:56:45-0300, James Almer wrote: >> > The muxer gets the extradata as created by the encoder only during init(). >> > Even if the encoder changes it in any way afterwards, it will never make >> > it to the muxer. That's why packet side data is used for this. >> > >> > The reason the encoder used the AVCodecContext extradata to store the >> > updated Streaminfo before creating the packet side data is most likely >> > because it was an already allocated buffer. Technically, it's not the >> > "proper" thing to do, but it also doesn't seem to make a difference. > Makes sense, thanks for the explanation. > > Updated patch attached with the following changes: > - Uses libavcodec/flac.h for the FLAC_STREAMINFO_SIZE and > FLAC_METADATA_TYPE_STREAMINFO definitions, per the feedback on the demuxer > patch. > - Fixes the sample size in bits written to the 'fLaC' audio box. > Thanks to Vittorio Giovara for pointing this out. > > > 0001-Add-experimental-muxing-support-for-FLAC-in-ISO-BMFF.patch > > > From e08e1b5041a331d640d190c39c00bdc61e81243c Mon Sep 17 00:00:00 2001 > From: Matthew Gregan <kine...@flim.org> > Date: Thu, 20 Oct 2016 17:28:11 +1300 > Subject: [PATCH 1/2] Add experimental muxing support for FLAC in ISO BMFF > (MP4). > > Based on the draft spec at > https://git.xiph.org/?p=flac.git;a=blob;f=doc/isoflac.txt > > '-strict -2' is required to create files in this format. > > Signed-off-by: Matthew Gregan <kine...@flim.org> > --- > libavformat/isom.c | 2 ++ > libavformat/movenc.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 45 insertions(+), 3 deletions(-) > > diff --git a/libavformat/isom.c b/libavformat/isom.c > index ab79e22..aacbe43 100644 > --- a/libavformat/isom.c > +++ b/libavformat/isom.c > @@ -60,6 +60,7 @@ const AVCodecTag ff_mp4_obj_type[] = { > { AV_CODEC_ID_EAC3 , 0xA6 }, > { AV_CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */ > { AV_CODEC_ID_VP9 , 0xC0 }, /* nonstandard, update when there is > a standard value */ > + { AV_CODEC_ID_FLAC , 0xC1 }, /* nonstandard, update when there is > a standard value */ > { AV_CODEC_ID_TSCC2 , 0xD0 }, /* nonstandard, camtasia uses it */ > { AV_CODEC_ID_VORBIS , 0xDD }, /* nonstandard, gpac uses it */ > { AV_CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* nonstandard, see > unsupported-embedded-subs-2.mp4 */ > @@ -345,6 +346,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = { > { AV_CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') }, > { AV_CODEC_ID_EVRC, MKTAG('s', 'e', 'v', 'c') }, /* 3GPP2 */ > { AV_CODEC_ID_SMV, MKTAG('s', 's', 'm', 'v') }, /* 3GPP2 */ > + { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') }, /* > nonstandard */
This is enables muxing into mov, which bypasses the experimental check below since mov isn't MODE_MP4. > { AV_CODEC_ID_NONE, 0 }, > }; > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index 6228192..06f6dc6 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -33,6 +33,7 @@ > #include "avc.h" > #include "libavcodec/ac3_parser.h" > #include "libavcodec/dnxhddata.h" > +#include "libavcodec/flac.h" > #include "libavcodec/get_bits.h" > #include "libavcodec/put_bits.h" > #include "libavcodec/vc1_common.h" > @@ -654,6 +655,26 @@ static int mov_write_wfex_tag(AVFormatContext *s, > AVIOContext *pb, MOVTrack *tra > return update_size(pb, pos); > } > > +static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track) > +{ > + int64_t pos = avio_tell(pb); > + avio_wb32(pb, 0); > + ffio_wfourcc(pb, "dfLa"); > + avio_w8(pb, 0); /* version */ > + avio_wb24(pb, 0); /* flags */ > + > + /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */ > + if (track->par->extradata_size != FLAC_STREAMINFO_SIZE) > + return AVERROR_INVALIDDATA; > + > + /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them > available. */ > + avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* > LastMetadataBlockFlag << 7 | BlockType */ > + avio_wb24(pb, track->par->extradata_size); /* Length */ > + avio_write(pb, track->par->extradata, track->par->extradata_size); /* > BlockData[Length] */ > + > + return update_size(pb, pos); > +} > + > static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack > *track) > { > uint32_t layout_tag, bitmap; > @@ -963,8 +984,13 @@ static int mov_write_audio_tag(AVFormatContext *s, > AVIOContext *pb, MOVMuxContex > avio_wb16(pb, 16); > avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */ > } else { /* reserved for mp4/3gp */ > - avio_wb16(pb, 2); > - avio_wb16(pb, 16); > + if (track->par->codec_id == AV_CODEC_ID_FLAC) { > + avio_wb16(pb, track->par->channels); > + avio_wb16(pb, track->par->bits_per_raw_sample); > + } else { > + avio_wb16(pb, 2); > + avio_wb16(pb, 16); > + } > avio_wb16(pb, 0); > } > > @@ -1009,6 +1035,8 @@ static int mov_write_audio_tag(AVFormatContext *s, > AVIOContext *pb, MOVMuxContex > mov_write_extradata_tag(pb, track); > else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) > mov_write_wfex_tag(s, pb, track); > + else if (track->par->codec_id == AV_CODEC_ID_FLAC) > + mov_write_dfla_tag(pb, track); > else if (track->vos_len > 0) > mov_write_glbl_tag(pb, track); > > @@ -1177,6 +1205,7 @@ static int mp4_get_codec_tag(AVFormatContext *s, > MOVTrack *track) > else if (track->par->codec_id == AV_CODEC_ID_DIRAC) tag = > MKTAG('d','r','a','c'); > else if (track->par->codec_id == AV_CODEC_ID_MOV_TEXT) tag = > MKTAG('t','x','3','g'); > else if (track->par->codec_id == AV_CODEC_ID_VC1) tag = > MKTAG('v','c','-','1'); > + else if (track->par->codec_id == AV_CODEC_ID_FLAC) tag = > MKTAG('f','L','a','C'); > else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) tag = > MKTAG('m','p','4','v'); > else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) tag = > MKTAG('m','p','4','a'); > else if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE) tag = > MKTAG('m','p','4','s'); > @@ -5019,7 +5048,8 @@ static int mov_write_single_packet(AVFormatContext *s, > AVPacket *pkt) > trk->start_cts = 0; > } > > - if (trk->par->codec_id == AV_CODEC_ID_MP4ALS) { > + if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || > + trk->par->codec_id == AV_CODEC_ID_FLAC) { > int side_size = 0; > uint8_t *side = av_packet_get_side_data(pkt, > AV_PKT_DATA_NEW_EXTRADATA, &side_size); > if (side && side_size > 0 && (side_size != > par->extradata_size || memcmp(side, par->extradata, side_size))) { > @@ -5733,6 +5763,16 @@ static int mov_init(AVFormatContext *s) > i, track->par->sample_rate); > } > } > + if (track->mode == MODE_MP4 && > + track->par->codec_id == AV_CODEC_ID_FLAC) { > + if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { > + av_log(s, AV_LOG_ERROR, > + "FLAC in MP4 support is experimental, add " > + "'-strict %d' if you want to use it.\n", > + FF_COMPLIANCE_EXPERIMENTAL); > + return AVERROR_EXPERIMENTAL; > + } > + } > } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { > track->timescale = st->time_base.den; > } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { > -- 2.10.1 > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel