[FFmpeg-devel] [PATCH] avformat/hlsenc: move init file write code block to hls_write_header

Steven Liu lq at chinaffmpeg.org
Sun May 10 02:09:18 EEST 2020



> 2020年5月10日 上午3:21,Andreas Rheinhardt <andreas.rheinhardt at gmail.com> 写道:
> 
> Steven Liu:
>> Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
>> ---
>> libavformat/hlsenc.c | 37 ++++++++++++++++++++-----------------
>> 1 file changed, 20 insertions(+), 17 deletions(-)
>> 
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index 5695c6cc95..a1eddade7b 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -2266,6 +2266,26 @@ static int hls_write_header(AVFormatContext *s)
>>                 }
>>             }
>>         }
>> +        if (hls->segment_type == SEGMENT_TYPE_FMP4 && !vs->init_range_length) {
>> +            int range_length = 0;
>> +            int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
>> +            av_write_frame(vs->avf, NULL); /* Flush any buffered data */
>> +            avio_tell(vs->avf->pb);
>> +            avio_flush(vs->avf->pb);
>> +            range_length = avio_close_dyn_buf(vs->avf->pb, &vs->init_buffer);
>> +            if (range_length <= 0)
>> +                return AVERROR(EINVAL);
>> +            avio_write(vs->out, vs->init_buffer, range_length);
>> +            if (!hls->resend_init_file)
>> +                av_freep(&vs->init_buffer);
>> +            vs->init_range_length = range_length;
>> +            avio_open_dyn_buf(&vs->avf->pb);
>> +            vs->packets_written = 0;
>> +            vs->start_pos = range_length;
>> +            if (!byterange_mode) {
>> +                hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
>> +            }
>> +        }
>>     }
>> 
>>     return ret;
>> @@ -2383,23 +2403,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>>         new_start_pos = avio_tell(oc->pb);
>>         vs->size = new_start_pos - vs->start_pos;
>>         avio_flush(oc->pb);
>> -        if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>> -            if (!vs->init_range_length) {
>> -                range_length = avio_close_dyn_buf(oc->pb, &vs->init_buffer);
>> -                if (range_length <= 0)
>> -                    return AVERROR(EINVAL);
>> -                avio_write(vs->out, vs->init_buffer, range_length);
>> -                if (!hls->resend_init_file)
>> -                    av_freep(&vs->init_buffer);
>> -                vs->init_range_length = range_length;
>> -                avio_open_dyn_buf(&oc->pb);
>> -                vs->packets_written = 0;
>> -                vs->start_pos = range_length;
>> -                if (!byterange_mode) {
>> -                    hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
>> -                }
>> -            }
>> -        }
>>         if (!byterange_mode) {
>>             if (vs->vtt_avf) {
>>                 hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->url);
>> 
> 
> 1. Delaying writing the header was introduced in commit
> 880b299381de1e66f8248abd6c320c7c490466a2 to fix ticket 6825 (where the
> number of channels in the input stream switches).
Ok, I get it, this is a good point.

> Have you tested
> whether your patch breaks said ticket again?
> 2. You don't need to check for vs->init_range_length being zero when
> writing the header as this is automatically fulfilled. (After all, one
> calls avformat_write_header() only once.)
> 3. There is also code in hls_write_trailer() that duplicates the code to
> write the init file (should actually have been factored out into a
> common function...). It has been added in commit
> 76b8e42c1f0453215244c45114d5aa302e2add7b to address ticket #7166 and if
> you always write the init file in write_header, you should also remove
> the code in write_trailer.
> 4. Commit 880b299381de1e66f8248abd6c320c7c490466a2 also added the
> packets_written member; it was initialized to 0 in mp4 mode and to 1 in
> non-mp4 mode. Since cff309097a3af4f7f2acb5b5f9fb914ba9ae45c3 this was
> set to 1 initially just in order to be reset to 0 a few lines below.
> Maybe packets_written should be removed completely? (I made a patch [2]
> to remove the currently redundant initializations.)
> 5. The current way of writing the init header (that you intend to remove
> in this commit) has a serious issue: If you have a subtitle and an audio
> stream, yet no video stream and if the audio is delayed sufficiently,
> then a subtitle packet triggers the output of the mp4 init header. But
> subtitles are output directly and not via dynamic buffers and yet the
> code presumes that the AVIOContext for output is a dynamic buffer. This
> leads to segfaults. (If you remember, this is point 6 in [1].) This
> patch seems to fix this; but if you drop this patch because of 1., this
> still needs to addressed.
I Get your point. 
Let me think about how to move it out of hls_write_packet,
Maybe hlsenc cannot support LowLatency HLS if it always in hls_write_packet.
Or maybe need modify some code in movenc, I want try only modify in hlsenc.
> 
> - Andreas
> 
> [1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2019-December/254420.html
> [2]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-May/262385.html
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".

Thanks

Steven Liu





More information about the ffmpeg-devel mailing list