1 /*
2 * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation version 2.1 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
17 *
18 */
19
20 #include <libdvbv5/mpeg_pes.h>
21 #include <libdvbv5/descriptors.h>
22 #include <libdvbv5/dvb-fe.h>
23 #include <inttypes.h>
24
25 #if __GNUC__ >= 9
26 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
27 #endif
28
dvb_mpeg_pes_init(struct dvb_v5_fe_parms * parms,const uint8_t * buf,ssize_t buflen,uint8_t * table)29 ssize_t dvb_mpeg_pes_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table)
30 {
31 struct dvb_mpeg_pes *pes = (struct dvb_mpeg_pes *) table;
32 const uint8_t *p = buf;
33 ssize_t bytes_read = 0;
34
35 memcpy(table, p, sizeof(struct dvb_mpeg_pes));
36 p += sizeof(struct dvb_mpeg_pes);
37 bytes_read += sizeof(struct dvb_mpeg_pes);
38
39 bswap32(pes->bitfield);
40 bswap16(pes->length);
41
42 if (pes->sync != 0x000001) {
43 dvb_logerr("mpeg pes invalid, sync 0x%06x should be 0x000001", pes->sync);
44 return -1;
45 }
46
47 if (pes->stream_id == DVB_MPEG_STREAM_PADDING) {
48 dvb_logwarn("mpeg pes padding stream ignored");
49 } else if (pes->stream_id == DVB_MPEG_STREAM_MAP ||
50 pes->stream_id == DVB_MPEG_STREAM_PRIVATE_2 ||
51 pes->stream_id == DVB_MPEG_STREAM_ECM ||
52 pes->stream_id == DVB_MPEG_STREAM_EMM ||
53 pes->stream_id == DVB_MPEG_STREAM_DIRECTORY ||
54 pes->stream_id == DVB_MPEG_STREAM_DSMCC ||
55 pes->stream_id == DVB_MPEG_STREAM_H222E ) {
56 dvb_logerr("mpeg pes: unsupported stream type 0x%04x", pes->stream_id);
57 return -2;
58 } else {
59 memcpy(pes->optional, p, sizeof(struct dvb_mpeg_pes_optional) -
60 sizeof(pes->optional->pts) -
61 sizeof(pes->optional->dts));
62 p += sizeof(struct dvb_mpeg_pes_optional) -
63 sizeof(pes->optional->pts) -
64 sizeof(pes->optional->dts);
65 bswap16(pes->optional->bitfield);
66 pes->optional->pts = 0;
67 pes->optional->dts = 0;
68 if (pes->optional->PTS_DTS & 2) {
69 struct ts_t pts;
70 memcpy(&pts, p, sizeof(pts));
71 p += sizeof(pts);
72 bswap16(pts.bitfield);
73 bswap16(pts.bitfield2);
74 if (pts.one != 1 || pts.one1 != 1 || pts.one2 != 1)
75 dvb_logwarn("mpeg pes: invalid pts");
76 else {
77 pes->optional->pts |= (uint64_t) pts.bits00;
78 pes->optional->pts |= (uint64_t) pts.bits15 << 15;
79 pes->optional->pts |= (uint64_t) pts.bits30 << 30;
80 }
81 }
82 if (pes->optional->PTS_DTS & 1) {
83 struct ts_t dts;
84 memcpy(&dts, p, sizeof(dts));
85 p += sizeof(dts);
86 bswap16(dts.bitfield);
87 bswap16(dts.bitfield2);
88 pes->optional->dts |= (uint64_t) dts.bits00;
89 pes->optional->dts |= (uint64_t) dts.bits15 << 15;
90 pes->optional->dts |= (uint64_t) dts.bits30 << 30;
91 }
92 bytes_read += sizeof(struct dvb_mpeg_pes_optional);
93 }
94 return bytes_read;
95 }
96
dvb_mpeg_pes_free(struct dvb_mpeg_pes * ts)97 void dvb_mpeg_pes_free(struct dvb_mpeg_pes *ts)
98 {
99 free(ts);
100 }
101
dvb_mpeg_pes_print(struct dvb_v5_fe_parms * parms,struct dvb_mpeg_pes * pes)102 void dvb_mpeg_pes_print(struct dvb_v5_fe_parms *parms, struct dvb_mpeg_pes *pes)
103 {
104 dvb_loginfo("MPEG PES");
105 dvb_loginfo(" - sync 0x%06x", pes->sync);
106 dvb_loginfo(" - stream_id 0x%04x", pes->stream_id);
107 dvb_loginfo(" - length %d", pes->length);
108 if (pes->stream_id == DVB_MPEG_STREAM_PADDING) {
109 } else if (pes->stream_id == DVB_MPEG_STREAM_MAP ||
110 pes->stream_id == DVB_MPEG_STREAM_PRIVATE_2 ||
111 pes->stream_id == DVB_MPEG_STREAM_ECM ||
112 pes->stream_id == DVB_MPEG_STREAM_EMM ||
113 pes->stream_id == DVB_MPEG_STREAM_DIRECTORY ||
114 pes->stream_id == DVB_MPEG_STREAM_DSMCC ||
115 pes->stream_id == DVB_MPEG_STREAM_H222E ) {
116 dvb_logwarn(" mpeg pes unsupported stream type 0x%04x", pes->stream_id);
117 } else {
118 dvb_loginfo(" mpeg pes optional");
119 dvb_loginfo(" - two %d", pes->optional->two);
120 dvb_loginfo(" - PES_scrambling_control %d", pes->optional->PES_scrambling_control);
121 dvb_loginfo(" - PES_priority %d", pes->optional->PES_priority);
122 dvb_loginfo(" - data_alignment_indicator %d", pes->optional->data_alignment_indicator);
123 dvb_loginfo(" - copyright %d", pes->optional->copyright);
124 dvb_loginfo(" - original_or_copy %d", pes->optional->original_or_copy);
125 dvb_loginfo(" - PTS_DTS %d", pes->optional->PTS_DTS);
126 dvb_loginfo(" - ESCR %d", pes->optional->ESCR);
127 dvb_loginfo(" - ES_rate %d", pes->optional->ES_rate);
128 dvb_loginfo(" - DSM_trick_mode %d", pes->optional->DSM_trick_mode);
129 dvb_loginfo(" - additional_copy_info %d", pes->optional->additional_copy_info);
130 dvb_loginfo(" - PES_CRC %d", pes->optional->PES_CRC);
131 dvb_loginfo(" - PES_extension %d", pes->optional->PES_extension);
132 dvb_loginfo(" - length %d", pes->optional->length);
133 if (pes->optional->PTS_DTS & 2)
134 dvb_loginfo(" - pts %" PRIu64 " (%fs)",
135 pes->optional->pts, (float) pes->optional->pts / 90000.0);
136 if (pes->optional->PTS_DTS & 1)
137 dvb_loginfo(" - dts %" PRIu64 " (%fs)",
138 pes->optional->dts, (float) pes->optional->dts/ 90000.0);
139 }
140 }
141