2 * dvb-mpegtools for the Siemens Fujitsu DVB PCI card
4 * Copyright (C) 2000, 2001 Marcus Metzler
5 * for convergence integrated media GmbH
6 * Copyright (C) 2002 Marcus Metzler
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 * The author can be reached at mocm@metzlerbros.de,
31 #define MAX_SEARCH 1024 * 1024
40 ssize_t save_read(int fd, void *buf, size_t count)
45 while(neof >= 0 && re < count){
46 neof = read(fd, buf+re, count - re);
47 if (neof > 0) re += neof;
51 if (neof < 0 && re == 0) return neof;
55 void init_pes(pes_packet *p){
66 p->pack_field_length = 0;
67 p->pack_header = (uint8_t *) NULL;
69 p->org_stuff_length = 0;
71 p->pes_ext = (uint8_t *) NULL;
72 p->pes_pckt_data = (uint8_t *) NULL;
74 p->mpeg = 2; // DEFAULT MPEG2
76 p->mpeg1_headr = NULL;
80 void kill_pes(pes_packet *p){
86 free(p->pes_pckt_data);
92 void setlength_pes(pes_packet *p){
94 ll = (short *) p->llength;
95 p->length = ntohs(*ll);
98 static void setl_pes(pes_packet *p){
101 p->pes_pckt_data = (uint8_t *)malloc(p->length);
104 void nlength_pes(pes_packet *p){
105 if (p->length <= 0xFFFF){
106 short *ll = (short *) p->llength;
115 static void nl_pes(pes_packet *p)
118 p->pes_pckt_data = (uint8_t *) malloc(p->length);
121 void pts2pts(uint8_t *av_pts, uint8_t *pts)
124 av_pts[0] = ((pts[0] & 0x06) << 5) |
125 ((pts[1] & 0xFC) >> 2);
126 av_pts[1] = ((pts[1] & 0x03) << 6) |
127 ((pts[2] & 0xFC) >> 2);
128 av_pts[2] = ((pts[2] & 0x02) << 6) |
129 ((pts[3] & 0xFE) >> 1);
130 av_pts[3] = ((pts[3] & 0x01) << 7) |
131 ((pts[4] & 0xFE) >> 1);
136 int cwrite_pes(uint8_t *buf, pes_packet *p, long length){
140 uint8_t headr[3] = { 0x00, 0x00 , 0x01};
142 if (length < p->length+p->pes_hlength){
143 fprintf(stderr,"Wrong buffer size in cwrite_pes\n");
150 buf[count] = p->stream_id;
153 switch ( p->stream_id ) {
155 case PROG_STREAM_MAP:
156 case PRIVATE_STREAM2:
157 case PROG_STREAM_DIR:
160 case PADDING_STREAM :
161 buf[count] = p->llength[0];
163 buf[count] = p->llength[1];
165 memcpy(buf+count,p->pes_pckt_data,p->length);
169 case ISO13522_STREAM:
170 case PRIVATE_STREAM1:
171 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
172 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
173 buf[count] = p->llength[0];
175 buf[count] = p->llength[1];
184 memcpy(buf+count,&p->flags1,1);
186 memcpy(buf+count,&p->flags2,1);
188 memcpy(buf+count,&p->pes_hlength,1);
191 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
192 memcpy(buf+count,p->pts,5);
195 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
196 memcpy(buf+count,p->pts,5);
198 memcpy(buf+count,p->dts,5);
201 if (p->flags2 & ESCR_FLAG){
202 memcpy(buf+count,p->escr,6);
205 if (p->flags2 & ES_RATE_FLAG){
206 memcpy(buf+count,p->es_rate,3);
209 if (p->flags2 & DSM_TRICK_FLAG){
210 memcpy(buf+count,&p->trick,1);
213 if (p->flags2 & ADD_CPY_FLAG){
214 memcpy(buf+count,&p->add_cpy,1);
217 if (p->flags2 & PES_CRC_FLAG){
218 memcpy(buf+count,p->prev_pes_crc,2);
221 if (p->flags2 & PES_EXT_FLAG){
222 memcpy(buf+count,&p->priv_flags,1);
225 if (p->priv_flags & PRIVATE_DATA){
226 memcpy(buf+count,p->pes_priv_data,16);
229 if (p->priv_flags & HEADER_FIELD){
230 memcpy(buf+count,&p->pack_field_length,
233 memcpy(buf+count,p->pack_header,
234 p->pack_field_length);
235 count += p->pack_field_length;
239 if ( p->priv_flags & PACK_SEQ_CTR){
240 memcpy(buf+count,&p->pck_sqnc_cntr,1);
242 memcpy(buf+count,&p->org_stuff_length,
247 if ( p->priv_flags & P_STD_BUFFER){
248 memcpy(buf+count,p->p_std,2);
251 if ( p->priv_flags & PES_EXT_FLAG2){
252 memcpy(buf+count,&p->pes_ext_lngth,1);
254 memcpy(buf+count,p->pes_ext,
256 count += p->pes_ext_lngth;
260 for (i=0;i<p->stuffing;i++) {
261 memcpy(buf+count,&dummy,1);
266 memcpy(buf+count,p->mpeg1_headr,p->mpeg1_pad);
267 count += p->mpeg1_pad;
269 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
270 memcpy(buf+count,p->pts,5);
273 else if ((p->flags2 & PTS_DTS_FLAGS) ==
275 memcpy(buf+count,p->pts,5);
277 memcpy(buf+count,p->dts,5);
281 memcpy(buf+count,p->pes_pckt_data,p->length);
289 void write_pes(int fd, pes_packet *p){
292 int l = p->length+p->pes_hlength;
294 buf = (uint8_t *) malloc(l);
295 length = cwrite_pes(buf,p,l);
296 write(fd,buf,length);
300 static unsigned int find_length(int f){
308 start = lseek(f,0,SEEK_CUR);
310 lseek(f,start,SEEK_SET);
311 while ( neof > 0 && !found ){
312 p = lseek(f,0,SEEK_CUR);
313 neof = save_read(f,&sync4,4);
314 if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
315 switch ( sync4[3] ) {
317 case PROG_STREAM_MAP:
318 case PRIVATE_STREAM2:
319 case PROG_STREAM_DIR:
322 case PADDING_STREAM :
324 case ISO13522_STREAM:
325 case PRIVATE_STREAM1:
326 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
327 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
331 q = lseek(f,0,SEEK_CUR);
336 q = lseek(f,0,SEEK_CUR);
337 lseek(f,start+2,SEEK_SET);
338 if (found) return (unsigned int)(q-start)-4-2;
339 else return (unsigned int)(q-start-2);
344 void cread_pes(char *buf, pes_packet *p){
346 uint8_t count, dummy, check;
351 switch ( p->stream_id ) {
353 case PROG_STREAM_MAP:
354 case PRIVATE_STREAM2:
355 case PROG_STREAM_DIR:
358 memcpy(p->pes_pckt_data,buf+c,p->length);
361 case PADDING_STREAM :
362 p->padding = p->length;
363 memcpy(p->pes_pckt_data,buf+c,p->length);
367 case ISO13522_STREAM:
368 case PRIVATE_STREAM1:
369 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
370 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
378 memcpy(&p->flags1,buf+c,1);
380 if ( (p->flags1 & 0xC0) == 0x80 ) p->mpeg = 2;
384 memcpy(&p->flags2,buf+c,1);
386 memcpy(&p->pes_hlength,buf+c,1);
389 p->length -=p->pes_hlength+3;
390 count = p->pes_hlength;
392 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
393 memcpy(p->pts,buf+c,5);
397 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
398 memcpy(p->pts,buf+c,5);
400 memcpy(p->dts,buf+c,5);
405 if (p->flags2 & ESCR_FLAG){
406 memcpy(p->escr,buf+c,6);
411 if (p->flags2 & ES_RATE_FLAG){
412 memcpy(p->es_rate,buf+c,3);
417 if (p->flags2 & DSM_TRICK_FLAG){
418 memcpy(&p->trick,buf+c,1);
423 if (p->flags2 & ADD_CPY_FLAG){
424 memcpy(&p->add_cpy,buf+c,1);
429 if (p->flags2 & PES_CRC_FLAG){
430 memcpy(p->prev_pes_crc,buf+c,2);
435 if (p->flags2 & PES_EXT_FLAG){
436 memcpy(&p->priv_flags,buf+c,1);
440 if (p->priv_flags & PRIVATE_DATA){
441 memcpy(p->pes_priv_data,buf+c,16);
446 if (p->priv_flags & HEADER_FIELD){
447 memcpy(&p->pack_field_length,buf+c,1);
449 p->pack_header = (uint8_t *)
450 malloc(p->pack_field_length);
451 memcpy(p->pack_header,buf+c,
452 p->pack_field_length);
453 c += p->pack_field_length;
454 count -= 1+p->pack_field_length;
457 if ( p->priv_flags & PACK_SEQ_CTR){
458 memcpy(&p->pck_sqnc_cntr,buf+c,1);
460 memcpy(&p->org_stuff_length,buf+c,1);
465 if ( p->priv_flags & P_STD_BUFFER){
466 memcpy(p->p_std,buf+c,2);
471 if ( p->priv_flags & PES_EXT_FLAG2){
472 memcpy(&p->pes_ext_lngth,buf+c,1);
474 p->pes_ext = (uint8_t *)
475 malloc(p->pes_ext_lngth);
476 memcpy(p->pes_ext,buf+c,
478 c += p->pes_ext_lngth;
479 count -= 1+p->pes_ext_lngth;
483 for(i = 0; i< count ;i++){
484 memcpy(&dummy,buf+c,1);
490 while (check == 0xFF){
491 memcpy(&check,buf+c,1);
496 if ( (check & 0xC0) == 0x40){
497 memcpy(&check,buf+c,1);
500 memcpy(&check,buf+c,1);
505 p->length -= p->mpeg1_pad;
508 if ( (check & 0x30)){
512 if (check == p->flags1){
515 p->mpeg1_headr = (uint8_t *)
516 malloc(p->mpeg1_pad);
517 p->pes_hlength = p->mpeg1_pad;
518 memcpy(p->mpeg1_headr,buf+c,
523 p->flags2 = (check & 0xF0) << 2;
524 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
525 memcpy(p->pts,buf+c,5);
530 else if ((p->flags2 & PTS_DTS_FLAGS) ==
532 memcpy(p->pts,buf+c,5);
534 memcpy(p->dts,buf+c,5);
537 p->pes_hlength += 10;
540 p->mpeg1_headr = (uint8_t *) malloc(p->mpeg1_pad);
541 p->pes_hlength = p->mpeg1_pad;
542 memcpy(p->mpeg1_headr,buf+c,
547 memcpy(p->pes_pckt_data,buf+c,p->length);
551 int read_pes(int f, pes_packet *p){
559 while (neof > 0 && !found) {
560 po = lseek(f,0,SEEK_CUR);
561 if (po < 0) return -1;
562 if ((neof = save_read(f,&sync4,4)) < 4) return -1;
563 if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
564 p->stream_id = sync4[3];
565 switch ( sync4[3] ) {
567 case PROG_STREAM_MAP:
568 case PRIVATE_STREAM2:
569 case PROG_STREAM_DIR:
572 case PADDING_STREAM :
574 case ISO13522_STREAM:
575 case PRIVATE_STREAM1:
576 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
577 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
578 if((neof = save_read(f,p->llength,2)) < 2)
582 p->length = find_length(f);
589 if (lseek(f,po+1,SEEK_SET) < po+1) return -1;
592 } else if(lseek(f,po+1,SEEK_SET) < po+1) return -1;
595 if (!found || !p->length) return 0;
598 buf = (uint8_t *) malloc(p->length);
599 if((neof = save_read(f,buf,p->length))< p->length) return -1;
600 cread_pes((char *)buf,p);
613 void init_ts(ts_packet *p){
623 p->adapt_ext_len = 0;
629 void kill_ts(ts_packet *p){
637 unsigned short pid_ts(ts_packet *p)
639 return get_pid(p->pid);
642 int cwrite_ts(uint8_t *buf, ts_packet *p, long length){
649 memcpy(buf+count,p->pid,2);
651 memcpy(buf+count,&p->flags,1);
655 if (! (p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
656 memcpy(buf+count,p->data,184);
659 memcpy(buf+count,&p->adapt_length,1);
661 memcpy(buf+count,&p->adapt_flags,1);
664 if ( p->adapt_flags & PCR_FLAG ){
665 memcpy(buf+count, p->pcr,6);
668 if ( p->adapt_flags & OPCR_FLAG ){
669 memcpy(buf+count, p->opcr,6);
672 if ( p->adapt_flags & SPLICE_FLAG ){
673 memcpy(buf+count, &p->splice_count,1);
676 if( p->adapt_flags & TRANS_PRIV){
677 memcpy(buf+count,&p->priv_dat_len,1);
679 memcpy(buf+count,p->priv_dat,p->priv_dat_len);
680 count += p->priv_dat_len;
683 if( p->adapt_flags & ADAP_EXT_FLAG){
684 memcpy(buf+count,&p->adapt_ext_len,1);
686 memcpy(buf+count,&p->adapt_eflags,1);
689 if( p->adapt_eflags & LTW_FLAG){
690 memcpy(buf+count,p->ltw,2);
693 if( p->adapt_eflags & PIECE_RATE){
694 memcpy(buf+count,p->piece_rate,3);
697 if( p->adapt_eflags & SEAM_SPLICE){
698 memcpy(buf+count,p->dts,5);
703 for(i=0; i < p->stuffing ; i++){
704 memcpy(buf+count,&dummy,1);
707 if (p->flags & PAYLOAD){
708 memcpy(buf+count,p->data,p->rest);
717 void write_ts(int fd, ts_packet *p){
719 uint8_t buf[TS_SIZE];
721 length = cwrite_ts(buf,p,TS_SIZE);
722 write(fd,buf,length);
725 int read_ts (int f, ts_packet *p){
732 while (neof > 0 && !found) {
733 neof = save_read(f,&sync,1);
737 neof = save_read(f,p->pid,2);
738 neof = save_read(f,&p->flags,1);
739 p->count = p->flags & COUNT_MASK;
741 if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
742 //no adapt. field only payload
743 neof = save_read(f,p->data,184);
748 if ( p->flags & ADAPT_FIELD ) {
750 neof = save_read(f,&p->adapt_length,1);
751 po = lseek(f,0,SEEK_CUR);
752 neof = save_read(f,&p->adapt_flags,1);
754 if ( p->adapt_flags & PCR_FLAG )
755 neof = save_read(f, p->pcr,6);
757 if ( p->adapt_flags & OPCR_FLAG )
758 neof = save_read(f, p->opcr,6);
760 if ( p->adapt_flags & SPLICE_FLAG )
761 neof = save_read(f, &p->splice_count,1);
763 if( p->adapt_flags & TRANS_PRIV){
764 neof = save_read(f,&p->priv_dat_len,1);
765 p->priv_dat = (uint8_t *) malloc(p->priv_dat_len);
766 neof = save_read(f,p->priv_dat,p->priv_dat_len);
769 if( p->adapt_flags & ADAP_EXT_FLAG){
770 neof = save_read(f,&p->adapt_ext_len,1);
771 neof = save_read(f,&p->adapt_eflags,1);
772 if( p->adapt_eflags & LTW_FLAG)
773 neof = save_read(f,p->ltw,2);
775 if( p->adapt_eflags & PIECE_RATE)
776 neof = save_read(f,p->piece_rate,3);
778 if( p->adapt_eflags & SEAM_SPLICE)
779 neof = save_read(f,p->dts,5);
781 q = lseek(f,0,SEEK_CUR);
782 p->stuffing = p->adapt_length -(q-po);
783 p->rest = 183-p->adapt_length;
784 lseek(f,q+p->stuffing,SEEK_SET);
785 if (p->flags & PAYLOAD) // payload
786 neof = save_read(f,p->data,p->rest);
788 lseek(f,q+p->rest,SEEK_SET);
793 void cread_ts (char *buf, ts_packet *p, long length){
800 while (count < length && !found) {
806 memcpy(p->pid,buf+count,2);
808 p->flags = buf[count];
810 p->count = p->flags & COUNT_MASK;
812 if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
813 //no adapt. field only payload
814 memcpy(p->data,buf+count,184);
819 if ( p->flags & ADAPT_FIELD ) {
821 p->adapt_length = buf[count];
824 memcpy(&p->adapt_flags,buf+count,1);
827 if ( p->adapt_flags & PCR_FLAG ){
828 memcpy( p->pcr,buf+count,6);
831 if ( p->adapt_flags & OPCR_FLAG ){
832 memcpy( p->opcr,buf+count,6);
835 if ( p->adapt_flags & SPLICE_FLAG ){
836 memcpy( &p->splice_count,buf+count,1);
839 if( p->adapt_flags & TRANS_PRIV){
840 memcpy(&p->priv_dat_len,buf+count,1);
842 p->priv_dat = (uint8_t *) malloc(p->priv_dat_len);
843 memcpy(p->priv_dat,buf+count,p->priv_dat_len);
844 count += p->priv_dat_len;
847 if( p->adapt_flags & ADAP_EXT_FLAG){
848 memcpy(&p->adapt_ext_len,buf+count,1);
850 memcpy(&p->adapt_eflags,buf+count,1);
852 if( p->adapt_eflags & LTW_FLAG){
853 memcpy(p->ltw,buf+count,2);
856 if( p->adapt_eflags & PIECE_RATE){
857 memcpy(p->piece_rate,buf+count,3);
860 if( p->adapt_eflags & SEAM_SPLICE){
861 memcpy(p->dts,buf+count,5);
866 p->stuffing = p->adapt_length -(q-po);
867 p->rest = 183-p->adapt_length;
868 count = q+p->stuffing;
869 if (p->flags & PAYLOAD){ // payload
870 memcpy(p->data,buf+count,p->rest);
885 void init_ps(ps_packet *p)
887 p->stuff_length=0xF8;
889 p->sheader_length = 0;
896 void kill_ps(ps_packet *p)
903 void setlength_ps(ps_packet *p)
906 ll = (short *) p->sheader_llength;
908 p->sheader_length = ntohs(*ll) - 6;
910 p->sheader_length = ntohs(*ll);
913 static void setl_ps(ps_packet *p)
916 p->data = (uint8_t *) malloc(p->sheader_length);
919 int mux_ps(ps_packet *p)
922 uint8_t *i = (uint8_t *)&mux;
924 i[1] = p->mux_rate[0];
925 i[2] = p->mux_rate[1];
926 i[3] = p->mux_rate[2];
932 int rate_ps(ps_packet *p)
935 uint8_t *i= (uint8_t *) &rate;
937 i[1] = p->rate_bound[0] & 0x7F;
938 i[2] = p->rate_bound[1];
939 i[3] = p->rate_bound[2];
947 uint32_t scr_base_ps(ps_packet *p) // only 32 bit!!
950 uint8_t *buf = (uint8_t *)&base;
952 buf[0] |= (long int)((p->scr[0] & 0x18) << 3);
953 buf[0] |= (long int)((p->scr[0] & 0x03) << 4);
954 buf[0] |= (long int)((p->scr[1] & 0xF0) >> 4);
956 buf[1] |= (long int)((p->scr[1] & 0x0F) << 4);
957 buf[1] |= (long int)((p->scr[2] & 0xF0) >> 4);
959 buf[2] |= (long int)((p->scr[2] & 0x08) << 4);
960 buf[2] |= (long int)((p->scr[2] & 0x03) << 5);
961 buf[2] |= (long int)((p->scr[3] & 0xF8) >> 3);
963 buf[3] |= (long int)((p->scr[3] & 0x07) << 5);
964 buf[3] |= (long int)((p->scr[4] & 0xF8) >> 3);
970 uint16_t scr_ext_ps(ps_packet *p)
974 ext = (short)(p->scr[5] >> 1);
975 ext += (short) (p->scr[4] & 0x03) * 128;
980 int cwrite_ps(uint8_t *buf, ps_packet *p, long length)
983 uint8_t headr1[4] = {0x00, 0x00, 0x01, 0xBA };
984 uint8_t headr2[4] = {0x00, 0x00, 0x01, 0xBB };
985 uint8_t buffy = 0xFF;
988 memcpy(buf,headr1,4);
991 memcpy(buf+count,p->scr,6);
993 memcpy(buf+count,p->mux_rate,3);
995 memcpy(buf+count,&p->stuff_length,1);
997 for(i=0; i< (p->stuff_length & 3); i++){
998 memcpy(buf+count,&buffy,1);
1002 memcpy(buf+count,p->scr,5);
1004 memcpy(buf+count,p->mux_rate,3);
1007 if (p->sheader_length){
1008 memcpy(buf+count,headr2,4);
1010 memcpy(buf+count,p->sheader_llength,2);
1013 memcpy(buf+count,p->rate_bound,3);
1015 memcpy(buf+count,&p->audio_bound,1);
1017 memcpy(buf+count,&p->video_bound,1);
1019 memcpy(buf+count,&p->reserved,1);
1022 memcpy(buf+count,p->data,p->sheader_length);
1023 count += p->sheader_length;
1029 void write_ps(int fd, ps_packet *p){
1031 uint8_t buf[PS_MAX];
1033 length = cwrite_ps(buf,p,PS_MAX);
1034 write(fd,buf,length);
1037 int read_ps (int f, ps_packet *p){
1047 po = lseek(f,0,SEEK_CUR);
1048 while (neof > 0 && !found && count < MAX_SEARCH) {
1049 neof = save_read(f,&headr,4);
1050 if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1051 if ( headr[3] == 0xBA )
1054 if ( headr[3] == 0xB9 ) break;
1055 else lseek(f,po+1,SEEK_SET);
1061 neof = save_read(f,p->scr,6);
1062 if (p->scr[0] & 0x40)
1068 neof = save_read(f,p->mux_rate,3);
1069 neof = save_read(f,&p->stuff_length,1);
1070 po = lseek(f,0,SEEK_CUR);
1071 lseek(f,po+(p->stuff_length & 3),SEEK_SET);
1073 p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1074 neof = save_read(f,p->mux_rate+1,2);
1077 po = lseek(f,0,SEEK_CUR);
1078 neof = save_read(f,headr,4);
1079 if (headr[0] == 0x00 && headr[1] == 0x00 &&
1080 headr[2] == 0x01 && headr[3] == 0xBB ) {
1081 neof = save_read(f,p->sheader_llength,2);
1084 neof = save_read(f,p->rate_bound,3);
1085 neof = save_read(f,&p->audio_bound,1);
1086 neof = save_read(f,&p->video_bound,1);
1087 neof = save_read(f,&p->reserved,1);
1089 neof = save_read(f,p->data,p->sheader_length);
1091 lseek(f,po,SEEK_SET);
1092 p->sheader_length = 0;
1097 q = lseek(f,0,SEEK_CUR);
1099 po = lseek(f,0,SEEK_CUR);
1100 neof = save_read(f,headr,4);
1101 lseek(f,po,SEEK_SET);
1102 if ( headr[0] == 0x00 && headr[1] == 0x00
1103 && headr[2] == 0x01 && headr[3] != 0xBA){
1105 neof = read_pes(f,&pes);
1109 } while ( neof > 0 && !done);
1111 lseek(f,q,SEEK_SET);
1116 void cread_ps (char *buf, ps_packet *p, long length){
1127 while ( count < length && !found && count < MAX_SEARCH) {
1128 headr = (uint8_t *)buf+c;
1130 if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1131 if ( headr[3] == 0xBA )
1134 if ( headr[3] == 0xB9 ) break;
1141 memcpy(p->scr,buf+c,6);
1143 if (p->scr[0] & 0x40)
1149 memcpy(p->mux_rate,buf+c,3);
1151 memcpy(&p->stuff_length,buf+c,1);
1154 c = po+(p->stuff_length & 3);
1156 p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1157 memcpy(p->mux_rate+1,buf+c,2);
1162 headr = (uint8_t *)buf+c;
1164 if (headr[0] == 0x00 && headr[1] == 0x00 &&
1165 headr[2] == 0x01 && headr[3] == 0xBB ) {
1166 memcpy(p->sheader_llength,buf+c,2);
1170 memcpy(p->rate_bound,buf+c,3);
1172 memcpy(&p->audio_bound,buf+c,1);
1174 memcpy(&p->video_bound,buf+c,1);
1176 memcpy(&p->reserved,buf+c,1);
1179 memcpy(p->data,buf+c,p->sheader_length);
1180 c += p->sheader_length;
1183 p->sheader_length = 0;
1190 headr = (uint8_t *)buf+c;
1191 if ( headr[0] == 0x00 && headr[1] == 0x00
1192 && headr[2] == 0x01 && headr[3] != 0xBA){
1194 // cread_pes(buf+c,&pes);
1198 } while (c < length && !done);
1214 void init_trans(trans *p)
1225 for (i = 0; i < MASKL*MAXFILT ; i++){
1229 for (i = 0; i < MAXFILT ; i++){
1230 p->sec[i].found = 0;
1231 p->sec[i].length = 0;
1235 int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask, uint8_t *filt, int pes)
1240 if ( filtn > MAXFILT-1 || filtn<0 ) return -1;
1241 p->pid[filtn] = pid;
1242 if (pes) p->pes |= (tflags)(1 << filtn);
1245 p->pes &= ~((tflags) (1 << filtn) );
1246 for (i = 0; i < MASKL ; i++){
1247 p->mask[off+i] = mask[i];
1248 p->filt[off+i] = filt[i];
1251 p->set |= (tflags) (1 << filtn);
1255 void clear_trans_filt(trans *p,int filtn)
1259 p->set &= ~((tflags) (1 << filtn) );
1260 p->pes &= ~((tflags) (1 << filtn) );
1261 p->is_full &= ~((tflags) (1 << filtn) );
1262 p->pes_start &= ~((tflags) (1 << filtn) );
1263 p->pes_started &= ~((tflags) (1 << filtn) );
1265 for (i = MASKL*filtn; i < MASKL*(filtn+1) ; i++){
1269 p->sec[filtn].found = 0;
1270 p->sec[filtn].length = 0;
1273 int filt_is_set(trans *p, int filtn)
1275 if (p->set & ((tflags)(1 << filtn))) return 1;
1279 int pes_is_set(trans *p, int filtn)
1281 if (p->pes & ((tflags)(1 << filtn))) return 1;
1285 int pes_is_started(trans *p, int filtn)
1287 if (p->pes_started & ((tflags)(1 << filtn))) return 1;
1291 int pes_is_start(trans *p, int filtn)
1293 if (p->pes_start & ((tflags)(1 << filtn))) return 1;
1297 int filt_is_ready(trans *p,int filtn)
1299 if (p->is_full & ((tflags)(1 << filtn))) return 1;
1303 void trans_filt(uint8_t *buf, int count, trans *p)
1306 //fprintf(stderr,"trans_filt\n");
1309 while (c < count && p->found <1 ){
1310 if ( buf[c] == 0x47) p->found = 1;
1312 p->packet[0] = 0x47;
1314 if (c == count) return;
1316 while( c < count && p->found < 188 && p->found > 0 ){
1317 p->packet[p->found] = buf[c];
1321 if (p->found == 188){
1326 if (c < count) trans_filt(buf+c,count-c,p);
1330 void tfilter(trans *p)
1335 uint8_t adapt_length = 0;
1339 // fprintf(stderr,"tfilter\n");
1341 cpid[0] = p->packet[1];
1342 cpid[1] = p->packet[2];
1343 tpid = get_pid(cpid);
1345 if ( p->packet[1]&0x80){
1346 fprintf(stderr,"Error in TS for PID: %d\n",
1351 flags = p->packet[3];
1353 if ( flags & ADAPT_FIELD ) {
1355 adapt_length = p->packet[4];
1358 c = 5 + adapt_length - (int)(!(flags & ADAPT_FIELD));
1359 if (flags & PAYLOAD){
1360 for ( l = 0; l < MAXFILT ; l++){
1361 if ( filt_is_set(p,l) ) {
1362 if ( p->pid[l] == tpid) {
1363 if ( pes_is_set(p,l) ){
1364 if (cpid[0] & PAY_START){
1387 void pes_filter(trans *p, int filtn, int off)
1392 if (filtn < 0 || filtn >= MAXFILT) return;
1396 buf = p->packet+off;
1397 if (pes_is_started(p,filtn)){
1398 p->is_full |= (tflags) (1 << filtn);
1399 memcpy(p->transbuf+c,buf,count);
1400 p->transcount[filtn] = count;
1404 section *get_filt_sec(trans *p, int filtn)
1408 sec = &p->sec[filtn];
1409 p->is_full &= ~((tflags) (1 << filtn) );
1413 int get_filt_buf(trans *p, int filtn,uint8_t **buf)
1415 *buf = p->transbuf+188*filtn;
1416 p->is_full &= ~((tflags) (1 << filtn) );
1417 return p->transcount[filtn];
1423 void sec_filter(trans *p, int filtn, int off)
1428 uint8_t *buf, *secbuf;
1431 // fprintf(stderr,"sec_filter\n");
1433 if (filtn < 0 || filtn >= MAXFILT) return;
1437 buf = p->packet+off;
1438 sec = &p->sec[filtn];
1439 secbuf = sec->payload;
1440 if(!filt_is_ready(p,filtn)){
1441 p->is_full &= ~((tflags) (1 << filtn) );
1448 if (c >= count) return;
1456 while ( c < count && sec->found < 3){
1457 secbuf[sec->found] = buf[c];
1461 if (c == count) return;
1463 if (!sec->length && sec->found == 3){
1464 sec->length |= ((secbuf[1] & 0x0F) << 8);
1465 sec->length |= (secbuf[2] & 0xFF);
1468 while ( c < count && sec->found < sec->length+3){
1469 secbuf[sec->found] = buf[c];
1474 if ( sec->length && sec->found == sec->length+3 ){
1476 for ( i = 0; i < MASKL; i++){
1479 error += (sec->payload[j]&p->mask[MASKL*filtn+i])^
1480 (p->filt[MASKL*filtn+i]&
1481 p->mask[MASKL*filtn+i]);
1484 p->is_full |= (tflags) (1 << filtn);
1486 if (buf[0]+1 < c ) c=count;
1489 if ( c < count ) sec_filter(p, filtn, off);
1496 void write_ps_headr( ps_packet *p, uint8_t *pts,int fd)
1499 uint8_t audio_bound = 1;
1502 uint8_t audio_lock = 1;
1503 uint8_t video_lock = 1;
1504 uint8_t video_bound = 1;
1505 uint8_t stream1 = 0XC0;
1506 uint8_t buffer1_scale = 1;
1507 uint32_t buffer1_size = 32;
1508 uint8_t stream2 = 0xE0;
1509 uint8_t buffer2_scale = 1;
1510 uint32_t buffer2_size = 230;
1524 p->scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1525 p->scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1526 p->scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1527 | ((pts[2] >> 5)&0x03);
1528 p->scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1529 p->scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1532 p->mux_rate[0] = (uint8_t)(muxr >> 14);
1533 p->mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
1534 p->mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
1536 p->stuff_length = 0xF8;
1538 p->sheader_llength[0] = 0x00;
1539 p->sheader_llength[1] = 0x0c;
1543 p->rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
1544 p->rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
1545 p->rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
1548 p->audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
1549 p->video_bound = (uint8_t)((audio_lock << 7)|
1550 (video_lock << 6)|0x20|video_bound);
1551 p->reserved = (uint8_t)(0xFF);
1553 p->data[0] = stream2;
1554 p->data[1] = (uint8_t) (0xc0 | (buffer2_scale << 5) |
1555 (buffer2_size >> 8));
1556 p->data[2] = (uint8_t) (buffer2_size & 0xff);
1557 p->data[3] = stream1;
1558 p->data[4] = (uint8_t) (0xc0 | (buffer1_scale << 5) |
1559 (buffer1_size >> 8));
1560 p->data[5] = (uint8_t) (buffer1_size & 0xff);
1568 void twrite(uint8_t const *buf)
1576 w = write(STDOUT_FILENO,buf+c,l);
1584 void init_p2t(p2t_t *p, void (*fkt)(uint8_t const *buf))
1586 memset(p->pes,0,TS_SIZE);
1590 if (fkt) p->t_out = fkt;
1591 else p->t_out = twrite;
1594 void clear_p2t(p2t_t *p)
1596 memset(p->pes,0,TS_SIZE);
1603 long int find_pes_header(uint8_t const *buf, long int length, int *frags)
1610 while (c < length-3 && !found) {
1611 if (buf[c] == 0x00 && buf[c+1] == 0x00 &&
1613 switch ( buf[c+3] ) {
1615 case PROG_STREAM_MAP:
1616 case PRIVATE_STREAM2:
1617 case PROG_STREAM_DIR:
1620 case PADDING_STREAM :
1621 case DSM_CC_STREAM :
1622 case ISO13522_STREAM:
1623 case PRIVATE_STREAM1:
1624 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1625 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1635 if (c == length-3 && !found){
1636 if (buf[length-1] == 0x00) *frags = 1;
1637 if (buf[length-2] == 0x00 &&
1638 buf[length-1] == 0x00) *frags = 2;
1639 if (buf[length-3] == 0x00 &&
1640 buf[length-2] == 0x00 &&
1641 buf[length-1] == 0x01) *frags = 3;
1648 void pes_to_ts( uint8_t const *buf, long int length, uint16_t pid, p2t_t *p)
1659 if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){
1665 if ( buf[c] == 0x01 ){
1676 case PROG_STREAM_MAP:
1677 case PRIVATE_STREAM2:
1678 case PROG_STREAM_DIR:
1681 case PADDING_STREAM :
1682 case DSM_CC_STREAM :
1683 case ISO13522_STREAM:
1684 case PRIVATE_STREAM1:
1685 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1686 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1692 memcpy(p->pes+p->pos,buf+c,TS_SIZE-4-p->pos);
1693 c += TS_SIZE-4-p->pos;
1694 p_to_t(p->pes,TS_SIZE-4,pid,&p->counter,
1708 c2 = find_pes_header(buf+c,length-c,&p->frags);
1709 if (c2 >= 0 && c2 < TS_SIZE-4-p->pos){
1711 } else l = TS_SIZE-4-p->pos;
1712 memcpy(p->pes+p->pos,buf,l);
1715 p_to_t(p->pes,p->pos,pid,&p->counter,
1722 c2 = find_pes_header(buf+c+add,length-c-add,&p->frags);
1726 p_to_t(buf+c,c2-c,pid,&p->counter,
1734 rest = l % (TS_SIZE-4);
1736 p_to_t(buf+c,l,pid,&p->counter,
1738 memcpy(p->pes,buf+c+l,rest);
1747 void p_to_t( uint8_t const *buf, long int length, uint16_t pid, uint8_t *counter,
1748 void (*ts_write)(uint8_t const *))
1752 uint8_t obuf[TS_SIZE];
1756 buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 )
1758 case PROG_STREAM_MAP:
1759 case PRIVATE_STREAM2:
1760 case PROG_STREAM_DIR:
1763 case PADDING_STREAM :
1764 case DSM_CC_STREAM :
1765 case ISO13522_STREAM:
1766 case PRIVATE_STREAM1:
1767 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1768 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1776 while ( c < length ){
1777 memset(obuf,0,TS_SIZE);
1778 if (length - c >= TS_SIZE-4){
1779 l = write_ts_header(pid, counter, pes_start
1781 memcpy(obuf+l, buf+c, TS_SIZE-l);
1784 l = write_ts_header(pid, counter, pes_start
1786 memcpy(obuf+l, buf+c, TS_SIZE-l);
1795 int write_ps_header(uint8_t *buf,
1798 uint8_t audio_bound,
1803 uint8_t video_bound,
1805 uint8_t buffer1_scale,
1806 uint32_t buffer1_size,
1808 uint8_t buffer2_scale,
1809 uint32_t buffer2_size)
1817 pts = (uint8_t *) &lpts;
1830 p.scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1831 p.scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1832 p.scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1833 | ((pts[2] >> 5)&0x03);
1834 p.scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1835 p.scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1838 p.mux_rate[0] = (uint8_t)(muxr >> 14);
1839 p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
1840 p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
1842 p.stuff_length = 0xF8;
1844 if (stream1 && stream2){
1845 p.sheader_llength[0] = 0x00;
1846 p.sheader_llength[1] = 0x0c;
1850 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
1851 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
1852 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
1855 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
1856 p.video_bound = (uint8_t)((audio_lock << 7)|
1857 (video_lock << 6)|0x20|video_bound);
1858 p.reserved = (uint8_t)(0xFF >> 1);
1860 p.data[0] = stream2;
1861 p.data[1] = (uint8_t) (0xc0 | (buffer2_scale << 5) |
1862 (buffer2_size >> 8));
1863 p.data[2] = (uint8_t) (buffer2_size & 0xff);
1864 p.data[3] = stream1;
1865 p.data[4] = (uint8_t) (0xc0 | (buffer1_scale << 5) |
1866 (buffer1_size >> 8));
1867 p.data[5] = (uint8_t) (buffer1_size & 0xff);
1869 cwrite_ps(buf, &p, PS_HEADER_L2);
1871 return PS_HEADER_L2;
1873 cwrite_ps(buf, &p, PS_HEADER_L1);
1875 return PS_HEADER_L1;
1882 #define MAX_PATH 256
1885 int break_up_filename(char *name, char *base_name, char *path, char *ext)
1887 int l,i,sstop,sstart;
1892 for( i= l-1; i >= 0; i--){
1893 if (sstop == l && name[i] == '.') sstop = i;
1894 if (sstart<0 && name[i] == '/') sstart = i+1;
1896 if (sstart < 0) sstart = 0;
1897 if (sstop-sstart < MAX_BASE){
1898 strncpy(base_name, name+sstart, sstop-sstart);
1899 base_name[sstop-sstart]=0;
1901 if( l - sstop + sstart < MAX_PATH){
1902 strncpy(path, name, sstart);
1905 fprintf(stderr,"PATH too long\n");
1914 if( l - sstop -1 < MAX_EXT){
1915 strncpy(ext, name+sstop+1, l-sstop-1);
1918 fprintf(stderr,"Extension too long\n");
1927 fprintf(stderr,"Name too long\n");
1931 printf("%d %d\n",sstart, sstop);
1932 printf("%s %d\n",name, strlen(name));
1933 printf("%s %d\n",base_name, strlen(base_name));
1934 printf("%s %d\n",path,strlen(path));
1935 printf("%s %d\n",ext,strlen(ext));
1941 int seek_mpg_start(uint8_t *buf, int size)
1953 if ( buf[c] == 0x00 ) found++;
1957 if ( buf[c] == 0x00 ) found++;
1962 if ( buf[c] == 0x01 ) found++;
1964 if ( buf[c] == 0x00 ) found = 2;
1969 if ( (buf[c] & 0xe0) == 0xe0 ) found++;
1974 if (c >= size) return -1;
1980 if (c >= size) return -1;
1982 if ( (buf[c] & 0xC0) == 0x80 ){
1985 if (c >= size) return -1;
1987 if (c >= size) return -1;
1990 while( buf[c] == 0xFF ) {
1992 if (c >= size) return -1;
1994 if ( (buf[c] & 0xC0) == 0x40) c+=2;
1995 if (c >= size) return -1;
1996 if ( (buf[c] & 0x30) ){
1997 if ( (buf[c] & 0x30) == 0x20) c+=5;
2000 if (c >= size) return -1;
2003 if ( buf[c] == 0x00 &&
2016 void write_mpg(int fstart, uint64_t length, int fdin, int fdout)
2018 // uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
2026 buf_size = sb.st_blksize;
2028 buf = (char *) alloca (buf_size + sizeof (int));
2030 lseek(fdin, fstart, SEEK_SET);
2032 while ( count < length && (l = read(fdin,buf,buf_size)) >= 0){
2033 if (l > 0) count+=l;
2035 printf("written %02.2f%%\r",(100.*count)/length);
2039 //write( fdout, mpeg_end, 4);
2043 #define CHECKBUF (1024*1024)
2044 #define ONE_GIG (1024UL*1024UL*1024UL)
2045 void split_mpg(char *name, uint64_t size)
2047 char base_name[MAX_BASE];
2048 char path[MAX_PATH];
2051 uint8_t buf[CHECKBUF];
2054 uint64_t length = 0;
2060 if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2063 if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2064 fprintf(stderr,"Can't open %s\n",name);
2070 length = sb.st_size;
2071 if ( length < ONE_GIG )
2072 printf("Filelength = %2.2f MB\n", length/1024./1024.);
2074 printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2076 if ( length < size ) length = size;
2078 printf("Splitting %s into Files with size <= %2.2f MB\n",name,
2082 read(fdin, buf, csize);
2083 if ( (mark = seek_mpg_start(buf,csize)) < 0){
2084 fprintf(stderr,"Couldn't find sequence header\n");
2090 for ( i = 0 ; i < length/size; i++){
2093 if (csize > length-last) csize = length-last;
2094 lseek(fdin, last+size-csize, SEEK_SET);
2095 read(fdin, buf, csize);
2096 if ( (mark = seek_mpg_start(buf,csize)) < 0){
2097 fprintf(stderr,"Couldn't find sequence header\n");
2101 sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2102 printf("writing %s\n",new_name);
2104 if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2106 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2107 S_IROTH|S_IWOTH)) < 0){
2108 fprintf(stderr,"Can't open %s\n",new_name);
2111 write_mpg(last, size-mark, fdin, fdout);
2112 last = last + size - mark;
2114 sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2115 printf("writing %s\n",new_name);
2117 if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2119 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2120 S_IROTH|S_IWOTH)) < 0){
2121 fprintf(stderr,"Can't open %s\n",new_name);
2124 write_mpg(last, length-last, fdin, fdout);
2130 void cut_mpg(char *name, uint64_t size)
2132 char base_name[MAX_BASE];
2133 char path[MAX_PATH];
2136 uint8_t buf[CHECKBUF];
2139 uint64_t length = 0;
2144 if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2147 if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2148 fprintf(stderr,"Can't open %s\n",name);
2154 length = sb.st_size;
2155 if ( length < ONE_GIG )
2156 printf("Filelength = %2.2f MB\n", length/1024./1024.);
2158 printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2160 if ( length < size ) length = size;
2162 printf("Splitting %s into 2 Files with length %.2f MB and %.2f MB\n",
2163 name, size/1024./1024., (length-size)/1024./1024.);
2166 read(fdin, buf, csize);
2167 if ( (mark = seek_mpg_start(buf,csize)) < 0){
2168 fprintf(stderr,"Couldn't find sequence header\n");
2174 if (csize > length-last) csize = length-last;
2175 lseek(fdin, last+size-csize, SEEK_SET);
2176 read(fdin, buf, csize);
2177 if ( (mark = seek_mpg_start(buf,csize)) < 0){
2178 fprintf(stderr,"Couldn't find sequence header\n");
2182 sprintf(new_name,"%s-1.%s",base_name,ext);
2183 printf("writing %s\n",new_name);
2185 if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2187 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2188 S_IROTH|S_IWOTH)) < 0){
2189 fprintf(stderr,"Can't open %s\n",new_name);
2192 write_mpg(last, size-mark, fdin, fdout);
2193 last = last + size - mark;
2195 sprintf(new_name,"%s-2.%s",base_name,ext);
2196 printf("writing %s\n",new_name);
2198 if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2200 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2201 S_IROTH|S_IWOTH)) < 0){
2202 fprintf(stderr,"Can't open %s\n",new_name);
2205 write_mpg(last, length-last, fdin, fdout);
2211 void write_all (int fd, uint8_t *data, int length)
2216 if ((r = write(fd, data, length)) > 0) {
2225 void read_all (int fd, uint8_t *data, int length)
2230 if( read(fd, data+c, 1) == 1) {
2232 if(data[c-1] == '\n') {
2238 fprintf (stderr, "Error reading socket\n");
2246 char *url2host (uint8_t *url, char **name, uint32_t *ip, uint32_t *port)
2249 struct hostent *hoste;
2250 struct in_addr haddr;
2253 if (!(strncmp(url, "http://", 7)))
2256 *name = strdup(url);
2263 while (*murl && *murl != ':' && *murl != '/') {
2264 if ((*murl < '0' || *murl > '9') && *murl != '.')
2269 (*name)[murl - url] = 0;
2271 if ((*ip = inet_addr(*name)) == INADDR_NONE)
2274 if (!(hoste = gethostbyname(*name)))
2276 memcpy (&haddr, hoste->h_addr, sizeof(haddr));
2280 if (!*murl || *murl == '/') {
2284 *port = atoi(++murl);
2286 while (*murl && *murl != '/')
2291 #define ACCEPT "Accept: video/mpeg, video/x-mpegurl, */*\r\n"
2293 int http_open (char *url)
2295 char purl[1024], *host, req[1024], *sptr;
2299 int reloc, relocnum = 0;
2300 struct sockaddr_in server;
2303 strncpy (purl, url, 1023);
2308 strcpy (req, "GET ");
2309 if (!(sptr = url2host(purl, &host, &ip, &port))) {
2310 fprintf (stderr, "Unknown host\n");
2314 sprintf (req + strlen(req),
2315 " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
2316 "whatever", "you want");
2318 sprintf(req + strlen(req),
2319 "Host: %s:%u\r\n", host, port);
2323 strcat (req, ACCEPT);
2324 strcat (req, "\r\n");
2326 server.sin_port = htons(port);
2327 server.sin_family = AF_INET;
2328 server.sin_addr.s_addr = ip;
2330 if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) {
2335 if (connect(sock, (struct sockaddr *)&server,
2341 write_all (sock, req, strlen(req));
2342 if (!(mfd = fileno(fdopen(sock, "rb")))) {
2348 read_all (mfd, req, 1023);
2349 if ((sptr = strchr(req, ' '))) {
2356 fprintf (stderr, "HTTP req failed:%s",
2362 read_all (mfd,req, 1023);
2363 if (!strncmp(req, "Location:", 9))
2364 strncpy (purl, req+10, 1023);
2365 } while (req[0] != '\r' && req[0] != '\n');
2366 } while (reloc && purl[0] && relocnum++ < 3);
2368 fprintf (stderr, "Too many HTTP relocations.\n");
2376 const char * strerrno (void)
2378 return strerror(errno);