[FFmpeg-devel] [PATCH] avformat/hlsenc: fix hls start and tail segment duration problem

Steven Liu lingjiujianke at gmail.com
Tue Jan 10 22:40:49 EET 2017


2017-01-10 8:05 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:

>
>
> 2017-01-10 1:06 GMT+08:00 Steven Liu <lq at chinaffmpeg.org>:
>
>> fix ticket: #6067
>>
>> Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
>> ---
>>  libavformat/hlsenc.c | 16 ++++++++++++----
>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index eeb450a..0fcb699 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -103,6 +103,7 @@ typedef struct HLSContext {
>>      int64_t recording_time;
>>      int has_video;
>>      int has_subtitle;
>> +    double dpp;           // duration per packet
>>      int64_t start_pts;
>>      int64_t end_pts;
>>      double duration;      // last segment duration computed so far, in
>> seconds
>> @@ -1216,10 +1217,16 @@ static int hls_write_packet(AVFormatContext *s,
>> AVPacket *pkt)
>>      if (pkt->pts == AV_NOPTS_VALUE)
>>          is_ref_pkt = can_split = 0;
>>
>> -    if (is_ref_pkt)
>> -        hls->duration = (double)(pkt->pts - hls->end_pts)
>> -                                   * st->time_base.num /
>> st->time_base.den;
>> +    if (is_ref_pkt) {
>> +        if (!hls->start_pos) {
>> +            hls->duration = (double)(pkt->pts - hls->end_pts)
>> +                                       * st->time_base.num /
>> st->time_base.den;
>> +            hls->dpp = (double)(pkt->duration) * st->time_base.num /
>> st->time_base.den;
>> +        } else {
>> +            hls->duration += (double)(pkt->duration) * st->time_base.num
>> / st->time_base.den;
>> +        }
>>
>> +    }
>>      if (can_split && av_compare_ts(pkt->pts - hls->start_pts,
>> st->time_base,
>>                                     end_pts, AV_TIME_BASE_Q) >= 0) {
>>          int64_t new_start_pos;
>> @@ -1289,7 +1296,8 @@ static int hls_write_trailer(struct AVFormatContext
>> *s)
>>      if (oc->pb) {
>>          hls->size = avio_tell(hls->avf->pb) - hls->start_pos;
>>          ff_format_io_close(s, &oc->pb);
>> -        hls_append_segment(s, hls, hls->duration, hls->start_pos,
>> hls->size);
>> +        /* after av_write_trailer, then duration + 1 duration per packet
>> */
>> +        hls_append_segment(s, hls, hls->duration + hls->dpp,
>> hls->start_pos, hls->size);
>>      }
>>
>>      if (vtt_oc) {
>> --
>> 2.10.1.382.ga23ca1b.dirty
>>
>>
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>
> update patch.
>
>
fix ticket: #6067

Tested-by: Pero
Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
---
 libavformat/hlsenc.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index eeb450a..3d2d41a 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -103,6 +103,8 @@ typedef struct HLSContext {
     int64_t recording_time;
     int has_video;
     int has_subtitle;
+    int new_start;
+    double dpp;           // duration per packet
     int64_t start_pts;
     int64_t end_pts;
     double duration;      // last segment duration computed so far, in
seconds
@@ -418,6 +420,7 @@ static int hls_mux_init(AVFormatContext *s)
         st->time_base = s->streams[i]->time_base;
     }
     hls->start_pos = 0;
+    hls->new_start = 1;

     return 0;
 }
@@ -1216,10 +1219,18 @@ static int hls_write_packet(AVFormatContext *s,
AVPacket *pkt)
     if (pkt->pts == AV_NOPTS_VALUE)
         is_ref_pkt = can_split = 0;

-    if (is_ref_pkt)
-        hls->duration = (double)(pkt->pts - hls->end_pts)
-                                   * st->time_base.num / st->time_base.den;
+    if (is_ref_pkt) {
+        if (hls->new_start) {
+            hls->new_start = 0;
+            hls->duration = (double)(pkt->pts - hls->end_pts)
+                                       * st->time_base.num /
st->time_base.den;
+            hls->dpp = (double)(pkt->duration) * st->time_base.num /
st->time_base.den;
+            av_log(s, AV_LOG_ERROR, "hls->dpp = [%lf]\n", hls->dpp);
+        } else {
+            hls->duration += (double)(pkt->duration) * st->time_base.num /
st->time_base.den;
+        }

+    }
     if (can_split && av_compare_ts(pkt->pts - hls->start_pts,
st->time_base,
                                    end_pts, AV_TIME_BASE_Q) >= 0) {
         int64_t new_start_pos;
@@ -1289,7 +1300,8 @@ static int hls_write_trailer(struct AVFormatContext
*s)
     if (oc->pb) {
         hls->size = avio_tell(hls->avf->pb) - hls->start_pos;
         ff_format_io_close(s, &oc->pb);
-        hls_append_segment(s, hls, hls->duration, hls->start_pos,
hls->size);
+        /* after av_write_trailer, then duration + 1 duration per packet */
+        hls_append_segment(s, hls, hls->duration + hls->dpp,
hls->start_pos, hls->size);
     }

     if (vtt_oc) {
-- 
2.10.1.382.ga23ca1b.dirty




applied!

Thanks!


More information about the ffmpeg-devel mailing list