[vlc-commits] mux: ts: don't map service type arbitrarily

Francois Cartegnie git at videolan.org
Mon Apr 25 14:41:18 CEST 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Apr 25 13:23:36 2016 +0200| [4025bcbd18644f76bc08750be81e28d8204619be] | committer: Francois Cartegnie

mux: ts: don't map service type arbitrarily

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4025bcbd18644f76bc08750be81e28d8204619be
---

 modules/mux/mpeg/tables.c |  162 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 126 insertions(+), 36 deletions(-)

diff --git a/modules/mux/mpeg/tables.c b/modules/mux/mpeg/tables.c
index 4cd2142..6279ab0 100644
--- a/modules/mux/mpeg/tables.c
+++ b/modules/mux/mpeg/tables.c
@@ -247,6 +247,78 @@ static void GetPMTmpeg4( vlc_object_t *p_object, dvbpsi_pmt_t *p_dvbpmt,
     dvbpsi_pmt_descriptor_add(&p_dvbpmt[0], 0x1d, bits.i_data, bits.p_data);
 }
 
+static void UpdateServiceType( uint8_t *pi_service_cat, uint8_t *pi_service_type, const pes_stream_t *p_pes )
+{
+    uint8_t i_type = 0x00;
+
+    switch( p_pes->i_stream_type )
+    {
+        case 0x01: /* MPEG1 */
+        case 0x02: /* MPEG2 */
+        case 0x80:
+            if( p_pes->i_height > 468 && p_pes->i_width > 720 )
+                i_type = 0x19;
+            else
+                i_type = 0x01;
+            break;
+
+        case 0x24: /* HEVC */
+        case 0x10: /* MPEG4 */
+        case 0x1b: /* H264 */
+        case 0xA0: /* private */
+        case 0xd1: /* dirac */
+            i_type = 0x16;
+            break;
+
+        default:
+            break;
+    }
+
+    if( i_type == 0x01 && p_pes->i_height > 468 && p_pes->i_width > 720 ) /* MPEG2 SD -> HD */
+    {
+         i_type = 0x11;
+    }
+    else if( i_type == 0x16 && p_pes->i_height > 468 && p_pes->i_width > 720 ) /* Advanced codec SD -> HD */
+    {
+         i_type = 0x19;
+    }
+
+    if( i_type != 0x00 )
+    {
+        if( *pi_service_cat != VIDEO_ES || i_type > *pi_service_type )
+        {
+            *pi_service_type = i_type;
+            *pi_service_cat = VIDEO_ES;
+        }
+        return;
+    }
+
+    if( *pi_service_cat != VIDEO_ES ) /* Don't overwrite video */
+    {
+        /* Not video, try audio */
+        switch( p_pes->i_stream_type )
+        {
+            case 0x03: /* MPEG1 audio */
+            case 0x04: /* MPEG2 audio */
+                i_type = 0x02;
+                break;
+
+            case 0x06:
+            case 0x0f:
+            case 0x81:
+            case 0x83:
+                i_type = 0x0A; /* Avanced codec digital radio */
+                break;
+
+            default:
+                break;
+        }
+
+        if( i_type > *pi_service_type )
+            *pi_service_type = i_type;
+    }
+}
+
 void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
                void *p_opaque, PEStoTSCallback pf_callback,
                int i_tsid, int i_pmt_version_number,
@@ -260,8 +332,19 @@ void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
             return;
 
     dvbpsi_sdt_t sdtpsi;
+    uint8_t *pi_service_types = NULL;
+    uint8_t *pi_service_cats = NULL;
     if( p_sdt )
+    {
         dvbpsi_sdt_init( &sdtpsi, 0x42, i_tsid, 1, true, p_sdt->i_netid );
+        pi_service_types = calloc( i_programs * 2, sizeof(uint8_t *) );
+        if( !pi_service_types )
+        {
+            free( dvbpmt );
+            return;
+        }
+        pi_service_cats = &pi_service_types[i_programs];
+    }
 
     for (unsigned i = 0; i < i_programs; i++ )
     {
@@ -270,40 +353,6 @@ void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
                         i_pmt_version_number,
                         true,      /* b_current_next */
                         i_pcr_pid );
-
-        if( !p_sdt )
-            continue;
-
-        dvbpsi_sdt_service_t *p_service = dvbpsi_sdt_service_add( &sdtpsi,
-            pi_programs_number[i],  /* service id */
-            false,     /* eit schedule */
-            false,     /* eit present */
-            4,         /* running status ("4=RUNNING") */
-            false );   /* free ca */
-
-        const char *psz_sdtprov = p_sdt->desc[i].psz_provider;
-        const char *psz_sdtserv = p_sdt->desc[i].psz_service_name;
-
-        if( !psz_sdtprov || !psz_sdtserv )
-            continue;
-        size_t provlen = VLC_CLIP(strlen(psz_sdtprov), 0, 255);
-        size_t servlen = VLC_CLIP(strlen(psz_sdtserv), 0, 255);
-
-        uint8_t psz_sdt_desc[3 + provlen + servlen];
-
-        psz_sdt_desc[0] = 0x01; /* digital television service */
-
-        /* service provider name length */
-        psz_sdt_desc[1] = (char)provlen;
-        memcpy( &psz_sdt_desc[2], psz_sdtprov, provlen );
-
-        /* service name length */
-        psz_sdt_desc[ 2 + provlen ] = (char)servlen;
-        memcpy( &psz_sdt_desc[3+provlen], psz_sdtserv, servlen );
-
-        dvbpsi_sdt_service_descriptor_add( p_service, 0x48,
-                                           (3 + provlen + servlen),
-                                           psz_sdt_desc );
     }
 
     for (unsigned i = 0; i < i_mapped_streams; i++ )
@@ -442,6 +491,13 @@ void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
             dvbpsi_pmt_es_descriptor_add( p_es, 0x0a, 4*p_stream->pes->i_langs,
                 p_stream->pes->lang);
         }
+
+        if( p_sdt )
+        {
+            UpdateServiceType( &pi_service_cats[p_stream->i_mapped_prog],
+                               &pi_service_types[p_stream->i_mapped_prog],
+                               p_stream->pes );
+        }
     }
 
     for (unsigned i = 0; i < i_programs; i++ )
@@ -453,9 +509,45 @@ void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
         dvbpsi_DeletePSISections(sect);
         dvbpsi_pmt_empty( &dvbpmt[i] );
     }
+    free( dvbpmt );
 
     if( p_sdt )
     {
+        for (unsigned i = 0; i < i_programs; i++ )
+        {
+            dvbpsi_sdt_service_t *p_service = dvbpsi_sdt_service_add( &sdtpsi,
+                                                                      pi_programs_number[i], /* service id */
+                                                                      false,     /* eit schedule */
+                                                                      false,     /* eit present */
+                                                                      4,         /* running status ("4=RUNNING") */
+                                                                      false );   /* free ca */
+
+            const char *psz_sdtprov = p_sdt->desc[i].psz_provider;
+            const char *psz_sdtserv = p_sdt->desc[i].psz_service_name;
+
+            if( !psz_sdtprov || !psz_sdtserv )
+                continue;
+            size_t provlen = VLC_CLIP(strlen(psz_sdtprov), 0, 255);
+            size_t servlen = VLC_CLIP(strlen(psz_sdtserv), 0, 255);
+
+            uint8_t psz_sdt_desc[3 + provlen + servlen];
+
+            psz_sdt_desc[0] = pi_service_types[i];
+
+            /* service provider name length */
+            psz_sdt_desc[1] = (char)provlen;
+            memcpy( &psz_sdt_desc[2], psz_sdtprov, provlen );
+
+            /* service name length */
+            psz_sdt_desc[ 2 + provlen ] = (char)servlen;
+            memcpy( &psz_sdt_desc[3+provlen], psz_sdtserv, servlen );
+
+            dvbpsi_sdt_service_descriptor_add( p_service, 0x48,
+                                               (3 + provlen + servlen),
+                                               psz_sdt_desc );
+        }
+        free( pi_service_types );
+
         dvbpsi_psi_section_t *sect = dvbpsi_sdt_sections_generate( p_dvbpsi, &sdtpsi );
         block_t *p_sdtblock = WritePSISection( sect );
         PEStoTS( p_opaque, pf_callback, p_sdtblock, p_sdt->ts.i_pid,
@@ -463,8 +555,6 @@ void BuildPMT( dvbpsi_t *p_dvbpsi, vlc_object_t *p_object,
         dvbpsi_DeletePSISections( sect );
         dvbpsi_sdt_empty( &sdtpsi );
     }
-
-    free( dvbpmt );
 }
 
 



More information about the vlc-commits mailing list