~ubuntu-branches/debian/jessie/tsdecrypt/jessie

« back to all changes in this revision

Viewing changes to libtsfuncs/pes_es.c

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2012-04-04 09:42:43 UTC
  • Revision ID: package-import@ubuntu.com-20120404094243-qsc40h18oolnxw5r
Tags: upstream-7.0
ImportĀ upstreamĀ versionĀ 7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * PES elementary stream functions
 
3
 * Copyright (C) 2010-2011 Unix Solutions Ltd.
 
4
 *
 
5
 * Released under MIT license.
 
6
 * See LICENSE-MIT.txt for license terms.
 
7
 */
 
8
#include <netdb.h>
 
9
#include <string.h>
 
10
 
 
11
#include "tsfuncs.h"
 
12
 
 
13
int ts_pes_es_mpeg_audio_header_parse(struct mpeg_audio_header *mpghdr, uint8_t *data, int datasz) {
 
14
        if (datasz < 4)
 
15
                return 0;
 
16
 
 
17
        uint8_t d1 = data[0];
 
18
        uint8_t d2 = data[1];
 
19
        uint8_t d3 = data[2];
 
20
        uint8_t d4 = data[3];
 
21
 
 
22
        mpghdr->syncword                = (int)d1 << 4 | (d2 >> 4);                     // 12 bits
 
23
        mpghdr->ID                              = bit_on(d2, bit_4);                            // 1 bit
 
24
        mpghdr->layer                   = (d2 &~ 0xf9) >> 1;                            // 2 bits
 
25
        mpghdr->protection_bit  = bit_on(d2, bit_1);                            // 1 bit
 
26
 
 
27
        mpghdr->bitrate_index   = d3 >> 4;                                                      // 4 bits
 
28
        mpghdr->sampl_freq              = (d3 &~ 0xf3) >> 2;                            // 2 bits
 
29
        mpghdr->padding_bit             = bit_on(d3, bit_2);                            // 1 bit
 
30
        mpghdr->private_bit             = bit_on(d3, bit_1);                            // 1 bit
 
31
 
 
32
        mpghdr->mode                    = d4 >> 6;                                                      // 2 bits
 
33
        mpghdr->mode_extension  = (d4 &~ 0xcf) >> 4;                            // 2 bits
 
34
        mpghdr->copyright               = bit_on(d4, bit_4);                            // 1 bit
 
35
        mpghdr->org_home                = bit_on(d4, bit_3);                            // 1 bit
 
36
        mpghdr->emphasis                = d4 &~ 0xfc;                                           // 2 bits
 
37
 
 
38
        if (mpghdr->syncword != 0xfff) {
 
39
                ts_LOGf("!!! Error parsing mpeg audio header! Syncword should be 0xfff but it is 0x%03x!\n", mpghdr->syncword);
 
40
                return 0;
 
41
        } else {
 
42
                mpghdr->initialized = 1;
 
43
                return 1;
 
44
        }
 
45
}
 
46
 
 
47
void ts_pes_es_mpeg_audio_header_dump(struct mpeg_audio_header *mpghdr) {
 
48
        if (!mpghdr->initialized)
 
49
                return;
 
50
        // See ISO-11172-3 for more info
 
51
        ts_LOGf("  - ES analyze audio frame\n");
 
52
        ts_LOGf("    - Syncword      : %x\n", mpghdr->syncword);
 
53
        if (mpghdr->syncword != 0xfff) {
 
54
                ts_LOGf("!!! ERROR: MPEG audo Syncword should be 0xfff!\n");
 
55
                return;
 
56
        }
 
57
        ts_LOGf("    - ID            : %d (%s)\n", mpghdr->ID, mpghdr->ID ? "MPEG Audio" : "Other");
 
58
        ts_LOGf("    - layer         : %d (%s)\n", mpghdr->layer,
 
59
                mpghdr->layer == 0 ? "reserved" :
 
60
                mpghdr->layer == 1 ? "Layer III" :
 
61
                mpghdr->layer == 2 ? "Layer II" :
 
62
                mpghdr->layer == 3 ? "Layer I" : "reserved"
 
63
        );
 
64
        ts_LOGf("    - protection_bit: %x\n", mpghdr->protection_bit);
 
65
        int br = 0;
 
66
        if (mpghdr->layer > 0 && mpghdr->layer < 4) {
 
67
                int bitrate_index_table[4][16] = {
 
68
                        [3] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1},      // Layer 1
 
69
                        [2] = { 0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, -1},      // Layer 2
 
70
                        [1] = { 0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, -1}       // Layer 3
 
71
                };
 
72
                br = bitrate_index_table[mpghdr->layer][mpghdr->bitrate_index];
 
73
        }
 
74
        ts_LOGf("    - bitrate_index : %d (%d kBit/s)\n", mpghdr->bitrate_index, br);
 
75
        ts_LOGf("    - sampl_freq    : %d (%s)\n", mpghdr->sampl_freq,
 
76
                mpghdr->sampl_freq == 0 ? "44.1 kHz" :
 
77
                mpghdr->sampl_freq == 1 ? "48 kHz" :
 
78
                mpghdr->sampl_freq == 2 ? "32 kHz" : "reserved"
 
79
        );
 
80
        ts_LOGf("    - padding_bit   : %d\n", mpghdr->padding_bit);
 
81
        ts_LOGf("    - private_bit   : %d\n", mpghdr->private_bit);
 
82
        ts_LOGf("    - mode          : %d (%s)\n", mpghdr->mode,
 
83
                mpghdr->mode == 0 ? "stereo" :
 
84
                mpghdr->mode == 1 ? "join_stereo" :
 
85
                mpghdr->mode == 2 ? "dual_channel" : "single_channel"
 
86
        );
 
87
        ts_LOGf("    - mode_extension: %x\n", mpghdr->mode_extension);
 
88
        ts_LOGf("    - copyright     : %x\n", mpghdr->copyright);
 
89
        ts_LOGf("    - org_home      : %x\n", mpghdr->org_home);
 
90
        ts_LOGf("    - emphasis      : %d (%s)\n", mpghdr->emphasis,
 
91
                mpghdr->emphasis == 0 ? "none" :
 
92
                mpghdr->emphasis == 1 ? "50/15 microseconds" :
 
93
                mpghdr->emphasis == 2 ? "reserved" : "CCITT J.17"
 
94
        );
 
95
}
 
96
 
 
97
void ts_pes_es_parse(struct ts_pes *pes) {
 
98
        if (!pes->es_data)
 
99
                return;
 
100
 
 
101
        // Parse MPEG audio packet header
 
102
        if ((pes->is_audio_mpeg1 || pes->is_audio_mpeg2) && pes->es_data_size > 4) {
 
103
                struct mpeg_audio_header mpghdr;
 
104
                memset(&mpghdr, 0, sizeof(struct mpeg_audio_header));
 
105
                ts_pes_es_mpeg_audio_header_parse(&mpghdr, pes->es_data, pes->es_data_size);
 
106
                if (mpghdr.initialized) {
 
107
                        pes->mpeg_audio_header = mpghdr;
 
108
                        if (mpghdr.ID) {
 
109
                                switch (mpghdr.layer) {
 
110
                                        case 3: pes->is_audio_mpeg1l1 = 1; break;
 
111
                                        case 2: pes->is_audio_mpeg1l2 = 1; break;
 
112
                                        case 1: pes->is_audio_mpeg1l3 = 1; break;
 
113
                                }
 
114
                        }
 
115
                }
 
116
        }
 
117
 
 
118
        // Look into elementary streams to detect AC3/DTS
 
119
        if (pes->is_audio_ac3) {
 
120
                if (pes->real_pes_packet_len >= 2 && (pes->es_data[0] == 0x0B && pes->es_data[1] == 0x77)) {
 
121
                        pes->is_audio     = 1;
 
122
                        pes->is_audio_ac3 = 1;
 
123
                        pes->is_audio_dts = 0;
 
124
                }
 
125
                if (pes->real_pes_packet_len >= 4 && (pes->es_data[0] == 0x7f && pes->es_data[1] == 0xfe && pes->es_data[2] == 0x80 && pes->es_data[3] == 0x01)) {
 
126
                        pes->is_audio     = 1;
 
127
                        pes->is_audio_ac3 = 0;
 
128
                        pes->is_audio_dts = 1;
 
129
                }
 
130
        }
 
131
}
 
132
 
 
133
void ts_pes_es_dump(struct ts_pes *pes) {
 
134
        if (pes->is_audio && pes->mpeg_audio_header.initialized) {
 
135
                ts_pes_es_mpeg_audio_header_dump(&pes->mpeg_audio_header);
 
136
        }
 
137
}