[vlc-commits] [Git][videolan/vlc][master] 5 commits: sout: hls: fix invalid playlist ref on error path

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Aug 31 09:08:34 UTC 2024



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
4d0cd55a by Alaric Senat at 2024-08-31T08:56:35+00:00
sout: hls: fix invalid playlist ref on error path

The playlist reference should only be held in the variant map when it's
asserted that the playlist creation will succeed. Otherwise the error
handling will delete the playlist while keeping an invalid reference in
the map.
The reference is already properly stored at the end of the `Add`
function, so this patch only reworks an unnecessary store.

- - - - -
8f2320ff by Alaric Senat at 2024-08-31T08:56:35+00:00
sout: hls: fix relative include path

- - - - -
a4e95080 by Alaric Senat at 2024-08-31T08:56:35+00:00
sout: hls: rename AVC formatting function

- - - - -
2d44d3c7 by Alaric Senat at 2024-08-31T08:56:35+00:00
sout: hls: fix printf error checks

printf's manual only specifies that a negative value is returned in case
of error.

- - - - -
953c5e91 by Alaric Senat at 2024-08-31T08:56:35+00:00
sout: hls: support HEVC

HEVC in TS only needed the implementation of the RFC6381 codec
description.
This patch adds it by manually parsing the SPS NAL unit to avoid
exposing a function in the hxxx_helper as only small set of the HEVC
profile description is used.

Co-Authored-By: François Cartegnie <fcvlcdev at free.fr>
Co-Authored-By: Soham Gupta <soham.gupta003 at gmail.com>

Refs #27391

- - - - -


2 changed files:

- modules/stream_out/hls/codecs.c
- modules/stream_out/hls/hls.c


Changes:

=====================================
modules/stream_out/hls/codecs.c
=====================================
@@ -25,10 +25,13 @@
 
 #include <vlc_memstream.h>
 
-#include "../codec/hxxx_helper.h"
+#include "../../codec/hxxx_helper.h"
+#include "../../packetizer/hevc_nal.h"
+#include "../../packetizer/hxxx_ep3b.h"
+#include "../../packetizer/hxxx_nal.h"
 #include "codecs.h"
 
-static int FormatAVC1(struct vlc_memstream *ms, const es_format_t *fmt)
+static int FormatAVC(struct vlc_memstream *ms, const es_format_t *fmt)
 {
     /* Parse the h264 constraint flag. */
     uint8_t constraints = 0;
@@ -43,16 +46,103 @@ static int FormatAVC1(struct vlc_memstream *ms, const es_format_t *fmt)
     }
     hxxx_helper_clean(&hh);
 
-    const int wrote = vlc_memstream_printf(
+    const int written = vlc_memstream_printf(
         ms, "avc1.%02X%02X%02X", profile, constraints, level);
-    return (wrote == -1) ? VLC_ENOMEM : VLC_SUCCESS;
+    return (written < 0) ? VLC_ENOMEM : VLC_SUCCESS;
+}
+
+static uint32_t ReverseBits(uint32_t in)
+{
+    uint32_t out = 0;
+    for (int i = 0; i < 32; ++i)
+    {
+        out |= in & 1;
+        if (i == 31)
+            break;
+        out <<= 1;
+        in >>= 1;
+    }
+    return out;
+}
+
+static int FormatHEVC(struct vlc_memstream *ms, const es_format_t *fmt)
+{
+    if (vlc_memstream_puts(ms, "hvc1") < 0)
+        return VLC_ENOMEM;
+
+    uint8_t to_skip = 8;
+    hxxx_iterator_ctx_t it;
+    hxxx_iterator_init(&it, fmt->p_extra, fmt->i_extra, 0);
+    const uint8_t *nal = NULL;
+    size_t nal_size;
+    if (hxxx_annexb_iterate_next(&it, &nal, &nal_size))
+    {
+        switch (hevc_getNALType(nal))
+        {
+            case HEVC_NAL_SPS:
+                break;
+            case HEVC_NAL_VPS:
+                to_skip += 24;
+                break;
+            default:
+                nal = NULL;
+                break;
+        }
+    }
+
+    /* NAL units aren't provisioned. Codec description will be minimal. */
+    if (unlikely(nal == NULL))
+        return VLC_SUCCESS;
+
+    const void *profile_space = nal + 2;
+    struct hxxx_bsfw_ep3b_ctx_s ep3b;
+    hxxx_bsfw_ep3b_ctx_init(&ep3b);
+    bs_t bs;
+    bs_init_custom(
+        &bs, profile_space, nal_size - 2, &hxxx_bsfw_ep3b_callbacks, &ep3b);
+
+    /* Jump to profile_tier_level @profile_space. */
+    bs_skip(&bs, to_skip);
+
+    const char *profile_space_ids[4] = {"", "A", "B", "C"};
+    const char *profile_space_id = profile_space_ids[bs_read(&bs, 2)];
+    const char tier_flag = (bs_read1(&bs) != 0) ? 'H' : 'L';
+    const uint8_t profile_idc = bs_read(&bs, 5);
+    const uint32_t profile_compatibility_flag = ReverseBits(bs_read(&bs, 32));
+    /* Read constraints. */
+    uint8_t constraints[6];
+    uint8_t cnstrflags = 0;
+    for (unsigned i = 0; i < ARRAY_SIZE(constraints); ++i)
+    {
+        constraints[i] = bs_read(&bs, 8);
+        cnstrflags |= (!!constraints[i] << i);
+    }
+    const uint8_t level_idc = bs_read(&bs, 8);
+
+    if (vlc_memstream_printf(ms,
+                             "%s.%u.%X.%c%u",
+                             profile_space_id,
+                             profile_idc,
+                             profile_compatibility_flag,
+                             tier_flag,
+                             level_idc) < 0)
+        return VLC_ENOMEM;
+
+    /* Append constraints bytes. */
+    for (unsigned i = 0; cnstrflags; cnstrflags >>= 1)
+    {
+        if (vlc_memstream_printf(ms, ".%2.2x", constraints[i++]) < 0)
+            return VLC_ENOMEM;
+    }
+
+    return VLC_SUCCESS;
 }
 
 static int FormatMP4A(struct vlc_memstream *ms, const es_format_t *fmt)
 {
-    const int wrote = vlc_memstream_printf(
+    const int written = vlc_memstream_printf(
         ms, "mp4a.40.%02x", (fmt->i_profile == -1) ? 2u : fmt->i_profile + 1u);
-    return (wrote == -1) ? VLC_ENOMEM : VLC_SUCCESS;
+    return (written < 0) ? VLC_ENOMEM : VLC_SUCCESS;
 }
 
 static int FormatWebVTT(struct vlc_memstream *ms)
@@ -66,7 +156,9 @@ int hls_codec_Format(struct vlc_memstream *ms, const es_format_t *fmt)
     switch (fmt->i_codec)
     {
         case VLC_CODEC_H264:
-            return FormatAVC1(ms, fmt);
+            return FormatAVC(ms, fmt);
+        case VLC_CODEC_HEVC:
+            return FormatHEVC(ms, fmt);
         case VLC_CODEC_MP4A:
             return FormatMP4A(ms, fmt);
         case VLC_CODEC_TEXT:
@@ -79,6 +171,7 @@ int hls_codec_Format(struct vlc_memstream *ms, const es_format_t *fmt)
 
 bool hls_codec_IsSupported(const es_format_t *fmt)
 {
-    return fmt->i_codec == VLC_CODEC_H264 || fmt->i_codec == VLC_CODEC_MP4A ||
-           fmt->i_codec == VLC_CODEC_TEXT || fmt->i_codec == VLC_CODEC_WEBVTT;
+    return fmt->i_codec == VLC_CODEC_H264 || fmt->i_codec == VLC_CODEC_HEVC ||
+           fmt->i_codec == VLC_CODEC_MP4A || fmt->i_codec == VLC_CODEC_TEXT ||
+           fmt->i_codec == VLC_CODEC_WEBVTT;
 }


=====================================
modules/stream_out/hls/hls.c
=====================================
@@ -801,9 +801,9 @@ Add(sout_stream_t *stream, const es_format_t *fmt, const char *es_id)
     hls_playlist_t *playlist;
     if (map != NULL)
     {
-        if (map->playlist_ref == NULL)
-            map->playlist_ref = AddPlaylist(stream, HLS_PLAYLIST_TYPE_TS, &sys->variant_playlists);
         playlist = map->playlist_ref;
+        if (playlist == NULL)
+            playlist = AddPlaylist(stream, HLS_PLAYLIST_TYPE_TS, &sys->variant_playlists);
     }
     else if (fmt->i_cat == SPU_ES)
         playlist = AddPlaylist(



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8bf7ebe4d7d3de209c2c0993a02245f4c0625a6f...953c5e91d245130fe14de9efd31b7010e5c9c356

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8bf7ebe4d7d3de209c2c0993a02245f4c0625a6f...953c5e91d245130fe14de9efd31b7010e5c9c356
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list