[FFmpeg-devel] [PATCH 1/4] lavf/segment: fix autobsf

Rodger Combs rodger.combs at gmail.com
Thu Oct 27 10:34:33 EEST 2016


> On Oct 27, 2016, at 02:07, Steven Liu <lingjiujianke at gmail.com> wrote:
> 
> 2016-10-27 15:01 GMT+08:00 Steven Liu <lingjiujianke at gmail.com <mailto:lingjiujianke at gmail.com>>:
> 
>> 
>> 
>> 2016-10-27 14:52 GMT+08:00 Rodger Combs <rodger.combs at gmail.com>:
>> 
>>> 
>>>> On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke at gmail.com> wrote:
>>>> 
>>>> 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs at gmail.com>:
>>>> 
>>>>> ---
>>>>> libavformat/segment.c | 40 +++++++++++++++++++++++++++++++++++++++-
>>>>> 1 file changed, 39 insertions(+), 1 deletion(-)
>>>>> 
>>>>> diff --git a/libavformat/segment.c b/libavformat/segment.c
>>>>> index 868f0a8..9b3dc17 100644
>>>>> --- a/libavformat/segment.c
>>>>> +++ b/libavformat/segment.c
>>>>> @@ -798,9 +798,26 @@ static int seg_write_header(AVFormatContext *s)
>>>>> {
>>>>>    SegmentContext *seg = s->priv_data;
>>>>>    AVFormatContext *oc = seg->avf;
>>>>> -    int ret;
>>>>> +    int ret, i;
>>>>> 
>>>>>    if (!seg->header_written) {
>>>>> +        for (i = 0; i < s->nb_streams; i++) {
>>>>> +            AVStream *st = oc->streams[i];
>>>>> +            AVCodecParameters *ipar, *opar;
>>>>> +
>>>>> +            ipar = s->streams[i]->codecpar;
>>>>> +            opar = oc->streams[i]->codecpar;
>>>>> +            avcodec_parameters_copy(opar, ipar);
>>>>> +            if (!oc->oformat->codec_tag ||
>>>>> +                av_codec_get_id (oc->oformat->codec_tag,
>>> ipar->codec_tag)
>>>>> == opar->codec_id ||
>>>>> +                av_codec_get_tag(oc->oformat->codec_tag,
>>> ipar->codec_id)
>>>>> <= 0) {
>>>>> +                opar->codec_tag = ipar->codec_tag;
>>>>> +            } else {
>>>>> +                opar->codec_tag = 0;
>>>>> +            }
>>>>> +            st->sample_aspect_ratio = s->streams[i]->sample_aspect_r
>>> atio;
>>>>> +            st->time_base = s->streams[i]->time_base;
>>>>> +        }
>>>>>        ret = avformat_write_header(oc, NULL);
>>>>>        if (ret < 0)
>>>>>            return ret;
>>>>> @@ -978,6 +995,25 @@ fail:
>>>>>    return ret;
>>>>> }
>>>>> 
>>>>> +static int seg_check_bitstream(struct AVFormatContext *s, const
>>> AVPacket
>>>>> *pkt)
>>>>> +{
>>>>> +    SegmentContext *seg = s->priv_data;
>>>>> +    AVFormatContext *oc = seg->avf;
>>>>> +    if (oc->oformat->check_bitstream) {
>>>>> +        int ret = oc->oformat->check_bitstream(oc, pkt);
>>>>> +        if (ret == 1) {
>>>>> +            AVStream *st = s->streams[pkt->stream_index];
>>>>> +            AVStream *ost = oc->streams[pkt->stream_index];
>>>>> +            st->internal->bsfcs = ost->internal->bsfcs;
>>>>> +            st->internal->nb_bsfcs = ost->internal->nb_bsfcs;
>>>>> +            ost->internal->bsfcs = NULL;
>>>>> +            ost->internal->nb_bsfcs = 0;
>>>>> +        }
>>>>> +        return ret;
>>>>> +    }
>>>>> +    return 1;
>>>>> +}
>>>>> +
>>>>> #define OFFSET(x) offsetof(SegmentContext, x)
>>>>> #define E AV_OPT_FLAG_ENCODING_PARAM
>>>>> static const AVOption options[] = {
>>>>> @@ -1041,6 +1077,7 @@ AVOutputFormat ff_segment_muxer = {
>>>>>    .write_packet   = seg_write_packet,
>>>>>    .write_trailer  = seg_write_trailer,
>>>>>    .deinit         = seg_free,
>>>>> +    .check_bitstream = seg_check_bitstream,
>>>>>    .priv_class     = &seg_class,
>>>>> };
>>>>> 
>>>>> @@ -1061,5 +1098,6 @@ AVOutputFormat ff_stream_segment_muxer = {
>>>>>    .write_packet   = seg_write_packet,
>>>>>    .write_trailer  = seg_write_trailer,
>>>>>    .deinit         = seg_free,
>>>>> +    .check_bitstream = seg_check_bitstream,
>>>>>    .priv_class     = &sseg_class,
>>>>> };
>>>>> --
>>>>> 2.10.0
>>>>> 
>>>>> _______________________________________________
>>>>> ffmpeg-devel mailing list
>>>>> ffmpeg-devel at ffmpeg.org
>>>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>>> 
>>>> 
>>>> This is move to usual area by Michael
>>>> you can refer to  commit id: e29d2d9c92e19b0caf05a2064d132ccdecdfc3d5
>>>> and
>>>> de9674c5eacc076894bd0f94bee0001ba6ab8344
>>> 
>>> See 45f5c5573203a48acb2dd6fbf18f4b0c25b7aff0 (which accidentally breaks
>>> autobsf for segment [patch was written before e29d2d9c92e19b0caf05a2064d132c
>>> cdecdfc3d5]).
>>> This is necessary for the separate-header-file functionality to work.
>>> 
>> refer to http://ffmpeg.org/pipermail/ffmpeg-devel/2016-June/196016.html
>> 
>>> 
>>>> _______________________________________________
>>>> ffmpeg-devel mailing list
>>>> ffmpeg-devel at ffmpeg.org
>>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel at ffmpeg.org
>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>> 
> 
> Maybe we should re-factor this BSF logic into a shareable function and
> make both av_write_frame and av_interleaved_write_frame use it then,
> instead of adding it to hlsenc (and after that even more
> playlist-muxers like dash, segment, etc)
> 
> 
> - Said by Hendrik Leppkes
> I think Hendrik Leppkes is right, and same here

The point is that when writing the header to a separate file (using the segment_header_filename option), we can't rely on the underlying muxer using auto-bsf. Since auto-bsf delays calling write_header until the first packet of each stream is written, we'd end up with an empty header file, with the header data being written into the first segment.

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org <mailto:ffmpeg-devel at ffmpeg.org>
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel <http://ffmpeg.org/mailman/listinfo/ffmpeg-devel>


More information about the ffmpeg-devel mailing list