[vlc-commits] [Git][videolan/vlc][master] 5 commits: access: rtp: refactor code to h26x header

Thomas Guillem (@tguillem) gitlab at videolan.org
Wed Feb 28 10:12:25 UTC 2024



Thomas Guillem pushed to branch master at VideoLAN / VLC


Commits:
7c9f7725 by François Cartegnie at 2024-02-28T09:54:31+00:00
access: rtp: refactor code to h26x header

- - - - -
d9994497 by François Cartegnie at 2024-02-28T09:54:31+00:00
access: rtp: packetize before output

- - - - -
5fa45e1c by François Cartegnie at 2024-02-28T09:54:31+00:00
access: rtp: generate h26x dts from packetized blocks

- - - - -
b4329d10 by François Cartegnie at 2024-02-28T09:54:31+00:00
access: rtp: use block dts for pcr when available

- - - - -
4d691734 by François Cartegnie at 2024-02-28T09:54:31+00:00
access: rtp: add H265 payload

- - - - -


6 changed files:

- modules/access/rtp/Makefile.am
- modules/access/rtp/h264.c
- + modules/access/rtp/h265.c
- + modules/access/rtp/h26x.h
- modules/access/rtp/rtp.c
- modules/demux/mpeg/h26x.c


Changes:

=====================================
modules/access/rtp/Makefile.am
=====================================
@@ -41,6 +41,7 @@ rtpparse_LTLIBRARIES = \
 	librtp_pcm_plugin.la \
 	librtp_raw_plugin.la \
 	librtp_h264_plugin.la \
+	librtp_h265_plugin.la \
 	librtp_opus_plugin.la \
 	librtp_xiph_plugin.la
 
@@ -52,7 +53,9 @@ librtp_pcm_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/access/rtp
 
 librtp_raw_plugin_la_SOURCES = access/rtp/raw.c
 
-librtp_h264_plugin_la_SOURCES = access/rtp/h264.c
+librtp_h264_plugin_la_SOURCES = access/rtp/h264.c access/rtp/h26x.h
+
+librtp_h265_plugin_la_SOURCES = access/rtp/h265.c access/rtp/h26x.h
 
 librtp_opus_plugin_la_SOURCES = access/rtp/opus.c
 


=====================================
modules/access/rtp/h264.c
=====================================
@@ -24,96 +24,21 @@
 
 #include <assert.h>
 
-#include <vlc_common.h>
+#include "h26x.h"
+
 #include <vlc_plugin.h>
-#include <vlc_block.h>
-#include <vlc_strings.h>
 #include <vlc_codec.h>
 
-#include "rtp.h"
-#include "sdp.h"
-
-struct rtp_h26x_sys
+struct h264_pt_opaque
 {
-    vlc_tick_t pts;
-    block_t **pp_packets_next;
-    block_t *p_packets;
-    block_t *xps;
-    struct vlc_rtp_es *es;
+    block_t *sdpxps;
+    vlc_object_t *obj;
 };
 
-static void rtp_h26x_clear(struct rtp_h26x_sys *sys)
-{
-    block_ChainRelease(sys->p_packets);
-    if(sys->xps)
-        block_Release(sys->xps);
-}
-
-static void rtp_h26x_init(struct rtp_h26x_sys *sys)
-{
-    sys->pts = VLC_TICK_INVALID;
-    sys->p_packets = NULL;
-    sys->pp_packets_next = &sys->p_packets;
-    sys->xps = NULL;
-    sys->es = NULL;
-}
-
-static const uint8_t annexbheader[] = { 0, 0, 0, 1 };
-
-static block_t * h26x_wrap_prefix(block_t *block, bool b_annexb)
-{
-    block = block_Realloc(block, 4, block->i_buffer);
-    if(block)
-    {
-        if(b_annexb)
-            memcpy(block->p_buffer, annexbheader, 4);
-        else
-            SetDWBE(block->p_buffer, block->i_buffer - 4);
-    }
-    return block;
-}
-
-static void h26x_extractbase64xps(const char *psz64,
-                                  const char *pszend,
-                                  void(*pf_output)(void *, uint8_t *, size_t),
-                                  void *outputsys)
-{
-    do
-    {
-        psz64 += strspn(psz64, " ");
-        uint8_t *xps = NULL;
-        size_t xpssz = vlc_b64_decode_binary(&xps, psz64);
-        pf_output(outputsys, xps, xpssz);
-        psz64 = strchr(psz64, ',');
-        if(psz64)
-            ++psz64;
-    } while(psz64 && *psz64 && psz64 < pszend);
-}
-
-static void h264_add_xps(void *priv, uint8_t *xps, size_t xpssz)
-{
-    block_t *b = block_heap_Alloc(xps, xpssz);
-    if(!b || !(b = h26x_wrap_prefix(b, true)))
-        return;
-
-    block_t ***ppp_append = priv;
-    **ppp_append = b;
-    *ppp_append = &((**ppp_append)->p_next);
-}
-
-static block_t * h264_fillextradata (const char *psz)
-{
-    block_t *xps = NULL;
-    block_t **pxps = &xps;
-    h26x_extractbase64xps(psz, strchr(psz, ';'), h264_add_xps, &pxps);
-    if(xps)
-        xps = block_ChainGather(xps);
-    return xps;
-}
-
 static void *rtp_h264_init(struct vlc_rtp_pt *pt)
 {
-    block_t *sdpparams = pt->opaque;
+    struct h264_pt_opaque *opaque = pt->opaque;
+    block_t *sdpparams = opaque->sdpxps;
     struct rtp_h26x_sys *sys = malloc(sizeof(*sys));
     if(!sys)
         return NULL;
@@ -123,7 +48,14 @@ static void *rtp_h264_init(struct vlc_rtp_pt *pt)
     es_format_Init (&fmt, VIDEO_ES, VLC_CODEC_H264);
     fmt.b_packetized = false;
 
-    sys->es = vlc_rtp_pt_request_es(pt, &fmt);
+    sys->p_packetizer = demux_PacketizerNew(opaque->obj, &fmt, "rtp packetizer");
+    if(!sys->p_packetizer)
+    {
+        free(sys);
+        return NULL;
+    }
+
+    sys->es = vlc_rtp_pt_request_es(pt, &sys->p_packetizer->fmt_out);
     if(sdpparams)
         sys->xps = block_Duplicate(sdpparams);
 
@@ -136,6 +68,8 @@ static void rtp_h264_destroy(struct vlc_rtp_pt *pt, void *data)
     struct rtp_h26x_sys *sys = data;
     if(sys)
     {
+        if(sys->p_packetizer)
+            demux_PacketizerDestroy(sys->p_packetizer);
         vlc_rtp_es_destroy(sys->es);
         rtp_h26x_clear(sys);
         free(sys);
@@ -226,41 +160,6 @@ static block_t * h264_chainsplit_MTAP(block_t *block, bool b_24ext,
     return p_chain;
 }
 
-static void h26x_output(struct rtp_h26x_sys *sys,
-                        block_t *block,
-                        vlc_tick_t pts, bool pcr, bool au_end)
-{
-//    if(pcr)
-//        es_out_SetPCR(out, pts);
-
-    if(!block)
-        return;
-
-    if(sys->xps)
-    {
-        block_t *xps = sys->xps;
-        sys->xps = NULL;
-        h26x_output(sys, xps, pts, pcr, false);
-    }
-
-    block->i_pts = pts;
-    block->i_dts = VLC_TICK_INVALID; /* RTP does not specify this */
-    if(au_end)
-        block->i_flags |= BLOCK_FLAG_AU_END;
-    vlc_rtp_es_send(sys->es, block);
-}
-
-static void h26x_output_blocks(struct rtp_h26x_sys *sys, bool b_annexb)
-{
-    if(!sys->p_packets)
-        return;
-    block_t *out = block_ChainGather(sys->p_packets);
-    sys->p_packets = NULL;
-    sys->pp_packets_next = &sys->p_packets;
-    out = h26x_wrap_prefix(out, b_annexb);
-    h26x_output(sys, out, sys->pts, true, false);
-}
-
 static void rtp_h264_decode(struct vlc_rtp_pt *pt, void *data, block_t *block,
                             const struct vlc_rtp_pktinfo *restrict info)
 {
@@ -354,9 +253,10 @@ drop:
 
 static void rtp_h264_release(struct vlc_rtp_pt *pt)
 {
-    block_t *sdpparams = pt->opaque;
-    if(sdpparams)
-        block_Release(sdpparams);
+    struct h264_pt_opaque *opaque = pt->opaque;
+    if(opaque->sdpxps)
+        block_Release(opaque->sdpxps);
+    free(opaque);
 }
 
 static const struct vlc_rtp_pt_operations rtp_h264_ops = {
@@ -380,12 +280,18 @@ static int rtp_h264_open(vlc_object_t *obj, struct vlc_rtp_pt *pt,
     else
         return VLC_ENOTSUP;
 
-    pt->opaque = NULL;
+    struct h264_pt_opaque *opaque = calloc(1, sizeof(*opaque));
+    if(!opaque)
+        return VLC_ENOMEM;
+    pt->opaque = opaque;
+
+    opaque->obj = obj;
+
     if(desc->parameters)
     {
         psz = strstr(desc->parameters, "sprop-parameter-sets=");
         if(psz)
-            pt->opaque = h264_fillextradata(psz + 21);
+            opaque->sdpxps = h26x_fillextradata(psz + 21);
     }
 
     return VLC_SUCCESS;


=====================================
modules/access/rtp/h265.c
=====================================
@@ -0,0 +1,331 @@
+/**
+ * @file h265.c
+ */
+/*****************************************************************************
+ * Copyright (C) 2022 VideoLabs, VLC authors and VideoLAN
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ ****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "h26x.h"
+
+#define FLAG_DONL 1
+
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+
+struct h265_pt_opaque
+{
+    block_t *sdpxps;
+    bool b_donl;
+    vlc_object_t *obj;
+};
+
+static void *rtp_h265_init(struct vlc_rtp_pt *pt)
+{
+    struct h265_pt_opaque *opaque = pt->opaque;
+    struct rtp_h26x_sys *sys = malloc(sizeof(*sys));
+    if(!sys)
+        return NULL;
+    rtp_h26x_init(sys);
+
+    es_format_t fmt;
+    es_format_Init (&fmt, VIDEO_ES, VLC_CODEC_HEVC);
+    fmt.b_packetized = false;
+
+    sys->p_packetizer = demux_PacketizerNew(opaque->obj, &fmt, "rtp packetizer");
+    if(!sys->p_packetizer)
+    {
+        free(sys);
+        return NULL;
+    }
+
+    sys->es = vlc_rtp_pt_request_es(pt, &sys->p_packetizer->fmt_out);
+    if(opaque->sdpxps)
+        sys->xps = block_Duplicate(opaque->sdpxps);
+    if(opaque->b_donl)
+        sys->flags = FLAG_DONL;
+
+    return sys;
+}
+
+static void rtp_h265_destroy(struct vlc_rtp_pt *pt, void *data)
+{
+    VLC_UNUSED(pt);
+    struct rtp_h26x_sys *sys = data;
+    if(sys)
+    {
+        if(sys->p_packetizer)
+            demux_PacketizerDestroy(sys->p_packetizer);
+        vlc_rtp_es_destroy(sys->es);
+        rtp_h26x_clear(sys);
+        free(sys);
+    }
+}
+
+static block_t * h265_deaggregate_AP(block_t *block, bool b_donl, bool b_annexb)
+{
+    size_t total = 0;
+
+    if(b_donl)
+    {
+        if(block->i_buffer < 4)
+        {
+            block_Release(block);
+            return NULL;
+        }
+        /* Skip Half DONL, so we always get an extra 1 byte extra prefix */
+        block->p_buffer += 1;
+        block->i_buffer -= 1;
+    }
+
+    const uint8_t *p = block->p_buffer;
+    size_t sz = block->i_buffer;
+
+    /* first pass, compute final size */
+    while(sz > (b_donl ? 2 : 1))
+    {
+        /* skip 1/2 DONL or DOND here */
+        if(b_donl)
+        {
+            p += 1;
+            sz -= 1;
+        }
+        size_t nalsz = GetWBE(p);
+        if(nalsz + 2 > sz)
+        {
+            vlc_assert_unreachable();
+            break;
+        }
+        total += nalsz + 4;
+        sz -= (nalsz + 2);
+        p += (nalsz + 2);
+    }
+    block_t *newblock = block_Alloc(total);
+    if(newblock)
+    {
+        uint8_t *dst = newblock->p_buffer;
+        p = block->p_buffer;
+        sz = block->i_buffer;
+        while(sz > (b_donl ? 2 : 1))
+        {
+            /* skip 1/2 DONL or DOND here */
+            if(b_donl)
+            {
+                p += 1;
+                sz -= 1;
+            }
+            size_t nalsz = GetWBE(p);
+            if(nalsz + 2 > sz)
+                break;
+            if(b_annexb)
+                memcpy(dst, annexbheader, 4);
+            else
+                SetDWBE(dst, nalsz);
+            dst += 4;
+            memcpy(dst, p + 2, nalsz);
+            dst += nalsz;
+            sz -= (nalsz + 2);
+            p += (nalsz + 2);
+        }
+        block_Release(block);
+        block = newblock;
+    }
+    else
+    {
+        block_Release(block);
+        block = NULL;
+    }
+    return block;
+}
+
+static void rtp_h265_decode (struct vlc_rtp_pt *pt, void *data, block_t *block,
+                             const struct vlc_rtp_pktinfo *restrict info)
+{
+    VLC_UNUSED(pt);
+    struct rtp_h26x_sys *sys = data;
+    const bool b_au_end = info->m;
+
+    if(block->i_buffer < 2)
+    {
+        block_Release(block);
+        return;
+    }
+
+    const uint8_t type = (block->p_buffer[0] & 0x7E) >> 1;
+    const uint8_t layerID = ((block->p_buffer[0] & 0x01) << 5) | (block->p_buffer[1] >> 3);
+    const uint8_t temporalID = block->p_buffer[1] & 0x07;
+    const vlc_tick_t pts = block->i_pts;
+
+    switch(type)
+    {
+        case 48: /* AP */
+            /* end unfinished aggregates */
+            h26x_output_blocks(sys, true);
+            /* skip header */
+            block->i_buffer -= 2;
+            block->p_buffer += 2;
+            block = h265_deaggregate_AP(block, sys->flags & FLAG_DONL, true);
+            h26x_output(sys, block, pts, true, b_au_end);
+            break;
+        case 49: /* FU */
+        {
+            if(block->i_buffer < ((sys->flags & FLAG_DONL) ? 6 : 4))
+                goto drop;
+            const bool start = block->p_buffer[2] & 0x80;
+            const bool end = block->p_buffer[2] & 0x40;
+            const uint8_t futype = block->p_buffer[2] & 0x3f;
+
+            /* skip FU header and rebuild NAL header */
+            if(start)
+            {
+                /* end unfinished aggregates */
+                h26x_output_blocks(sys, true);
+                /* rebuild NAL header, overwriting last PAYL[DON]FU 2 bytes */
+                if(sys->flags & FLAG_DONL)
+                {
+                    block->i_buffer -= 3;
+                    block->p_buffer += 3;
+                }
+                else
+                {
+                    block->i_buffer -= 1;
+                    block->p_buffer += 1;
+                }
+                block->p_buffer[0] = (futype << 1) | (layerID >> 5);
+                block->p_buffer[1] = (layerID << 3) | temporalID;
+                sys->pts = pts;
+            }
+            else /* trail data */
+            {
+                block->i_buffer -= (sys->flags & FLAG_DONL) ? 5 : 3;
+                block->p_buffer += (sys->flags & FLAG_DONL) ? 5 : 3;
+            }
+            block_ChainLastAppend(&sys->pp_packets_next, block);
+            if(end)
+            {
+                block_t *out = block_ChainGather(sys->p_packets);
+                sys->p_packets = NULL;
+                sys->pp_packets_next = &sys->p_packets;
+                out = h26x_wrap_prefix(out, true);
+                h26x_output(sys, out, pts, true, b_au_end);
+            }
+            break;
+        }
+        case 50: /* PACI */
+        {
+            if(block->i_buffer < 5 || (block->p_buffer[3] & 0x01))
+                goto drop;
+            const uint8_t cType = ((block->p_buffer[2] & 0x7f) >> 1);
+            const uint8_t PHSize = ((block->p_buffer[2] & 0x01) << 7)
+                                 | (block->p_buffer[3] >> 4);
+            if(PHSize >= block->i_buffer - 4)
+                goto drop;
+            /* skip extension, and add the payload header */
+            block->p_buffer[0] = (block->p_buffer[0] & 0x81) | (cType << 1);
+            block->p_buffer[4 + PHSize - 2 + 0] = block->p_buffer[0];
+            block->p_buffer[4 + PHSize - 2 + 1] = block->p_buffer[1];
+            block->p_buffer -= 4 + PHSize;
+            block->i_buffer += 4 + PHSize;
+            /* pass to original payload handler */
+            rtp_h265_decode(pt, data, block, info);
+            break;
+        }
+        default:
+            /* end unfinished aggregates */
+            h26x_output_blocks(sys, true);
+            /* raw single NAL */
+            if(sys->flags & FLAG_DONL) /* optional DONL */
+            {
+                if(block->i_buffer < 4)
+                    goto drop;
+                /* NALHDR DONL NALPAYL -> NALHDR NALPAYL */
+                block->p_buffer[2] = block->p_buffer[0];
+                block->p_buffer[3] = block->p_buffer[1];
+                block->p_buffer += 2;
+                block->i_buffer -= 2;
+            }
+            block = h26x_wrap_prefix(block, true);
+            h26x_output(sys, block, pts, true, b_au_end);
+    }
+    return;
+
+drop:
+    if(block)
+        block_Release(block);
+}
+
+static void rtp_h265_release(struct vlc_rtp_pt *pt)
+{
+    struct h265_pt_opaque *opaque = pt->opaque;
+    if(opaque->sdpxps)
+        block_Release(opaque->sdpxps);
+    free(opaque);
+}
+
+static const struct vlc_rtp_pt_operations rtp_h265_ops = {
+    rtp_h265_release, rtp_h265_init, rtp_h265_destroy, rtp_h265_decode,
+};
+
+static int rtp_h265_open(vlc_object_t *obj, struct vlc_rtp_pt *pt,
+                         const struct vlc_sdp_pt *desc)
+{
+    if (vlc_ascii_strcasecmp(desc->name, "H265") == 0)
+        pt->ops = &rtp_h265_ops;
+    else
+        return VLC_ENOTSUP;
+
+    struct h265_pt_opaque *opaque = calloc(1, sizeof(*opaque));
+    if(!opaque)
+        return VLC_ENOMEM;
+    pt->opaque = opaque;
+
+    opaque->obj = obj;
+
+    if(desc->parameters)
+    {
+        const char *psz = strstr(desc->parameters, "sprop-max-don-diff=");
+        if(psz)
+            opaque->b_donl = (atoi(psz + 19) > 0);
+        block_t **append = &opaque->sdpxps;
+        const char *props[] = { "sprop-vps=", "sprop-sps=", "sprop-pps=" };
+        for(int i=0; i<ARRAY_SIZE(props); i++)
+        {
+            psz = strstr(desc->parameters, props[i]);
+            if(!psz)
+                continue;
+            block_t *xps = h26x_fillextradata(psz + 10);
+            if(xps)
+                block_ChainLastAppend(&append, xps);
+        }
+        if(opaque->sdpxps)
+            opaque->sdpxps = block_ChainGather(opaque->sdpxps);
+    }
+
+    return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+    set_shortname(N_("RTP H265"))
+    set_description(N_("RTP H265 payload parser"))
+    set_subcategory(SUBCAT_INPUT_DEMUX)
+    set_rtp_parser_callback(rtp_h265_open)
+    add_shortcut("video/H265")
+vlc_module_end()


=====================================
modules/access/rtp/h26x.h
=====================================
@@ -0,0 +1,160 @@
+/**
+ * @file h26x.h
+ */
+/*****************************************************************************
+ * Copyright (C) 2022 VideoLabs, VLC authors and VideoLAN
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ ****************************************************************************/
+#include <vlc_common.h>
+#include <vlc_block.h>
+#include <vlc_strings.h>
+#include <vlc_codec.h>
+#include <vlc_demux.h>
+
+#include "rtp.h"
+#include "../live555_dtsgen.h"
+
+static const uint8_t annexbheader[] = { 0, 0, 0, 1 };
+
+struct rtp_h26x_sys
+{
+    unsigned flags;
+    vlc_tick_t pts;
+    block_t **pp_packets_next;
+    block_t *p_packets;
+    block_t *xps;
+    struct vlc_rtp_es *es;
+    decoder_t *p_packetizer;
+    struct dtsgen_t dtsgen;
+};
+
+static void rtp_h26x_clear(struct rtp_h26x_sys *sys)
+{
+    block_ChainRelease(sys->p_packets);
+    if(sys->xps)
+        block_Release(sys->xps);
+}
+
+static void rtp_h26x_init(struct rtp_h26x_sys *sys)
+{
+    sys->flags = 0;
+    sys->pts = VLC_TICK_INVALID;
+    sys->p_packets = NULL;
+    sys->pp_packets_next = &sys->p_packets;
+    sys->xps = NULL;
+    sys->es = NULL;
+    sys->p_packetizer = NULL;
+    dtsgen_Init(&sys->dtsgen);
+}
+
+static void h26x_extractbase64xps(const char *psz64,
+                                  const char *pszend,
+                                  void(*pf_output)(void *, uint8_t *, size_t),
+                                  void *outputsys)
+{
+    do
+    {
+        psz64 += strspn(psz64, " ");
+        uint8_t *xps = NULL;
+        size_t xpssz = vlc_b64_decode_binary(&xps, psz64);
+        pf_output(outputsys, xps, xpssz);
+        psz64 = strchr(psz64, ',');
+        if(psz64)
+            ++psz64;
+    } while(psz64 && *psz64 && psz64 < pszend);
+}
+
+static block_t * h26x_wrap_prefix(block_t *block, bool b_annexb)
+{
+    block = block_Realloc(block, 4, block->i_buffer);
+    if(block)
+    {
+        if(b_annexb)
+            memcpy(block->p_buffer, annexbheader, 4);
+        else
+            SetDWBE(block->p_buffer, block->i_buffer - 4);
+    }
+    return block;
+}
+
+static void h26x_add_xps(void *priv, uint8_t *xps, size_t xpssz)
+{
+    block_t *b = block_heap_Alloc(xps, xpssz);
+    if(!b || !(b = h26x_wrap_prefix(b, true)))
+        return;
+
+    block_t ***ppp_append = priv;
+    **ppp_append = b;
+    *ppp_append = &((**ppp_append)->p_next);
+}
+
+static block_t * h26x_fillextradata (const char *psz)
+{
+    block_t *xps = NULL;
+    block_t **pxps = &xps;
+    h26x_extractbase64xps(psz, strchr(psz, ';'), h26x_add_xps, &pxps);
+    if(xps)
+        xps = block_ChainGather(xps);
+    return xps;
+}
+
+static void h26x_output(struct rtp_h26x_sys *sys,
+                        block_t *block,
+                        vlc_tick_t pts, bool pcr, bool au_end)
+{
+    if(!block)
+        return;
+
+    if(sys->xps)
+    {
+        block_t *xps = sys->xps;
+        sys->xps = NULL;
+        h26x_output(sys, xps, pts, pcr, false);
+    }
+
+    if(block->i_flags & BLOCK_FLAG_DISCONTINUITY)
+        dtsgen_Resync(&sys->dtsgen);
+
+    block->i_pts = pts;
+    block->i_dts = VLC_TICK_INVALID; /* RTP does not specify this */
+    if(au_end)
+        block->i_flags |= BLOCK_FLAG_AU_END;
+
+    block_t *p_out;
+    for(int i=0; i<(1+!!au_end); i++)
+    {
+        while((p_out = sys->p_packetizer->pf_packetize(sys->p_packetizer,
+                                                       block ? &block : NULL)))
+        {
+            dtsgen_AddNextPTS(&sys->dtsgen, p_out->i_pts);
+            vlc_tick_t dts = dtsgen_GetDTS(&sys->dtsgen);
+            p_out->i_dts = dts;
+            vlc_rtp_es_send(sys->es, p_out);
+        }
+        block = NULL; // for drain iteration
+    }
+}
+
+static void h26x_output_blocks(struct rtp_h26x_sys *sys, bool b_annexb)
+{
+    if(!sys->p_packets)
+        return;
+    block_t *out = block_ChainGather(sys->p_packets);
+    sys->p_packets = NULL;
+    sys->pp_packets_next = &sys->p_packets;
+    out = h26x_wrap_prefix(out, b_annexb);
+    h26x_output(sys, out, sys->pts, true, false);
+}


=====================================
modules/access/rtp/rtp.c
=====================================
@@ -78,8 +78,10 @@ static void vlc_rtp_es_id_send(struct vlc_rtp_es *es, block_t *block)
 
     /* TODO: Don't set PCR here. Breaks multiple sources (in a session)
      * and more importantly eventually multiple sessions. */
-    if (block->i_pts != VLC_TICK_INVALID)
-        es_out_SetPCR(ei->out, block->i_pts);
+    vlc_tick_t pcr = (block->i_dts != VLC_TICK_INVALID) ? block->i_dts
+                                                        : block->i_pts;
+    if (pcr != VLC_TICK_INVALID)
+        es_out_SetPCR(ei->out, pcr);
     es_out_Send(ei->out, ei->id, block);
 }
 


=====================================
modules/demux/mpeg/h26x.c
=====================================
@@ -480,10 +480,6 @@ static int Demux( demux_t *p_demux)
             bool frame = p_block_out->i_flags & BLOCK_FLAG_TYPE_MASK;
             const vlc_tick_t i_frame_length = p_block_out->i_length;
 
-            /* first output */
-            if( date_Get( &p_sys->output_dts ) == VLC_TICK_0 )
-                es_out_SetPCR( p_demux->out, date_Get( &p_sys->output_dts ) );
-
             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
 
             vlc_tick_t pcr = b_eof ? dts : date_Get( &p_sys->output_dts );
@@ -503,8 +499,6 @@ static int Demux( demux_t *p_demux)
                 }
             }
 
-            es_out_SetPCR( p_demux->out, pcr );
-
             p_block_out = p_next;
         }
     }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/79d2ab78ab14253954045790349591419151a171...4d691734b189ccae3300c8d0d40eb6428fadd486

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/79d2ab78ab14253954045790349591419151a171...4d691734b189ccae3300c8d0d40eb6428fadd486
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