diff mbox

[FFmpeg-devel,1/2] lavf/dashenc: Don't put non-mp4 streams in HLS manifests.

Message ID 20181128113609.16637-1-andrey.semashev@gmail.com
State Accepted
Commit 2a5cf8a241e3591015dfc94ecca66ffe5b08e29e
Headers show

Commit Message

Andrey Semashev Nov. 28, 2018, 11:36 a.m. UTC
The only native HLS implementation in the wild (Safari browser) doesn't
support WebM. And at least some MSE-based players (e.g. shaka-player)
cannot handle WebM media segments when playing HLS. So just skip non-mp4
streams from HLS manifests. Note that such streams will still be described
by the DASH manifest and therefore consumed by players supporting DASH.
---
 libavformat/dashenc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Jeyapal, Karthick Nov. 28, 2018, 4:52 p.m. UTC | #1
On 11/28/18 5:06 PM, Andrey Semashev wrote:
> The only native HLS implementation in the wild (Safari browser) doesn't

> support WebM. And at least some MSE-based players (e.g. shaka-player)

> cannot handle WebM media segments when playing HLS. So just skip non-mp4

> streams from HLS manifests. Note that such streams will still be described

> by the DASH manifest and therefore consumed by players supporting DASH.

> ---

>  libavformat/dashenc.c | 13 ++++++++++++-

>  1 file changed, 12 insertions(+), 1 deletion(-)

>

> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c

> index 6ce70e0076..a7d8c4e237 100644

> --- a/libavformat/dashenc.c

> +++ b/libavformat/dashenc.c

> @@ -225,6 +225,7 @@ static inline SegmentType select_segment_type(SegmentType segment_type, enum AVC

>  static int init_segment_types(AVFormatContext *s)

>  {

>      DASHContext *c = s->priv_data;

> +    int has_mp4_streams = 0;

>      for (int i = 0; i < s->nb_streams; ++i) {

>          OutputStream *os = &c->streams[i];

>          SegmentType segment_type = select_segment_type(

> @@ -235,6 +236,12 @@ static int init_segment_types(AVFormatContext *s)

>              av_log(s, AV_LOG_ERROR, "Could not select DASH segment type for stream %d\n", i);

>              return AVERROR_MUXER_NOT_FOUND;

>          }

> +        has_mp4_streams |= segment_type == SEGMENT_TYPE_MP4;

> +    }

> +

> +    if (c->hls_playlist && !has_mp4_streams) {

> +         av_log(s, AV_LOG_WARNING, "No mp4 streams, disabling HLS manifest generation\n");

> +         c->hls_playlist = 0;

>      }

>  

>      return 0;

> @@ -510,7 +517,7 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatCont

>          }

>          avio_printf(out, "\t\t\t\t</SegmentList>\n");

>      }

> -    if (c->hls_playlist && start_index < os->nb_segments)

> +    if (c->hls_playlist && start_index < os->nb_segments && os->segment_type == SEGMENT_TYPE_MP4)

>      {

>          int timescale = os->ctx->streams[0]->time_base.den;

>          char temp_filename_hls[1024];

> @@ -944,6 +951,8 @@ static int write_manifest(AVFormatContext *s, int final)

>              OutputStream *os = &c->streams[i];

>              if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)

>                  continue;

> +            if (os->segment_type != SEGMENT_TYPE_MP4)

> +                continue;

>              get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);

>              ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,

>                                           playlist_file, i, is_default);

> @@ -967,6 +976,8 @@ static int write_manifest(AVFormatContext *s, int final)

>              int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;

>              if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)

>                  continue;

> +            if (os->segment_type != SEGMENT_TYPE_MP4)

> +                continue;

>              av_strlcpy(codec_str, os->codec_str, sizeof(codec_str));

>              if (max_audio_bitrate) {

>                  agroup = (char *)audio_group;

LGTM

Regards,
Karthick
diff mbox

Patch

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 6ce70e0076..a7d8c4e237 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -225,6 +225,7 @@  static inline SegmentType select_segment_type(SegmentType segment_type, enum AVC
 static int init_segment_types(AVFormatContext *s)
 {
     DASHContext *c = s->priv_data;
+    int has_mp4_streams = 0;
     for (int i = 0; i < s->nb_streams; ++i) {
         OutputStream *os = &c->streams[i];
         SegmentType segment_type = select_segment_type(
@@ -235,6 +236,12 @@  static int init_segment_types(AVFormatContext *s)
             av_log(s, AV_LOG_ERROR, "Could not select DASH segment type for stream %d\n", i);
             return AVERROR_MUXER_NOT_FOUND;
         }
+        has_mp4_streams |= segment_type == SEGMENT_TYPE_MP4;
+    }
+
+    if (c->hls_playlist && !has_mp4_streams) {
+         av_log(s, AV_LOG_WARNING, "No mp4 streams, disabling HLS manifest generation\n");
+         c->hls_playlist = 0;
     }
 
     return 0;
@@ -510,7 +517,7 @@  static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatCont
         }
         avio_printf(out, "\t\t\t\t</SegmentList>\n");
     }
-    if (c->hls_playlist && start_index < os->nb_segments)
+    if (c->hls_playlist && start_index < os->nb_segments && os->segment_type == SEGMENT_TYPE_MP4)
     {
         int timescale = os->ctx->streams[0]->time_base.den;
         char temp_filename_hls[1024];
@@ -944,6 +951,8 @@  static int write_manifest(AVFormatContext *s, int final)
             OutputStream *os = &c->streams[i];
             if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
                 continue;
+            if (os->segment_type != SEGMENT_TYPE_MP4)
+                continue;
             get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
             ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,
                                          playlist_file, i, is_default);
@@ -967,6 +976,8 @@  static int write_manifest(AVFormatContext *s, int final)
             int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;
             if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
                 continue;
+            if (os->segment_type != SEGMENT_TYPE_MP4)
+                continue;
             av_strlcpy(codec_str, os->codec_str, sizeof(codec_str));
             if (max_audio_bitrate) {
                 agroup = (char *)audio_group;