Mercurial > mplayer.hg
comparison mplayer.c @ 746:cd1f0d4de0b8
new audio playback and A-V sync code
author | arpi_esp |
---|---|
date | Thu, 10 May 2001 03:39:54 +0000 |
parents | c3e0bdb64027 |
children | 717e4677d9ce |
comparison
equal
deleted
inserted
replaced
745:c653430f0789 | 746:cd1f0d4de0b8 |
---|---|
25 #include <linux/cdrom.h> | 25 #include <linux/cdrom.h> |
26 | 26 |
27 #include "version.h" | 27 #include "version.h" |
28 #include "config.h" | 28 #include "config.h" |
29 | 29 |
30 #ifndef OUTBURST | 30 #ifndef MAX_OUTBURST |
31 #error "=============================================" | 31 #error "=============================================" |
32 #error "Please re-run ./configure and then try again!" | 32 #error "Please re-run ./configure and then try again!" |
33 #error "=============================================" | 33 #error "=============================================" |
34 #endif | 34 #endif |
35 | 35 |
252 int len; | 252 int len; |
253 len=demux_read_data(sh_audio->ds,buf,size); | 253 len=demux_read_data(sh_audio->ds,buf,size); |
254 return len; | 254 return len; |
255 } | 255 } |
256 | 256 |
257 | |
258 //#include "dec_audio.c" | 257 //#include "dec_audio.c" |
259 | 258 |
260 //**************************************************************************// | 259 //**************************************************************************// |
261 // The OpenDivX stuff: | 260 // The OpenDivX stuff: |
262 //**************************************************************************// | 261 //**************************************************************************// |
302 fake_ALSA_len=0; | 301 fake_ALSA_len=0; |
303 } | 302 } |
304 } | 303 } |
305 } | 304 } |
306 #endif | 305 #endif |
306 | |
307 //**************************************************************************// | |
308 | |
309 int audio_delay_method=2; | |
310 int audio_buffer_size=-1; | |
311 | |
312 int get_audio_delay(int audio_fd){ | |
313 if(audio_delay_method==2){ | |
314 // | |
315 int r=0; | |
316 if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1) | |
317 return r; | |
318 audio_delay_method=1; // fallback if not supported | |
319 } | |
320 if(audio_delay_method==1){ | |
321 // SNDCTL_DSP_GETOSPACE | |
322 audio_buf_info zz; | |
323 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1) | |
324 return audio_buffer_size-zz.bytes; | |
325 audio_delay_method=0; // fallback if not supported | |
326 } | |
327 return audio_buffer_size; | |
328 } | |
329 | |
330 | |
307 //**************************************************************************// | 331 //**************************************************************************// |
308 | 332 |
309 // AVI file header reader/parser/writer: | 333 // AVI file header reader/parser/writer: |
310 //#include "aviheader.c" | 334 //#include "aviheader.c" |
311 //#include "aviwrite.c" | 335 //#include "aviwrite.c" |
399 extern int init_audio(sh_audio_t *sh_audio); | 423 extern int init_audio(sh_audio_t *sh_audio); |
400 extern int init_video_codec(sh_video_t *sh_video); | 424 extern int init_video_codec(sh_video_t *sh_video); |
401 extern void mpeg2_allocate_image_buffers(picture_t * picture); | 425 extern void mpeg2_allocate_image_buffers(picture_t * picture); |
402 extern void write_avi_header_1(FILE *f,int fcc,float fps,int width,int height); | 426 extern void write_avi_header_1(FILE *f,int fcc,float fps,int width,int height); |
403 extern int vo_init(void); | 427 extern int vo_init(void); |
404 extern int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int maxlen); | 428 extern int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen); |
405 | 429 |
406 char* filename=NULL; //"MI2-Trailer.avi"; | 430 char* filename=NULL; //"MI2-Trailer.avi"; |
407 int i; | 431 int i; |
408 int seek_to_sec=0; | 432 int seek_to_sec=0; |
409 int seek_to_byte=0; | 433 int seek_to_byte=0; |
422 #ifdef ALSA_TIMER | 446 #ifdef ALSA_TIMER |
423 int alsa=1; | 447 int alsa=1; |
424 #else | 448 #else |
425 int alsa=0; | 449 int alsa=0; |
426 #endif | 450 #endif |
427 int audio_buffer_size=-1; | |
428 int audio_id=-1; | 451 int audio_id=-1; |
429 int video_id=-1; | 452 int video_id=-1; |
430 int dvdsub_id=-1; | 453 int dvdsub_id=-1; |
431 float default_max_pts_correction=0.01f; | 454 float default_max_pts_correction=0.01f; |
432 int delay_corrected=1; | 455 int delay_corrected=1; |
1029 if(verbose) printf("Initializing audio codec...\n"); | 1052 if(verbose) printf("Initializing audio codec...\n"); |
1030 if(!init_audio(sh_audio)){ | 1053 if(!init_audio(sh_audio)){ |
1031 printf("Couldn't initialize audio codec! -> nosound\n"); | 1054 printf("Couldn't initialize audio codec! -> nosound\n"); |
1032 has_audio=0; | 1055 has_audio=0; |
1033 } else { | 1056 } else { |
1034 printf("AUDIO: samplerate=%d channels=%d bps=%d\n",sh_audio->samplerate,sh_audio->channels,sh_audio->samplesize); | 1057 printf("AUDIO: samplerate=%d channels=%d bps=%d ratio: %d->%d\n",sh_audio->samplerate,sh_audio->channels,sh_audio->samplesize, |
1058 sh_audio->i_bps,sh_audio->o_bps); | |
1035 } | 1059 } |
1036 } | 1060 } |
1037 | 1061 |
1038 //================== Init VIDEO (codec & libvo) ========================== | 1062 //================== Init VIDEO (codec & libvo) ========================== |
1039 | 1063 |
1280 fflush(stdout); | 1304 fflush(stdout); |
1281 | 1305 |
1282 //================== MAIN: ========================== | 1306 //================== MAIN: ========================== |
1283 { | 1307 { |
1284 int audio_fd=-1; | 1308 int audio_fd=-1; |
1285 float buffer_delay=0; | 1309 int outburst=OUTBURST; |
1310 float audio_buffer_delay=0; | |
1311 | |
1312 //float buffer_delay=0; | |
1286 float frame_correction=0; // A-V timestamp kulonbseg atlagolas | 1313 float frame_correction=0; // A-V timestamp kulonbseg atlagolas |
1287 int frame_corr_num=0; // | 1314 int frame_corr_num=0; // |
1288 float a_frame=0; // Audio | 1315 float a_frame=0; // Audio |
1289 float v_frame=0; // Video | 1316 float v_frame=0; // Video |
1290 float time_frame=0; // Timer | 1317 float time_frame=0; // Timer |
1360 | 1387 |
1361 if(has_audio){ | 1388 if(has_audio){ |
1362 #ifdef USE_XMMP_AUDIO | 1389 #ifdef USE_XMMP_AUDIO |
1363 if(audio_buffer_size==-1){ | 1390 if(audio_buffer_size==-1){ |
1364 // Measuring buffer size: | 1391 // Measuring buffer size: |
1365 buffer_delay=pSound->QueryDelay(pSound, 0); | 1392 audio_buffer_delay=pSound->QueryDelay(pSound, 0); |
1366 } else { | 1393 } else { |
1367 // -abs commandline option | 1394 // -abs commandline option |
1368 buffer_delay=audio_buffer_size/(float)(sh_audio->o_bps); | 1395 audio_buffer_delay=audio_buffer_size/(float)(sh_audio->o_bps); |
1369 } | 1396 } |
1370 #else | 1397 #else |
1371 int r; | 1398 int r; |
1399 audio_buf_info zz; | |
1400 | |
1372 r=(sh_audio->samplesize==2)?AFMT_S16_LE:AFMT_U8;ioctl (audio_fd, SNDCTL_DSP_SETFMT, &r); | 1401 r=(sh_audio->samplesize==2)?AFMT_S16_LE:AFMT_U8;ioctl (audio_fd, SNDCTL_DSP_SETFMT, &r); |
1373 r=sh_audio->channels-1; ioctl (audio_fd, SNDCTL_DSP_STEREO, &r); | 1402 r=sh_audio->channels-1; ioctl (audio_fd, SNDCTL_DSP_STEREO, &r); |
1374 r=sh_audio->samplerate; if(ioctl (audio_fd, SNDCTL_DSP_SPEED, &r)==-1) | 1403 r=sh_audio->samplerate; if(ioctl (audio_fd, SNDCTL_DSP_SPEED, &r)==-1){ |
1375 printf("audio_setup: your card doesn't support %d Hz samplerate\n",r); | 1404 printf("audio_setup: your card doesn't support %d Hz samplerate => nosound\n",r); |
1376 | 1405 has_audio=0; |
1377 #if 0 | 1406 } else |
1378 // r = (64 << 16) + 1024; | 1407 printf("audio_setup: using %d Hz samplerate (requested: %d)\n",r,sh_audio->samplerate); |
1379 r = (65536 << 16) + 512; | 1408 |
1380 if(ioctl (audio_fd, SNDCTL_DSP_SETFRAGMENT, &r)==-1) | 1409 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){ |
1381 printf("audio_setup: your card doesn't support setting fragments\n",r); | 1410 printf("audio_setup: driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"); |
1382 #endif | 1411 r=0; |
1412 if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &r)==-1){ | |
1413 printf("audio_setup: %d bytes/frag (config.h)\n",outburst); | |
1414 } else { | |
1415 outburst=r; | |
1416 printf("audio_setup: %d bytes/frag (GETBLKSIZE)\n",outburst); | |
1417 } | |
1418 } else { | |
1419 printf("audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n", | |
1420 zz.fragments, zz.fragstotal, zz.fragsize, zz.bytes); | |
1421 if(audio_buffer_size==-1) audio_buffer_size=zz.bytes; | |
1422 outburst=zz.fragsize; | |
1423 } | |
1383 | 1424 |
1384 if(audio_buffer_size==-1){ | 1425 if(audio_buffer_size==-1){ |
1385 // Measuring buffer size: | 1426 // Measuring buffer size: |
1386 audio_buffer_size=0; | 1427 audio_buffer_size=0; |
1387 #ifdef HAVE_AUDIO_SELECT | 1428 #ifdef HAVE_AUDIO_SELECT |
1389 fd_set rfds; | 1430 fd_set rfds; |
1390 struct timeval tv; | 1431 struct timeval tv; |
1391 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); | 1432 FD_ZERO(&rfds); FD_SET(audio_fd,&rfds); |
1392 tv.tv_sec=0; tv.tv_usec = 0; | 1433 tv.tv_sec=0; tv.tv_usec = 0; |
1393 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; | 1434 if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break; |
1394 write(audio_fd,&sh_audio->a_buffer[sh_audio->a_buffer_len],OUTBURST); | 1435 write(audio_fd,&sh_audio->a_buffer[sh_audio->a_buffer_len],outburst); |
1395 audio_buffer_size+=OUTBURST; | 1436 audio_buffer_size+=outburst; |
1396 } | 1437 } |
1397 if(audio_buffer_size==0){ | 1438 if(audio_buffer_size==0){ |
1398 printf("\n *** Your audio driver DOES NOT support select() ***\n"); | 1439 printf("\n *** Your audio driver DOES NOT support select() ***\n"); |
1399 printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); | 1440 printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); |
1400 exit_player("audio_init"); | 1441 exit_player("audio_init"); |
1401 } | 1442 } |
1402 #endif | 1443 #endif |
1403 } | 1444 } |
1404 buffer_delay=audio_buffer_size/(float)(sh_audio->o_bps); | 1445 audio_buffer_delay=audio_buffer_size/(float)(sh_audio->o_bps); |
1405 #endif | 1446 #endif |
1406 a_frame=-(buffer_delay); | 1447 printf("Audio buffer size: %d bytes, delay: %5.3fs\n",audio_buffer_size,audio_buffer_delay); |
1407 printf("Audio buffer size: %d bytes, delay: %5.3fs\n",audio_buffer_size,buffer_delay); | 1448 |
1449 // a_frame=-(audio_buffer_delay); | |
1450 a_frame=0; | |
1408 // RESET_AUDIO(audio_fd); | 1451 // RESET_AUDIO(audio_fd); |
1409 } | 1452 } |
1410 | 1453 |
1411 | 1454 |
1412 if(!has_audio){ | 1455 if(!has_audio){ |
1426 current_module=NULL; | 1469 current_module=NULL; |
1427 | 1470 |
1428 //==================== START PLAYING ======================= | 1471 //==================== START PLAYING ======================= |
1429 | 1472 |
1430 if(file_format==DEMUXER_TYPE_AVI){ | 1473 if(file_format==DEMUXER_TYPE_AVI){ |
1431 a_pts=d_audio->pts-(buffer_delay+audio_delay); | 1474 a_pts=d_audio->pts; |
1432 audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime; | 1475 audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime; |
1433 // audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)/default_fps; | 1476 // audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)/default_fps; |
1434 if(verbose){ | 1477 if(verbose){ |
1435 printf("AVI Initial frame delay: %5.3f\n",(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime); | 1478 printf("AVI Initial frame delay: %5.3f\n",(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime); |
1436 printf("v: audio_delay=%5.3f buffer_delay=%5.3f a_pts=%5.3f a_frame=%5.3f\n", | 1479 printf("v: audio_delay=%5.3f buffer_delay=%5.3f a_pts=%5.3f a_frame=%5.3f\n", |
1437 audio_delay,buffer_delay,a_pts,a_frame); | 1480 audio_delay,audio_buffer_delay,a_pts,a_frame); |
1438 printf("START: a_pts=%5.3f v_pts=%5.3f \n",d_audio->pts,d_video->pts); | 1481 printf("START: a_pts=%5.3f v_pts=%5.3f \n",d_audio->pts,d_video->pts); |
1439 } | 1482 } |
1440 delay_corrected=0; // has to correct PTS diffs | 1483 delay_corrected=0; // has to correct PTS diffs |
1441 d_video->pts=0;d_audio->pts=0; // PTS is outdated now! | 1484 d_video->pts=0;d_audio->pts=0; // PTS is outdated now! |
1442 } | 1485 } |
1450 InitTimer(); | 1493 InitTimer(); |
1451 | 1494 |
1452 while(!eof){ | 1495 while(!eof){ |
1453 | 1496 |
1454 /*========================== PLAY AUDIO ============================*/ | 1497 /*========================== PLAY AUDIO ============================*/ |
1455 | 1498 if(!has_audio){ |
1499 int playsize=512; | |
1500 a_frame+=playsize/(float)(sh_audio->o_bps); | |
1501 a_pts+=playsize/(float)(sh_audio->o_bps); | |
1502 //time_frame+=playsize/(float)(sh_audio->o_bps); | |
1503 | |
1504 } else | |
1456 while(has_audio){ | 1505 while(has_audio){ |
1506 unsigned int t; | |
1507 int playsize=outburst; | |
1508 audio_buf_info zz; | |
1509 int use_select=1; | |
1510 | |
1511 if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){ | |
1512 // calculate exact buffer space: | |
1513 playsize=zz.fragments*zz.fragsize; | |
1514 if(!playsize) break; // buffer is full, do not block here!!! | |
1515 use_select=0; | |
1516 } | |
1517 | |
1518 if(playsize>MAX_OUTBURST) playsize=MAX_OUTBURST; // we shouldn't exceed it! | |
1519 //if(playsize>outburst) playsize=outburst; | |
1457 | 1520 |
1458 // Update buffer if needed | 1521 // Update buffer if needed |
1459 unsigned int t=GetTimer(); | 1522 t=GetTimer(); |
1460 current_module="decode_audio"; // Enter AUDIO decoder module | 1523 current_module="decode_audio"; // Enter AUDIO decoder module |
1461 //sh_audio->codec->driver=has_audio; // FIXME! | 1524 while(sh_audio->a_buffer_len<playsize && !d_audio->eof){ |
1462 while(sh_audio->a_buffer_len<OUTBURST && !d_audio->eof){ | 1525 int ret=decode_audio(sh_audio,&sh_audio->a_buffer[sh_audio->a_buffer_len], |
1463 int ret=decode_audio(sh_audio,&sh_audio->a_buffer[sh_audio->a_buffer_len],sh_audio->a_buffer_size-sh_audio->a_buffer_len); | 1526 playsize-sh_audio->a_buffer_len,sh_audio->a_buffer_size-sh_audio->a_buffer_len); |
1464 if(ret>0) sh_audio->a_buffer_len+=ret; else break; | 1527 if(ret>0) sh_audio->a_buffer_len+=ret; else break; |
1465 } | 1528 } |
1466 current_module=NULL; // Leave AUDIO decoder module | 1529 current_module=NULL; // Leave AUDIO decoder module |
1467 t=GetTimer()-t;audio_time_usage+=t*0.000001; | 1530 t=GetTimer()-t;audio_time_usage+=t*0.000001; |
1468 | 1531 |
1532 if(playsize>sh_audio->a_buffer_len) playsize=sh_audio->a_buffer_len; | |
1533 playsize/=outburst; playsize*=outburst; // rounding to fragment boundary | |
1534 | |
1535 // printf("play %d bytes of %d [max: %d]\n",playsize,sh_audio->a_buffer_len,sh_audio->a_buffer_size); | |
1469 | 1536 |
1470 // Play sound from the buffer: | 1537 // Play sound from the buffer: |
1471 if(sh_audio->a_buffer_len>=OUTBURST){ // if not EOF | 1538 if(playsize>0){ // if not EOF |
1472 #ifdef USE_XMMP_AUDIO | 1539 #ifdef USE_XMMP_AUDIO |
1473 pSound->Write( pSound, sh_audio->a_buffer, OUTBURST ); | 1540 pSound->Write( pSound, sh_audio->a_buffer, playsize ); |
1474 #else | 1541 #else |
1475 #ifdef SIMULATE_ALSA | 1542 #ifdef SIMULATE_ALSA |
1476 fake_ALSA_write(audio_fd,sh_audio->a_buffer,OUTBURST); // for testing purposes | 1543 fake_ALSA_write(audio_fd,sh_audio->a_buffer,playsize); // for testing purposes |
1477 #else | 1544 #else |
1478 write(audio_fd,sh_audio->a_buffer,OUTBURST); | 1545 playsize=write(audio_fd,sh_audio->a_buffer,playsize); |
1479 #endif | 1546 #endif |
1480 #endif | 1547 #endif |
1481 sh_audio->a_buffer_len-=OUTBURST; | 1548 if(playsize>0){ |
1482 memcpy(sh_audio->a_buffer,&sh_audio->a_buffer[OUTBURST],sh_audio->a_buffer_len); | 1549 sh_audio->a_buffer_len-=playsize; |
1550 memcpy(sh_audio->a_buffer,&sh_audio->a_buffer[playsize],sh_audio->a_buffer_len); | |
1551 a_frame+=playsize/(float)(sh_audio->o_bps); | |
1552 //a_pts+=playsize/(float)(sh_audio->o_bps); | |
1553 // time_frame+=playsize/(float)(sh_audio->o_bps); | |
1554 } | |
1483 #ifndef USE_XMMP_AUDIO | 1555 #ifndef USE_XMMP_AUDIO |
1484 #ifndef SIMULATE_ALSA | 1556 #ifndef SIMULATE_ALSA |
1485 // check buffer | 1557 // check buffer |
1486 #ifdef HAVE_AUDIO_SELECT | 1558 #ifdef HAVE_AUDIO_SELECT |
1487 { fd_set rfds; | 1559 if(use_select){ // do not use this code if SNDCTL_DSP_GETOSPACE works |
1560 fd_set rfds; | |
1488 struct timeval tv; | 1561 struct timeval tv; |
1489 FD_ZERO(&rfds); | 1562 FD_ZERO(&rfds); |
1490 FD_SET(audio_fd, &rfds); | 1563 FD_SET(audio_fd, &rfds); |
1491 tv.tv_sec = 0; | 1564 tv.tv_sec = 0; |
1492 tv.tv_usec = 0; | 1565 tv.tv_usec = 0; |
1493 if(select(audio_fd+1, NULL, &rfds, NULL, &tv)){ | 1566 if(select(audio_fd+1, NULL, &rfds, NULL, &tv)){ |
1494 a_frame+=OUTBURST/(float)(sh_audio->o_bps); | 1567 a_frame+=OUTBURST/(float)(sh_audio->o_bps); |
1495 a_pts+=OUTBURST/(float)(sh_audio->o_bps); | 1568 // a_pts+=OUTBURST/(float)(sh_audio->o_bps); |
1496 // printf("Filling audio buffer...\n"); | 1569 // printf("Filling audio buffer...\n"); |
1497 continue; | 1570 continue; |
1498 // } else { | 1571 // } else { |
1499 // printf("audio buffer full...\n"); | 1572 // printf("audio buffer full...\n"); |
1500 } | 1573 } |
1506 | 1579 |
1507 break; | 1580 break; |
1508 } // if(has_audio) | 1581 } // if(has_audio) |
1509 | 1582 |
1510 /*========================== UPDATE TIMERS ============================*/ | 1583 /*========================== UPDATE TIMERS ============================*/ |
1511 | 1584 #if 0 |
1512 a_frame+=OUTBURST/(float)(sh_audio->o_bps); | |
1513 a_pts+=OUTBURST/(float)(sh_audio->o_bps); | |
1514 | |
1515 if(alsa){ | 1585 if(alsa){ |
1516 // Use system timer for sync, not audio card/driver | 1586 // Use system timer for sync, not audio card/driver |
1517 time_frame+=OUTBURST/(float)(sh_audio->o_bps); | |
1518 time_frame-=GetRelativeTime(); | 1587 time_frame-=GetRelativeTime(); |
1519 if(time_frame<-0.1 || time_frame>0.1){ | 1588 if(time_frame<-0.1 || time_frame>0.1){ |
1520 time_frame=0; | 1589 time_frame=0; |
1521 } else { | 1590 } else { |
1522 while(time_frame>0.022){ | 1591 while(time_frame>0.022){ |
1527 usleep(0); | 1596 usleep(0); |
1528 time_frame-=GetRelativeTime(); | 1597 time_frame-=GetRelativeTime(); |
1529 } | 1598 } |
1530 } | 1599 } |
1531 } | 1600 } |
1532 | 1601 #endif |
1533 | 1602 |
1534 /*========================== PLAY VIDEO ============================*/ | 1603 /*========================== PLAY VIDEO ============================*/ |
1535 | 1604 |
1536 if(1) | 1605 if(1) |
1537 while(v_frame<a_frame || force_redraw){ | 1606 while(1){ |
1538 | 1607 |
1539 float frame_time=1; | 1608 float frame_time=1; |
1540 float pts1=d_video->pts; | 1609 float pts1=d_video->pts; |
1541 | 1610 |
1542 current_module="decode_video"; | 1611 current_module="decode_video"; |
1543 | 1612 |
1544 if(!force_redraw && v_frame+0.1<a_frame) drop_frame=1; else drop_frame=0; | 1613 // if(!force_redraw && v_frame+0.1<a_frame) drop_frame=1; else drop_frame=0; |
1545 drop_frame_cnt+=drop_frame; | 1614 drop_frame_cnt+=drop_frame; |
1546 | 1615 |
1547 //-------------------- Decode a frame: ----------------------- | 1616 //-------------------- Decode a frame: ----------------------- |
1548 switch(sh_video->codec->driver){ | 1617 switch(sh_video->codec->driver){ |
1549 case 3: { | 1618 case 3: { |
1712 sh_video->fps=1.0f/d; | 1781 sh_video->fps=1.0f/d; |
1713 } | 1782 } |
1714 } | 1783 } |
1715 v_frame+=frame_time; | 1784 v_frame+=frame_time; |
1716 v_pts+=frame_time; | 1785 v_pts+=frame_time; |
1786 time_frame+=frame_time; // for nosound | |
1787 | |
1788 // It's time to sleep... | |
1789 time_frame-=GetRelativeTime(); // reset timer | |
1790 | |
1791 if(has_audio){ | |
1792 int delay=get_audio_delay(audio_fd); | |
1793 if(verbose)printf("delay=%d\n",delay); | |
1794 time_frame=v_frame; | |
1795 time_frame-=a_frame-(float)delay/(float)sh_audio->o_bps; | |
1796 } else { | |
1797 if(time_frame<-0.1 || time_frame>0.1) time_frame=0; | |
1798 } | |
1799 | |
1800 if(verbose)printf("sleep: %5.3f a:%6.3f v:%6.3f \n",stime,a_frame,v_frame); | |
1801 | |
1802 while(time_frame>0.005){ | |
1803 if(time_frame<=0.020) | |
1804 usleep(0); // sleep 10ms | |
1805 else | |
1806 usleep(1000000*(time_frame-0.002)); | |
1807 time_frame-=GetRelativeTime(); | |
1808 } | |
1717 | 1809 |
1718 if(!drop_frame){ | 1810 if(!drop_frame){ |
1719 current_module="flip_page"; | 1811 current_module="flip_page"; |
1720 video_out->flip_page(); | 1812 video_out->flip_page(); |
1721 current_module=NULL; | 1813 current_module=NULL; |
1724 | 1816 |
1725 if(eof) break; | 1817 if(eof) break; |
1726 if(force_redraw){ | 1818 if(force_redraw){ |
1727 --force_redraw; | 1819 --force_redraw; |
1728 if(!force_redraw) osd_function=OSD_PLAY; | 1820 if(!force_redraw) osd_function=OSD_PLAY; |
1821 continue; | |
1729 } | 1822 } |
1730 | 1823 |
1731 // printf("A:%6.1f V:%6.1f A-V:%7.3f frame=%5.2f \r",d_audio->pts,d_video->pts,d_audio->pts-d_video->pts,a_frame); | 1824 // printf("A:%6.1f V:%6.1f A-V:%7.3f frame=%5.2f \r",d_audio->pts,d_video->pts,d_audio->pts-d_video->pts,a_frame); |
1732 // fflush(stdout); | 1825 // fflush(stdout); |
1733 | 1826 |
1734 #if 1 | 1827 #if 1 |
1735 /*================ A-V TIMESTAMP CORRECTION: =========================*/ | 1828 /*================ A-V TIMESTAMP CORRECTION: =========================*/ |
1736 if(has_audio){ | 1829 if(has_audio){ |
1830 // unplayed bytes in our and soundcard/dma buffer: | |
1831 int delay_bytes=get_audio_delay(audio_fd)+sh_audio->a_buffer_len; | |
1832 float delay=(float)delay_bytes/(float)sh_audio->o_bps; | |
1833 | |
1737 if(pts_from_bps && (file_format==DEMUXER_TYPE_AVI)){ | 1834 if(pts_from_bps && (file_format==DEMUXER_TYPE_AVI)){ |
1738 // a_pts=(float)ds_tell(d_audio)/sh_audio->wf.nAvgBytesPerSec-(buffer_delay+audio_delay); | 1835 // a_pts=(float)ds_tell(d_audio)/sh_audio->wf.nAvgBytesPerSec-(buffer_delay+audio_delay); |
1739 a_pts=(float)ds_tell(d_audio)/sh_audio->wf->nAvgBytesPerSec-(buffer_delay); | 1836 a_pts=(float)ds_tell(d_audio)/sh_audio->wf->nAvgBytesPerSec; |
1740 delay_corrected=1; // hack | 1837 delay_corrected=1; // hack |
1741 } else | 1838 } else |
1742 if(d_audio->pts){ | 1839 if(d_audio->pts){ |
1743 // printf("\n=== APTS a_pts=%5.3f v_pts=%5.3f === \n",d_audio->pts,d_video->pts); | 1840 // printf("\n=== APTS a_pts=%5.3f v_pts=%5.3f === \n",d_audio->pts,d_video->pts); |
1744 #if 1 | 1841 #if 1 |
1745 if(!delay_corrected){ | 1842 if(!delay_corrected){ |
1746 float x=d_audio->pts-d_video->pts-(buffer_delay+audio_delay); | 1843 float x=d_audio->pts-d_video->pts-(delay+audio_delay); |
1747 float y=-(buffer_delay+audio_delay); | 1844 float y=-(delay+audio_delay); |
1748 printf("Initial PTS delay: %5.3f sec (calculated: %5.3f)\n",x,y); | 1845 printf("Initial PTS delay: %5.3f sec (calculated: %5.3f)\n",x,y); |
1749 audio_delay+=x; | 1846 audio_delay+=x; |
1750 //a_pts-=x; | 1847 //a_pts-=x; |
1751 delay_corrected=1; | 1848 delay_corrected=1; |
1752 if(verbose) | 1849 if(verbose) |
1753 printf("v: audio_delay=%5.3f buffer_delay=%5.3f a.pts=%5.3f v.pts=%5.3f\n", | 1850 printf("v: audio_delay=%5.3f buffer_delay=%5.3f a.pts=%5.3f v.pts=%5.3f\n", |
1754 audio_delay,buffer_delay,d_audio->pts,d_video->pts); | 1851 audio_delay,delay,d_audio->pts,d_video->pts); |
1755 } | 1852 } |
1756 #endif | 1853 #endif |
1757 a_pts=d_audio->pts-(buffer_delay+audio_delay); | 1854 // a_pts=(ds_tell_pts(d_audio)+sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
1758 d_audio->pts=0; | 1855 // printf("a_pts+=%6.3f \n",a_pts); |
1856 // a_pts=d_audio->pts-a_pts; | |
1857 | |
1858 a_pts=d_audio->pts; | |
1859 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; | |
1860 | |
1861 //a_pts=d_audio->pts; d_audio->pts=0; | |
1759 } | 1862 } |
1760 if(d_video->pts) v_pts=d_video->pts; | 1863 if(d_video->pts) v_pts=d_video->pts; |
1761 if(frame_corr_num==5){ | 1864 if(frame_corr_num==5){ |
1762 float x=(frame_correction/5.0f); | 1865 float x=(frame_correction/5.0f); |
1763 if(delay_corrected){ | 1866 if(delay_corrected){ |
1764 printf("A:%6.1f V:%6.1f A-V:%7.3f",a_pts,v_pts,x); | 1867 // printf("A:%6.1f V:%6.1f A-V:%7.3f",a_pts-audio_delay-delay,v_pts,x); |
1868 printf("A:%6.1f (%6.1f) V:%6.1f A-V:%7.3f",a_pts,a_pts-audio_delay-delay,v_pts,x); | |
1765 x*=0.5f; | 1869 x*=0.5f; |
1766 if(x<-max_pts_correction) x=-max_pts_correction; else | 1870 if(x<-max_pts_correction) x=-max_pts_correction; else |
1767 if(x> max_pts_correction) x= max_pts_correction; | 1871 if(x> max_pts_correction) x= max_pts_correction; |
1768 max_pts_correction=default_max_pts_correction; | 1872 max_pts_correction=default_max_pts_correction; |
1769 a_frame+=x; c_total+=x; | 1873 a_frame+=x; c_total+=x; |
1777 ); | 1881 ); |
1778 fflush(stdout); | 1882 fflush(stdout); |
1779 } | 1883 } |
1780 frame_corr_num=0; frame_correction=0; | 1884 frame_corr_num=0; frame_correction=0; |
1781 } | 1885 } |
1782 if(frame_corr_num>=0) frame_correction+=a_pts-v_pts; | 1886 if(frame_corr_num>=0) frame_correction+=(a_pts-delay-audio_delay)-v_pts; |
1783 } else { | 1887 } else { |
1784 // No audio: | 1888 // No audio: |
1785 if(d_video->pts) v_pts=d_video->pts; | 1889 if(d_video->pts) v_pts=d_video->pts; |
1786 if(frame_corr_num==5){ | 1890 if(frame_corr_num==5){ |
1787 // printf("A: --- V:%6.1f \r",v_pts); | 1891 // printf("A: --- V:%6.1f \r",v_pts); |
1823 #ifdef HAVE_GUI | 1927 #ifdef HAVE_GUI |
1824 } else while( osd_function != OSD_PLAY ) usleep( 1000 ); | 1928 } else while( osd_function != OSD_PLAY ) usleep( 1000 ); |
1825 #endif | 1929 #endif |
1826 } | 1930 } |
1827 | 1931 |
1932 | |
1933 if(!force_redraw) break; | |
1828 } // while(v_frame<a_frame || force_redraw) | 1934 } // while(v_frame<a_frame || force_redraw) |
1829 | 1935 |
1830 | 1936 |
1831 //================= Keyboard events, SEEKing ==================== | 1937 //================= Keyboard events, SEEKing ==================== |
1832 | 1938 |
1855 rel_seek_secs+=600;break; | 1961 rel_seek_secs+=600;break; |
1856 case KEY_PAGE_DOWN: | 1962 case KEY_PAGE_DOWN: |
1857 rel_seek_secs-=600;break; | 1963 rel_seek_secs-=600;break; |
1858 // delay correction: | 1964 // delay correction: |
1859 case '+': | 1965 case '+': |
1860 buffer_delay+=0.1; // increase audio buffer delay | 1966 audio_delay+=0.1; // increase audio buffer delay |
1861 a_frame-=0.1; | 1967 a_frame-=0.1; |
1862 break; | 1968 break; |
1863 case '-': | 1969 case '-': |
1864 buffer_delay-=0.1; // decrease audio buffer delay | 1970 audio_delay-=0.1; // decrease audio buffer delay |
1865 a_frame+=0.1; | 1971 a_frame+=0.1; |
1866 break; | 1972 break; |
1867 // quit | 1973 // quit |
1868 case KEY_ESC: // ESC | 1974 case KEY_ESC: // ESC |
1869 case KEY_ENTER: // ESC | 1975 case KEY_ENTER: // ESC |
1984 //printf("v-pts recalc! %5.3f -> %5.3f \n",v_pts,avi_video_pts); | 2090 //printf("v-pts recalc! %5.3f -> %5.3f \n",v_pts,avi_video_pts); |
1985 v_pts=avi_video_pts; | 2091 v_pts=avi_video_pts; |
1986 #else | 2092 #else |
1987 avi_video_pts=v_pts; | 2093 avi_video_pts=v_pts; |
1988 #endif | 2094 #endif |
1989 a_pts=avi_video_pts-(buffer_delay); | 2095 a_pts=avi_video_pts; |
1990 //a_pts=v_pts; //-(buffer_delay+audio_delay); | 2096 //a_pts=v_pts; //-(buffer_delay+audio_delay); |
1991 | 2097 |
1992 if(has_audio){ | 2098 if(has_audio){ |
1993 int i; | 2099 int i; |
1994 int apos=0; | 2100 int apos=0; |
2187 } | 2293 } |
2188 | 2294 |
2189 max_pts_correction=0.1; | 2295 max_pts_correction=0.1; |
2190 frame_corr_num=-5; frame_correction=0; | 2296 frame_corr_num=-5; frame_correction=0; |
2191 force_redraw=5; | 2297 force_redraw=5; |
2192 a_frame=-buffer_delay-skip_audio_secs; | 2298 a_frame=-skip_audio_secs; |
2193 // a_frame=-audio_delay-buffer_delay-skip_audio_secs; | 2299 // a_frame=-audio_delay-buffer_delay-skip_audio_secs; |
2194 v_frame=0; // !!!!!! | 2300 v_frame=0; // !!!!!! |
2195 audio_time_usage=0; video_time_usage=0; vout_time_usage=0; | 2301 audio_time_usage=0; video_time_usage=0; vout_time_usage=0; |
2196 // num_frames=real_num_frames=0; | 2302 // num_frames=real_num_frames=0; |
2197 | 2303 |