[FFmpeg-devel] hlsenc: intialize only on ref_pkt and drop all packets

Submitted by Miroslav Slugeň on Feb. 12, 2017, 6:31 p.m.

Details

Message ID 58A0AA0F.8040906@email.cz
State New
Headers show

Commit Message

Miroslav Slugeň Feb. 12, 2017, 6:31 p.m.
This patch will fix cutting hls segments into exactly same length. 
Because it will intialize only on first ref_packet, which is video 
frame, not audio frame (old behavior)

It will also drop all packets without PTS, drop all packets before 
initialization and drop all packets before first intialization packet PTS.

Now it should be possible to create segments at exactly same length if 
we use new -force_key_frames hls:time_in_seconds parameter.

This is required to support adaptive HLS.

Comments

Michael Niedermayer Feb. 12, 2017, 10:35 p.m.
On Sun, Feb 12, 2017 at 07:31:43PM +0100, Miroslav Slugeň wrote:
> This patch will fix cutting hls segments into exactly same length.
> Because it will intialize only on first ref_packet, which is video
> frame, not audio frame (old behavior)
> 
> It will also drop all packets without PTS, drop all packets before
> initialization and drop all packets before first intialization
> packet PTS.
> 
> Now it should be possible to create segments at exactly same length
> if we use new -force_key_frames hls:time_in_seconds parameter.
> 
> This is required to support adaptive HLS.
> 
> -- 
> Miroslav Slugeň
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 

>  hlsenc.c |   24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 7f784939c938c7697be2178647828a36815fc731  0001-hlsenc-intialize-only-on-ref_pkt-and-drop-all-packet.patch
> From a59a7dbe6fdcab64c1402adb8f11cc31400f4516 Mon Sep 17 00:00:00 2001
> From: Miroslav Slugen <thunder.m@email.cz>
> Date: Sun, 12 Feb 2017 19:25:54 +0100
> Subject: [PATCH 1/1] hlsenc: intialize only on ref_pkt and drop all packets
>  before initialized
> 
> ---
>  libavformat/hlsenc.c | 24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index ad5205a..226dd89 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -1278,10 +1278,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>          oc = hls->avf;
>          stream_index = pkt->stream_index;
>      }
> -    if (hls->start_pts == AV_NOPTS_VALUE) {
> -        hls->start_pts = pkt->pts;
> -        hls->end_pts   = pkt->pts;
> -    }
>  
>      if (hls->has_video) {
>          can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> @@ -1292,6 +1288,11 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>          is_ref_pkt = can_split = 0;
>  
>      if (is_ref_pkt) {
> +        if (hls->start_pts == AV_NOPTS_VALUE) {
> +            hls->start_pts = pkt->pts;
> +            hls->end_pts   = pkt->pts;
> +        }
> +
>          if (hls->new_start) {
>              hls->new_start = 0;
>              hls->duration = (double)(pkt->pts - hls->end_pts)
> @@ -1371,6 +1372,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>          }
>      }
>  
> +    if (pkt->pts == AV_NOPTS_VALUE) {
> +        av_log(s, AV_LOG_WARNING, "packet has no PTS, dropping packet from stream: %d\n", pkt->stream_index);
> +        return 0;
> +    }
> +
> +    if (hls->start_pts == AV_NOPTS_VALUE) {
> +        av_log(s, AV_LOG_WARNING, "stream not initialized yet, dropping packet from stream: %d\n", pkt->stream_index);
> +        return 0;
> +    }
> +
> +    if (pkt->pts + pkt->duration <= hls->start_pts) {
> +        av_log(s, AV_LOG_WARNING, "packet has PTS < START PTS (%"PRId64" < %"PRId64"), dropping packet from stream: %d\n", pkt->pts, hls->start_pts, pkt->stream_index);
> +        return 0;
> +    }

This triggers for subtitle streams, for example:

./ffmpeg -i matrixbench_mpeg2.mpg -i fate-suite/sub/MovText_capability_tester.mp4  -f hls  -hls_segment_filename  /tmp/file.%d.ts -t 10   /tmp/file.m3u8


[...]
Miroslav Slugeň Feb. 13, 2017, 7:56 a.m.
Dne 12.2.2017 v 23:35 Michael Niedermayer napsal(a):
> On Sun, Feb 12, 2017 at 07:31:43PM +0100, Miroslav Slugeň wrote:
>> This patch will fix cutting hls segments into exactly same length.
>> Because it will intialize only on first ref_packet, which is video
>> frame, not audio frame (old behavior)
>>
>> It will also drop all packets without PTS, drop all packets before
>> initialization and drop all packets before first intialization
>> packet PTS.
>>
>> Now it should be possible to create segments at exactly same length
>> if we use new -force_key_frames hls:time_in_seconds parameter.
>>
>> This is required to support adaptive HLS.
>>
>> -- 
>> Miroslav Slugeň
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>   hlsenc.c |   24 ++++++++++++++++++++----
>>   1 file changed, 20 insertions(+), 4 deletions(-)
>> 7f784939c938c7697be2178647828a36815fc731  0001-hlsenc-intialize-only-on-ref_pkt-and-drop-all-packet.patch
>>  From a59a7dbe6fdcab64c1402adb8f11cc31400f4516 Mon Sep 17 00:00:00 2001
>> From: Miroslav Slugen <thunder.m@email.cz>
>> Date: Sun, 12 Feb 2017 19:25:54 +0100
>> Subject: [PATCH 1/1] hlsenc: intialize only on ref_pkt and drop all packets
>>   before initialized
>>
>> ---
>>   libavformat/hlsenc.c | 24 ++++++++++++++++++++----
>>   1 file changed, 20 insertions(+), 4 deletions(-)
>>
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index ad5205a..226dd89 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -1278,10 +1278,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>>           oc = hls->avf;
>>           stream_index = pkt->stream_index;
>>       }
>> -    if (hls->start_pts == AV_NOPTS_VALUE) {
>> -        hls->start_pts = pkt->pts;
>> -        hls->end_pts   = pkt->pts;
>> -    }
>>   
>>       if (hls->has_video) {
>>           can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
>> @@ -1292,6 +1288,11 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>>           is_ref_pkt = can_split = 0;
>>   
>>       if (is_ref_pkt) {
>> +        if (hls->start_pts == AV_NOPTS_VALUE) {
>> +            hls->start_pts = pkt->pts;
>> +            hls->end_pts   = pkt->pts;
>> +        }
>> +
>>           if (hls->new_start) {
>>               hls->new_start = 0;
>>               hls->duration = (double)(pkt->pts - hls->end_pts)
>> @@ -1371,6 +1372,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
>>           }
>>       }
>>   
>> +    if (pkt->pts == AV_NOPTS_VALUE) {
>> +        av_log(s, AV_LOG_WARNING, "packet has no PTS, dropping packet from stream: %d\n", pkt->stream_index);
>> +        return 0;
>> +    }
>> +
>> +    if (hls->start_pts == AV_NOPTS_VALUE) {
>> +        av_log(s, AV_LOG_WARNING, "stream not initialized yet, dropping packet from stream: %d\n", pkt->stream_index);
>> +        return 0;
>> +    }
>> +
>> +    if (pkt->pts + pkt->duration <= hls->start_pts) {
>> +        av_log(s, AV_LOG_WARNING, "packet has PTS < START PTS (%"PRId64" < %"PRId64"), dropping packet from stream: %d\n", pkt->pts, hls->start_pts, pkt->stream_index);
>> +        return 0;
>> +    }
> This triggers for subtitle streams, for example:
>
> ./ffmpeg -i matrixbench_mpeg2.mpg -i fate-suite/sub/MovText_capability_tester.mp4  -f hls  -hls_segment_filename  /tmp/file.%d.ts -t 10   /tmp/file.m3u8
>
>
> [...]
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Otherwise patch is ok? Should i just check that stream is subtitles and 
add exception for it?

M.
Michael Niedermayer Feb. 13, 2017, 12:59 p.m.
On Mon, Feb 13, 2017 at 08:56:19AM +0100, Miroslav Slugeň wrote:
> Dne 12.2.2017 v 23:35 Michael Niedermayer napsal(a):
> >On Sun, Feb 12, 2017 at 07:31:43PM +0100, Miroslav Slugeň wrote:
> >>This patch will fix cutting hls segments into exactly same length.
> >>Because it will intialize only on first ref_packet, which is video
> >>frame, not audio frame (old behavior)
> >>
> >>It will also drop all packets without PTS, drop all packets before
> >>initialization and drop all packets before first intialization
> >>packet PTS.
> >>
> >>Now it should be possible to create segments at exactly same length
> >>if we use new -force_key_frames hls:time_in_seconds parameter.
> >>
> >>This is required to support adaptive HLS.
> >>
> >>-- 
> >>Miroslav Slugeň
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>  hlsenc.c |   24 ++++++++++++++++++++----
> >>  1 file changed, 20 insertions(+), 4 deletions(-)
> >>7f784939c938c7697be2178647828a36815fc731  0001-hlsenc-intialize-only-on-ref_pkt-and-drop-all-packet.patch
> >> From a59a7dbe6fdcab64c1402adb8f11cc31400f4516 Mon Sep 17 00:00:00 2001
> >>From: Miroslav Slugen <thunder.m@email.cz>
> >>Date: Sun, 12 Feb 2017 19:25:54 +0100
> >>Subject: [PATCH 1/1] hlsenc: intialize only on ref_pkt and drop all packets
> >>  before initialized
> >>
> >>---
> >>  libavformat/hlsenc.c | 24 ++++++++++++++++++++----
> >>  1 file changed, 20 insertions(+), 4 deletions(-)
> >>
> >>diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> >>index ad5205a..226dd89 100644
> >>--- a/libavformat/hlsenc.c
> >>+++ b/libavformat/hlsenc.c
> >>@@ -1278,10 +1278,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
> >>          oc = hls->avf;
> >>          stream_index = pkt->stream_index;
> >>      }
> >>-    if (hls->start_pts == AV_NOPTS_VALUE) {
> >>-        hls->start_pts = pkt->pts;
> >>-        hls->end_pts   = pkt->pts;
> >>-    }
> >>      if (hls->has_video) {
> >>          can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> >>@@ -1292,6 +1288,11 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
> >>          is_ref_pkt = can_split = 0;
> >>      if (is_ref_pkt) {
> >>+        if (hls->start_pts == AV_NOPTS_VALUE) {
> >>+            hls->start_pts = pkt->pts;
> >>+            hls->end_pts   = pkt->pts;
> >>+        }
> >>+
> >>          if (hls->new_start) {
> >>              hls->new_start = 0;
> >>              hls->duration = (double)(pkt->pts - hls->end_pts)
> >>@@ -1371,6 +1372,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
> >>          }
> >>      }
> >>+    if (pkt->pts == AV_NOPTS_VALUE) {
> >>+        av_log(s, AV_LOG_WARNING, "packet has no PTS, dropping packet from stream: %d\n", pkt->stream_index);
> >>+        return 0;
> >>+    }
> >>+
> >>+    if (hls->start_pts == AV_NOPTS_VALUE) {
> >>+        av_log(s, AV_LOG_WARNING, "stream not initialized yet, dropping packet from stream: %d\n", pkt->stream_index);
> >>+        return 0;
> >>+    }
> >>+
> >>+    if (pkt->pts + pkt->duration <= hls->start_pts) {
> >>+        av_log(s, AV_LOG_WARNING, "packet has PTS < START PTS (%"PRId64" < %"PRId64"), dropping packet from stream: %d\n", pkt->pts, hls->start_pts, pkt->stream_index);
> >>+        return 0;
> >>+    }
> >This triggers for subtitle streams, for example:
> >
> >./ffmpeg -i matrixbench_mpeg2.mpg -i fate-suite/sub/MovText_capability_tester.mp4  -f hls  -hls_segment_filename  /tmp/file.%d.ts -t 10   /tmp/file.m3u8
> >
> >
> >[...]
> >
> >
> >
> >_______________________________________________
> >ffmpeg-devel mailing list
> >ffmpeg-devel@ffmpeg.org
> >http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

> Otherwise patch is ok? Should i just check that stream is subtitles
> and add exception for it?

i did not review the patch, just tested and found the issue listed
above

I dont know in what other cases these conditions trigger, but
discarding packets in a muxer looks odd (which is why i tested it a
bit)

[...]

Patch hide | download patch | download mbox

From a59a7dbe6fdcab64c1402adb8f11cc31400f4516 Mon Sep 17 00:00:00 2001
From: Miroslav Slugen <thunder.m@email.cz>
Date: Sun, 12 Feb 2017 19:25:54 +0100
Subject: [PATCH 1/1] hlsenc: intialize only on ref_pkt and drop all packets
 before initialized

---
 libavformat/hlsenc.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index ad5205a..226dd89 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1278,10 +1278,6 @@  static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         oc = hls->avf;
         stream_index = pkt->stream_index;
     }
-    if (hls->start_pts == AV_NOPTS_VALUE) {
-        hls->start_pts = pkt->pts;
-        hls->end_pts   = pkt->pts;
-    }
 
     if (hls->has_video) {
         can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
@@ -1292,6 +1288,11 @@  static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         is_ref_pkt = can_split = 0;
 
     if (is_ref_pkt) {
+        if (hls->start_pts == AV_NOPTS_VALUE) {
+            hls->start_pts = pkt->pts;
+            hls->end_pts   = pkt->pts;
+        }
+
         if (hls->new_start) {
             hls->new_start = 0;
             hls->duration = (double)(pkt->pts - hls->end_pts)
@@ -1371,6 +1372,21 @@  static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         }
     }
 
+    if (pkt->pts == AV_NOPTS_VALUE) {
+        av_log(s, AV_LOG_WARNING, "packet has no PTS, dropping packet from stream: %d\n", pkt->stream_index);
+        return 0;
+    }
+
+    if (hls->start_pts == AV_NOPTS_VALUE) {
+        av_log(s, AV_LOG_WARNING, "stream not initialized yet, dropping packet from stream: %d\n", pkt->stream_index);
+        return 0;
+    }
+
+    if (pkt->pts + pkt->duration <= hls->start_pts) {
+        av_log(s, AV_LOG_WARNING, "packet has PTS < START PTS (%"PRId64" < %"PRId64"), dropping packet from stream: %d\n", pkt->pts, hls->start_pts, pkt->stream_index);
+        return 0;
+    }
+
     ret = ff_write_chained(oc, stream_index, pkt, s, 0);
 
     return ret;
-- 
2.1.4