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 unsigned int bitrates[3][16] =
32 {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
33 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
34 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
36 uint32_t freq[4] = {441, 480, 320, 0};
37 static uint32_t samples[4] = { 384, 1152, 0, 0};
38 char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
41 void copy_ptslm(PTS_List *a, PTS_List *b)
49 void clear_ptslm(PTS_List *a)
57 void init_ptsl(PTS_List *ptsl)
60 for (i=0;i< MAX_PTS;i++){
61 clear_ptslm(&ptsl[i]);
65 int del_pts(PTS_List *ptsl, int pos, int nr)
70 for( i = 0; i < nr-1; i++){
71 if(pos > ptsl[i].pos && pos >= ptsl[i+1].pos) del++;
75 for( i = 0; i < nr-del; i++){
76 copy_ptslm(&ptsl[i], &ptsl[i+del]);
82 int del_ptss(PTS_List *ptsl, int pts, int *nb)
89 for( i = 0; i < nr; i++){
90 if(pts > ptsl[i].PTS){
97 for( i = 0; i < nr-del; i++){
98 copy_ptslm(&ptsl[i], &ptsl[i+del]);
105 int add_pts(PTS_List *ptsl, uint32_t pts, int pos, int spos, int nr, uint32_t dts)
109 for ( i=0;i < nr; i++) if (spos && ptsl[i].pos == pos) return nr;
111 nr = del_pts(ptsl, ptsl[1].pos+1, nr);
122 void add_vpts(Remux *rem, uint8_t *pts)
124 uint32_t PTS = trans_pts_dts(pts);
125 rem->vptsn = add_pts(rem->vpts_list, PTS, rem->vwrite, rem->awrite,
129 void add_apts(Remux *rem, uint8_t *pts)
131 uint32_t PTS = trans_pts_dts(pts);
132 rem->aptsn = add_pts(rem->apts_list, PTS, rem->awrite, rem->vwrite,
136 void del_vpts(Remux *rem)
138 rem->vptsn = del_pts(rem->vpts_list, rem->vread, rem->vptsn);
141 void del_apts(Remux *rem)
143 rem->aptsn = del_pts(rem->apts_list, rem->aread, rem->aptsn);
147 void copy_framelm(FRAME_List *a, FRAME_List *b)
157 void clear_framelm(FRAME_List *a)
167 void init_framel(FRAME_List *framel)
170 for (i=0;i< MAX_FRAME;i++){
171 clear_framelm(&framel[i]);
175 int del_frame(FRAME_List *framel, int pos, int nr)
180 for( i = 0; i < nr-1; i++){
181 if(pos > framel[i].pos && pos >= framel[i+1].pos) del++;
185 for( i = 0; i < nr-del; i++){
186 copy_framelm(&framel[i], &framel[i+del]);
192 int add_frame(FRAME_List *framel, uint32_t frame, int pos, int type, int nr,
193 uint32_t time, uint32_t pts, uint32_t dts)
197 if (nr == MAX_FRAME) {
198 nr = del_frame(framel, framel[1].pos+1, nr);
202 framel[i].type = type;
204 framel[i].FRAME = frame;
205 framel[i].time = time;
211 void add_vframe(Remux *rem, uint32_t frame, long int pos, int type, int time,
212 uint32_t pts, uint32_t dts)
214 rem->vframen = add_frame(rem->vframe_list, frame, pos, type,
215 rem->vframen, time, pts, dts);
218 void add_aframe(Remux *rem, uint32_t frame, long int pos, uint32_t pts)
220 rem->aframen = add_frame(rem->aframe_list, frame, pos, 0,
221 rem->aframen, 0, pts, pts);
224 void del_vframe(Remux *rem)
226 rem->vframen = del_frame(rem->vframe_list, rem->vread, rem->vframen);
229 void del_aframe(Remux *rem)
231 rem->aframen = del_frame(rem->aframe_list, rem->aread, rem->aframen);
235 void printpts(uint32_t pts)
237 fprintf(stderr,"%2d:%02d:%02d.%03d",
238 (int)(pts/90000.)/3600,
239 ((int)(pts/90000.)%3600)/60,
240 ((int)(pts/90000.)%3600)%60,
241 (((int)(pts/90.)%3600000)%60000)%1000
246 void find_vframes( Remux *rem, uint8_t *buf, int l)
256 uint32_t tempref = 0;
259 if (buf[c] == 0x00 &&
264 hour = (int)((buf[c]>>2)& 0x1F);
265 min = (int)(((buf[c]<<4)& 0x30)|
266 ((buf[c+1]>>4)& 0x0F));
267 sec = (int)(((buf[c+1]<<3)& 0x38)|
268 ((buf[c+2]>>5)& 0x07));
270 time = 3600*hour + 60*min + sec;
272 time = (uint32_t)((uint64_t)time - rem->time_off);
274 min = (time%3600)/60;
275 sec = (time%3600)%60;
277 buf[c] |= (hour & 0x1F) << 2;
278 buf[c] |= (min & 0x30) >> 4;
279 buf[c+1] |= (min & 0x0F) << 4;
280 buf[c+1] |= (sec & 0x38) >> 3;
281 buf[c+2] |= (sec & 0x07) >> 5;*/
286 if ( buf[c] == 0x00 &&
291 tempref = (buf[c+1]>>6) & 0x03;
292 tempref |= buf[c] << 2;
294 type = ((buf[c+1]&0x38) >>3);
295 if ( rem->video_info.framerate){
296 pts = ((uint64_t)rem->vframe + tempref + 1
297 - rem->groupframe ) * 90000ULL
298 /rem->video_info.framerate
300 dts = (uint64_t)rem->vframe * 90000ULL/
301 rem->video_info.framerate
305 fprintf(stderr,"MYPTS:");
306 printpts((uint32_t)pts-rem->vpts_off);
307 fprintf(stderr," REALPTS:");
308 printpts(rem->vpts_list[rem->vptsn-1].PTS-rem->vpts_off);
309 fprintf(stderr," DIFF:");
310 printpts(pts-(uint64_t)rem->vpts_list[rem->vptsn-1].PTS);
311 // fprintf(stderr," DIST: %4d",-rem->vpts_list[rem->vptsn-1].pos+(rem->vwrite+c-4));
312 //fprintf(stderr," ERR: %3f",(double)(-rem->vpts_list[rem->vptsn-1].PTS+pts)/(rem->vframe+1));
313 fprintf(stderr,"\r");
317 rem->vptsn = add_pts(rem->vpts_list,(uint32_t)pts
328 add_vframe( rem, rem->vframe, rem->vwrite+c, type,
334 void find_aframes( Remux *rem, uint8_t *buf, int l)
343 if ( buf[c] == 0xFF &&
344 (buf[c+1] & 0xF8) == 0xF8) {
346 if ( rem->audio_info.layer >= 0){
347 sam = samples[3-rem->audio_info.layer];
348 fr = freq[rem->audio_info.frequency] ;
350 pts = ( (uint64_t)rem->aframe * sam * 900ULL)/fr
354 fprintf(stderr,"MYPTS:");
355 printpts((uint32_t)pts-rem->apts_off);
356 fprintf(stderr," REALPTS:");
357 printpts(rem->apts_list[rem->aptsn-1].PTS-rem->apts_off);
358 fprintf(stderr," DIFF:");
359 printpts((uint32_t)((uint64_t)rem->apts_list[rem->aptsn-1].PTS-pts));
360 // fprintf(stderr," DIST: %4d",-rem->apts_list[rem->aptsn-1].pos+(rem->awrite+c-2));
361 fprintf(stderr,"\r");
363 rem->aptsn = add_pts(rem->apts_list,(uint32_t)pts
371 add_aframe( rem, rem->aframe, rem->awrite+c, pts);
377 int refill_buffy(Remux *rem)
382 ringbuffy *vbuf = &rem->vid_buffy;
383 ringbuffy *abuf = &rem->aud_buffy;
386 acount = abuf->size-ring_rest(abuf);
387 vcount = vbuf->size-ring_rest(vbuf);
390 while ( acount > MAX_PLENGTH && vcount > MAX_PLENGTH && count < 10){
394 if ((neof = read_pes(fin,&pes)) <= 0) return -1;
395 switch(pes.stream_id){
396 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
398 if( rem->audio_info.layer < 0 &&
399 (pes.flags2 & PTS_DTS) )
400 add_apts(rem, pes.pts);
401 find_aframes( rem, pes.pes_pckt_data, pes.length);
402 ring_write(abuf,(char *)pes.pes_pckt_data,pes.length);
403 rem->awrite += pes.length;
405 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
407 if( !rem->video_info.framerate &&
408 (pes.flags2 & PTS_DTS) )
409 add_vpts(rem, pes.pts);
411 find_vframes( rem, pes.pes_pckt_data, pes.length);
413 ring_write(vbuf,(char *)pes.pes_pckt_data,pes.length);
414 rem->vwrite += pes.length;
417 acount = abuf->size-ring_rest(abuf);
418 vcount = vbuf->size-ring_rest(vbuf);
421 if (count < 10) return 0;
425 int vring_read( Remux *rem, uint8_t *buf, int l)
430 if (ring_rest(&rem->vid_buffy) <= l)
431 r = refill_buffy(rem);
434 c = ring_read(&rem->vid_buffy, (char *) buf, l);
441 int aring_read( Remux *rem, uint8_t *buf, int l)
446 if (ring_rest(&rem->aud_buffy) <= l)
447 r = refill_buffy(rem);
450 c = ring_read(&rem->aud_buffy, (char *)buf, l);
457 int vring_peek( Remux *rem, uint8_t *buf, int l, long off)
461 if (ring_rest(&rem->vid_buffy) <= l)
464 c = ring_peek(&rem->vid_buffy, (char *) buf, l, off);
468 int aring_peek( Remux *rem, uint8_t *buf, int l, long off)
472 if (ring_rest(&rem->aud_buffy) <= l)
475 c = ring_peek(&rem->aud_buffy, (char *)buf, l, off);
480 int get_video_info(Remux *rem)
488 ringbuffy *vid_buffy = &rem->vid_buffy;
489 VideoInfo *vi = &rem->video_info;
491 while (found < 4 && ring_rest(vid_buffy)){
494 vring_peek( rem, b, 4, 0);
495 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
496 && b[3] == 0xb3) found = 4;
499 vring_read( rem, b, 1);
502 rem->vframe = rem->vframen-1;
504 if (! found) return -1;
505 buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x01; buf[3] = 0xb3;
507 if(vring_peek(rem, buf, 12, 0) < 12) return -1;
509 vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
510 vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
512 sw = (int)((headr[3]&0xF0) >> 4) ;
516 fprintf(stderr,"Videostream: ASPECT: 1:1");
517 vi->aspect_ratio = 100;
520 fprintf(stderr,"Videostream: ASPECT: 4:3");
521 vi->aspect_ratio = 133;
524 fprintf(stderr,"Videostream: ASPECT: 16:9");
525 vi->aspect_ratio = 177;
528 fprintf(stderr,"Videostream: ASPECT: 2.21:1");
529 vi->aspect_ratio = 221;
533 fprintf(stderr,"Videostream: ASPECT: reserved");
534 vi->aspect_ratio = 0;
538 vi->aspect_ratio = 0;
542 fprintf(stderr," Size = %dx%d",vi->horizontal_size,vi->vertical_size);
544 sw = (int)(headr[3]&0x0F);
548 fprintf(stderr," FRate: 23.976 fps");
549 vi->framerate = 24000/1001.;
553 fprintf(stderr," FRate: 24 fps");
558 fprintf(stderr," FRate: 25 fps");
560 form = VIDEO_MODE_PAL;
563 fprintf(stderr," FRate: 29.97 fps");
564 vi->framerate = 30000/1001.;
565 form = VIDEO_MODE_NTSC;
568 fprintf(stderr," FRate: 30 fps");
570 form = VIDEO_MODE_NTSC;
573 fprintf(stderr," FRate: 50 fps");
575 form = VIDEO_MODE_PAL;
578 fprintf(stderr," FRate: 60 fps");
580 form = VIDEO_MODE_NTSC;
584 rem->dts_delay = (int)(7.0/vi->framerate/2.0*90000);
586 vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL)
587 | ((headr[5] << 2) & 0x000003FCUL) |
588 (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
590 fprintf(stderr," BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
592 fprintf(stderr,"\n");
593 vi->video_format = form;
596 marker_bit (&video_bs, 1);
597 vi->vbv_buffer_size = getbits (&video_bs, 10);
598 vi->CSPF = get1bit (&video_bs);
604 int get_audio_info( Remux *rem)
610 ringbuffy *aud_buffy = &rem->aud_buffy;
611 AudioInfo *ai = &rem->audio_info;
613 while(!ring_rest(aud_buffy) && !refill_buffy(rem));
614 while (found < 2 && ring_rest(aud_buffy)){
617 aring_peek( rem, b, 2, 0);
619 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
623 aring_read( rem, b, 1);
627 if (!found) return -1;
628 rem->aframe = rem->aframen-1;
630 if (aring_peek(rem, buf, 3, 0) < 1) return -1;
633 ai->layer = (buf[1] & 0x06) >> 1;
635 fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);
638 ai->bit_rate = bitrates[(3-ai->layer)][(headr[0] >> 4 )]*1000;
640 if (ai->bit_rate == 0)
641 fprintf (stderr," Bit rate: free");
642 else if (ai->bit_rate == 0xf)
643 fprintf (stderr," BRate: reserved");
645 fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000);
648 ai->frequency = (headr[0] & 0x0c ) >> 2;
649 if (ai->frequency == 3)
650 fprintf (stderr, " Freq: reserved\n");
652 fprintf (stderr," Freq: %2.1f kHz\n",
653 freq[ai->frequency]/10.);
660 void init_remux(Remux *rem, int fin, int fout, int mult)
662 rem->video_info.framerate = 0;
663 rem->audio_info.layer = -1;
666 ring_init(&rem->vid_buffy, 40*BUFFYSIZE*mult);
667 ring_init(&rem->aud_buffy, BUFFYSIZE*mult);
668 init_ptsl(rem->vpts_list);
669 init_ptsl(rem->apts_list);
670 init_framel(rem->vframe_list);
671 init_framel(rem->aframe_list);
705 uint32_t bytes2pts(int bytes, int rate)
707 if (bytes < 0xFFFFFFFFUL/720000UL)
708 return (uint32_t)(bytes*720000UL/rate);
710 return (uint32_t)(bytes/rate*720000UL);
713 long pts2bytes( uint32_t pts, int rate)
715 if (pts < 0xEFFFFFFFUL/rate)
716 return (pts*rate/720000);
718 return (pts* (rate/720000));
721 int write_audio_pes( Remux *rem, uint8_t *buf, int *alength)
728 int length = *alength;
730 if (!length) return 0;
731 p = PS_HEADER_L1+PES_H_MIN;
733 if (rem->apts_old != rem->apts){
734 pts = (uint32_t)((uint64_t)rem->apts + rem->apts_delay - rem->apts_off);
737 if ( length+p >= rem->pack_size){
738 length = rem->pack_size;
740 if (rem->pack_size-length-p <= PES_MIN){
741 stuff = rem->pack_size - length;
742 length = rem->pack_size;
746 pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1,
749 pos += write_pes_header( 0xC0, length-pos, pts, buf+pos, stuff);
750 add = aring_read( rem, buf+pos, length-pos);
752 if (add < 0) return -1;
754 rem->apts_old = rem->apts;
755 rem->apts = rem->apts_list[0].PTS;
757 if (pos+PES_MIN < rem->pack_size){
758 pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
760 pos = rem->pack_size;
762 if (pos != rem->pack_size) {
763 fprintf(stderr,"apos: %d\n",pos);
770 int write_video_pes( Remux *rem, uint8_t *buf, int *vlength)
778 int length = *vlength;
781 if (! length) return 0;
782 p = PS_HEADER_L1+PES_H_MIN;
784 if (rem->vpts_old != rem->vpts){
785 pts = (uint32_t)((uint64_t)rem->vpts + rem->vpts_delay - rem->vpts_off);
788 if ( length+p >= rem->pack_size){
789 length = rem->pack_size;
791 if (rem->pack_size - length - p <= PES_MIN){
792 stuff = rem->pack_size - length;
793 length = rem->pack_size;
798 pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1,
801 pos += write_pes_header( 0xE0, length-pos, pts, buf+pos, stuff);
802 add = vring_read( rem, buf+pos, length-pos);
804 if (add < 0) return -1;
806 rem->vpts_old = rem->vpts;
808 rem->vpts = rem->vpts_list[0].PTS;
809 rem->vdts = rem->vpts_list[0].dts;
810 if ( diff > 0) rem->SCR += diff;
811 if (pos+PES_MIN < rem->pack_size){
812 // fprintf(stderr,"vstuffing: %d \n",rem->pack_size-pos);
813 pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
815 pos = rem->pack_size;
820 void print_info( Remux *rem , int ret)
826 while(! newtime && i < rem->vframen) {
827 if( (newtime = rem->vframe_list[i].time)) break;
830 if (newtime) time = newtime;
832 fprintf(stderr,"SCR:");
834 fprintf(stderr," VDTS:");
835 printpts((uint32_t)((uint64_t)rem->vdts - rem->vpts_off + rem->vpts_delay));
836 fprintf(stderr," APTS:");
837 printpts((uint32_t)((uint64_t)rem->apts - rem->apts_off + rem->apts_delay));
838 fprintf(stderr," TIME:%2d:", time/3600);
839 fprintf(stderr,"%02d:", (time%3600)/60);
840 fprintf(stderr,"%02d", (time%3600)%60);
841 if (ret) fprintf(stderr,"\n");
842 else fprintf(stderr,"\r");
845 void remux(int fin, int fout, int pack_size, int mult)
849 uint8_t buf[MAX_PACK_L];
854 uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
855 uint32_t SCR_inc = 0;
858 long vbuf_max, abuf_max;
859 PTS_List abufl[MAX_PTS];
860 PTS_List vbufl[MAX_PTS];
874 if (mult < 0 || mult >1000){
875 fprintf(stderr,"Multipler too large\n");
878 init_remux(&rem, fin, fout, mult);
879 rem.pack_size = pack_size;
880 data_size = pack_size - MAX_H_SIZE;
881 fprintf(stderr,"pack_size: %d header_size: %d data size: %d\n",
882 pack_size, MAX_H_SIZE, data_size);
884 fprintf(stderr,"Package size: %d\n",pack_size);
886 if ( get_video_info(&rem) < 0 ){
887 fprintf(stderr,"ERROR: Can't find valid video stream\n");
892 while(! rem.time_off && i < rem.vframen) {
893 if( (rem.time_off = rem.vframe_list[i].time)) break;
897 if ( get_audio_info(&rem) < 0 ){
898 fprintf(stderr,"ERROR: Can't find valid audio stream\n");
902 rem.vpts = rem.vpts_list[0].PTS;
904 rem.vpts_off = rem.vpts;
905 fprintf(stderr,"Video start PTS = %fs \n",rem.vpts_off/90000.);
906 rem.apts = rem.apts_list[0].PTS;
907 rem.apts_off = rem.apts;
908 ptsdiff = rem.vpts - rem.apts;
909 if (ptsdiff > 0) rem.vpts_off -= ptsdiff;
910 else rem.apts_off -= -ptsdiff;
911 fprintf(stderr,"Audio start PTS = %fs\n",rem.apts_off/90000.);
912 fprintf(stderr,"Difference Video - Audio = %fs\n",ptsdiff/90000.);
913 fprintf(stderr,"Time offset = %ds\n",rem.time_off);
915 rem.muxr = (rem.video_info.bit_rate +
916 rem.audio_info.bit_rate)/400;
917 fprintf(stderr,"MUXRATE: %.2f Mb/sec\n",rem.muxr/2500.);
918 SCR_inc = 1800 * pack_size / rem.muxr;
921 while ( rem.vptsn < 2 && !r) r = refill_buffy(&rem);
923 while ( rem.aptsn < 2 && !r) r = refill_buffy(&rem);
925 //rem.vpts_delay = (uint32_t)(2*90000ULL* (uint64_t)pack_size/rem.muxr);
926 rem.vpts_delay = rem.dts_delay;
927 rem.apts_delay = rem.vpts_delay;
933 pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1,
934 0xC0, 0, 32, 0xE0, 1, 230);
935 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, buf+pos,0);
937 write( fout, buf, pos);
941 print_info( &rem, 1 );
943 while( ring_rest(&rem.aud_buffy) && ring_rest(&rem.vid_buffy) ){
950 while ( rem.aframen < 2 && !r1)
951 r1 = refill_buffy(&rem);
952 while ( rem.vframen < 2 && !r2)
953 r2 = refill_buffy(&rem);
956 if ( !r1 && apos <= rem.aread)
957 apos = rem.aframe_list[1].pos;
958 if ( !r2 && vpos <= rem.vread)
959 vpos = rem.vframe_list[1].pos;
960 apack_size = apos - rem.aread;
961 vpack_size = vpos - rem.vread;
964 next_vdts = (uint32_t)((uint64_t)rem.vdts + rem.vpts_delay
966 ok_video = ( rem.SCR < next_vdts);
968 next_apts = (uint32_t)((uint64_t)rem.apts + rem.apts_delay
970 ok_audio = ( rem.SCR < next_apts);
972 asize = (apack_size > data_size ? data_size: apack_size);
973 vsize = (vpack_size > data_size ? data_size: vpack_size);
975 fprintf(stderr,"vframen: %d aframen: %d v_ok: %d a_ok: %d v_buf: %d a_buf: %d vpacks: %d apacks: %d\n",rem.vframen,rem.aframen, ok_video, ok_audio, (int)vbuf,(int)abuf,vsize, asize);
978 if( vbuf+vsize < vbuf_max && vsize && ok_audio ){
979 fprintf(stderr,"1 ");
980 pos = write_video_pes( &rem, buf, &vpack_size);
981 write( fout, buf, pos);
983 vbufn = add_pts( vbufl, rem.vdts, vpack_size,
986 } else if ( abuf+asize < abuf_max && asize &&
988 fprintf(stderr,"2 ");
989 pos = write_audio_pes( &rem, buf, &apack_size);
990 write( fout, buf, pos);
992 abufn = add_pts( abufl, rem.apts, apack_size,
995 } else if ( abuf+asize < abuf_max && asize &&
997 fprintf(stderr,"3 ");
998 pos = write_audio_pes( &rem, buf, &apack_size);
999 write( fout, buf, pos);
1001 abufn = add_pts( abufl, rem.apts, apack_size,
1004 } else if (vbuf+vsize < vbuf_max && vsize &&
1006 fprintf(stderr,"4 ");
1007 pos = write_video_pes( &rem, buf, &vpack_size);
1008 write( fout, buf, pos);
1010 vbufn = add_pts( vbufl, rem.vdts, vpack_size,
1014 fprintf(stderr,"5 ");
1015 pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0,
1016 1, 1, 1, 0, 0, 0, 0, 0, 0);
1018 pos += write_pes_header( PADDING_STREAM, pack_size-pos,
1020 write( fout, buf, pos);
1024 //fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn);
1025 //fprintf(stderr,"vbuf: %5d abuf: %4d\n", vbuf,abuf);
1027 if (rem.SCR > rem.vdts+rem.vpts_off -rem.vpts_delay)
1028 rem.SCR = rem.vdts-rem.vpts_off;
1029 rem.SCR = (uint32_t)((uint64_t) rem.SCR + SCR_inc);
1031 if ( rem.apts_off + rem.SCR < rem.apts_delay ) pts_d = 0;
1032 else pts_d = (uint64_t) rem.SCR + rem.apts_off - rem.apts_delay;
1033 abuf -= del_ptss( abufl, (uint32_t) pts_d, &abufn);
1035 if ( rem.vpts_off + rem.SCR < rem.vpts_delay ) pts_d = 0;
1036 else pts_d = (uint64_t) rem.SCR + rem.vpts_off - rem.vpts_delay;
1037 vbuf -= del_ptss( vbufl, (uint32_t) pts_d, &vbufn);
1039 print_info( &rem, 1);
1040 //fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn);
1041 //fprintf(stderr,"vbuf: %5d abuf: %4d\n\n", vbuf,abuf);
1045 pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1,
1048 pos += write_pes_header( PADDING_STREAM, pack_size-pos-4, 0,
1050 pos = rem.pack_size-4;
1051 write( fout, buf, pos);
1053 write( fout, mpeg_end, 4);
1054 fprintf(stderr,"\ndone\n");
1059 struct pes_buffer_s{
1060 ringbuffy pes_buffy;
1062 PTS_List pts_list[MAX_PTS];
1063 FRAME_List frame_list[MAX_FRAME];
1070 void init_PESBuffer(PESBuffer *pbuf, int pes_size, int buf_size, uint8_t type)
1072 init_framel( pbuf->frame_list);
1073 init_ptsl( pbuf->pts_list);
1074 ring_init( &pbuf->pes_buffy, buf_size);
1075 pbuf->pes_size = pes_size;
1086 PESBuffer pbuf_list[MAX_PBUF];
1091 void init_REMUX(REMUX *rem)
1099 #define ABUF_SIZE REPACK*1024
1100 #define VBUF_SIZE REPACK*10240
1102 void remux_main(uint8_t *buf, int count, void *pr)
1106 p2p *p = (p2p *) pr;
1108 REMUX *rem = (REMUX *) p->data;
1109 uint8_t type = buf[3];
1110 int *npbuf = &(rem->num_pbuf);
1113 case PRIVATE_STREAM1:
1114 bufsize = ABUF_SIZE;
1115 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1116 if (!bufsize) bufsize = VBUF_SIZE;
1117 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1118 if (!bufsize) bufsize = ABUF_SIZE;
1120 for ( i = 0; i < *npbuf; i++){
1121 if ( type == rem->pbuf_list[i].type ){
1127 if ( *npbuf < MAX_PBUF ){
1128 init_PESBuffer(&rem->pbuf_list[*npbuf],
1129 p->repack+6, bufsize, type);
1133 fprintf(stderr,"Not enough PES buffers\n");
1142 pbuf = &(rem->pbuf_list[b]);
1143 if (ring_write(&(pbuf->pes_buffy),(char *)buf,count) != count){
1144 fprintf(stderr,"buffer overflow type 0x%2x\n",type);
1147 pbuf->written += count;
1148 if ((p->flag2 & PTS_DTS_FLAGS)){
1149 uint32_t PTS = trans_pts_dts(p->pts);
1150 add_pts(pbuf->pts_list, PTS, pbuf->written,
1151 pbuf->written, 0, 0);
1158 void output_mux(p2p *p)
1162 ringbuffy *pes_buffy;
1163 REMUX *rem = (REMUX *) p->data;
1164 int repack = p->repack;
1165 int npbuf = rem->num_pbuf;
1167 for ( i = 0; i < npbuf; i++){
1168 pbuf = &(rem->pbuf_list[i]);
1169 pes_buffy = &pbuf->pes_buffy;
1170 filling = pes_buffy->size - ring_rest(pes_buffy);
1171 if (filling/(2 *repack)){
1172 pbuf->read += ring_read_file(pes_buffy, p->fd1,
1173 (filling/repack)*repack);
1182 void remux2(int fdin, int fdout)
1187 uint64_t length = 0;
1192 init_p2p(&p, remux_main, REPACK);
1194 p.data = (void *) &rem;
1197 if (fdin != STDIN_FILENO) verb = 1;
1200 length = lseek(fdin, 0, SEEK_END);
1201 lseek(fdin,0,SEEK_SET);
1205 count = read(fdin,buf,SIZE);
1208 fprintf(stderr,"Writing %2.2f %%\r",
1211 get_pes(buf,count,&p,pes_repack);