~ubuntu-branches/ubuntu/precise/me-tv/precise-proposed

« back to all changes in this revision

Viewing changes to src/dvb_si.cc

  • Committer: Bazaar Package Importer
  • Author(s): Philipp Kern
  • Date: 2008-07-23 14:03:56 UTC
  • mfrom: (1.1.3 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080723140356-m6ze7fbkydes42c7
Tags: 0.5.33-3
Fix xine-lib ffmpeg dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "log.hh"
23
23
#include "string_utility.hh"
24
24
#include "application.hh"
 
25
#include "libucsi/atsc/types.h"
25
26
 
26
27
#define SHORT_EVENT                     0x4D
27
28
#define EXTENDED_EVENT          0x4E
28
29
 
 
30
#define GPS_EPOCH                       315964800
 
31
 
 
32
void dump(guchar* buffer, gsize length)
 
33
{
 
34
        for (guint i = 0; i < length; i++)
 
35
        {
 
36
                guchar ch = buffer[i];
 
37
                if (g_ascii_isalnum(ch))
 
38
                {
 
39
                        Log::write ("buffer[%d] = 0x%02X; // (%c)", i, ch, ch);
 
40
                }
 
41
                else
 
42
                {
 
43
                        Log::write ("buffer[%d] = 0x%02X;", i, ch);
 
44
                }
 
45
        }
 
46
}
 
47
 
29
48
static guint32 crc_table[256] = {
30
49
    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
31
50
    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
88
107
Event::Event()
89
108
{
90
109
        event_id = 0;
91
 
        start_time_MJD = 0;
92
 
        start_time_UTC = 0;
 
110
        start_time = 0;
93
111
        duration = 0;
94
112
        running_status = 0;
95
113
        free_CA_mode = 0;
96
 
        
97
 
        dur_hour = 0;
98
 
        dur_min = 0;
99
 
        dur_sec = 0;
100
 
        
101
 
        start_year = 0;
102
 
        start_month = 0;
103
 
        start_day = 0;
104
 
        
105
 
        start_hour = 0;
106
 
        start_min = 0;
107
 
        start_sec = 0;
108
114
}
109
115
 
110
116
DvbSectionParser::DvbSectionParser()
156
162
        }
157
163
}
158
164
 
 
165
gsize get_atsc_text(String& string, const guchar* buffer)
 
166
{
 
167
        size_t text_position = 0;
 
168
        gsize offset = 0;
 
169
        
 
170
        gsize number_strings = buffer[offset++];
 
171
        for (guint i = 0; i < number_strings; i++)
 
172
        {
 
173
                offset += 3;
 
174
                gsize number_segments = buffer[offset++];
 
175
                for (guint j = 0; j < number_segments; j++)
 
176
                {
 
177
                        struct atsc_text_string_segment* segment = (struct atsc_text_string_segment*)&buffer[offset];
 
178
                        
 
179
                        uint8_t* text = NULL;
 
180
                        size_t text_length = 0;
 
181
                        
 
182
                        atsc_text_segment_decode(segment, &text, &text_length, &text_position);
 
183
 
 
184
                        string.append((const gchar*)text, text_position);
 
185
                }
 
186
        }
 
187
        
 
188
        return offset;
 
189
}
 
190
 
159
191
gboolean DvbSectionParser::find_descriptor(uint8_t tag, const unsigned char *buf, int descriptors_loop_len, 
160
192
        const unsigned char **desc, int *desc_len)
161
193
{
332
364
        }
333
365
}
334
366
 
 
367
void DvbSectionParser::parse_psip_mgt(DvbDemuxer& demuxer, MasterGuideTable& table)
 
368
{
 
369
        gsize section_length = read_section(demuxer);
 
370
        guint offset = 9;
 
371
        guint tables_defined = get_bits(&buffer[offset], 0, 16);
 
372
        offset += 2;
 
373
        
 
374
        for (guint i = 0; i < tables_defined; i++)
 
375
        {
 
376
                MasterGuideTableTable mgtt;
 
377
                mgtt.type = get_bits(&buffer[offset], 0, 16);
 
378
                offset += 2;
 
379
                mgtt.pid = get_bits(&buffer[offset], 3, 13);
 
380
                table.tables.push_back(mgtt);   
 
381
                offset += 7;
 
382
                guint table_type_descriptors_length = get_bits(&buffer[offset], 4, 12);
 
383
                offset += table_type_descriptors_length + 2;
 
384
        }
 
385
}
 
386
 
 
387
void DvbSectionParser::parse_psip_eis(DvbDemuxer& demuxer, EventInformationSection& section)
 
388
{
 
389
        gsize section_length = read_section(demuxer);
 
390
        guint offset = 3;
 
391
 
 
392
        section.service_id = get_bits(&buffer[offset], 0, 16);
 
393
        
 
394
        offset += 6;
 
395
        guint num_events_in_section = buffer[offset++];
 
396
        
 
397
        for (int i = 0; i < num_events_in_section; i++)
 
398
        {
 
399
                Event event;
 
400
 
 
401
                event.event_id          = get_bits (&buffer[offset], 2, 14); offset += 2;
 
402
                event.start_time        = get_bits (&buffer[offset], 0, 32); offset += 4;
 
403
                event.duration          = get_bits (&buffer[offset], 4, 20); offset += 3;
 
404
 
 
405
                event.start_time += GPS_EPOCH;
 
406
                event.start_time += timezone;
 
407
                
 
408
                gsize title_length = buffer[offset++];
 
409
                if (title_length > 0)
 
410
                {
 
411
                        get_atsc_text (event.title, &buffer[offset++]);
 
412
                        offset += title_length;
 
413
                }
 
414
                
 
415
                guint descriptors_length = buffer[offset++];
 
416
                offset += descriptors_length;
 
417
                
 
418
                section.events.push_back(event);
 
419
        }
 
420
}
 
421
 
335
422
void DvbSectionParser::parse_eis(DvbDemuxer& demuxer, EventInformationSection& section)
336
423
{
337
424
        gsize section_length = read_section(demuxer);
354
441
        {
355
442
                Event event;
356
443
 
357
 
                event.event_id                   = get_bits (&buffer[offset], 0, 16);
358
 
                event.start_time_MJD             = get_bits (&buffer[offset], 16, 16);
359
 
                event.start_time_UTC             = get_bits (&buffer[offset], 32, 24);
360
 
                event.duration                   = get_bits (&buffer[offset], 56, 24);
361
 
                event.running_status             = get_bits (&buffer[offset], 80, 3);
362
 
                event.free_CA_mode               = get_bits (&buffer[offset], 83, 1);
 
444
                gulong  start_time_MJD;  // 16
 
445
                gulong  start_time_UTC;  // 24
 
446
                gulong  duration;
 
447
 
 
448
                event.event_id                  = get_bits (&buffer[offset], 0, 16);
 
449
                start_time_MJD                  = get_bits (&buffer[offset], 16, 16);
 
450
                start_time_UTC                  = get_bits (&buffer[offset], 32, 24);
 
451
                duration                                = get_bits (&buffer[offset], 56, 24);
 
452
                event.running_status    = get_bits (&buffer[offset], 80, 3);
 
453
                event.free_CA_mode              = get_bits (&buffer[offset], 83, 1);
363
454
 
364
455
                unsigned int descriptors_loop_length  = get_bits (&buffer[offset], 84, 12);
365
456
                offset += 12;
366
457
                unsigned int end_descriptor_offset = descriptors_loop_length + offset;
367
458
 
368
 
                event.dur_hour = ((event.duration >> 20)&0xf)*10+((event.duration >> 16)&0xf);
369
 
                event.dur_min =  ((event.duration >> 12)&0xf)*10+((event.duration >>  8)&0xf);
370
 
                event.dur_sec =  ((event.duration >>  4)&0xf)*10+((event.duration      )&0xf);
 
459
                guint event_dur_hour = ((duration >> 20)&0xf)*10+((duration >> 16)&0xf);
 
460
                guint event_dur_min =  ((duration >> 12)&0xf)*10+((duration >>  8)&0xf);
 
461
                guint event_dur_sec =  ((duration >>  4)&0xf)*10+((duration      )&0xf);
371
462
 
372
 
                if ( event.start_time_MJD > 0 )
 
463
                event.duration = (event_dur_hour*60 + event_dur_min) * 60;
 
464
                
 
465
                guint event_start_day = 0;
 
466
                guint event_start_month = 0;
 
467
                guint event_start_year = 0;
 
468
                
 
469
                if (start_time_MJD > 0 && event.event_id != 0)
373
470
                {
374
 
                        long year =  (long) ((event.start_time_MJD  - 15078.2) / 365.25);
375
 
                        long month =  (long) ((event.start_time_MJD - 14956.1 - (long)(year * 365.25) ) / 30.6001);
376
 
                        event.start_day =  (long) (event.start_time_MJD - 14956 - (long)(year * 365.25) - (long)(month * 30.6001));
 
471
                        long year =  (long) ((start_time_MJD  - 15078.2) / 365.25);
 
472
                        long month =  (long) ((start_time_MJD - 14956.1 - (long)(year * 365.25) ) / 30.6001);
 
473
                        event_start_day =  (long) (start_time_MJD - 14956 - (long)(year * 365.25) - (long)(month * 30.6001));
377
474
 
378
475
                        long k = (month == 14 || month == 15) ? 1 : 0;
379
476
 
380
 
                        event.start_year = year + k + 1900;
381
 
                        event.start_month = month - 1 - k * 12;
382
 
                }
383
 
 
384
 
                event.start_hour = ((event.start_time_UTC >> 20)&0xf)*10+((event.start_time_UTC >> 16)&0xf);
385
 
                event.start_min =  ((event.start_time_UTC >> 12)&0xf)*10+((event.start_time_UTC >>  8)&0xf);
386
 
                event.start_sec =  ((event.start_time_UTC >>  4)&0xf)*10+((event.start_time_UTC      )&0xf);
387
 
 
388
 
                while (offset < end_descriptor_offset)
389
 
                {
390
 
                        offset += decode_short_event(&buffer[offset], event);
391
 
                }
 
477
                        event_start_year = year + k + 1900;
 
478
                        event_start_month = month - 1 - k * 12;
 
479
 
 
480
                        guint event_start_hour = ((start_time_UTC >> 20)&0xf)*10+((start_time_UTC >> 16)&0xf);
 
481
                        guint event_start_min =  ((start_time_UTC >> 12)&0xf)*10+((start_time_UTC >>  8)&0xf);
 
482
                        guint event_start_sec =  ((start_time_UTC >>  4)&0xf)*10+((start_time_UTC      )&0xf);
 
483
 
 
484
                        struct tm t;
 
485
 
 
486
                        memset(&t, 0, sizeof(struct tm));
 
487
 
 
488
                        t.tm_min        = event_start_min;
 
489
                        t.tm_hour       = event_start_hour;
 
490
                        t.tm_mday       = event_start_day;
 
491
                        t.tm_mon        = event_start_month - 1;
 
492
                        t.tm_year       = event_start_year - 1900;
 
493
                        
 
494
                        event.start_time = mktime(&t);
392
495
                
393
 
                if (offset > end_descriptor_offset)
394
 
                {
395
 
                        throw Exception("ASSERT: offset > end_descriptor_offset");
 
496
                        while (offset < end_descriptor_offset)
 
497
                        {
 
498
                                offset += decode_event_descriptor(&buffer[offset], event);
 
499
                        }
 
500
 
 
501
                        if (offset > end_descriptor_offset)
 
502
                        {
 
503
                                throw Exception("ASSERT: offset > end_descriptor_offset");
 
504
                        }
 
505
 
 
506
                        section.events.push_back( event );
396
507
                }
397
 
 
398
 
                section.events.push_back( event );
399
508
        }
400
509
        section.crc = get_bits (&buffer[offset], 0, 32);
401
510
        offset += 4;
406
515
        }
407
516
}
408
517
 
409
 
gsize DvbSectionParser::decode_short_event (const guchar* buffer, Event& event)
 
518
gsize DvbSectionParser::decode_event_descriptor (const guchar* event_buffer, Event& event)
410
519
{
411
 
        if (buffer[1] == 0)
 
520
        if (event_buffer[1] == 0)
412
521
        {
413
522
                return 2;
414
523
        }
415
 
                
416
 
        gsize descriptor_length = buffer[1] + 2;
 
524
 
 
525
        gsize descriptor_length = event_buffer[1] + 2;
417
526
        
418
 
        switch(buffer[0])
419
 
        {
 
527
        guint descriptor_tag = event_buffer[0]; 
 
528
        switch(descriptor_tag)
 
529
        {               
 
530
        case EXTENDED_EVENT:
 
531
                {
 
532
                        String language;
 
533
                        String title;
 
534
                        String description;
 
535
 
 
536
                        language = get_lang_desc (event_buffer);
 
537
                        unsigned int offset = 6;
 
538
                        guint length_of_items = event_buffer[offset];
 
539
                        offset++;
 
540
                        while (length_of_items > offset - 7)
 
541
                        {
 
542
                                offset += get_text(description, &event_buffer[offset]);                 
 
543
                                offset += get_text(title, &event_buffer[offset]);
 
544
                        }
 
545
                        offset += get_text(description, &event_buffer[offset]);
 
546
                        
 
547
                        if (event.description.is_empty())
 
548
                        {
 
549
                                event.description = description;
 
550
                        }
 
551
 
 
552
                        if (event.title.is_empty())
 
553
                        {
 
554
                                event.title = title;
 
555
                        }
 
556
                }
 
557
                break;
 
558
 
420
559
        case SHORT_EVENT:
421
560
                {
422
561
                        String language;
423
562
                        String title;
424
563
                        String description;
425
564
                        
426
 
                        language = get_lang_desc (buffer);
 
565
                        language = get_lang_desc (event_buffer);
427
566
                        unsigned int offset = 5;
428
 
                        offset += get_text(title, &buffer[offset]);
429
 
                        offset += get_text(description, &buffer[offset]);
 
567
                        offset += get_text(title, &event_buffer[offset]);
 
568
                        offset += get_text(description, &event_buffer[offset]);
430
569
                        
431
570
                        if (event.title.is_empty())
432
571
                        {
467
606
        return val;
468
607
}
469
608
 
470
 
gsize DvbSectionParser::get_text(String& s, const guchar* buffer)
 
609
 
 
610
gsize DvbSectionParser::get_text(String& s, const guchar* text_buffer)
471
611
{
472
 
        gsize length = buffer[0];
 
612
        gsize length = text_buffer[0];
473
613
        guint text_index = 0;
474
614
        gchar text[length];
475
615
        guint index = 0;
486
626
                }
487
627
                else // Determine codeset from stream
488
628
                {                       
489
 
                        if (buffer[index] < 0x20)
 
629
                        if (text_buffer[index] < 0x20)
490
630
                        {
491
 
                                switch (buffer[index])
 
631
                                switch (text_buffer[index])
492
632
                                {
493
633
                                case 0x01: codeset = "ISO-8859-5"; break;
494
634
                                case 0x02: codeset = "ISO-8859-6"; break;
507
647
                                        {
508
648
                                                // Skip 0x00
509
649
                                                index++;
510
 
                                                if (buffer[index] != 0x00)
 
650
                                                if (text_buffer[index] != 0x00)
511
651
                                                {
512
652
                                                        Log::write(_("Warning: second byte of code table id was not 0"));
513
653
                                                }
514
654
                                                
515
655
                                                index++;
516
656
                                                
517
 
                                                switch(buffer[index])
 
657
                                                switch(text_buffer[index])
518
658
                                                {
519
659
                                                case 0x01: codeset = "ISO-8859-1"; break;
520
660
                                                case 0x02: codeset = "ISO-8859-2"; break;
543
683
 
544
684
                if (epg_encoding == "iso6937")
545
685
                {
546
 
                        s = convert_iso6937(buffer + index, length);
 
686
                        s = convert_iso6937(text_buffer + index, length);
547
687
                }
548
688
                else
549
689
                {
551
691
                        {
552
692
                                while (index < (length + 1))
553
693
                                {
554
 
                                        u_char ch = buffer[index];
 
694
                                        u_char ch = text_buffer[index];
555
695
 
556
696
                                        if (codeset == "UTF-16BE")
557
697
                                        {
601
741
                                        Log::write("Length: %d", length);
602
742
                                        for (guint i = 0; i < (length+1); i++)
603
743
                                        {
604
 
                                                gchar ch = buffer[i];
 
744
                                                gchar ch = text_buffer[i];
605
745
                                                if (!isprint(ch))
606
746
                                                {
607
 
                                                        Log::write("buffer[%d]\t= 0x%02X", i, buffer[i]);
 
747
                                                        Log::write("text_buffer[%d]\t= 0x%02X", i, text_buffer[i]);
608
748
                                                }
609
749
                                                else
610
750
                                                {
611
 
                                                        Log::write("buffer[%d]\t= 0x%02X '%c'", i, buffer[i], buffer[i]);
 
751
                                                        Log::write("text_buffer[%d]\t= 0x%02X '%c'", i, text_buffer[i], text_buffer[i]);
612
752
                                                }
613
753
                                        }
614
754
                                        throw Exception(message);
627
767
        return length + 1;
628
768
}
629
769
 
630
 
String DvbSectionParser::convert_iso6937(const guchar* buffer, gsize length)
 
770
String DvbSectionParser::convert_iso6937(const guchar* text_buffer, gsize length)
631
771
{
632
772
        String result;
633
773
        gint val;
635
775
        
636
776
        for (i=0; i<length; i++ )
637
777
        {
638
 
                if ( buffer[i]<0x20 || (buffer[i]>=0x80 && buffer[i]<=0x9f) )
 
778
                if ( text_buffer[i]<0x20 || (text_buffer[i]>=0x80 && text_buffer[i]<=0x9f) )
639
779
                {
640
780
                        continue; // control codes
641
781
                }
642
782
                
643
 
                if ( buffer[i]>=0xC0 && buffer[i]<=0xCF ) // next char has accent
 
783
                if ( text_buffer[i]>=0xC0 && text_buffer[i]<=0xCF ) // next char has accent
644
784
                {
645
785
                        if ( i==length-1 ) // Accent char not followed by char
646
786
                        {
647
787
                                continue;
648
788
                        }
649
789
                        
650
 
                        val = ( buffer[i]<<8 ) + buffer[i+1];
 
790
                        val = ( text_buffer[i]<<8 ) + text_buffer[i+1];
651
791
                        ++i;
652
792
                        
653
793
                        switch (val)
822
962
                }
823
963
                else
824
964
                {
825
 
                        switch ( buffer[i] )
 
965
                        switch ( text_buffer[i] )
826
966
                        {
827
967
                                case 0xa0: result += gunichar(0x00A0); break; //NO-BREAK SPACE
828
968
                                case 0xa1: result += gunichar(0x00A1); break; //INVERTED EXCLAMATION MARK
897
1037
                                case 0xfd:      result += gunichar(0x0167); break; //LATIN SMALL LETTER T WITH STROKE
898
1038
                                case 0xfe:      result += gunichar(0x014B); break; //LATIN SMALL LETTER ENG (Sami)
899
1039
                                case 0xff: result += gunichar(0x00AD); break; //SOFT HYPHEN
900
 
                                default: result += (char)buffer[i];
 
1040
                                default: result += (char)text_buffer[i];
901
1041
                        }
902
1042
                }
903
1043
        }