Ticket #1660: 1660-v1.patch
File 1660-v1.patch, 7.1 KB (added by , 18 years ago) |
---|
-
libs/libmythtv/mpegrecorder.h
4 4 #define MPEGRECORDER_H_ 5 5 6 6 #include "recorderbase.h" 7 #include "DeviceReadBuffer.h" 7 8 8 9 struct AVFormatContext; 9 10 struct AVPacket; 10 11 11 class MpegRecorder : public RecorderBase 12 class MpegRecorder : public RecorderBase, private ReaderPausedCB 12 13 { 13 14 public: 14 15 MpegRecorder(TVRec*); … … 56 57 57 58 void ResetForNewFile(void); 58 59 60 void ReaderPaused(int fd); 61 bool PauseAndWait(int timeout = 100); 62 59 63 bool deviceIsMpegFile; 60 64 int bufferSize; 61 65 62 66 // State 63 67 bool recording; 64 bool encoding;68 bool request_recording; 65 69 bool errored; 66 70 67 71 // Pausing state … … 79 83 // Input file descriptors 80 84 int chanfd; 81 85 int readfd; 86 DeviceReadBuffer *drb; 82 87 83 88 // Keyframe tracking inforamtion 84 89 int keyframedist; -
libs/libmythtv/mpegrecorder.cpp
73 73 deviceIsMpegFile(false), 74 74 bufferSize(4096), 75 75 // State 76 recording(false), encoding(false),76 recording(false), request_recording(false), 77 77 errored(false), 78 78 // Pausing state 79 79 cleartimeonpause(false), … … 88 88 audvolume(80), 89 89 // Input file descriptors 90 90 chanfd(-1), readfd(-1), 91 drb(NULL), 91 92 // Keyframe tracking inforamtion 92 93 keyframedist(15), gopset(false), 93 94 leftovers(0), lastpackheaderpos(0), … … 98 99 buildbuffer(new unsigned char[kBuildBufferMaxSize + 1]), 99 100 buildbuffersize(0) 100 101 { 102 drb = new DeviceReadBuffer(this); 101 103 } 102 104 103 105 MpegRecorder::~MpegRecorder() … … 113 115 close(chanfd); 114 116 chanfd = -1; 115 117 } 118 116 119 if (readfd >= 0) 117 120 { 118 121 close(readfd); 119 122 readfd = -1; 120 123 } 124 125 if (drb) 126 { 127 delete drb; 128 drb = NULL; 129 } 121 130 } 122 131 123 132 void MpegRecorder::SetOption(const QString &opt, int value) … … 462 471 return; 463 472 } 464 473 465 encoding = true;474 request_recording = true; 466 475 recording = true; 467 476 unsigned char *buffer = new unsigned char[bufferSize + 1]; 468 477 int ret; … … 470 479 MythTimer elapsedTimer; 471 480 float elapsed; 472 481 473 struct timeval tv;474 fd_set rdset;475 476 482 if (deviceIsMpegFile) 477 483 elapsedTimer.start(); 478 484 479 while ( encoding)485 while (deviceIsMpegFile && request_recording && !errored) 480 486 { 481 487 if (PauseAndWait(100)) 482 488 continue; … … 494 500 if (readfd < 0) 495 501 readfd = open(videodevice.ascii(), O_RDWR); 496 502 497 tv.tv_sec = 5;498 tv.tv_usec = 0;499 FD_ZERO(&rdset);500 FD_SET(readfd, &rdset);501 502 switch (select(readfd + 1, &rdset, NULL, NULL, &tv))503 {504 case -1:505 if (errno == EINTR)506 continue;507 508 VERBOSE(VB_IMPORTANT, LOC_ERR + "Select error" + ENO);509 continue;510 511 case 0:512 VERBOSE(VB_IMPORTANT, LOC_ERR + "select timeout - "513 "ivtv driver has stopped responding");514 515 if (close(readfd) != 0)516 {517 VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO);518 }519 520 readfd = -1; // Force PVR card to be reopened on next iteration521 continue;522 523 default: break;524 }525 526 503 ret = read(readfd, buffer, bufferSize); 527 504 528 if ((ret == 0) && 529 (deviceIsMpegFile)) 505 if (ret == 0) 530 506 { 531 507 close(readfd); 532 508 readfd = open(videodevice.ascii(), O_RDONLY); … … 535 511 ret = read(readfd, buffer, bufferSize); 536 512 if (ret <= 0) 537 513 { 538 encoding = false;514 request_recording = false; 539 515 continue; 540 516 } 541 517 } … … 552 528 } 553 529 } 554 530 531 if (!deviceIsMpegFile) 532 { 533 VERBOSE(VB_IMPORTANT, QString("DRB:Setup(%1, %2)") 534 .arg(videodevice).arg(readfd)); 535 if (!drb->Setup(videodevice, readfd)) 536 { 537 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate DRB buffer"); 538 //Close(); 539 errored = true; 540 } 541 else 542 { 543 drb->Start(); 544 } 545 } 546 547 while (request_recording && !errored && !deviceIsMpegFile) 548 { 549 if (PauseAndWait(100)) 550 continue; 551 552 ssize_t len = drb->Read(buffer, bufferSize); 553 if (len > 0) 554 { 555 ProcessData(buffer, len); 556 } 557 else if (len == 0) 558 { 559 // Recover from timeout error by reopening ivtv device. 560 VERBOSE(VB_IMPORTANT, LOC_ERR + "Driver has stopped responding."); 561 /* 562 drb->Stop(); 563 if (close(readfd) != 0) 564 VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); 565 readfd = open(videodevice.ascii(), O_RDWR); 566 if (readfd < 0) 567 errored = true; 568 drb->Reset(videodevice, readfd); 569 drb->Start(); 570 */ 571 } 572 573 // Check for DRB errors 574 if (drb->IsErrored()) 575 { 576 VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected"); 577 errored = true; 578 } 579 580 if (drb->IsEOF()) 581 { 582 VERBOSE(VB_IMPORTANT, LOC_ERR + "Device EOF detected"); 583 errored = true; 584 } 585 } 586 587 if (drb && drb->IsRunning()) 588 drb->Stop(); 589 590 //Close(); 591 555 592 FinishRecording(); 556 593 557 594 delete[] buffer; 558 595 recording = false; 559 596 } 560 597 598 void MpegRecorder::StopRecording(void) 599 { 600 request_recording = false; 601 602 if (drb && drb->IsRunning()) 603 drb->Stop(); 604 605 while (recording) 606 usleep(2000); 607 } 608 561 609 bool MpegRecorder::SetupRecording(void) 562 610 { 563 611 leftovers = 0xFFFFFFFF; … … 664 712 buildbuffersize += leftlen; 665 713 } 666 714 667 void MpegRecorder::StopRecording(void)668 {669 encoding = false;670 }671 672 715 void MpegRecorder::ResetForNewFile(void) 673 716 { 674 717 errored = false; … … 694 737 void MpegRecorder::Pause(bool clear) 695 738 { 696 739 cleartimeonpause = clear; 697 paused = false; 698 request_pause = true; 740 RecorderBase::Pause(clear); 699 741 } 700 742 743 void MpegRecorder::ReaderPaused(int /*fd*/) 744 { 745 pauseWait.wakeAll(); 746 if (tvrec) 747 tvrec->RecorderPaused(); 748 } 749 750 bool MpegRecorder::PauseAndWait(int timeout) 751 { 752 if (request_pause) 753 { 754 paused = true; 755 if (!drb->IsPaused()) 756 drb->SetRequestPause(true); 757 758 unpauseWait.wait(timeout); 759 } 760 else if (drb->IsPaused()) 761 { 762 drb->SetRequestPause(false); 763 drb->WaitForUnpause(timeout); 764 paused = drb->IsPaused(); 765 } 766 else 767 { 768 paused = false; 769 } 770 return paused; 771 } 772 701 773 long long MpegRecorder::GetKeyframePosition(long long desired) 702 774 { 703 775 QMutexLocker locker(&positionMapLock);