00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <stdint.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032 #ifdef USING_MINGW
00033 #include <winsock2.h>
00034 #else
00035 #include <netinet/in.h>
00036 #endif
00037
00038 #include "ts.h"
00039 #include "element.h"
00040 #include "pes.h"
00041
00042 uint16_t get_pid(uint8_t *pid)
00043 {
00044 uint16_t pp = 0;
00045
00046 pp = (pid[0] & PID_MASK_HI)<<8;
00047 pp |= pid[1];
00048
00049 return pp;
00050 }
00051
00052 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
00053 {
00054 int c=0;
00055 int found=0;
00056
00057 if (!vpid || !apid || !ac3pid || !buf || !len) return 0;
00058
00059 *vpid = 0;
00060 *apid = 0;
00061 *ac3pid = 0;
00062
00063 while ( c+TS_SIZE < len){
00064 if (buf[c] == buf[c+TS_SIZE]) break;
00065 c++;
00066 }
00067
00068 while(found<2 && c < len){
00069 if (buf[c+1] & PAY_START) {
00070 int off = 4;
00071
00072 if ( buf[c+3] & ADAPT_FIELD) {
00073 off += buf[c+4] + 1;
00074 }
00075
00076 if (off < TS_SIZE-4){
00077 if (!*vpid && (buf[c+off+3] & 0xF0) == 0xE0){
00078 *vpid = get_pid(buf+c+1);
00079 if (vpos) *vpos = c+off+3;
00080 found++;
00081 }
00082 if (!*ac3pid && buf[c+off+3] == 0xBD){
00083 int l=off+4;
00084 int f=0;
00085
00086 while ( l < TS_SIZE && f<2){
00087 uint8_t b=buf[c+l];
00088 switch(f){
00089 case 0:
00090 if ( b == 0x0b)
00091 f = 1;
00092 break;
00093
00094 case 1:
00095 if ( b == 0x77)
00096 f = 2;
00097 else if ( b != 0x0b)
00098 f = 0;
00099 }
00100 l++;
00101 }
00102 if (f==2){
00103 *ac3pid = get_pid(buf+c+1);
00104 if (ac3pos) *ac3pos = c+off+3;
00105 found++;
00106 }
00107 }
00108 if (!*apid && ((buf[c+off+3] & 0xF0) == 0xC0 ||
00109 (buf[c+off+3] & 0xF0) == 0xD0)){
00110 *apid = get_pid(buf+c+1);
00111 if (apos) *apos = c+off+3;
00112 found++;
00113 }
00114 }
00115 }
00116 c+= TS_SIZE;
00117 }
00118 return found;
00119 }
00120
00121
00122 int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len)
00123 {
00124 return find_pids_pos(vpid, apid, ac3pid, buf, len, NULL, NULL, NULL);
00125 }
00126
00127
00128
00129 static unsigned int crc_table[256] = {
00130 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
00131 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
00132 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
00133 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
00134 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
00135 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
00136 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
00137 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
00138 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
00139 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
00140 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
00141 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
00142 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
00143 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
00144 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
00145 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
00146 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
00147 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
00148 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
00149 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
00150 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
00151 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
00152 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
00153 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
00154 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
00155 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
00156 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
00157 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
00158 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
00159 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
00160 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
00161 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
00162 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
00163 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
00164 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
00165 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
00166 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
00167 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
00168 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
00169 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
00170 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
00171 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
00172 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
00173
00174 unsigned int crc32_04c11db7 (const unsigned char *d, int len, unsigned int crc)
00175 {
00176 register int i;
00177 const unsigned char *u=(unsigned char*)d;
00178
00179 for (i=0; i<len; i++)
00180 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];
00181
00182 return crc;
00183 }
00184
00185 static int write_ts_header(int pid, int payload_start, int count,
00186 int64_t SCR, uint8_t *obuf, int stuff)
00187 {
00188 int c = 0;
00189 uint8_t *scr;
00190 uint32_t lscr;
00191 uint16_t scr_ext = 0;
00192
00193 obuf[c++] = 0x47;
00194 obuf[c++] = (payload_start ? 0x40 : 0x00) | ((pid >> 8) & 0x1f);
00195 obuf[c++] = pid & 0xff;
00196 obuf[c++] = ((SCR >= 0 || stuff) ? 0x30 : 0x10) | count;
00197 if (SCR >= 0|| stuff) {
00198 if (stuff)
00199 stuff--;
00200 int size = stuff;
00201 unsigned char flags = 0;
00202 if(SCR >= 0) {
00203 if(size < 7)
00204 size = 7;
00205 flags |= 0x10;
00206 }
00207 obuf[c++] = size;
00208 if(size) {
00209 obuf[c++] = flags;
00210 size--;
00211 }
00212 if(SCR >= 0) {
00213 uint8_t bit;
00214 lscr = (uint32_t) ((SCR/300ULL) & 0xFFFFFFFFULL);
00215 bit = (lscr & 0x01) << 7;
00216 lscr = htonl(lscr >> 1);
00217 scr = (uint8_t *) 𝓁
00218 scr_ext = (uint16_t) ((SCR%300ULL) & 0x1FFULL);
00219 obuf[c++] = scr[0];
00220 obuf[c++] = scr[1];
00221 obuf[c++] = scr[2];
00222 obuf[c++] = scr[3];
00223 obuf[c++] = bit | 0x7e | (scr_ext >> 8);
00224 obuf[c++] = scr_ext & 0xff;
00225 size -= 6;
00226 }
00227 while(size-- > 0)
00228 obuf[c++] = 0xff;
00229 }
00230 return c;
00231 }
00232
00233 int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR, uint8_t *buf,
00234 int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
00235 {
00236
00237 static int count = 0;
00238 int add;
00239 int pos = 0;
00240 int p = 0;
00241 int stuff = 0;
00242 int length = *vlength;
00243
00244 if (! length) return 0;
00245 p = 4;
00246 if ( ptsdts ) {
00247 p += PES_H_MIN + 8;
00248
00249 if ( ptsdts == PTS_ONLY) {
00250 p += 5;
00251 } else if (ptsdts == PTS_DTS){
00252 p += 10;
00253 }
00254 }
00255 if ( length+p >= TS_SIZE){
00256 length = TS_SIZE;
00257 } else {
00258 stuff = TS_SIZE - length - p;
00259 length = TS_SIZE;
00260 }
00261 if(ptsdts) {
00262
00263 pos = write_ts_header(TS_VIDPID, 1, count, SCR, buf, stuff);
00264
00265 pos += write_pes_header( 0xE0, 6, vpts, vdts, buf+pos,
00266 0, ptsdts);
00267 } else {
00268 pos = write_ts_header(TS_VIDPID, 0, count, -1, buf, stuff);
00269 }
00270 count = (count+1) & 0x0f;
00271
00272 if (length-pos > *vlength){
00273 fprintf(stderr,"WHAT THE HELL %d > %d\n", length-pos,
00274 *vlength);
00275 }
00276
00277 add = ring_read( vrbuffer, buf+pos, length-pos);
00278 *vlength = add;
00279 if (add < 0) return -1;
00280 pos += add;
00281
00282 return pos;
00283 }
00284
00285 int write_audio_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
00286 uint8_t ptsdts, ringbuffer *arbuffer)
00287 {
00288 static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00289 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00290 int add;
00291 int pos = 0;
00292 int p = 0;
00293 int stuff = 0;
00294 int length = *alength;
00295
00296 if (!length) return 0;
00297 p = 4;
00298
00299 if (ptsdts == PTS_ONLY){
00300 p += PES_H_MIN + 5;
00301 }
00302
00303 if ( length+p >= TS_SIZE){
00304 length = TS_SIZE;
00305 } else {
00306 stuff = TS_SIZE - length - p;
00307 length = TS_SIZE;
00308 }
00309 if(ptsdts) {
00310 pos = write_ts_header(TS_MP2PID+n, 1, count[n], -1, buf, stuff);
00311 pos += write_pes_header( 0xC0+n, *alength + PES_H_MIN + 5, pts,
00312 0, buf+pos, 0, ptsdts);
00313 } else {
00314 pos = write_ts_header(TS_MP2PID+n, 0, count[n], -1, buf, stuff);
00315 }
00316 count[n] = (count[n]+1) & 0x0f;
00317 add = ring_read( arbuffer, buf+pos, length-pos);
00318 *alength = add;
00319 if (add < 0) return -1;
00320 pos += add;
00321
00322 if (pos != TS_SIZE) {
00323 fprintf(stderr,"apos: %d\n",pos);
00324 exit(1);
00325 }
00326
00327 return pos;
00328 }
00329
00330 int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
00331 uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer)
00332 {
00333 static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00334 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00335 int add;
00336 int pos = 0;
00337 int p = 0;
00338 int stuff = 0;
00339 int length = *alength;
00340
00341 if (!length) return 0;
00342 p = 4;
00343
00344 if (ptsdts == PTS_ONLY){
00345 p += PES_H_MIN + 5 + 4;
00346 }
00347
00348 if ( length+p >= TS_SIZE){
00349 length = TS_SIZE;
00350 } else {
00351 stuff = TS_SIZE - length - p;
00352 length = TS_SIZE;
00353 }
00354 if(ptsdts) {
00355 pos = write_ts_header(TS_AC3PID+n, 1, count[n], -1, buf, stuff);
00356 pos += write_pes_header( PRIVATE_STREAM1,
00357 *alength + 4 + PES_H_MIN + 5,
00358 pts, 0, buf+pos, 0, ptsdts);
00359 buf[pos] = 0x80 + n;
00360 buf[pos+1] = nframes;
00361 buf[pos+2] = 0x00;
00362 buf[pos+3] = 0x00;
00363 pos += 4;
00364 } else {
00365 pos = write_ts_header(TS_AC3PID+n, 0, count[n], -1, buf, stuff);
00366 }
00367 count[n] = (count[n]+1) & 0x0f;
00368
00369 add = ring_read( ac3rbuffer, buf+pos, length-pos);
00370 *alength = add;
00371 if (add < 0) return -1;
00372 pos += add;
00373
00374 if (pos != TS_SIZE) {
00375 fprintf(stderr,"apos: %d\n",pos);
00376 exit(1);
00377 }
00378
00379 return pos;
00380 }
00381
00382 void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num, uint8_t *buf)
00383 {
00384 #define PMTPID 0x20
00385 static int count = 0;
00386 int pos, i, pmtpos = 13;
00387
00388
00389 uint8_t pat[17] = {0x00, 0x00, 0xb0, 0x0d, 0xfe, 0xef, 0xc1, 0x00, 0x00,
00390 0x00, 0x00, 0xe0, PMTPID, 0x00, 0x00, 0x00, 0x00};
00391 uint8_t pmt[184] ={0x00, 0x02, 0xb0, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,
00392 0x00, 0x00, 0xf0, 0x00};
00393
00394
00395 pat[10] = prog_num;
00396 pos = write_ts_header(0x00, 1, count, -1, buf, 0);
00397 *(uint32_t *)(pat+13)= htonl(crc32_04c11db7(pat+1, 12, 0xffffffff));
00398 memcpy(buf+pos, pat, 17);
00399 pos += 17;
00400 memset(buf+pos, 0xff, TS_SIZE - pos);
00401 pos = TS_SIZE;
00402
00403 pos += write_ts_header(PMTPID, 1, count, -1, buf+pos, 0);
00404 for(i = 0; i <= extcnt; i++) {
00405 uint8_t type;
00406 uint32_t pid;
00407 int n = ext[i-1].strmnum;
00408 if(i == 0) {
00409 type = 0x02;
00410 pid = TS_VIDPID;
00411 } else if(ext[i-1].type == MPEG_AUDIO) {
00412 type = 0x04;
00413 pid = TS_MP2PID + n;
00414 } else if(ext[i-1].type == AC3) {
00415 type = 0x81;
00416 pid = TS_AC3PID + n;
00417 } else {
00418 type = 0xff;
00419 pid = 0x1fff;
00420 }
00421 pmt[pmtpos++] = type;
00422 pmt[pmtpos++] = 0xe0 | (0xff & (pid >> 8));
00423 pmt[pmtpos++] = 0xff & pid;
00424 pmt[pmtpos++] = 0xf0;
00425 if(strlen(ext[i-1].language) == 3) {
00426 pmt[pmtpos++] = 0x06;
00427 pmt[pmtpos++] = 0x0a;
00428 pmt[pmtpos++] = 0x04;
00429 pmt[pmtpos++] = ext[i-1].language[0];
00430 pmt[pmtpos++] = ext[i-1].language[1];
00431 pmt[pmtpos++] = ext[i-1].language[2];
00432 pmt[pmtpos++] = 0x00;
00433 } else {
00434 pmt[pmtpos++] = 0x00;
00435 }
00436 }
00437 pmt[3] = pmtpos + 4 - 3 - 1;
00438 pmt[5] = prog_num;
00439 pmt[9] = 0xf0 | (0xff & (TS_VIDPID >> 8));
00440 pmt[10] = 0xff & TS_VIDPID;
00441 *(uint32_t *)&pmt[pmtpos] = htonl(crc32_04c11db7(&pmt[1], pmtpos -1,
00442 0xffffffff));
00443 pmtpos+=4;
00444 memcpy(buf+pos, pmt, pmtpos);
00445 pos += pmtpos;
00446 memset(buf+pos, 0xff, 2*TS_SIZE - pos);
00447 pos = 2*TS_SIZE;
00448 count = (count+1) & 0x0f;
00449 }