diff mbox

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

Message ID 20161027061613.44001-1-rodger.combs@gmail.com
State Accepted
Commit 8e6478b723affe4d44f94d34b98e0c47f6a0b411
Headers show

Commit Message

Rodger Combs Oct. 27, 2016, 6:16 a.m. UTC
---
 libavformat/segment.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

Comments

Steven Liu Oct. 27, 2016, 6:41 a.m. UTC | #1
2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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_ratio;
> +            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@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
Rodger Combs Oct. 27, 2016, 6:52 a.m. UTC | #2
> On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke@gmail.com> wrote:
> 
> 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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_ratio;
>> +            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@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 e29d2d9c92e19b0caf05a2064d132ccdecdfc3d5]).
This is necessary for the separate-header-file functionality to work.

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Steven Liu Oct. 27, 2016, 7:01 a.m. UTC | #3
2016-10-27 14:52 GMT+08:00 Rodger Combs <rodger.combs@gmail.com>:

>
> > On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke@gmail.com> wrote:
> >
> > 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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_
> ratio;
> >> +            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@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@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Steven Liu Oct. 27, 2016, 7:07 a.m. UTC | #4
2016-10-27 15:01 GMT+08:00 Steven Liu <lingjiujianke@gmail.com>:

>
>
> 2016-10-27 14:52 GMT+08:00 Rodger Combs <rodger.combs@gmail.com>:
>
>>
>> > On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke@gmail.com> wrote:
>> >
>> > 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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@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@ffmpeg.org
>> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@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
Rodger Combs Oct. 27, 2016, 7:34 a.m. UTC | #5
> On Oct 27, 2016, at 02:07, Steven Liu <lingjiujianke@gmail.com> wrote:
> 
> 2016-10-27 15:01 GMT+08:00 Steven Liu <lingjiujianke@gmail.com <mailto:lingjiujianke@gmail.com>>:
> 
>> 
>> 
>> 2016-10-27 14:52 GMT+08:00 Rodger Combs <rodger.combs@gmail.com>:
>> 
>>> 
>>>> On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke@gmail.com> wrote:
>>>> 
>>>> 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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@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@ffmpeg.org
>>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel@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@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel <http://ffmpeg.org/mailman/listinfo/ffmpeg-devel>
Steven Liu Oct. 27, 2016, 7:43 a.m. UTC | #6
2016-10-27 15:34 GMT+08:00 Rodger Combs <rodger.combs@gmail.com>:

>
> > On Oct 27, 2016, at 02:07, Steven Liu <lingjiujianke@gmail.com> wrote:
> >
> > 2016-10-27 15:01 GMT+08:00 Steven Liu <lingjiujianke@gmail.com <mailto:
> lingjiujianke@gmail.com>>:
> >
> >>
> >>
> >> 2016-10-27 14:52 GMT+08:00 Rodger Combs <rodger.combs@gmail.com>:
> >>
> >>>
> >>>> On Oct 27, 2016, at 01:41, Steven Liu <lingjiujianke@gmail.com>
> wrote:
> >>>>
> >>>> 2016-10-27 14:16 GMT+08:00 Rodger Combs <rodger.combs@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@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@ffmpeg.org
> >>>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >>>
> >>> _______________________________________________
> >>> ffmpeg-devel mailing list
> >>> ffmpeg-devel@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.
>
> Can this move to shareable function? because hlsenc and other list muxer
maybe have same problem.

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

Patch

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_ratio;
+            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,
 };