Message ID | 20200520061021.368-1-martin@martin.st |
---|---|
State | Accepted |
Headers | show |
Series | [FFmpeg-devel,v2] movenc: Use first H264/HEVC frame as extradata, if it is missing | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
On 5/20/2020 3:10 AM, Martin Storsjö wrote: > Sticking a full frame in the extradata works, as the code for writing > the avcC/hvcC extracts the relevant parameter set NAL units - provided > that they actually exist in the frame. > > Some encoders don't provide split out extradata directly on init (or > at all). In particular, the MediaFoundation encoder wrapper doesn't > always (depending on the actual encoder device) - this is the case for > Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). > > This only works for cases where the moov hasn't already been written > (e.g. when not writing fragmented mp4 with empty_moov, unless using > the delay_moov option). > > Signed-off-by: Martin Storsjö <martin@martin.st> > --- > libavformat/movenc.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index 27d7621e27..6a85440a3f 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) > > if ((par->codec_id == AV_CODEC_ID_DNXHD || > par->codec_id == AV_CODEC_ID_TRUEHD || > - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { > + par->codec_id == AV_CODEC_ID_AC3 || > + par->codec_id == AV_CODEC_ID_H264 || > + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { nit: You could add the h264 and hevc lines above the truehd one, and get a smaller diff. LGTM either way. > /* copy frame to create needed atoms */ > trk->vos_len = size; > trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); >
On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: > Sticking a full frame in the extradata works, as the code for writing > the avcC/hvcC extracts the relevant parameter set NAL units - provided > that they actually exist in the frame. > > Some encoders don't provide split out extradata directly on init (or > at all). In particular, the MediaFoundation encoder wrapper doesn't > always (depending on the actual encoder device) - this is the case for > Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). > > This only works for cases where the moov hasn't already been written > (e.g. when not writing fragmented mp4 with empty_moov, unless using > the delay_moov option). > > Signed-off-by: Martin Storsjö <martin@martin.st> > --- > libavformat/movenc.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index 27d7621e27..6a85440a3f 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) > > if ((par->codec_id == AV_CODEC_ID_DNXHD || > par->codec_id == AV_CODEC_ID_TRUEHD || > - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { > + par->codec_id == AV_CODEC_ID_AC3 || > + par->codec_id == AV_CODEC_ID_H264 || > + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { > /* copy frame to create needed atoms */ > trk->vos_len = size; > trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); This changes avcintra output example testcase: ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf scale=1920:1080 -an file.mov thx [...]
On Thu, 21 May 2020, Michael Niedermayer wrote: > On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >> Sticking a full frame in the extradata works, as the code for writing >> the avcC/hvcC extracts the relevant parameter set NAL units - provided >> that they actually exist in the frame. >> >> Some encoders don't provide split out extradata directly on init (or >> at all). In particular, the MediaFoundation encoder wrapper doesn't >> always (depending on the actual encoder device) - this is the case for >> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >> >> This only works for cases where the moov hasn't already been written >> (e.g. when not writing fragmented mp4 with empty_moov, unless using >> the delay_moov option). >> >> Signed-off-by: Martin Storsjö <martin@martin.st> >> --- >> libavformat/movenc.c | 4 +++- >> 1 file changed, 3 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >> index 27d7621e27..6a85440a3f 100644 >> --- a/libavformat/movenc.c >> +++ b/libavformat/movenc.c >> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) >> >> if ((par->codec_id == AV_CODEC_ID_DNXHD || >> par->codec_id == AV_CODEC_ID_TRUEHD || >> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >> + par->codec_id == AV_CODEC_ID_AC3 || >> + par->codec_id == AV_CODEC_ID_H264 || >> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >> /* copy frame to create needed atoms */ >> trk->vos_len = size; >> trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); > > This changes avcintra output > > example testcase: > ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf scale=1920:1080 -an file.mov Right, if explicitly disabling global headers on the encoder, this will end up putting them back. Any ideas on what the best path forward would be? // Martin
Martin Storsjö: > On Thu, 21 May 2020, Michael Niedermayer wrote: > >> On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >>> Sticking a full frame in the extradata works, as the code for writing >>> the avcC/hvcC extracts the relevant parameter set NAL units - provided >>> that they actually exist in the frame. >>> >>> Some encoders don't provide split out extradata directly on init (or >>> at all). In particular, the MediaFoundation encoder wrapper doesn't >>> always (depending on the actual encoder device) - this is the case for >>> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >>> >>> This only works for cases where the moov hasn't already been written >>> (e.g. when not writing fragmented mp4 with empty_moov, unless using >>> the delay_moov option). >>> >>> Signed-off-by: Martin Storsjö <martin@martin.st> >>> --- >>> libavformat/movenc.c | 4 +++- >>> 1 file changed, 3 insertions(+), 1 deletion(-) >>> >>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >>> index 27d7621e27..6a85440a3f 100644 >>> --- a/libavformat/movenc.c >>> +++ b/libavformat/movenc.c >>> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, >>> AVPacket *pkt) >>> >>> if ((par->codec_id == AV_CODEC_ID_DNXHD || >>> par->codec_id == AV_CODEC_ID_TRUEHD || >>> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >>> + par->codec_id == AV_CODEC_ID_AC3 || >>> + par->codec_id == AV_CODEC_ID_H264 || >>> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >>> /* copy frame to create needed atoms */ >>> trk->vos_len = size; >>> trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); >> >> This changes avcintra output >> >> example testcase: >> ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr >> -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf >> scale=1920:1080 -an file.mov > > Right, if explicitly disabling global headers on the encoder, this will > end up putting them back. > > Any ideas on what the best path forward would be? > > // Martin If I am not mistaken, then the sample created by the above command line is annex b in mp4 which is against the spec. So changing the output is nothing to worry about. - Andreas
On Thu, 21 May 2020, Andreas Rheinhardt wrote: > Martin Storsjö: >> On Thu, 21 May 2020, Michael Niedermayer wrote: >> >>> On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >>>> Sticking a full frame in the extradata works, as the code for writing >>>> the avcC/hvcC extracts the relevant parameter set NAL units - provided >>>> that they actually exist in the frame. >>>> >>>> Some encoders don't provide split out extradata directly on init (or >>>> at all). In particular, the MediaFoundation encoder wrapper doesn't >>>> always (depending on the actual encoder device) - this is the case for >>>> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >>>> >>>> This only works for cases where the moov hasn't already been written >>>> (e.g. when not writing fragmented mp4 with empty_moov, unless using >>>> the delay_moov option). >>>> >>>> Signed-off-by: Martin Storsjö <martin@martin.st> >>>> --- >>>> libavformat/movenc.c | 4 +++- >>>> 1 file changed, 3 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >>>> index 27d7621e27..6a85440a3f 100644 >>>> --- a/libavformat/movenc.c >>>> +++ b/libavformat/movenc.c >>>> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, >>>> AVPacket *pkt) >>>> >>>> if ((par->codec_id == AV_CODEC_ID_DNXHD || >>>> par->codec_id == AV_CODEC_ID_TRUEHD || >>>> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >>>> + par->codec_id == AV_CODEC_ID_AC3 || >>>> + par->codec_id == AV_CODEC_ID_H264 || >>>> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >>>> /* copy frame to create needed atoms */ >>>> trk->vos_len = size; >>>> trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); >>> >>> This changes avcintra output >>> >>> example testcase: >>> ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr >>> -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf >>> scale=1920:1080 -an file.mov >> >> Right, if explicitly disabling global headers on the encoder, this will >> end up putting them back. >> >> Any ideas on what the best path forward would be? >> >> // Martin > > If I am not mistaken, then the sample created by the above command line > is annex b in mp4 which is against the spec. So changing the output is > nothing to worry about. No, the mov muxer does rewrite the bitstream from annex b to mp4 form, regardless of whether there was any broken out parameter sets in the extradata. I presume the intent is that with libx264, normally you'd have parameter sets prepended on each IDR frame. If the global headers flag is set, the parameter sets are placed in extradata and not prepended on each frame. And I guess it's needed for the AVC intra spec to have the parameter sets included in each frame, instead of tucked away in the avc1 global header. I guess the main question is, does it matter and/or does it break anything, if we now include parameter sets in avc1 like a normal mov/mp4, for AVC intra, while the parameter sets still are available within the frames as well. // Martin
Martin Storsjö: > On Thu, 21 May 2020, Andreas Rheinhardt wrote: > >> Martin Storsjö: >>> On Thu, 21 May 2020, Michael Niedermayer wrote: >>> >>>> On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >>>>> Sticking a full frame in the extradata works, as the code for writing >>>>> the avcC/hvcC extracts the relevant parameter set NAL units - provided >>>>> that they actually exist in the frame. >>>>> >>>>> Some encoders don't provide split out extradata directly on init (or >>>>> at all). In particular, the MediaFoundation encoder wrapper doesn't >>>>> always (depending on the actual encoder device) - this is the case for >>>>> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >>>>> >>>>> This only works for cases where the moov hasn't already been written >>>>> (e.g. when not writing fragmented mp4 with empty_moov, unless using >>>>> the delay_moov option). >>>>> >>>>> Signed-off-by: Martin Storsjö <martin@martin.st> >>>>> --- >>>>> libavformat/movenc.c | 4 +++- >>>>> 1 file changed, 3 insertions(+), 1 deletion(-) >>>>> >>>>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >>>>> index 27d7621e27..6a85440a3f 100644 >>>>> --- a/libavformat/movenc.c >>>>> +++ b/libavformat/movenc.c >>>>> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, >>>>> AVPacket *pkt) >>>>> >>>>> if ((par->codec_id == AV_CODEC_ID_DNXHD || >>>>> par->codec_id == AV_CODEC_ID_TRUEHD || >>>>> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >>>>> + par->codec_id == AV_CODEC_ID_AC3 || >>>>> + par->codec_id == AV_CODEC_ID_H264 || >>>>> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >>>>> /* copy frame to create needed atoms */ >>>>> trk->vos_len = size; >>>>> trk->vos_data = av_malloc(size + >>>>> AV_INPUT_BUFFER_PADDING_SIZE); >>>> >>>> This changes avcintra output >>>> >>>> example testcase: >>>> ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr >>>> -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf >>>> scale=1920:1080 -an file.mov >>> >>> Right, if explicitly disabling global headers on the encoder, this will >>> end up putting them back. >>> >>> Any ideas on what the best path forward would be? >>> >>> // Martin >> >> If I am not mistaken, then the sample created by the above command line >> is annex b in mp4 which is against the spec. So changing the output is >> nothing to worry about. > > No, the mov muxer does rewrite the bitstream from annex b to mp4 form, > regardless of whether there was any broken out parameter sets in the > extradata. > Sure about that? The check used is if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) { If trk->vos_len is zero (which is a requirement for your patch to have any effect), no reformatting will be performed. - Andreas
On Thu, 21 May 2020, Andreas Rheinhardt wrote: > Martin Storsjö: >> On Thu, 21 May 2020, Andreas Rheinhardt wrote: >> >>> Martin Storsjö: >>>> On Thu, 21 May 2020, Michael Niedermayer wrote: >>>> >>>>> On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >>>>>> Sticking a full frame in the extradata works, as the code for writing >>>>>> the avcC/hvcC extracts the relevant parameter set NAL units - provided >>>>>> that they actually exist in the frame. >>>>>> >>>>>> Some encoders don't provide split out extradata directly on init (or >>>>>> at all). In particular, the MediaFoundation encoder wrapper doesn't >>>>>> always (depending on the actual encoder device) - this is the case for >>>>>> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >>>>>> >>>>>> This only works for cases where the moov hasn't already been written >>>>>> (e.g. when not writing fragmented mp4 with empty_moov, unless using >>>>>> the delay_moov option). >>>>>> >>>>>> Signed-off-by: Martin Storsjö <martin@martin.st> >>>>>> --- >>>>>> libavformat/movenc.c | 4 +++- >>>>>> 1 file changed, 3 insertions(+), 1 deletion(-) >>>>>> >>>>>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >>>>>> index 27d7621e27..6a85440a3f 100644 >>>>>> --- a/libavformat/movenc.c >>>>>> +++ b/libavformat/movenc.c >>>>>> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, >>>>>> AVPacket *pkt) >>>>>> >>>>>> if ((par->codec_id == AV_CODEC_ID_DNXHD || >>>>>> par->codec_id == AV_CODEC_ID_TRUEHD || >>>>>> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >>>>>> + par->codec_id == AV_CODEC_ID_AC3 || >>>>>> + par->codec_id == AV_CODEC_ID_H264 || >>>>>> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >>>>>> /* copy frame to create needed atoms */ >>>>>> trk->vos_len = size; >>>>>> trk->vos_data = av_malloc(size + >>>>>> AV_INPUT_BUFFER_PADDING_SIZE); >>>>> >>>>> This changes avcintra output >>>>> >>>>> example testcase: >>>>> ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr >>>>> -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf >>>>> scale=1920:1080 -an file.mov >>>> >>>> Right, if explicitly disabling global headers on the encoder, this will >>>> end up putting them back. >>>> >>>> Any ideas on what the best path forward would be? >>>> >>>> // Martin >>> >>> If I am not mistaken, then the sample created by the above command line >>> is annex b in mp4 which is against the spec. So changing the output is >>> nothing to worry about. >> >> No, the mov muxer does rewrite the bitstream from annex b to mp4 form, >> regardless of whether there was any broken out parameter sets in the >> extradata. >> > Sure about that? The check used is > > if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && > *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) { > > If trk->vos_len is zero (which is a requirement for your patch to have > any effect), no reformatting will be performed. Oh, indeed, you're right. However wrong that is from the mov/mp4 point of view, it may very well be that AVC intra is supposed to be written like this in mov/mp4 files - but we'd need a word from somebody who actually knows that case. Hmm, and unfortunately, this check is further up in the function, than when creating the vos_data/vos_len from the frame, so the first frame doesn't end up converted correctly in my case... Will send a new patch to fix that. // Martin
On Thu, May 21, 2020 at 2:00 PM Martin Storsjö <martin@martin.st> wrote: > > Oh, indeed, you're right. > > However wrong that is from the mov/mp4 point of view, it may very well be > that AVC intra is supposed to be written like this in mov/mp4 files - but > we'd need a word from somebody who actually knows that case. > The best way to figure out if a user wants to do AVC Intra muxing would be to either a) require specific codec_tag/muxing mode be set by user or b) attempt to somehow properly check the actual bit stream within `mov_get_h264_codec_tag` to make the selection proper. Right now the system seems to base that if you are doing H.264, and have no codec_tag set already, then `mov_get_h264_codec_tag` attempts to set an AVC Intra codec_tag (which hits TAG_IS_AVCI), which then attempts to mux things in that proprietary way. Currently the check only checks for 10bit 4:2:0/4:2:2 or specific resolutions (which include 1080p and such). And I'm not sure if even the fallback there is a standard codec_tag, since it is not one of those I remember from 14496-15 (although my memory might just be bad). By default, and if the output got written with a standard 14496-15 etc codec_tag, then AVC intra muxing mode should not utilized. And just a note for the record, the logic in `mov_get_h264_codec_tag` seems to already be somewhat imperfect, as I've seen users attempting to encode 10bit H.264 normally into MOV, and one had to force a codec_tag to be avc1 for a non-broken file to be generated (as in, even FFmpeg itself couldn't read the file after muxing with the default selected codec_tag). Just my two cents, Jan
On Thu, 21 May 2020, Jan Ekström wrote: > On Thu, May 21, 2020 at 2:00 PM Martin Storsjö <martin@martin.st> wrote: >> >> Oh, indeed, you're right. >> >> However wrong that is from the mov/mp4 point of view, it may very well be >> that AVC intra is supposed to be written like this in mov/mp4 files - but >> we'd need a word from somebody who actually knows that case. >> > > The best way to figure out if a user wants to do AVC Intra muxing > would be to either a) require specific codec_tag/muxing mode be set by > user or b) attempt to somehow properly check the actual bit stream > within `mov_get_h264_codec_tag` to make the selection proper. Right > now the system seems to base that if you are doing H.264, and have no > codec_tag set already, then `mov_get_h264_codec_tag` attempts to set > an AVC Intra codec_tag (which hits TAG_IS_AVCI), which then attempts > to mux things in that proprietary way. Thanks for the insight into this case, that it really is intended to mux it this way. I hadn't known what TAG_IS_AVCI is really, but with that it should be easy to fix this case. // Martin
On Thu, 21 May 2020, Michael Niedermayer wrote: > On Wed, May 20, 2020 at 09:10:21AM +0300, Martin Storsjö wrote: >> Sticking a full frame in the extradata works, as the code for writing >> the avcC/hvcC extracts the relevant parameter set NAL units - provided >> that they actually exist in the frame. >> >> Some encoders don't provide split out extradata directly on init (or >> at all). In particular, the MediaFoundation encoder wrapper doesn't >> always (depending on the actual encoder device) - this is the case for >> Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). >> >> This only works for cases where the moov hasn't already been written >> (e.g. when not writing fragmented mp4 with empty_moov, unless using >> the delay_moov option). >> >> Signed-off-by: Martin Storsjö <martin@martin.st> >> --- >> libavformat/movenc.c | 4 +++- >> 1 file changed, 3 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >> index 27d7621e27..6a85440a3f 100644 >> --- a/libavformat/movenc.c >> +++ b/libavformat/movenc.c >> @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) >> >> if ((par->codec_id == AV_CODEC_ID_DNXHD || >> par->codec_id == AV_CODEC_ID_TRUEHD || >> - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { >> + par->codec_id == AV_CODEC_ID_AC3 || >> + par->codec_id == AV_CODEC_ID_H264 || >> + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { >> /* copy frame to create needed atoms */ >> trk->vos_len = size; >> trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); > > This changes avcintra output > > example testcase: > ./ffmpeg -i ~/videos/mm-short.mpg -avcintra-class 100 -tune psnr -flags +ildct-global_header -t 0.5 -pix_fmt yuv422p10 -vf scale=1920:1080 -an file.mov I believe this should be fixed by "[PATCH v2] movenc: Fix conversion of the first frame for extradata-less H264/HEVC". // Martin
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 27d7621e27..6a85440a3f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -5584,7 +5584,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if ((par->codec_id == AV_CODEC_ID_DNXHD || par->codec_id == AV_CODEC_ID_TRUEHD || - par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { + par->codec_id == AV_CODEC_ID_AC3 || + par->codec_id == AV_CODEC_ID_H264 || + par->codec_id == AV_CODEC_ID_HEVC) && !trk->vos_len) { /* copy frame to create needed atoms */ trk->vos_len = size; trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
Sticking a full frame in the extradata works, as the code for writing the avcC/hvcC extracts the relevant parameter set NAL units - provided that they actually exist in the frame. Some encoders don't provide split out extradata directly on init (or at all). In particular, the MediaFoundation encoder wrapper doesn't always (depending on the actual encoder device) - this is the case for Qualcomm's HEVC encoder on SD835, and also on some QSV H264 encoders). This only works for cases where the moov hasn't already been written (e.g. when not writing fragmented mp4 with empty_moov, unless using the delay_moov option). Signed-off-by: Martin Storsjö <martin@martin.st> --- libavformat/movenc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)