~ubuntu-branches/ubuntu/lucid/vlc/lucid-security

« back to all changes in this revision

Viewing changes to modules/demux/ts.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2009-09-25 14:44:17 UTC
  • mfrom: (3.5.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090925144417-87vomt575d0agvqa
Tags: 1.0.2-1ubuntu1
* Merge from Debian unstable (LP: #435524), remaining changes:
  - build against xulrunner-dev instead of iceape-dev
  - build against libx264-dev and install libx264 plugin
  - add Xb-Npp header to vlc package
  - recommend vlc-plugin-pulse for vlc

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * ts.c: Transport Stream input module for VLC.
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2004-2005 the VideoLAN team
5
 
 * $Id: 97de799e24e87bd0853bb5ab1974b5bb79fef47f $
 
5
 * $Id: 514096befa2e29e2baa09d7c2968b7f507bc9f0e $
6
6
 *
7
7
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
8
 *          Jean-Paul Saman <jpsaman #_at_# m2x.nl>
374
374
    bool        b_start_record;
375
375
};
376
376
 
 
377
static int i_broken_epg;
 
378
 
377
379
static int Demux    ( demux_t *p_demux );
378
380
static int DemuxFile( demux_t *p_demux );
379
381
static int Control( demux_t *p_demux, int i_query, va_list args );
2574
2576
 
2575
2577
 
2576
2578
#ifdef TS_USE_DVB_SI
 
2579
/* FIXME same than dvbsi_to_utf8 from dvb access */
 
2580
static char *EITConvertToUTF8( const unsigned char *psz_instring,
 
2581
                               size_t i_length )
 
2582
{
 
2583
    const char *psz_encoding;
 
2584
    char *psz_outstring;
 
2585
    char psz_encbuf[sizeof( "ISO_8859-123" )];
 
2586
    size_t i_in, i_out, offset = 1;
 
2587
    vlc_iconv_t iconv_handle;
 
2588
 
 
2589
    if( i_length < 1 ) return NULL;
 
2590
    if( psz_instring[0] >= 0x20 )
 
2591
    {
 
2592
        /* According to ETSI EN 300 468 Annex A, this should be ISO6937,
 
2593
         * but some broadcasters use different charset... */
 
2594
        if ( i_broken_epg == 1 )
 
2595
        {
 
2596
           psz_encoding = "ISO_8859-1";
 
2597
        }
 
2598
        else
 
2599
        {
 
2600
           psz_encoding = "ISO_6937";
 
2601
        }
 
2602
 
 
2603
        offset = 0;
 
2604
    }
 
2605
    else switch( psz_instring[0] )
 
2606
    {
 
2607
    case 0x01:
 
2608
        psz_encoding = "ISO_8859-5";
 
2609
        break;
 
2610
    case 0x02:
 
2611
        psz_encoding = "ISO_8859-6";
 
2612
        break;
 
2613
    case 0x03:
 
2614
        psz_encoding = "ISO_8859-7";
 
2615
        break;
 
2616
    case 0x04:
 
2617
        psz_encoding = "ISO_8859-8";
 
2618
        break;
 
2619
    case 0x05:
 
2620
        psz_encoding = "ISO_8859-9";
 
2621
        break;
 
2622
    case 0x06:
 
2623
        psz_encoding = "ISO_8859-10";
 
2624
        break;
 
2625
    case 0x07:
 
2626
        psz_encoding = "ISO_8859-11";
 
2627
        break;
 
2628
    case 0x08:
 
2629
        psz_encoding = "ISO_8859-12";
 
2630
        break;
 
2631
    case 0x09:
 
2632
        psz_encoding = "ISO_8859-13";
 
2633
        break;
 
2634
    case 0x0a:
 
2635
        psz_encoding = "ISO_8859-14";
 
2636
        break;
 
2637
    case 0x0b:
 
2638
        psz_encoding = "ISO_8859-15";
 
2639
        break;
 
2640
    case 0x10:
 
2641
#warning Is Latin-10 (psz_instring[2] == 16) really illegal?
 
2642
        if( i_length < 3 || psz_instring[1] != 0x00 || psz_instring[2] > 15
 
2643
         || psz_instring[2] == 0 )
 
2644
        {
 
2645
            psz_encoding = "UTF-8";
 
2646
            offset = 0;
 
2647
        }
 
2648
        else
 
2649
        {
 
2650
            sprintf( psz_encbuf, "ISO_8859-%u", psz_instring[2] );
 
2651
            psz_encoding = psz_encbuf;
 
2652
            offset = 3;
 
2653
        }
 
2654
        break;
 
2655
    case 0x11:
 
2656
#warning Is there a BOM or do we use a fixed endianess?
 
2657
        psz_encoding = "UTF-16";
 
2658
        break;
 
2659
    case 0x12:
 
2660
        psz_encoding = "KSC5601-1987";
 
2661
        break;
 
2662
    case 0x13:
 
2663
        psz_encoding = "GB2312"; /* GB-2312-1980 */
 
2664
        break;
 
2665
    case 0x14:
 
2666
        psz_encoding = "BIG-5";
 
2667
        break;
 
2668
    case 0x15:
 
2669
        psz_encoding = "UTF-8";
 
2670
        break;
 
2671
    default:
 
2672
        /* invalid */
 
2673
        psz_encoding = "UTF-8";
 
2674
        offset = 0;
 
2675
    }
 
2676
 
 
2677
    i_in = i_length - offset;
 
2678
    i_out = i_in * 6 + 1;
 
2679
 
 
2680
    psz_outstring = malloc( i_out );
 
2681
    if( !psz_outstring )
 
2682
    {
 
2683
        return NULL;
 
2684
    }
 
2685
 
 
2686
    iconv_handle = vlc_iconv_open( "UTF-8", psz_encoding );
 
2687
    if( iconv_handle == (vlc_iconv_t)(-1) )
 
2688
    {
 
2689
         /* Invalid character set (e.g. ISO_8859-12) */
 
2690
         memcpy( psz_outstring, &psz_instring[offset], i_in );
 
2691
         psz_outstring[i_in] = '\0';
 
2692
         EnsureUTF8( psz_outstring );
 
2693
    }
 
2694
    else
 
2695
    {
 
2696
        const char *psz_in = (const char *)&psz_instring[offset];
 
2697
        char *psz_out = psz_outstring;
 
2698
 
 
2699
        while( vlc_iconv( iconv_handle, &psz_in, &i_in,
 
2700
                          &psz_out, &i_out ) == (size_t)(-1) )
 
2701
        {
 
2702
            /* skip naughty byte. This may fail terribly for multibyte stuff,
 
2703
             * but what can we do anyway? */
 
2704
            psz_in++;
 
2705
            i_in--;
 
2706
            vlc_iconv( iconv_handle, NULL, NULL, NULL, NULL ); /* reset */
 
2707
        }
 
2708
        vlc_iconv_close( iconv_handle );
 
2709
 
 
2710
        *psz_out = '\0';
 
2711
    }
 
2712
    return psz_outstring;
 
2713
}
 
2714
 
2577
2715
static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt )
2578
2716
{
2579
2717
    demux_sys_t          *p_sys = p_demux->p_sys;
2595
2733
             p_sdt->i_ts_id, p_sdt->i_version, p_sdt->b_current_next,
2596
2734
             p_sdt->i_network_id );
2597
2735
 
 
2736
    i_broken_epg = 0;
 
2737
 
2598
2738
    for( p_srv = p_sdt->p_first_service; p_srv; p_srv = p_srv->p_next )
2599
2739
    {
2600
2740
        vlc_meta_t          *p_meta;
2637
2777
                    "DVB MHP service"
2638
2778
                };
2639
2779
                dvbpsi_service_dr_t *pD = dvbpsi_DecodeServiceDr( p_dr );
2640
 
                char str1[257];
2641
 
                char str2[257];
2642
 
 
2643
 
                memcpy( str1, pD->i_service_provider_name,
2644
 
                        pD->i_service_provider_name_length );
2645
 
                str1[pD->i_service_provider_name_length] = '\0';
2646
 
                memcpy( str2, pD->i_service_name, pD->i_service_name_length );
2647
 
                str2[pD->i_service_name_length] = '\0';
 
2780
                char *str1 = NULL;
 
2781
                char *str2 = NULL;
 
2782
 
 
2783
                /* Workarounds for broadcasters with broken EPG */
 
2784
 
 
2785
                if ( p_sdt->i_network_id == 133 )
 
2786
                   i_broken_epg = 1;  /* SKY DE & BetaDigital use ISO8859-1 */
 
2787
 
 
2788
                if ( (pD->i_service_provider_name_length == 4) &&
 
2789
                     !strncmp(pD->i_service_provider_name, "CSAT", 4) )
 
2790
                   i_broken_epg = 1;  /* CanalSat FR uses ISO8859-1 */
 
2791
 
 
2792
                /* FIXME: Digital+ ES also uses ISO8859-1 */
 
2793
 
 
2794
                str1 = EITConvertToUTF8(pD->i_service_provider_name,
 
2795
                                        pD->i_service_provider_name_length);
 
2796
                str2 = EITConvertToUTF8(pD->i_service_name,
 
2797
                                        pD->i_service_name_length);
2648
2798
 
2649
2799
                msg_Dbg( p_demux, "    - type=%d provider=%s name=%s",
2650
2800
                         pD->i_service_type, str1, str2 );
2653
2803
                vlc_meta_SetPublisher( p_meta, str1 );
2654
2804
                if( pD->i_service_type >= 0x01 && pD->i_service_type <= 0x10 )
2655
2805
                    psz_type = ppsz_type[pD->i_service_type];
 
2806
                free( str1 );
 
2807
                free( str2 );
2656
2808
            }
2657
2809
        }
2658
2810
 
2742
2894
}
2743
2895
#undef CVT_FROM_BCD
2744
2896
 
2745
 
/* FIXME same than dvbsi_to_utf8 from dvb access */
2746
 
static char *EITConvertToUTF8( const unsigned char *psz_instring,
2747
 
                               size_t i_length )
2748
 
{
2749
 
    const char *psz_encoding;
2750
 
    char *psz_outstring;
2751
 
    char psz_encbuf[sizeof( "ISO_8859-123" )];
2752
 
    size_t i_in, i_out, offset = 1;
2753
 
    vlc_iconv_t iconv_handle;
2754
 
 
2755
 
    if( i_length < 1 ) return NULL;
2756
 
    if( psz_instring[0] >= 0x20 )
2757
 
    {
2758
 
        psz_encoding = "ISO_8859-1";
2759
 
        /* According to the specification, this should be ISO6937,
2760
 
         * but it seems Latin-1 is used instead. */
2761
 
        offset = 0;
2762
 
    }
2763
 
    else switch( psz_instring[0] )
2764
 
    {
2765
 
    case 0x01:
2766
 
        psz_encoding = "ISO_8859-5";
2767
 
        break;
2768
 
    case 0x02:
2769
 
        psz_encoding = "ISO_8859-6";
2770
 
        break;
2771
 
    case 0x03:
2772
 
        psz_encoding = "ISO_8859-7";
2773
 
        break;
2774
 
    case 0x04:
2775
 
        psz_encoding = "ISO_8859-8";
2776
 
        break;
2777
 
    case 0x05:
2778
 
        psz_encoding = "ISO_8859-9";
2779
 
        break;
2780
 
    case 0x06:
2781
 
        psz_encoding = "ISO_8859-10";
2782
 
        break;
2783
 
    case 0x07:
2784
 
        psz_encoding = "ISO_8859-11";
2785
 
        break;
2786
 
    case 0x08:
2787
 
        psz_encoding = "ISO_8859-12";
2788
 
        break;
2789
 
    case 0x09:
2790
 
        psz_encoding = "ISO_8859-13";
2791
 
        break;
2792
 
    case 0x0a:
2793
 
        psz_encoding = "ISO_8859-14";
2794
 
        break;
2795
 
    case 0x0b:
2796
 
        psz_encoding = "ISO_8859-15";
2797
 
        break;
2798
 
    case 0x10:
2799
 
#warning Is Latin-10 (psz_instring[2] == 16) really illegal?
2800
 
        if( i_length < 3 || psz_instring[1] != 0x00 || psz_instring[2] > 15
2801
 
         || psz_instring[2] == 0 )
2802
 
        {
2803
 
            psz_encoding = "UTF-8";
2804
 
            offset = 0;
2805
 
        }
2806
 
        else
2807
 
        {
2808
 
            sprintf( psz_encbuf, "ISO_8859-%u", psz_instring[2] );
2809
 
            psz_encoding = psz_encbuf;
2810
 
            offset = 3;
2811
 
        }
2812
 
        break;
2813
 
    case 0x11:
2814
 
#warning Is there a BOM or do we use a fixed endianess?
2815
 
        psz_encoding = "UTF-16";
2816
 
        break;
2817
 
    case 0x12:
2818
 
        psz_encoding = "KSC5601-1987";
2819
 
        break;
2820
 
    case 0x13:
2821
 
        psz_encoding = "GB2312"; /* GB-2312-1980 */
2822
 
        break;
2823
 
    case 0x14:
2824
 
        psz_encoding = "BIG-5";
2825
 
        break;
2826
 
    case 0x15:
2827
 
        psz_encoding = "UTF-8";
2828
 
        break;
2829
 
    default:
2830
 
        /* invalid */
2831
 
        psz_encoding = "UTF-8";
2832
 
        offset = 0;
2833
 
    }
2834
 
 
2835
 
    i_in = i_length - offset;
2836
 
    i_out = i_in * 6 + 1;
2837
 
 
2838
 
    psz_outstring = malloc( i_out );
2839
 
    if( !psz_outstring )
2840
 
    {
2841
 
        return NULL;
2842
 
    }
2843
 
 
2844
 
    iconv_handle = vlc_iconv_open( "UTF-8", psz_encoding );
2845
 
    if( iconv_handle == (vlc_iconv_t)(-1) )
2846
 
    {
2847
 
         /* Invalid character set (e.g. ISO_8859-12) */
2848
 
         memcpy( psz_outstring, &psz_instring[offset], i_in );
2849
 
         psz_outstring[i_in] = '\0';
2850
 
         EnsureUTF8( psz_outstring );
2851
 
    }
2852
 
    else
2853
 
    {
2854
 
        const char *psz_in = (const char *)&psz_instring[offset];
2855
 
        char *psz_out = psz_outstring;
2856
 
 
2857
 
        while( vlc_iconv( iconv_handle, &psz_in, &i_in,
2858
 
                          &psz_out, &i_out ) == (size_t)(-1) )
2859
 
        {
2860
 
            /* skip naughty byte. This may fail terribly for multibyte stuff,
2861
 
             * but what can we do anyway? */
2862
 
            psz_in++;
2863
 
            i_in--;
2864
 
            vlc_iconv( iconv_handle, NULL, NULL, NULL, NULL ); /* reset */
2865
 
        }
2866
 
        vlc_iconv_close( iconv_handle );
2867
 
 
2868
 
        *psz_out = '\0';
2869
 
    }
2870
 
    return psz_outstring;
2871
 
}
2872
 
 
2873
 
static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit )
 
2897
 
 
2898
static void EITCallBack( demux_t *p_demux,
 
2899
                         dvbpsi_eit_t *p_eit, bool b_current_following )
2874
2900
{
2875
2901
    demux_sys_t        *p_sys = p_demux->p_sys;
2876
2902
    dvbpsi_eit_event_t *p_evt;
2953
2979
                        if( psz_dsc && psz_itm )
2954
2980
                        {
2955
2981
                            msg_Dbg( p_demux, "       - desc='%s' item='%s'", psz_dsc, psz_itm );
2956
 
 
 
2982
#if 0
2957
2983
                            psz_extra = realloc( psz_extra, strlen(psz_extra) + strlen(psz_dsc) + strlen(psz_itm) + 3 + 1 );
2958
2984
                            strcat( psz_extra, "(" );
2959
2985
                            strcat( psz_extra, psz_dsc );
2960
2986
                            strcat( psz_extra, " " );
2961
2987
                            strcat( psz_extra, psz_itm );
2962
2988
                            strcat( psz_extra, ")" );
 
2989
#endif
2963
2990
                        }
2964
2991
                        free( psz_dsc );
2965
2992
                        free( psz_itm );
2974
3001
 
2975
3002
        /* */
2976
3003
        if( i_start > 0 )
2977
 
            vlc_epg_AddEvent( p_epg, i_start, i_duration, psz_name, psz_text, psz_extra );
 
3004
            vlc_epg_AddEvent( p_epg, i_start, i_duration, psz_name, psz_text,
 
3005
                              *psz_extra ? psz_extra : NULL );
2978
3006
 
2979
3007
        /* Update "now playing" field */
2980
3008
        if( p_evt->i_running_status == 0x04 && i_start > 0 )
2987
3015
    }
2988
3016
    if( p_epg->i_event > 0 )
2989
3017
    {
2990
 
        if( p_eit->i_service_id == p_sys->i_current_program )
 
3018
        if( p_eit->i_service_id == p_sys->i_current_program && b_current_following )
2991
3019
        {
2992
3020
            p_sys->i_dvb_length = 0;
2993
3021
            p_sys->i_dvb_start = 0;
3004
3032
 
3005
3033
    dvbpsi_DeleteEIT( p_eit );
3006
3034
}
 
3035
static void EITCallBackCurrentFollowing( demux_t *p_demux, dvbpsi_eit_t *p_eit )
 
3036
{
 
3037
    EITCallBack( p_demux, p_eit, true );
 
3038
}
 
3039
static void EITCallBackSchedule( demux_t *p_demux, dvbpsi_eit_t *p_eit )
 
3040
{
 
3041
    EITCallBack( p_demux, p_eit, false );
 
3042
}
3007
3043
 
3008
3044
static void PSINewTableCallBack( demux_t *p_demux, dvbpsi_handle h,
3009
3045
                                 uint8_t  i_table_id, uint16_t i_extension )
3027
3063
        msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3028
3064
                 i_table_id, i_table_id, i_extension, i_extension );
3029
3065
 
3030
 
        dvbpsi_AttachEIT( h, i_table_id, i_extension,
3031
 
                          (dvbpsi_eit_callback)EITCallBack, p_demux );
 
3066
        dvbpsi_eit_callback cb = i_table_id == 0x4e ?
 
3067
                                    (dvbpsi_eit_callback)EITCallBackCurrentFollowing :
 
3068
                                    (dvbpsi_eit_callback)EITCallBackSchedule;
 
3069
        dvbpsi_AttachEIT( h, i_table_id, i_extension, cb, p_demux );
3032
3070
    }
3033
3071
}
3034
3072
#endif