00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <string.h>
00029
00030 #include "element.h"
00031 #include "mpg_common.h"
00032 #include "pes.h"
00033
00034 unsigned int slots [4] = {12, 144, 0, 0};
00035 unsigned int bitrates[3][16] =
00036 {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
00037 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
00038 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
00039
00040 uint32_t freq[4] = {441, 480, 320, 0};
00041 static uint64_t samples[4] = { 384, 1152, 1152, 1536};
00042 char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
00043
00044 unsigned int ac3_bitrates[32] =
00045 {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
00046 0,0,0,0,0,0,0,0,0,0,0,0,0};
00047 static uint8_t ac3half[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
00048 uint32_t ac3_freq[4] = {480, 441, 320, 0};
00049
00050 #define DEBUG 1
00051
00052 uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames)
00053 {
00054 int64_t newpts=0;
00055
00056 newpts = (pts + (frames *samples [3-aframe->layer] * 27000000ULL)
00057 / aframe->frequency);
00058 return newpts>0 ? newpts%MAX_PTS2: MAX_PTS2+newpts;
00059 }
00060
00061 void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
00062 {
00063 int64_t diff;
00064 uint64_t di;
00065 int c=0;
00066
00067 di = (samples [3-aframe->layer] * 27000000ULL);
00068 diff = ptsdiff(origpts,pts);
00069 c=(aframe->frequency * diff+di/2)/di;
00070 if (c) fprintf(stderr,"fix audio frames %d\n",c);
00071 *acount += c;
00072 }
00073
00074
00075 uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount)
00076 {
00077 int64_t newdts = 0, newpts = 0;
00078 int64_t fnum = s->current_tmpref - gcount + fcount;
00079
00080
00081 if ( s->pulldown == NOPULLDOWN ) {
00082 newdts = ( (fcount-1) * SEC_PER + *pts);
00083 newpts = ((fnum ) * SEC_PER + *pts);
00084 } else {
00085 uint64_t extra_time = 0;
00086
00087
00088 if ( s->pulldown == PULLDOWN32)
00089 extra_time = SEC_PER;
00090 else
00091 extra_time = 3*SEC_PER/2;
00092
00093 newdts = (fcount - 1) * 5ULL * SEC_PER / 4ULL +
00094 ((fcount - 1)%2)*extra_time +
00095 *pts;
00096
00097 if ((s->pulldown == PULLDOWN23) && (fcount-1))
00098 newdts -= SEC_PER/2;
00099
00100 newpts = SEC_PER +
00101 (fnum -1) * 5ULL * SEC_PER / 4ULL +
00102 ((fnum - 1)%2)*extra_time +
00103 *pts;
00104
00105 }
00106
00107
00108 *pts = newpts >= 0 ? newpts%MAX_PTS2: MAX_PTS2+newpts;
00109 return newdts >= 0 ? newdts%MAX_PTS2: MAX_PTS2+newdts;
00110 }
00111
00112 void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts, uint64_t pts,
00113 uint64_t origdts, uint64_t dts)
00114 {
00115 int64_t pdiff = 0;
00116 int64_t ddiff = 0;
00117 int64_t pframe = 0;
00118 int64_t dframe = 0;
00119 int psig=0;
00120 int dsig=0;
00121 int64_t fr=0;
00122
00123 pdiff = ptsdiff(origpts,pts);
00124 ddiff = ptsdiff(origdts,dts);
00125 psig = pdiff > 0;
00126 dsig = ddiff > 0;
00127 if (!psig) pdiff = -pdiff;
00128 if (!dsig) ddiff = -ddiff;
00129
00130 if ( s->pulldown == NOPULLDOWN ) {
00131 dframe = (ddiff+SEC_PER/2ULL) / SEC_PER;
00132 pframe = (pdiff+SEC_PER/2ULL) / SEC_PER;
00133 } else {
00134 dframe = (4ULL*ddiff/5ULL+SEC_PER/2ULL) / SEC_PER;
00135 pframe = (4ULL*pdiff/5ULL+SEC_PER/2ULL) / SEC_PER;
00136 }
00137
00138 if (!psig) fr = -(int)pframe;
00139 else fr = (int)pframe;
00140 if (!dsig) fr -= (int)dframe;
00141 else fr += (int)dframe;
00142 *frame = *frame + fr/2;
00143 if (fr/2) fprintf(stderr,"fixed video frame %d\n",
00144 (int)fr/2);
00145 }
00146
00147
00148 void pts2time(uint64_t pts, uint8_t *buf, int len)
00149 {
00150 uint8_t h,m,s;
00151 int c = 0;
00152
00153 pts = (pts/300)%MAX_PTS;
00154 h = (uint8_t)(pts/90000)/3600;
00155 m = (uint8_t)((pts/90000)%3600)/60;
00156 s = (uint8_t)((pts/90000)%3600)%60;
00157
00158 while (c+7 < len){
00159 if (buf[c] == 0x00 && buf[c+1] == 0x00 && buf[c+2] == 0x01 &&
00160 buf[c+3] == GROUP_START_CODE && (buf[c+5] & 0x08)){
00161 buf[c+4] &= ~(0x7F);
00162 buf[c+4] |= (h & 0x1F) << 2;
00163 buf[c+4] |= (m & 0x30) >> 4;
00164
00165 buf[c+5] &= ~(0xF7);
00166 buf[c+5] |= (m & 0x0F) << 4;
00167 buf[c+5] |= (s & 0x38) >> 3;
00168
00169 buf[c+6] &= ~(0xE0);
00170 buf[c+6] |= (s & 0x07) << 5;
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 c = len;
00181
00182
00183 } else c++;
00184 }
00185
00186 }
00187
00188
00189 int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
00190 {
00191 uint8_t buf[150];
00192 uint8_t *headr;
00193 int sw,i;
00194 int form = -1;
00195 int c = 0;
00196 int re = 0;
00197
00198
00199 s->set = 0;
00200 s->ext_set = 0;
00201 s->pulldown_set = 0;
00202 if ((re = ring_find_mpg_header(rbuf, SEQUENCE_HDR_CODE, off, le)) < 0)
00203 return re;
00204 headr = buf+4;
00205 if (ring_peek(rbuf, buf, 150, off) < 0) return -2;
00206
00207 s->h_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
00208 s->v_size = ((headr[1] &0x0F) << 8) | (headr[2]);
00209
00210 sw = (int)((headr[3]&0xF0) >> 4) ;
00211
00212 if (DEBUG){
00213 switch( sw ){
00214 case 1:
00215 fprintf(stderr,"Video: aspect ratio: 1:1");
00216 s->aspect_ratio = 100;
00217 break;
00218 case 2:
00219 fprintf(stderr,"Video: aspect ratio: 4:3");
00220 s->aspect_ratio = 133;
00221 break;
00222 case 3:
00223 fprintf(stderr,"Video: aspect ratio: 16:9");
00224 s->aspect_ratio = 177;
00225 break;
00226 case 4:
00227 fprintf(stderr,"Video: aspect ratio: 2.21:1");
00228 s->aspect_ratio = 221;
00229 break;
00230
00231 case 5 ... 15:
00232 fprintf(stderr,"Video: aspect ratio: reserved");
00233 s->aspect_ratio = 0;
00234 break;
00235
00236 default:
00237 s->aspect_ratio = 0;
00238 return -3;
00239 }
00240 }
00241
00242 if (DEBUG) fprintf(stderr," size = %dx%d",s->h_size,s->v_size);
00243
00244 sw = (int)(headr[3]&0x0F);
00245
00246 switch ( sw ) {
00247 case 1:
00248 s->frame_rate = 23976;
00249 form = -1;
00250 break;
00251 case 2:
00252 s->frame_rate = 24000;
00253 form = -1;
00254 break;
00255 case 3:
00256 s->frame_rate = 25000;
00257 form = VIDEO_PAL;
00258 break;
00259 case 4:
00260 s->frame_rate = 29970;
00261 form = VIDEO_NTSC;
00262 break;
00263 case 5:
00264 s->frame_rate = 30000;
00265 form = VIDEO_NTSC;
00266 break;
00267 case 6:
00268 s->frame_rate = 50000;
00269 form = VIDEO_PAL;
00270 break;
00271 case 7:
00272 s->frame_rate = 60000;
00273 form = VIDEO_NTSC;
00274 break;
00275 }
00276 if (DEBUG) fprintf(stderr," frame rate: %2.3f fps",s->frame_rate/1000.);
00277
00278 s->bit_rate = (((headr[4] << 10) & 0x0003FC00UL)
00279 | ((headr[5] << 2) & 0x000003FCUL) |
00280 (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
00281
00282 if (DEBUG) fprintf(stderr," bit rate: %.2f Mbit/s",400*(s->bit_rate)/1000000.);
00283 if (DEBUG) fprintf(stderr,"\n");
00284
00285 s->video_format = form;
00286
00287
00288
00289 s->vbv_buffer_size = (( headr[7] & 0xF8) >> 3 ) | (( headr[6] & 0x1F )<< 5);
00290 s->flags = ( headr[7] & 0x06);
00291 if (DEBUG) fprintf(stderr, " vbvbuffer %d\n",16*1024*(s->vbv_buffer_size));
00292
00293 c += 8;
00294 if ( !(s->flags & INTRAQ_FLAG) )
00295 s->flags = ( headr[7] & 0x07);
00296 else {
00297 s->flags |= headr[c+63] & 0x01;
00298 memset(s->intra_quant, 0, 64);
00299 for (i=0;i<64;i++)
00300 s->intra_quant[i] |= (headr[c+i] >> 1) |
00301 (( headr[c-1+i] & 0x01) << 7);
00302
00303 c += 64;
00304 }
00305 if (s->flags & NONINTRAQ_FLAG){
00306 memcpy(s->non_intra_quant, headr+c, 64);
00307 c += 64;
00308 }
00309 s->set=1;
00310
00311 return c;
00312 }
00313
00314 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, int off, int type, int le)
00315 {
00316 int found = 0;
00317 int c=0;
00318 int l;
00319 uint8_t b1,b2,m2;
00320 int r=0;
00321
00322 memset(buf,0,7);
00323 b1 = 0x00;
00324 b2 = 0x00;
00325 m2 = 0xFF;
00326 switch(type){
00327 case AC3:
00328 b1 = 0x0B;
00329 b2 = 0x77;
00330 l = 6;
00331 break;
00332
00333 case MPEG_AUDIO:
00334 b1 = 0xFF;
00335 b2 = 0xF8;
00336 m2 = 0xF8;
00337 l = 4;
00338 break;
00339
00340 default:
00341 return -1;
00342 }
00343
00344 c = off;
00345 while ( c-off < le){
00346 uint8_t b;
00347 if ((r = mring_peek(rbuf, &b, 1, c)) <0) return -1;
00348 switch(found){
00349
00350 case 0:
00351 if ( b == b1) found = 1;
00352 break;
00353
00354 case 1:
00355 if ( (b&m2) == b2){
00356 if ((r = mring_peek(rbuf, buf, l, c-1)) < -1)
00357 return -2;
00358 return c-1-off;
00359 } else if ( b != b1) found = 0;
00360 }
00361 c++;
00362 }
00363 if (found) return -2;
00364 return -1;
00365 }
00366
00367 int find_audio_s(uint8_t *rbuf, int off, int type, int le)
00368 {
00369 int found = 0;
00370 int c=0;
00371 int l;
00372 uint8_t b1,b2,m2;
00373
00374 b1 = 0x00;
00375 b2 = 0x00;
00376 m2 = 0xFF;
00377 switch(type){
00378 case AC3:
00379 b1 = 0x0B;
00380 b2 = 0x77;
00381 l = 6;
00382 break;
00383
00384 case MPEG_AUDIO:
00385 b1 = 0xFF;
00386 b2 = 0xF8;
00387 m2 = 0xF8;
00388 l = 4;
00389 break;
00390
00391 default:
00392 return -1;
00393 }
00394
00395 c = off;
00396 while ( c < le){
00397 uint8_t b=rbuf[c];
00398 switch(found){
00399 case 0:
00400 if ( b == b1) found = 1;
00401 break;
00402
00403 case 1:
00404 if ( (b&m2) == b2){
00405 return c-1;
00406 } else if ( b != b1) found = 0;
00407 }
00408 c++;
00409 }
00410 if (found) return -2;
00411 return -1;
00412 }
00413
00414 int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, int off, int le,
00415 int type)
00416 {
00417 uint8_t headr[7];
00418 uint8_t frame;
00419 int fr;
00420 int half = 0;
00421 int c=0;
00422
00423 if ( (c = find_audio_sync(rbuf, headr, off, type, le))
00424 != 0 ) {
00425 if (c==-2){
00426 fprintf(stderr,"Incomplete audio header\n");
00427 return -2;
00428 }
00429 fprintf(stderr,"Error in audio header\n");
00430 return -1;
00431 }
00432 switch (type){
00433
00434 case MPEG_AUDIO:
00435 if ( af->layer != ((headr[1] & 0x06) >> 1) ){
00436 if ( headr[1] == 0xff){
00437 return -3;
00438 } else {
00439 #ifdef IN_DEBUG
00440 fprintf(stderr,"Wrong audio layer\n");
00441 #endif
00442 return -1;
00443 }
00444 }
00445 if ( af->bit_rate !=
00446 (bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000)){
00447 #ifdef IN_DEBUG
00448 fprintf(stderr,"Wrong audio bit rate\n");
00449 #endif
00450 return -1;
00451 }
00452 break;
00453
00454 case AC3:
00455 frame = (headr[4]&0x3F);
00456 if (af->bit_rate != ac3_bitrates[frame>>1]*1000){
00457 #ifdef IN_DEBUG
00458 fprintf(stderr,"Wrong audio bit rate\n");
00459 #endif
00460 return -1;
00461 }
00462 half = ac3half[headr[5] >> 3];
00463 fr = (headr[4] & 0xc0) >> 6;
00464 if (af->frequency != ((ac3_freq[fr] *100) >> half)){
00465 #ifdef IN_DEBUG
00466 fprintf(stderr,"Wrong audio frequency\n");
00467 #endif
00468 return -1;
00469 }
00470
00471 break;
00472
00473 }
00474
00475 return 0;
00476 }
00477
00478
00479 int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
00480 {
00481 int c = 0;
00482 int fr =0;
00483 uint8_t headr[7];
00484
00485 af->set=0;
00486
00487 if ( (c = find_audio_sync(rbuf, headr, off, MPEG_AUDIO,le)) < 0 )
00488 return c;
00489
00490 af->layer = (headr[1] & 0x06) >> 1;
00491
00492 if (DEBUG)
00493 fprintf(stderr,"Audiostream: layer: %d", 4-af->layer);
00494
00495
00496 af->bit_rate = bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000;
00497
00498 if (DEBUG){
00499 if (af->bit_rate == 0)
00500 fprintf (stderr," Bit rate: free");
00501 else if (af->bit_rate == 0xf)
00502 fprintf (stderr," BRate: reserved");
00503 else
00504 fprintf (stderr," BRate: %d kb/s", af->bit_rate/1000);
00505 }
00506
00507 fr = (headr[2] & 0x0c ) >> 2;
00508 af->frequency = freq[fr]*100;
00509
00510 if (DEBUG){
00511 if (af->frequency == 3)
00512 fprintf (stderr, " Freq: reserved");
00513 else
00514 fprintf (stderr," Freq: %2.1f kHz",
00515 af->frequency/1000.);
00516 }
00517 af->off = c;
00518 af->set = 1;
00519
00520 af->frametime = ((samples [3-af->layer] * 27000000ULL) / af->frequency);
00521 af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency;
00522 fprintf(stderr," frame size: %d (", af->framesize);
00523 printpts(af->frametime);
00524 fprintf(stderr,") ");
00525
00526 return c;
00527 }
00528
00529 int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
00530 {
00531 int c=0;
00532 uint8_t headr[7];
00533 uint8_t frame;
00534 int half = 0;
00535 int fr;
00536
00537
00538 af->set=0;
00539
00540 if ((c = find_audio_sync(rbuf, headr, off, AC3, le)) < 0 )
00541 return c;
00542
00543 af->off = c;
00544
00545 af->layer = 0;
00546
00547 if (DEBUG) fprintf (stderr,"AC3 stream:");
00548 frame = (headr[4]&0x3F);
00549 af->bit_rate = ac3_bitrates[frame>>1]*1000;
00550 half = ac3half[headr[5] >> 3];
00551 if (DEBUG) fprintf (stderr," bit rate: %d kb/s", af->bit_rate/1000);
00552 fr = (headr[4] & 0xc0) >> 6;
00553 af->frequency = (ac3_freq[fr] *100) >> half;
00554
00555 if (DEBUG) fprintf (stderr," freq: %d Hz\n", af->frequency);
00556
00557 switch (headr[4] & 0xc0) {
00558 case 0:
00559 af->framesize = 4 * af->bit_rate/1000;
00560 break;
00561
00562 case 0x40:
00563 af->framesize = 2 * (320 * af->bit_rate / 147000 + (frame & 1));
00564 break;
00565
00566 case 0x80:
00567 af->framesize = 6 * af->bit_rate/1000;
00568 break;
00569 }
00570
00571 if (DEBUG) fprintf (stderr," frame size %d\n", af->framesize);
00572
00573 af->off = c;
00574 af->set = 1;
00575
00576
00577 af->frametime = 0;
00578
00579 return c;
00580 }
00581
00582
00583 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
00584 {
00585 uint8_t *headr;
00586 uint8_t buf[12];
00587 uint8_t ext_id;
00588 int re=0;
00589
00590 if (( re =ring_find_mpg_header(rbuf, EXTENSION_START_CODE, off, le)) < 0){
00591 fprintf(stderr,"Error in find_mpg_header");
00592 return re;
00593 }
00594
00595 if (ring_peek(rbuf, buf, 5, off) < 0) return -2;
00596 headr=buf+4;
00597
00598 ext_id = (headr[0]&0xF0) >> 4;
00599
00600 switch (ext_id){
00601 case SEQUENCE_EXTENSION:{
00602 uint16_t hsize;
00603 uint16_t vsize;
00604 uint32_t vbvb;
00605 uint32_t bitrate;
00606 uint8_t fr_n, fr_d;
00607
00608
00609 if (s->ext_set || !s->set) break;
00610 if (ring_peek(rbuf, buf, 10, off) < 0) return -2;
00611 headr=buf+4;
00612
00613 if (DEBUG) fprintf(stderr,"Sequence Extension:");
00614 s->profile = ((headr[0]&0x0F) << 4) | ((headr[1]&0xF0) >> 4);
00615 if (headr[1]&0x08) s->progressive = 1;
00616 else s->progressive = 0;
00617 s->chroma = (headr[1]&0x06)>>1;
00618 if (DEBUG){
00619 switch(s->chroma){
00620 case 0:
00621 fprintf(stderr," chroma reserved ");
00622 break;
00623 case 1:
00624 fprintf(stderr," chroma 4:2:0 ");
00625 break;
00626 case 2:
00627 fprintf(stderr," chroma 4:2:2 ");
00628 break;
00629 case 3:
00630 fprintf(stderr," chroma 4:4:4 ");
00631 break;
00632 }
00633 }
00634
00635 hsize = ((headr[1]&0x01)<<12) | ((headr[2]&0x80)<<6);
00636 vsize = ((headr[2]&0x60)<<7);
00637 s->h_size |= hsize;
00638 s->v_size |= vsize;
00639 if (DEBUG) fprintf(stderr," size = %dx%d",s->h_size,s->v_size);
00640
00641 bitrate = ((headr[2]& 0x1F) << 25) | (( headr[3] & 0xFE ) << 17);
00642 s->bit_rate |= bitrate;
00643
00644 if (DEBUG) fprintf(stderr," bit rate: %.2f Mbit/s",400.*(s->bit_rate)/1000000.);
00645
00646
00647 vbvb = (headr[4]<<10);
00648 s->vbv_buffer_size |= vbvb;
00649 if (DEBUG) fprintf(stderr, " vbvbuffer %d",16*1024*(s->vbv_buffer_size));
00650 fr_n = (headr[5] & 0x60) >> 6;
00651 fr_d = (headr[5] & 0x1F);
00652
00653 s->frame_rate = s->frame_rate * (fr_n+1) / (fr_d+1);
00654 if (DEBUG) fprintf(stderr," frame rate: %2.3f\n", s->frame_rate/1000.);
00655 s->ext_set=1;
00656 break;
00657 }
00658
00659 case SEQUENCE_DISPLAY_EXTENSION:
00660 break;
00661
00662 case PICTURE_CODING_EXTENSION:{
00663 int pulldown = 0;
00664
00665 if (!s->set || s->pulldown_set) break;
00666 if (ring_peek(rbuf, buf, 10, off) < 0) return -2;
00667 headr=buf+4;
00668
00669 if ( (headr[2]&0x03) != 0x03 ) break;
00670 if ( (headr[3]&0x02) ) pulldown = 1;
00671
00672 if (pulldown){
00673 if (s->current_tmpref)
00674 s->pulldown = PULLDOWN23;
00675 else
00676 s->pulldown = PULLDOWN32;
00677 s->pulldown_set = 1;
00678 }
00679 if (DEBUG){
00680 switch (s->pulldown) {
00681 case PULLDOWN32:
00682 if (DEBUG) fprintf(stderr,"Picture Coding Extension:");
00683 fprintf(stderr," 3:2 pulldown detected \n");
00684 break;
00685 case PULLDOWN23:
00686 if (DEBUG) fprintf(stderr,"Picture Coding Extension:");
00687 fprintf(stderr," 2:3 pulldown detected \n");
00688 break;
00689
00690
00691 }
00692 }
00693 break;
00694 }
00695 case QUANT_MATRIX_EXTENSION:
00696 break;
00697 case PICTURE_DISPLAY_EXTENSION:
00698 break;
00699 }
00700
00701
00702 return ext_id;
00703 }
00704