dvbd / src / remux.c @ a24dbbce
History | View | Annotate | Download (26.1 KB)
1 |
#include "remux.h" |
---|---|
2 |
|
3 |
unsigned int bitrates[3][16] = |
4 |
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, |
5 |
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, |
6 |
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; |
7 |
|
8 |
uint32_t freq[4] = {441, 480, 320, 0}; |
9 |
static uint32_t samples[4] = { 384, 1152, 0, 0}; |
10 |
char *frames[3] = {"I-Frame","P-Frame","B-Frame"}; |
11 |
|
12 |
|
13 |
void copy_ptslm(PTS_List *a, PTS_List *b)
|
14 |
{ |
15 |
a->pos = b->pos; |
16 |
a->PTS = b->PTS; |
17 |
a->dts = b->dts; |
18 |
a->spos = b->spos; |
19 |
} |
20 |
|
21 |
void clear_ptslm(PTS_List *a)
|
22 |
{ |
23 |
a->pos = 0;
|
24 |
a->PTS = 0;
|
25 |
a->dts = 0;
|
26 |
a->spos = 0;
|
27 |
} |
28 |
|
29 |
void init_ptsl(PTS_List *ptsl)
|
30 |
{ |
31 |
int i;
|
32 |
for (i=0;i< MAX_PTS;i++){ |
33 |
clear_ptslm(&ptsl[i]); |
34 |
} |
35 |
} |
36 |
|
37 |
int del_pts(PTS_List *ptsl, int pos, int nr) |
38 |
{ |
39 |
int i;
|
40 |
int del = 0; |
41 |
|
42 |
for( i = 0; i < nr-1; i++){ |
43 |
if(pos > ptsl[i].pos && pos >= ptsl[i+1].pos) del++; |
44 |
} |
45 |
|
46 |
if(del)
|
47 |
for( i = 0; i < nr-del; i++){ |
48 |
copy_ptslm(&ptsl[i], &ptsl[i+del]); |
49 |
} |
50 |
|
51 |
return nr-del;
|
52 |
} |
53 |
|
54 |
int del_ptss(PTS_List *ptsl, int pts, int *nb) |
55 |
{ |
56 |
int i;
|
57 |
int del = 0; |
58 |
int sum = 0; |
59 |
int nr = *nb;
|
60 |
|
61 |
for( i = 0; i < nr; i++){ |
62 |
if(pts > ptsl[i].PTS){
|
63 |
del++; |
64 |
sum += ptsl[i].pos; |
65 |
} |
66 |
} |
67 |
|
68 |
if(del)
|
69 |
for( i = 0; i < nr-del; i++){ |
70 |
copy_ptslm(&ptsl[i], &ptsl[i+del]); |
71 |
} |
72 |
|
73 |
*nb = nr-del; |
74 |
return sum;
|
75 |
} |
76 |
|
77 |
int add_pts(PTS_List *ptsl, uint32_t pts, int pos, int spos, int nr, uint32_t dts) |
78 |
{ |
79 |
int i;
|
80 |
|
81 |
for ( i=0;i < nr; i++) if (spos && ptsl[i].pos == pos) return nr; |
82 |
if (nr == MAX_PTS) {
|
83 |
nr = del_pts(ptsl, ptsl[1].pos+1, nr); |
84 |
} else nr++;
|
85 |
i = nr-1;
|
86 |
|
87 |
ptsl[i].pos = pos; |
88 |
ptsl[i].spos = spos; |
89 |
ptsl[i].PTS = pts; |
90 |
ptsl[i].dts = dts; |
91 |
return nr;
|
92 |
} |
93 |
|
94 |
void add_vpts(Remux *rem, uint8_t *pts)
|
95 |
{ |
96 |
uint32_t PTS = ntohl(trans_pts_dts(pts)); |
97 |
rem->vptsn = add_pts(rem->vpts_list, PTS, rem->vwrite, rem->awrite, |
98 |
rem->vptsn, PTS); |
99 |
} |
100 |
|
101 |
void add_apts(Remux *rem, uint8_t *pts)
|
102 |
{ |
103 |
uint32_t PTS = ntohl(trans_pts_dts(pts)); |
104 |
rem->aptsn = add_pts(rem->apts_list, PTS, rem->awrite, rem->vwrite, |
105 |
rem->aptsn, PTS); |
106 |
} |
107 |
|
108 |
void del_vpts(Remux *rem)
|
109 |
{ |
110 |
rem->vptsn = del_pts(rem->vpts_list, rem->vread, rem->vptsn); |
111 |
} |
112 |
|
113 |
void del_apts(Remux *rem)
|
114 |
{ |
115 |
rem->aptsn = del_pts(rem->apts_list, rem->aread, rem->aptsn); |
116 |
} |
117 |
|
118 |
|
119 |
void copy_framelm(FRAME_List *a, FRAME_List *b)
|
120 |
{ |
121 |
a->type = b->type; |
122 |
a->pos = b->pos; |
123 |
a->FRAME = b->FRAME; |
124 |
a->time = b->time; |
125 |
a->pts = b->pts; |
126 |
a->dts = b->dts; |
127 |
} |
128 |
|
129 |
void clear_framelm(FRAME_List *a)
|
130 |
{ |
131 |
a->type = 0;
|
132 |
a->pos = 0;
|
133 |
a->FRAME = 0;
|
134 |
a->time = 0;
|
135 |
a->pts = 0;
|
136 |
a->dts = 0;
|
137 |
} |
138 |
|
139 |
void init_framel(FRAME_List *framel)
|
140 |
{ |
141 |
int i;
|
142 |
for (i=0;i< MAX_FRAME;i++){ |
143 |
clear_framelm(&framel[i]); |
144 |
} |
145 |
} |
146 |
|
147 |
int del_frame(FRAME_List *framel, int pos, int nr) |
148 |
{ |
149 |
int i;
|
150 |
int del = 0; |
151 |
|
152 |
for( i = 0; i < nr-1; i++){ |
153 |
if(pos > framel[i].pos && pos >= framel[i+1].pos) del++; |
154 |
} |
155 |
|
156 |
if(del)
|
157 |
for( i = 0; i < nr-del; i++){ |
158 |
copy_framelm(&framel[i], &framel[i+del]); |
159 |
} |
160 |
|
161 |
return nr-del;
|
162 |
} |
163 |
|
164 |
int add_frame(FRAME_List *framel, uint32_t frame, int pos, int type, int nr, |
165 |
uint32_t time, uint32_t pts, uint32_t dts) |
166 |
{ |
167 |
int i;
|
168 |
|
169 |
if (nr == MAX_FRAME) {
|
170 |
nr = del_frame(framel, framel[1].pos+1, nr); |
171 |
} else nr++;
|
172 |
i = nr-1;
|
173 |
|
174 |
framel[i].type = type; |
175 |
framel[i].pos = pos; |
176 |
framel[i].FRAME = frame; |
177 |
framel[i].time = time; |
178 |
framel[i].pts = pts; |
179 |
framel[i].dts = dts; |
180 |
return nr;
|
181 |
} |
182 |
|
183 |
void add_vframe(Remux *rem, uint32_t frame, long int pos, int type, int time, |
184 |
uint32_t pts, uint32_t dts) |
185 |
{ |
186 |
rem->vframen = add_frame(rem->vframe_list, frame, pos, type, |
187 |
rem->vframen, time, pts, dts); |
188 |
} |
189 |
|
190 |
void add_aframe(Remux *rem, uint32_t frame, long int pos, uint32_t pts) |
191 |
{ |
192 |
rem->aframen = add_frame(rem->aframe_list, frame, pos, 0,
|
193 |
rem->aframen, 0, pts, pts);
|
194 |
} |
195 |
|
196 |
void del_vframe(Remux *rem)
|
197 |
{ |
198 |
rem->vframen = del_frame(rem->vframe_list, rem->vread, rem->vframen); |
199 |
} |
200 |
|
201 |
void del_aframe(Remux *rem)
|
202 |
{ |
203 |
rem->aframen = del_frame(rem->aframe_list, rem->aread, rem->aframen); |
204 |
} |
205 |
|
206 |
|
207 |
void printpts(uint32_t pts)
|
208 |
{ |
209 |
fprintf(stderr,"%2d:%02d:%02d.%03d",
|
210 |
(int)(pts/90000.)/3600, |
211 |
((int)(pts/90000.)%3600)/60, |
212 |
((int)(pts/90000.)%3600)%60, |
213 |
(((int)(pts/90.)%3600000)%60000)%1000 |
214 |
); |
215 |
} |
216 |
|
217 |
|
218 |
void find_vframes( Remux *rem, uint8_t *buf, int l) |
219 |
{ |
220 |
int c = 0; |
221 |
int type;
|
222 |
uint32_t time = 0;
|
223 |
int hour;
|
224 |
int min;
|
225 |
int sec;
|
226 |
u64 pts=0;
|
227 |
u64 dts=0;
|
228 |
uint32_t tempref = 0;
|
229 |
|
230 |
while ( c < l - 6){ |
231 |
if (buf[c] == 0x00 && |
232 |
buf[c+1] == 0x00 && |
233 |
buf[c+2] == 0x01 && |
234 |
buf[c+3] == 0xB8) { |
235 |
c += 4;
|
236 |
hour = (int)((buf[c]>>2)& 0x1F); |
237 |
min = (int)(((buf[c]<<4)& 0x30)| |
238 |
((buf[c+1]>>4)& 0x0F)); |
239 |
sec = (int)(((buf[c+1]<<3)& 0x38)| |
240 |
((buf[c+2]>>5)& 0x07)); |
241 |
|
242 |
time = 3600*hour + 60*min + sec; |
243 |
if ( rem->time_off){
|
244 |
time = (uint32_t)((u64)time - rem->time_off); |
245 |
hour = time/3600;
|
246 |
min = (time%3600)/60; |
247 |
sec = (time%3600)%60; |
248 |
/*
|
249 |
buf[c] |= (hour & 0x1F) << 2;
|
250 |
buf[c] |= (min & 0x30) >> 4;
|
251 |
buf[c+1] |= (min & 0x0F) << 4;
|
252 |
buf[c+1] |= (sec & 0x38) >> 3;
|
253 |
buf[c+2] |= (sec & 0x07) >> 5;*/
|
254 |
} |
255 |
rem->group++; |
256 |
rem->groupframe = 0;
|
257 |
} |
258 |
if ( buf[c] == 0x00 && |
259 |
buf[c+1] == 0x00 && |
260 |
buf[c+2] == 0x01 && |
261 |
buf[c+3] == 0x00) { |
262 |
c += 4;
|
263 |
tempref = (buf[c+1]>>6) & 0x03; |
264 |
tempref |= buf[c] << 2;
|
265 |
|
266 |
type = ((buf[c+1]&0x38) >>3); |
267 |
if ( rem->video_info.framerate){
|
268 |
pts = ((u64)rem->vframe + tempref + 1
|
269 |
- rem->groupframe ) * 90000ULL
|
270 |
/rem->video_info.framerate |
271 |
+ rem->vpts_off; |
272 |
dts = (u64)rem->vframe * 90000ULL/
|
273 |
rem->video_info.framerate |
274 |
+ rem->vpts_off; |
275 |
|
276 |
/*
|
277 |
fprintf(stderr,"MYPTS:");
|
278 |
printpts((uint32_t)pts-rem->vpts_off);
|
279 |
fprintf(stderr," REALPTS:");
|
280 |
printpts(rem->vpts_list[rem->vptsn-1].PTS-rem->vpts_off);
|
281 |
fprintf(stderr," DIFF:");
|
282 |
printpts(pts-(u64)rem->vpts_list[rem->vptsn-1].PTS);
|
283 |
fprintf(stderr," DIST: %4d",-rem->vpts_list[rem->vptsn-1].pos+(rem->vwrite+c-4));
|
284 |
//fprintf(stderr," ERR: %3f",(double)(-rem->vpts_list[rem->vptsn-1].PTS+pts)/(rem->vframe+1));
|
285 |
fprintf(stderr,"\r");
|
286 |
*/
|
287 |
|
288 |
|
289 |
rem->vptsn = add_pts(rem->vpts_list,(uint32_t)pts |
290 |
,rem->vwrite+c-4,
|
291 |
rem->awrite, |
292 |
rem->vptsn, |
293 |
(uint32_t)dts); |
294 |
|
295 |
|
296 |
|
297 |
} |
298 |
rem->vframe++; |
299 |
rem->groupframe++; |
300 |
add_vframe( rem, rem->vframe, rem->vwrite+c, type, |
301 |
time, pts, dts); |
302 |
} else c++;
|
303 |
} |
304 |
} |
305 |
|
306 |
void find_aframes( Remux *rem, uint8_t *buf, int l) |
307 |
{ |
308 |
int c = 0; |
309 |
u64 pts = 0;
|
310 |
int sam;
|
311 |
uint32_t fr; |
312 |
|
313 |
|
314 |
while ( c < l - 2){ |
315 |
if ( buf[c] == 0xFF && |
316 |
(buf[c+1] & 0xF8) == 0xF8) { |
317 |
c += 2;
|
318 |
if ( rem->audio_info.layer >= 0){ |
319 |
sam = samples[3-rem->audio_info.layer];
|
320 |
fr = freq[rem->audio_info.frequency] ; |
321 |
|
322 |
pts = ( (u64)rem->aframe * sam * 900ULL)/fr
|
323 |
+ rem->apts_off; |
324 |
|
325 |
/*
|
326 |
fprintf(stderr,"MYPTS:");
|
327 |
printpts((uint32_t)pts-rem->apts_off);
|
328 |
fprintf(stderr," REALPTS:");
|
329 |
printpts(rem->apts_list[rem->aptsn-1].PTS-rem->apts_off);
|
330 |
fprintf(stderr," DIFF:");
|
331 |
printpts((uint32_t)((u64)rem->apts_list[rem->aptsn-1].PTS-pts));
|
332 |
fprintf(stderr," DIST: %4d",-rem->apts_list[rem->aptsn-1].pos+(rem->awrite+c-2));
|
333 |
fprintf(stderr,"\r");
|
334 |
*/
|
335 |
rem->aptsn = add_pts(rem->apts_list,(uint32_t)pts |
336 |
,rem->awrite+c-2,
|
337 |
rem->vwrite, |
338 |
rem->aptsn, |
339 |
(uint32_t)pts); |
340 |
} |
341 |
|
342 |
rem->aframe++; |
343 |
add_aframe( rem, rem->aframe, rem->awrite+c, pts); |
344 |
|
345 |
} else c++;
|
346 |
} |
347 |
} |
348 |
|
349 |
int refill_buffy(Remux *rem)
|
350 |
{ |
351 |
pes_packet pes; |
352 |
int count = 0; |
353 |
int acount, vcount;
|
354 |
ringbuffy *vbuf = &rem->vid_buffy; |
355 |
ringbuffy *abuf = &rem->aud_buffy; |
356 |
int fin = rem->fin;
|
357 |
|
358 |
acount = abuf->size-ring_rest(abuf); |
359 |
vcount = vbuf->size-ring_rest(vbuf); |
360 |
|
361 |
|
362 |
while ( acount > MAX_PLENGTH && vcount > MAX_PLENGTH && count < 10){ |
363 |
int neof;
|
364 |
count++; |
365 |
init_pes(&pes); |
366 |
if ((neof = read_pes(fin,&pes)) <= 0) return -1; |
367 |
switch(pes.stream_id){
|
368 |
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
369 |
rem->apes++; |
370 |
if( rem->audio_info.layer < 0 && |
371 |
(pes.flags2 & PTS_DTS) ) |
372 |
add_apts(rem, pes.pts); |
373 |
find_aframes( rem, pes.pes_pckt_data, pes.length); |
374 |
ring_write(abuf,(char *)pes.pes_pckt_data,pes.length);
|
375 |
rem->awrite += pes.length; |
376 |
break;
|
377 |
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
378 |
rem->vpes++; |
379 |
if( !rem->video_info.framerate &&
|
380 |
(pes.flags2 & PTS_DTS) ) |
381 |
add_vpts(rem, pes.pts); |
382 |
|
383 |
find_vframes( rem, pes.pes_pckt_data, pes.length); |
384 |
|
385 |
ring_write(vbuf,(char *)pes.pes_pckt_data,pes.length);
|
386 |
rem->vwrite += pes.length; |
387 |
break;
|
388 |
} |
389 |
acount = abuf->size-ring_rest(abuf); |
390 |
vcount = vbuf->size-ring_rest(vbuf); |
391 |
kill_pes(&pes); |
392 |
} |
393 |
if (count < 10) return 0; |
394 |
return 1; |
395 |
} |
396 |
|
397 |
int vring_read( Remux *rem, uint8_t *buf, int l) |
398 |
{ |
399 |
int c = 0; |
400 |
int r = 0; |
401 |
|
402 |
if (ring_rest(&rem->vid_buffy) <= l)
|
403 |
r = refill_buffy(rem); |
404 |
if (r) return -1; |
405 |
|
406 |
c = ring_read(&rem->vid_buffy, (char *) buf, l);
|
407 |
rem->vread += c; |
408 |
del_vpts(rem); |
409 |
del_vframe(rem); |
410 |
return c;
|
411 |
} |
412 |
|
413 |
int aring_read( Remux *rem, uint8_t *buf, int l) |
414 |
{ |
415 |
int c = 0; |
416 |
int r = 0; |
417 |
|
418 |
if (ring_rest(&rem->aud_buffy) <= l)
|
419 |
r = refill_buffy(rem); |
420 |
if (r) return -1; |
421 |
|
422 |
c = ring_read(&rem->aud_buffy, (char *)buf, l);
|
423 |
rem->aread += c; |
424 |
del_apts(rem); |
425 |
del_aframe(rem); |
426 |
return c;
|
427 |
} |
428 |
|
429 |
int vring_peek( Remux *rem, uint8_t *buf, int l, long off) |
430 |
{ |
431 |
int c = 0; |
432 |
|
433 |
if (ring_rest(&rem->vid_buffy) <= l)
|
434 |
refill_buffy(rem); |
435 |
|
436 |
c = ring_peek(&rem->vid_buffy, (char *) buf, l, off);
|
437 |
return c;
|
438 |
} |
439 |
|
440 |
int aring_peek( Remux *rem, uint8_t *buf, int l, long off) |
441 |
{ |
442 |
int c = 0; |
443 |
|
444 |
if (ring_rest(&rem->aud_buffy) <= l)
|
445 |
refill_buffy(rem); |
446 |
|
447 |
c = ring_peek(&rem->aud_buffy, (char *)buf, l, off);
|
448 |
return c;
|
449 |
} |
450 |
|
451 |
|
452 |
int get_video_info(Remux *rem)
|
453 |
{ |
454 |
uint8_t buf[12];
|
455 |
uint8_t *headr; |
456 |
int found = 0; |
457 |
int sw;
|
458 |
long off = 0; |
459 |
int form = -1; |
460 |
ringbuffy *vid_buffy = &rem->vid_buffy; |
461 |
VideoInfo *vi = &rem->video_info; |
462 |
|
463 |
while (found < 4 && ring_rest(vid_buffy)){ |
464 |
uint8_t b[3];
|
465 |
|
466 |
vring_peek( rem, b, 4, 0); |
467 |
if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 |
468 |
&& b[3] == 0xb3) found = 4; |
469 |
else {
|
470 |
off++; |
471 |
vring_read( rem, b, 1);
|
472 |
} |
473 |
} |
474 |
rem->vframe = rem->vframen-1;
|
475 |
|
476 |
if (! found) return -1; |
477 |
buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x01; buf[3] = 0xb3; |
478 |
headr = buf+4;
|
479 |
if(vring_peek(rem, buf, 12, 0) < 12) return -1; |
480 |
|
481 |
vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); |
482 |
vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); |
483 |
|
484 |
sw = (int)((headr[3]&0xF0) >> 4) ; |
485 |
|
486 |
switch( sw ){
|
487 |
case 1: |
488 |
fprintf(stderr,"Videostream: ASPECT: 1:1");
|
489 |
vi->aspect_ratio = 100;
|
490 |
break;
|
491 |
case 2: |
492 |
fprintf(stderr,"Videostream: ASPECT: 4:3");
|
493 |
vi->aspect_ratio = 133;
|
494 |
break;
|
495 |
case 3: |
496 |
fprintf(stderr,"Videostream: ASPECT: 16:9");
|
497 |
vi->aspect_ratio = 177;
|
498 |
break;
|
499 |
case 4: |
500 |
fprintf(stderr,"Videostream: ASPECT: 2.21:1");
|
501 |
vi->aspect_ratio = 221;
|
502 |
break;
|
503 |
|
504 |
case 5 ... 15: |
505 |
fprintf(stderr,"Videostream: ASPECT: reserved");
|
506 |
vi->aspect_ratio = 0;
|
507 |
break;
|
508 |
|
509 |
default:
|
510 |
vi->aspect_ratio = 0;
|
511 |
return -1; |
512 |
} |
513 |
|
514 |
fprintf(stderr," Size = %dx%d",vi->horizontal_size,vi->vertical_size);
|
515 |
|
516 |
sw = (int)(headr[3]&0x0F); |
517 |
|
518 |
switch ( sw ) {
|
519 |
case 1: |
520 |
fprintf(stderr," FRate: 23.976 fps");
|
521 |
vi->framerate = 24000/1001.; |
522 |
form = -1;
|
523 |
break;
|
524 |
case 2: |
525 |
fprintf(stderr," FRate: 24 fps");
|
526 |
vi->framerate = 24;
|
527 |
form = -1;
|
528 |
break;
|
529 |
case 3: |
530 |
fprintf(stderr," FRate: 25 fps");
|
531 |
vi->framerate = 25;
|
532 |
form = VIDEO_MODE_PAL; |
533 |
break;
|
534 |
case 4: |
535 |
fprintf(stderr," FRate: 29.97 fps");
|
536 |
vi->framerate = 30000/1001.; |
537 |
form = VIDEO_MODE_NTSC; |
538 |
break;
|
539 |
case 5: |
540 |
fprintf(stderr," FRate: 30 fps");
|
541 |
vi->framerate = 30;
|
542 |
form = VIDEO_MODE_NTSC; |
543 |
break;
|
544 |
case 6: |
545 |
fprintf(stderr," FRate: 50 fps");
|
546 |
vi->framerate = 50;
|
547 |
form = VIDEO_MODE_PAL; |
548 |
break;
|
549 |
case 7: |
550 |
fprintf(stderr," FRate: 60 fps");
|
551 |
vi->framerate = 60;
|
552 |
form = VIDEO_MODE_NTSC; |
553 |
break;
|
554 |
} |
555 |
|
556 |
rem->dts_delay = (int)(7.0/vi->framerate/2.0*90000); |
557 |
|
558 |
vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) |
559 |
| ((headr[5] << 2) & 0x000003FCUL) | |
560 |
(((headr[6] & 0xC0) >> 6) & 0x00000003UL)); |
561 |
|
562 |
fprintf(stderr," BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.); |
563 |
|
564 |
fprintf(stderr,"\n");
|
565 |
vi->video_format = form; |
566 |
|
567 |
/*
|
568 |
marker_bit (&video_bs, 1);
|
569 |
vi->vbv_buffer_size = getbits (&video_bs, 10);
|
570 |
vi->CSPF = get1bit (&video_bs);
|
571 |
*/
|
572 |
return form;
|
573 |
} |
574 |
|
575 |
|
576 |
int get_audio_info( Remux *rem)
|
577 |
{ |
578 |
uint8_t *headr; |
579 |
uint8_t buf[3];
|
580 |
long off = 0; |
581 |
int found = 0; |
582 |
ringbuffy *aud_buffy = &rem->aud_buffy; |
583 |
AudioInfo *ai = &rem->audio_info; |
584 |
|
585 |
while(!ring_rest(aud_buffy) && !refill_buffy(rem));
|
586 |
while (found < 2 && ring_rest(aud_buffy)){ |
587 |
uint8_t b[2];
|
588 |
refill_buffy(rem); |
589 |
aring_peek( rem, b, 2, 0); |
590 |
|
591 |
if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) |
592 |
found = 2;
|
593 |
else {
|
594 |
off++; |
595 |
aring_read( rem, b, 1);
|
596 |
} |
597 |
} |
598 |
|
599 |
if (!found) return -1; |
600 |
rem->aframe = rem->aframen-1;
|
601 |
|
602 |
if (aring_peek(rem, buf, 3, 0) < 1) return -1; |
603 |
headr = buf+2;
|
604 |
|
605 |
ai->layer = (buf[1] & 0x06) >> 1; |
606 |
|
607 |
fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer); |
608 |
|
609 |
|
610 |
ai->bit_rate = bitrates[(3-ai->layer)][(headr[0] >> 4 )]*1000; |
611 |
|
612 |
if (ai->bit_rate == 0) |
613 |
fprintf (stderr," Bit rate: free");
|
614 |
else if (ai->bit_rate == 0xf) |
615 |
fprintf (stderr," BRate: reserved");
|
616 |
else
|
617 |
fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000); |
618 |
|
619 |
|
620 |
ai->frequency = (headr[0] & 0x0c ) >> 2; |
621 |
if (ai->frequency == 3) |
622 |
fprintf (stderr, " Freq: reserved\n");
|
623 |
else
|
624 |
fprintf (stderr," Freq: %2.1f kHz\n",
|
625 |
freq[ai->frequency]/10.); |
626 |
|
627 |
return 0; |
628 |
} |
629 |
|
630 |
|
631 |
|
632 |
void init_remux(Remux *rem, int fin, int fout, int mult) |
633 |
{ |
634 |
rem->video_info.framerate = 0;
|
635 |
rem->audio_info.layer = -1;
|
636 |
rem->fin = fin; |
637 |
rem->fout = fout; |
638 |
ring_init(&rem->vid_buffy, 40*BUFFYSIZE*mult);
|
639 |
ring_init(&rem->aud_buffy, BUFFYSIZE*mult); |
640 |
init_ptsl(rem->vpts_list); |
641 |
init_ptsl(rem->apts_list); |
642 |
init_framel(rem->vframe_list); |
643 |
init_framel(rem->aframe_list); |
644 |
|
645 |
rem->vptsn = 0;
|
646 |
rem->aptsn = 0;
|
647 |
rem->vframen = 0;
|
648 |
rem->aframen = 0;
|
649 |
rem->vframe = 0;
|
650 |
rem->aframe = 0;
|
651 |
rem->vcframe = 0;
|
652 |
rem->acframe = 0;
|
653 |
rem->vpts = 0;
|
654 |
rem->vdts = 0;
|
655 |
rem->apts_off = 0;
|
656 |
rem->vpts_off = 0;
|
657 |
rem->apts_delay= 0;
|
658 |
rem->vpts_delay= 0;
|
659 |
rem->dts_delay = 0;
|
660 |
rem->apts = 0;
|
661 |
rem->vpes = 0;
|
662 |
rem->apes = 0;
|
663 |
rem->vpts_old = 0;
|
664 |
rem->apts_old = 0;
|
665 |
rem->SCR = 0;
|
666 |
rem->vwrite = 0;
|
667 |
rem->awrite = 0;
|
668 |
rem->vread = 0;
|
669 |
rem->aread = 0;
|
670 |
rem->group = 0;
|
671 |
rem->groupframe= 0;
|
672 |
rem->pack_size = 0;
|
673 |
rem->muxr = 0;
|
674 |
rem->time_off = 0;
|
675 |
} |
676 |
|
677 |
uint32_t bytes2pts(int bytes, int rate) |
678 |
{ |
679 |
if (bytes < 0xFFFFFFFFUL/720000UL) |
680 |
return (uint32_t)(bytes*720000UL/rate); |
681 |
else
|
682 |
return (uint32_t)(bytes/rate*720000UL); |
683 |
} |
684 |
|
685 |
long pts2bytes( uint32_t pts, int rate) |
686 |
{ |
687 |
if (pts < 0xEFFFFFFFUL/rate) |
688 |
return (pts*rate/720000); |
689 |
else
|
690 |
return (pts* (rate/720000)); |
691 |
} |
692 |
|
693 |
int write_audio_pes( Remux *rem, uint8_t *buf, int *alength) |
694 |
{ |
695 |
int add;
|
696 |
int pos = 0; |
697 |
int p = 0; |
698 |
uint32_t pts = 0;
|
699 |
int stuff = 0; |
700 |
int length = *alength;
|
701 |
|
702 |
if (!length) return 0; |
703 |
p = PS_HEADER_L1+PES_H_MIN; |
704 |
|
705 |
if (rem->apts_old != rem->apts){
|
706 |
pts = (uint32_t)((u64)rem->apts + rem->apts_delay - rem->apts_off); |
707 |
p += 5;
|
708 |
} |
709 |
if ( length+p >= rem->pack_size){
|
710 |
length = rem->pack_size; |
711 |
} else {
|
712 |
if (rem->pack_size-length-p <= PES_MIN){
|
713 |
stuff = rem->pack_size - length; |
714 |
length = rem->pack_size; |
715 |
} else
|
716 |
length = length+p; |
717 |
} |
718 |
pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, |
719 |
0, 0, 0, 0, 0, 0); |
720 |
|
721 |
pos += write_pes_header( 0xC0, length-pos, pts, buf+pos, stuff);
|
722 |
add = aring_read( rem, buf+pos, length-pos); |
723 |
*alength = add; |
724 |
if (add < 0) return -1; |
725 |
pos += add; |
726 |
rem->apts_old = rem->apts; |
727 |
rem->apts = rem->apts_list[0].PTS;
|
728 |
|
729 |
if (pos+PES_MIN < rem->pack_size){
|
730 |
pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
|
731 |
buf+pos, 0);
|
732 |
pos = rem->pack_size; |
733 |
} |
734 |
if (pos != rem->pack_size) {
|
735 |
fprintf(stderr,"apos: %d\n",pos);
|
736 |
exit(1);
|
737 |
} |
738 |
|
739 |
return pos;
|
740 |
} |
741 |
|
742 |
int write_video_pes( Remux *rem, uint8_t *buf, int *vlength) |
743 |
{ |
744 |
int add;
|
745 |
int pos = 0; |
746 |
int p = 0; |
747 |
uint32_t pts = 0;
|
748 |
uint32_t dts = 0;
|
749 |
int stuff = 0; |
750 |
int length = *vlength;
|
751 |
long diff = 0; |
752 |
|
753 |
if (! length) return 0; |
754 |
p = PS_HEADER_L1+PES_H_MIN; |
755 |
|
756 |
if (rem->vpts_old != rem->vpts){
|
757 |
pts = (uint32_t)((u64)rem->vpts + rem->vpts_delay - rem->vpts_off); |
758 |
p += 5;
|
759 |
} |
760 |
if ( length+p >= rem->pack_size){
|
761 |
length = rem->pack_size; |
762 |
} else {
|
763 |
if (rem->pack_size - length - p <= PES_MIN){
|
764 |
stuff = rem->pack_size - length; |
765 |
length = rem->pack_size; |
766 |
} else
|
767 |
length = length+p; |
768 |
} |
769 |
|
770 |
pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, |
771 |
0, 0, 0, 0, 0, 0); |
772 |
|
773 |
pos += write_pes_header( 0xE0, length-pos, pts, buf+pos, stuff);
|
774 |
add = vring_read( rem, buf+pos, length-pos); |
775 |
*vlength = add; |
776 |
if (add < 0) return -1; |
777 |
pos += add; |
778 |
rem->vpts_old = rem->vpts; |
779 |
dts = rem->vdts; |
780 |
rem->vpts = rem->vpts_list[0].PTS;
|
781 |
rem->vdts = rem->vpts_list[0].dts;
|
782 |
if ( diff > 0) rem->SCR += diff; |
783 |
if (pos+PES_MIN < rem->pack_size){
|
784 |
// fprintf(stderr,"vstuffing: %d \n",rem->pack_size-pos);
|
785 |
pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
|
786 |
buf+pos, 0);
|
787 |
pos = rem->pack_size; |
788 |
} |
789 |
return pos;
|
790 |
} |
791 |
|
792 |
void print_info( Remux *rem , int ret) |
793 |
{ |
794 |
int newtime = 0; |
795 |
static int time = 0; |
796 |
int i = 0; |
797 |
|
798 |
while(! newtime && i < rem->vframen) {
|
799 |
if( (newtime = rem->vframe_list[i].time)) break; |
800 |
i++; |
801 |
} |
802 |
if (newtime) time = newtime;
|
803 |
|
804 |
fprintf(stderr,"SCR:");
|
805 |
printpts(rem->SCR); |
806 |
fprintf(stderr," VDTS:");
|
807 |
printpts((uint32_t)((u64)rem->vdts - rem->vpts_off + rem->vpts_delay)); |
808 |
fprintf(stderr," APTS:");
|
809 |
printpts((uint32_t)((u64)rem->apts - rem->apts_off + rem->apts_delay)); |
810 |
fprintf(stderr," TIME:%2d:", time/3600); |
811 |
fprintf(stderr,"%02d:", (time%3600)/60); |
812 |
fprintf(stderr,"%02d", (time%3600)%60); |
813 |
if (ret) fprintf(stderr,"\n"); |
814 |
else fprintf(stderr,"\r"); |
815 |
} |
816 |
|
817 |
void remux(int fin, int fout, int pack_size, int mult) |
818 |
{ |
819 |
Remux rem; |
820 |
long ptsdiff;
|
821 |
uint8_t buf[MAX_PACK_L]; |
822 |
long pos = 0; |
823 |
int r = 0; |
824 |
int i, r1, r2;
|
825 |
long packets = 0; |
826 |
uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 }; |
827 |
uint32_t SCR_inc = 0;
|
828 |
int data_size;
|
829 |
long vbuf, abuf;
|
830 |
long vbuf_max, abuf_max;
|
831 |
PTS_List abufl[MAX_PTS]; |
832 |
PTS_List vbufl[MAX_PTS]; |
833 |
int abufn = 0; |
834 |
int vbufn = 0; |
835 |
u64 pts_d = 0;
|
836 |
int ok_audio;
|
837 |
int ok_video;
|
838 |
uint32_t apos = 0;
|
839 |
uint32_t vpos = 0;
|
840 |
int vpack_size = 0; |
841 |
int apack_size = 0; |
842 |
|
843 |
init_ptsl(abufl); |
844 |
init_ptsl(vbufl); |
845 |
|
846 |
init_remux(&rem, fin, fout, mult); |
847 |
rem.pack_size = pack_size; |
848 |
data_size = pack_size - MAX_H_SIZE; |
849 |
fprintf(stderr,"pack_size: %d header_size: %d data size: %d\n",
|
850 |
pack_size, MAX_H_SIZE, data_size); |
851 |
refill_buffy(&rem); |
852 |
fprintf(stderr,"Package size: %d\n",pack_size);
|
853 |
|
854 |
if ( get_video_info(&rem) < 0 ){ |
855 |
fprintf(stderr,"ERROR: Can't find valid video stream\n");
|
856 |
exit(1);
|
857 |
} |
858 |
|
859 |
i = 0;
|
860 |
while(! rem.time_off && i < rem.vframen) {
|
861 |
if( (rem.time_off = rem.vframe_list[i].time)) break; |
862 |
i++; |
863 |
} |
864 |
|
865 |
if ( get_audio_info(&rem) < 0 ){ |
866 |
fprintf(stderr,"ERROR: Can't find valid audio stream\n");
|
867 |
exit(1);
|
868 |
} |
869 |
|
870 |
rem.vpts = rem.vpts_list[0].PTS;
|
871 |
rem.vdts = rem.vpts; |
872 |
rem.vpts_off = rem.vpts; |
873 |
fprintf(stderr,"Video start PTS = %fs \n",rem.vpts_off/90000.); |
874 |
rem.apts = rem.apts_list[0].PTS;
|
875 |
rem.apts_off = rem.apts; |
876 |
ptsdiff = rem.vpts - rem.apts; |
877 |
if (ptsdiff > 0) rem.vpts_off -= ptsdiff; |
878 |
else rem.apts_off -= -ptsdiff;
|
879 |
fprintf(stderr,"Audio start PTS = %fs\n",rem.apts_off/90000.); |
880 |
fprintf(stderr,"Difference Video - Audio = %fs\n",ptsdiff/90000.); |
881 |
fprintf(stderr,"Time offset = %ds\n",rem.time_off);
|
882 |
|
883 |
rem.muxr = (rem.video_info.bit_rate + |
884 |
rem.audio_info.bit_rate)/400;
|
885 |
fprintf(stderr,"MUXRATE: %.2f Mb/sec\n",rem.muxr/2500.); |
886 |
SCR_inc = 1800 * pack_size / rem.muxr;
|
887 |
|
888 |
r = 0;
|
889 |
while ( rem.vptsn < 2 && !r) r = refill_buffy(&rem); |
890 |
r = 0;
|
891 |
while ( rem.aptsn < 2 && !r) r = refill_buffy(&rem); |
892 |
|
893 |
//rem.vpts_delay = (uint32_t)(2*90000ULL* (u64)pack_size/rem.muxr);
|
894 |
rem.vpts_delay = rem.dts_delay; |
895 |
rem.apts_delay = rem.vpts_delay; |
896 |
|
897 |
vbuf_max = 29440;
|
898 |
abuf_max = 4096;
|
899 |
vbuf = 0;
|
900 |
abuf = 0;
|
901 |
pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, |
902 |
0xC0, 0, 32, 0xE0, 1, 230); |
903 |
pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, buf+pos,0); |
904 |
pos = rem.pack_size; |
905 |
write( fout, buf, pos); |
906 |
|
907 |
apos = rem.aread; |
908 |
vpos = rem.vread; |
909 |
print_info( &rem, 1 );
|
910 |
|
911 |
while( ring_rest(&rem.aud_buffy) && ring_rest(&rem.vid_buffy) ){
|
912 |
uint32_t next_apts; |
913 |
uint32_t next_vdts; |
914 |
int asize, vsize;
|
915 |
|
916 |
r1 = 0;
|
917 |
r2 = 0;
|
918 |
while ( rem.aframen < 2 && !r1) |
919 |
r1 = refill_buffy(&rem); |
920 |
while ( rem.vframen < 2 && !r2) |
921 |
r2 = refill_buffy(&rem); |
922 |
if (r1 && r2) break; |
923 |
|
924 |
if ( !r1 && apos <= rem.aread)
|
925 |
apos = rem.aframe_list[1].pos;
|
926 |
if ( !r2 && vpos <= rem.vread)
|
927 |
vpos = rem.vframe_list[1].pos;
|
928 |
apack_size = apos - rem.aread; |
929 |
vpack_size = vpos - rem.vread; |
930 |
|
931 |
|
932 |
next_vdts = (uint32_t)((u64)rem.vdts + rem.vpts_delay |
933 |
- rem.vpts_off) ; |
934 |
ok_video = ( rem.SCR < next_vdts); |
935 |
|
936 |
next_apts = (uint32_t)((u64)rem.apts + rem.apts_delay |
937 |
- rem.apts_off) ; |
938 |
ok_audio = ( rem.SCR < next_apts); |
939 |
|
940 |
asize = (apack_size > data_size ? data_size: apack_size); |
941 |
vsize = (vpack_size > data_size ? data_size: vpack_size); |
942 |
|
943 |
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); |
944 |
|
945 |
|
946 |
if( vbuf+vsize < vbuf_max && vsize && ok_audio ){
|
947 |
fprintf(stderr,"1 ");
|
948 |
pos = write_video_pes( &rem, buf, &vpack_size); |
949 |
write( fout, buf, pos); |
950 |
vbuf += vpack_size; |
951 |
vbufn = add_pts( vbufl, rem.vdts, vpack_size, |
952 |
0, vbufn, 0); |
953 |
packets++; |
954 |
} else if ( abuf+asize < abuf_max && asize && |
955 |
ok_video ){ |
956 |
fprintf(stderr,"2 ");
|
957 |
pos = write_audio_pes( &rem, buf, &apack_size); |
958 |
write( fout, buf, pos); |
959 |
abuf += apack_size; |
960 |
abufn = add_pts( abufl, rem.apts, apack_size, |
961 |
0, abufn, 0); |
962 |
packets++; |
963 |
} else if ( abuf+asize < abuf_max && asize && |
964 |
!ok_audio){ |
965 |
fprintf(stderr,"3 ");
|
966 |
pos = write_audio_pes( &rem, buf, &apack_size); |
967 |
write( fout, buf, pos); |
968 |
abuf += apack_size; |
969 |
abufn = add_pts( abufl, rem.apts, apack_size, |
970 |
0, abufn, 0); |
971 |
packets++; |
972 |
} else if (vbuf+vsize < vbuf_max && vsize && |
973 |
!ok_video){ |
974 |
fprintf(stderr,"4 ");
|
975 |
pos = write_video_pes( &rem, buf, &vpack_size); |
976 |
write( fout, buf, pos); |
977 |
vbuf += vpack_size; |
978 |
vbufn = add_pts( vbufl, rem.vdts, vpack_size, |
979 |
0, vbufn, 0); |
980 |
packets++; |
981 |
} else {
|
982 |
fprintf(stderr,"5 ");
|
983 |
pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, |
984 |
1, 1, 1, 0, 0, 0, 0, 0, 0); |
985 |
|
986 |
pos += write_pes_header( PADDING_STREAM, pack_size-pos, |
987 |
0, buf+pos, 0); |
988 |
write( fout, buf, pos); |
989 |
} |
990 |
|
991 |
|
992 |
//fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn);
|
993 |
//fprintf(stderr,"vbuf: %5d abuf: %4d\n", vbuf,abuf);
|
994 |
|
995 |
if (rem.SCR > rem.vdts+rem.vpts_off -rem.vpts_delay)
|
996 |
rem.SCR = rem.vdts-rem.vpts_off; |
997 |
rem.SCR = (uint32_t)((u64) rem.SCR + SCR_inc); |
998 |
|
999 |
if ( rem.apts_off + rem.SCR < rem.apts_delay ) pts_d = 0; |
1000 |
else pts_d = (u64) rem.SCR + rem.apts_off - rem.apts_delay;
|
1001 |
abuf -= del_ptss( abufl, (uint32_t) pts_d, &abufn); |
1002 |
|
1003 |
if ( rem.vpts_off + rem.SCR < rem.vpts_delay ) pts_d = 0; |
1004 |
else pts_d = (u64) rem.SCR + rem.vpts_off - rem.vpts_delay;
|
1005 |
vbuf -= del_ptss( vbufl, (uint32_t) pts_d, &vbufn); |
1006 |
|
1007 |
print_info( &rem, 1);
|
1008 |
//fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn);
|
1009 |
//fprintf(stderr,"vbuf: %5d abuf: %4d\n\n", vbuf,abuf);
|
1010 |
|
1011 |
|
1012 |
} |
1013 |
pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, |
1014 |
0, 0, 0, 0, 0, 0); |
1015 |
|
1016 |
pos += write_pes_header( PADDING_STREAM, pack_size-pos-4, 0, |
1017 |
buf+pos, 0);
|
1018 |
pos = rem.pack_size-4;
|
1019 |
write( fout, buf, pos); |
1020 |
|
1021 |
write( fout, mpeg_end, 4);
|
1022 |
fprintf(stderr,"\ndone\n");
|
1023 |
} |
1024 |
|
1025 |
|
1026 |
typedef
|
1027 |
struct pes_buffer_s{
|
1028 |
ringbuffy pes_buffy; |
1029 |
uint8_t type; |
1030 |
PTS_List pts_list[MAX_PTS]; |
1031 |
FRAME_List frame_list[MAX_FRAME]; |
1032 |
int pes_size;
|
1033 |
uint64_t written; |
1034 |
uint64_t read; |
1035 |
} PESBuffer; |
1036 |
|
1037 |
|
1038 |
void init_PESBuffer(PESBuffer *pbuf, int pes_size, int buf_size, uint8_t type) |
1039 |
{ |
1040 |
init_framel( pbuf->frame_list); |
1041 |
init_ptsl( pbuf->pts_list); |
1042 |
ring_init( &pbuf->pes_buffy, buf_size); |
1043 |
pbuf->pes_size = pes_size; |
1044 |
pbuf->type = type; |
1045 |
pbuf->written = 0;
|
1046 |
pbuf->read = 0;
|
1047 |
} |
1048 |
|
1049 |
|
1050 |
#define MAX_PBUF 4 |
1051 |
|
1052 |
typedef
|
1053 |
struct remux_s{
|
1054 |
PESBuffer pbuf_list[MAX_PBUF]; |
1055 |
int num_pbuf;
|
1056 |
} REMUX; |
1057 |
|
1058 |
|
1059 |
void init_REMUX(REMUX *rem)
|
1060 |
{ |
1061 |
rem->num_pbuf = 0;
|
1062 |
} |
1063 |
|
1064 |
|
1065 |
|
1066 |
#define REPACK 2048 |
1067 |
#define ABUF_SIZE REPACK*1024 |
1068 |
#define VBUF_SIZE REPACK*10240 |
1069 |
|
1070 |
void remux_main(uint8_t *buf, int count, p2p *p) |
1071 |
{ |
1072 |
int i, b;
|
1073 |
int bufsize = 0; |
1074 |
PESBuffer *pbuf; |
1075 |
REMUX *rem = (REMUX *) p->data; |
1076 |
uint8_t type = buf[3];
|
1077 |
int *npbuf = &(rem->num_pbuf);
|
1078 |
|
1079 |
switch ( type ){
|
1080 |
case PRIVATE_STREAM1:
|
1081 |
bufsize = ABUF_SIZE; |
1082 |
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
1083 |
if (!bufsize) bufsize = VBUF_SIZE;
|
1084 |
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
1085 |
if (!bufsize) bufsize = ABUF_SIZE;
|
1086 |
b = -1;
|
1087 |
for ( i = 0; i < *npbuf; i++){ |
1088 |
if ( type == rem->pbuf_list[i].type ){
|
1089 |
b = i; |
1090 |
break;
|
1091 |
} |
1092 |
} |
1093 |
if (b < 0){ |
1094 |
if ( *npbuf < MAX_PBUF ){
|
1095 |
init_PESBuffer(&rem->pbuf_list[*npbuf], |
1096 |
p->repack+6, bufsize, type);
|
1097 |
b = *npbuf; |
1098 |
(*npbuf)++; |
1099 |
} else {
|
1100 |
fprintf(stderr,"Not enough PES buffers\n");
|
1101 |
exit(1);
|
1102 |
} |
1103 |
} |
1104 |
break;
|
1105 |
default:
|
1106 |
return;
|
1107 |
} |
1108 |
|
1109 |
pbuf = &(rem->pbuf_list[b]); |
1110 |
if (ring_write(&(pbuf->pes_buffy),(char *)buf,count) != count){ |
1111 |
fprintf(stderr,"buffer overflow type 0x%2x\n",type);
|
1112 |
exit(1);
|
1113 |
} else {
|
1114 |
pbuf->written += count; |
1115 |
if ((p->flag2 & PTS_DTS_FLAGS)){
|
1116 |
uint32_t PTS = ntohl(trans_pts_dts(p->pts)); |
1117 |
add_pts(pbuf->pts_list, PTS, pbuf->written, |
1118 |
pbuf->written, 0, 0); |
1119 |
} |
1120 |
p->flag2 = 0;
|
1121 |
} |
1122 |
|
1123 |
} |
1124 |
|
1125 |
void output_mux(p2p *p)
|
1126 |
{ |
1127 |
int i, filling;
|
1128 |
PESBuffer *pbuf; |
1129 |
ringbuffy *pes_buffy; |
1130 |
REMUX *rem = (REMUX *) p->data; |
1131 |
int repack = p->repack;
|
1132 |
int npbuf = rem->num_pbuf;
|
1133 |
|
1134 |
for ( i = 0; i < npbuf; i++){ |
1135 |
pbuf = &(rem->pbuf_list[i]); |
1136 |
pes_buffy = &pbuf->pes_buffy; |
1137 |
filling = pes_buffy->size - ring_rest(pes_buffy); |
1138 |
if (filling/(2 *repack)){ |
1139 |
pbuf->read += ring_read_file(pes_buffy, p->fd1, |
1140 |
(filling/repack)*repack); |
1141 |
} |
1142 |
} |
1143 |
} |
1144 |
|
1145 |
|
1146 |
|
1147 |
#define SIZE 32768 |
1148 |
|
1149 |
void remux2(int fdin, int fdout) |
1150 |
{ |
1151 |
p2p p; |
1152 |
int count = 1; |
1153 |
uint8_t buf[SIZE]; |
1154 |
uint64_t length = 0;
|
1155 |
uint64_t l = 0;
|
1156 |
int verb = 0; |
1157 |
REMUX rem; |
1158 |
|
1159 |
init_p2p(&p, remux_main, REPACK); |
1160 |
p.fd1 = fdout; |
1161 |
p.data = (void *) &rem;
|
1162 |
|
1163 |
|
1164 |
if (fdin != STDIN_FILENO) verb = 1; |
1165 |
|
1166 |
if (verb) {
|
1167 |
length = lseek(fdin, 0, SEEK_END);
|
1168 |
lseek(fdin,0,SEEK_SET);
|
1169 |
} |
1170 |
|
1171 |
while (count > 0){ |
1172 |
count = read(fdin,buf,SIZE); |
1173 |
l += count; |
1174 |
if (verb)
|
1175 |
fprintf(stderr,"Writing %2.2f %%\r",
|
1176 |
100.*l/length); |
1177 |
|
1178 |
get_pes(buf,count,&p,pes_repack); |
1179 |
output_mux(&p); |
1180 |
} |
1181 |
|
1182 |
} |