Ticket #5866: hdpvr-fix-channel-changes.patch
File hdpvr-fix-channel-changes.patch, 13.2 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/mpegrecorder.
old new 86 86 87 87 void ResetForNewFile(void); 88 88 89 bool WaitFor_HDPVR(void); 89 90 void HandleResolutionChanges(void); 90 91 91 92 inline bool CheckCC(uint pid, uint cc); 92 93 93 94 bool deviceIsMpegFile; 94 95 int bufferSize; 95 useconds_t ioctl_recovery;96 96 97 97 // Driver info 98 98 QString card; -
libs/libmythtv/mpegrecorder.
old new 19 19 #include <sys/stat.h> 20 20 #include <sys/ioctl.h> 21 21 #include <sys/time.h> 22 #include <sys/poll.h> 22 23 23 24 // avlib headers 24 25 extern "C" { … … 389 390 has_buggy_vbi = true; 390 391 requires_special_pause = 391 392 (version >= IVTV_KERNEL_VERSION(0, 10, 0)); 392 ioctl_recovery = 0;393 393 } 394 394 else if (driver == "pvrusb2") 395 395 { … … 398 398 has_v4l2_vbi = true; 399 399 has_buggy_vbi = true; 400 400 requires_special_pause = true; 401 ioctl_recovery = 0;402 401 } 403 402 else if (driver == "hdpvr") 404 403 { … … 409 408 bzero(_stream_id, sizeof(_stream_id)); 410 409 bzero(_pid_status, sizeof(_pid_status)); 411 410 memset(_continuity_counter, 0xff, sizeof(_continuity_counter)); 412 ioctl_recovery = 1000;413 411 } 414 412 else 415 413 { … … 417 415 bufferSize = 4096; 418 416 usingv4l2 = has_v4l2_vbi = true; 419 417 has_buggy_vbi = requires_special_pause = false; 420 ioctl_recovery = 0;421 418 } 422 419 } 423 420 … … 491 488 492 489 bool MpegRecorder::SetFormat(int chanfd) 493 490 { 491 uint idx; 494 492 struct v4l2_format vfmt; 495 493 bzero(&vfmt, sizeof(vfmt)); 496 494 497 495 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 498 496 499 if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0) 497 for (idx = 0; idx < 20; ++idx) 498 { 499 if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) == 0) 500 break; 501 usleep(100 * 1000); 502 } 503 504 if (idx == 10) 500 505 { 501 506 VERBOSE(VB_IMPORTANT, LOC_ERR + "Error getting format" + ENO); 502 507 return false; 503 508 } 504 usleep(ioctl_recovery);505 509 506 510 vfmt.fmt.pix.width = width; 507 511 vfmt.fmt.pix.height = height; 508 512 509 if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0) 513 for (idx = 0; idx < 20; ++idx) 514 { 515 if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) == 0) 516 break; 517 usleep(100 * 1000); 518 } 519 520 if (idx == 20) 510 521 { 511 522 VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO); 512 523 return false; 513 524 } 514 usleep(ioctl_recovery);515 525 516 526 return true; 517 527 } … … 519 529 /// Set audio language mode 520 530 bool MpegRecorder::SetLanguageMode(int chanfd) 521 531 { 532 uint idx; 522 533 struct v4l2_tuner vt; 523 534 bzero(&vt, sizeof(struct v4l2_tuner)); 524 if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0) 535 536 for (idx = 0; idx < 20; ++idx) 537 { 538 if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) == 0) 539 break; 540 usleep(100 * 1000); 541 } 542 543 if (idx == 20) 525 544 { 526 545 VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO); 527 546 return false; 528 547 } 529 usleep(ioctl_recovery);530 548 531 549 switch (language) 532 550 { … … 556 574 success = false; 557 575 } 558 576 559 if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0) 577 for (idx = 0; idx < 20; ++idx) 578 { 579 if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) == 0) 580 break; 581 usleep(100 * 1000); 582 } 583 584 if (idx == 20) 560 585 { 561 586 VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO); 562 587 success = false; 563 588 } 564 usleep(ioctl_recovery);565 589 566 590 return success; 567 591 } … … 569 593 bool MpegRecorder::SetRecordingVolume(int chanfd) 570 594 { 571 595 // Get volume min/max values 596 uint idx; 572 597 struct v4l2_queryctrl qctrl; 573 598 qctrl.id = V4L2_CID_AUDIO_VOLUME; 574 if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) 599 600 for (idx = 0; idx < 20; ++idx) 601 { 602 if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0) 603 break; 604 usleep(100 * 1000); 605 } 606 607 if (idx == 20) 575 608 { 576 609 VERBOSE(VB_IMPORTANT, LOC_WARN + 577 610 "Unable to get recording volume parameters(max/min)" + ENO + … … 579 612 qctrl.maximum = 65535; 580 613 qctrl.minimum = 0; 581 614 } 582 usleep(ioctl_recovery);583 615 584 616 // calculate volume in card units. 585 617 int range = qctrl.maximum - qctrl.minimum; … … 591 623 ctrl.id = V4L2_CID_AUDIO_VOLUME; 592 624 ctrl.value = ctrl_volume; 593 625 594 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0) 626 for (idx = 0; idx < 20; ++idx) 627 { 628 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) == 0) 629 break; 630 usleep(100 * 1000); 631 } 632 633 if (idx == 20) 595 634 { 596 635 VERBOSE(VB_IMPORTANT, LOC_WARN + 597 636 "Unable to set recording volume" + ENO + "\n\t\t\t" + 598 637 "If you are using an AverMedia M179 card this is normal."); 599 638 return false; 600 639 } 601 usleep(ioctl_recovery);602 640 603 641 return true; 604 642 } … … 746 784 ctrl_list.push_back(tmp_ctrl); 747 785 } 748 786 749 static void set_ctrls(int fd, vector<struct v4l2_ext_control> &ext_ctrls, 750 useconds_t ioctl_recovery) 787 static void set_ctrls(int fd, vector<struct v4l2_ext_control> &ext_ctrls) 751 788 { 752 789 static QMutex control_description_lock; 753 790 static QMap<uint32_t,QString> control_description; … … 776 813 777 814 for (uint i = 0; i < ext_ctrls.size(); i++) 778 815 { 816 uint idx; 779 817 struct v4l2_ext_controls ctrls; 780 818 bzero(&ctrls, sizeof(struct v4l2_ext_controls)); 781 819 … … 785 823 ctrls.count = 1; 786 824 ctrls.controls = &ext_ctrls[i]; 787 825 788 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) 826 for (idx = 0; idx < 20; ++idx) 827 { 828 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) == 0) 829 break; 830 usleep(100 * 1000); 831 } 832 833 if (idx == 20) 789 834 { 790 835 QMutexLocker locker(&control_description_lock); 791 836 VERBOSE(VB_IMPORTANT, QString("mpegrecorder.cpp:set_ctrls(): ") + … … 793 838 .arg(control_description[ext_ctrls[i].id]).arg(value) + 794 839 ENO); 795 840 } 796 usleep(ioctl_recovery);797 841 } 798 842 } 799 843 … … 828 872 bitrate = high_mpeg4avgbitrate; 829 873 830 874 // query supported audio codecs and prefer AC3 875 uint idx; 831 876 struct v4l2_queryctrl qctrl; 832 877 qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; 833 if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) 878 879 for (idx = 0; idx < 20; ++idx) 880 { 881 if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0) 882 break; 883 usleep(100 * 1000); 884 } 885 886 if (idx == 20) 834 887 { 835 888 VERBOSE(VB_IMPORTANT, LOC_WARN + 836 889 "Unable to get supported audio codecs." + ENO); 837 890 } 838 891 else 839 892 { 840 usleep(ioctl_recovery);841 893 if (qctrl.minimum != qctrl.maximum) 842 894 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, 843 895 qctrl.maximum); … … 859 911 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 860 912 maxbitrate * 1000); 861 913 862 set_ctrls(chanfd, ext_ctrls , ioctl_recovery);914 set_ctrls(chanfd, ext_ctrls); 863 915 864 916 bool ok; 865 917 int audioinput = audiodevice.toUInt(&ok); 866 918 if (ok) 867 919 { 920 uint idx; 868 921 struct v4l2_audio ain; 869 922 bzero(&ain, sizeof(ain)); 870 923 ain.index = audioinput; 871 if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0) 924 925 for (idx = 0; idx < 20; ++idx) 926 { 927 if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) == 0) 928 break; 929 usleep(100 * 1000); 930 } 931 932 if (idx == 20) 872 933 { 873 934 VERBOSE(VB_IMPORTANT, LOC_WARN + 874 935 "Unable to get audio input."); 875 936 } 876 937 else 877 938 { 878 usleep(ioctl_recovery);879 939 ain.index = audioinput; 880 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0) 940 941 for (idx = 0; idx < 20; ++idx) 942 { 943 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) == 0) 944 break; 945 usleep(100 * 1000); 946 } 947 948 if (idx == 20) 881 949 { 882 950 VERBOSE(VB_IMPORTANT, LOC_WARN + 883 951 "Unable to set audio input."); 884 952 } 885 usleep(ioctl_recovery);886 953 } 887 954 } 888 955 … … 1415 1482 if (!request_pause && paused) 1416 1483 { 1417 1484 VERBOSE(VB_RECORD, LOC + "PauseAndWait unpause"); 1485 1486 if (driver == "hdpvr") 1487 { 1488 h264_parser.Reset(); 1489 _wait_for_keyframe_option = true; 1490 _seen_sps = false; 1491 1492 // Sleep any less than 1.5 seconds, and the HD-PVR will 1493 // return the old resolution, when the resolution is changing. 1494 usleep(1500 * 1000); 1495 } 1496 1418 1497 // Some drivers require streaming to be disabled before 1419 1498 // an input switch and other channel format setting. 1420 1499 if (requires_special_pause) … … 1451 1530 HandleSingleProgramPMT(_stream_data->PMTSingleProgram()); 1452 1531 } 1453 1532 1454 _wait_for_keyframe_option = true;1455 1533 if (StartEncoding(readfd)) 1456 1534 { 1457 1535 _device_read_buffer->Start(); … … 1478 1556 1479 1557 VERBOSE(VB_RECORD, LOC + "StartEncoding"); 1480 1558 1481 for (int idx = 0; idx < 10; ++idx)1559 for (int idx = 0; idx < 20; ++idx) 1482 1560 { 1483 1561 if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) 1484 1562 { 1563 if (driver == "hdpvr") 1564 { 1565 h264_parser.Reset(); 1566 _wait_for_keyframe_option = true; 1567 _seen_sps = false; 1568 } 1569 1485 1570 VERBOSE(VB_RECORD, LOC + "Encoding started"); 1486 usleep(ioctl_recovery);1487 1571 return true; 1488 1572 } 1489 1573 … … 1493 1577 return false; 1494 1578 } 1495 1579 1496 usleep( 250 * 1000);1580 usleep(100 * 1000); 1497 1581 } 1498 1582 1499 1583 VERBOSE(VB_IMPORTANT, LOC_ERR + "StartEncoding - giving up" + ENO); … … 1510 1594 1511 1595 VERBOSE(VB_RECORD, LOC + "StopEncoding"); 1512 1596 1513 for (int idx = 0; idx < 10; ++idx)1597 for (int idx = 0; idx < 20; ++idx) 1514 1598 { 1515 1599 if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) 1516 1600 { 1517 usleep(ioctl_recovery);1518 1601 VERBOSE(VB_RECORD, LOC + "Encoding stopped"); 1519 1602 return true; 1520 1603 } … … 1525 1608 return false; 1526 1609 } 1527 1610 1528 usleep( 250 * 1000);1611 usleep(100 * 1000); 1529 1612 } 1530 1613 1531 1614 VERBOSE(VB_IMPORTANT, LOC_ERR + "StopEncoding - giving up" + ENO); … … 1593 1676 void MpegRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt) 1594 1677 { 1595 1678 if (!pmt) 1596 {1679 { 1597 1680 return; 1598 1681 } 1599 1682 … … 1613 1696 DTVRecorder::BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i]))); 1614 1697 } 1615 1698 1699 bool MpegRecorder::WaitFor_HDPVR(void) 1700 { 1701 // After a resolution change, it can take the HD-PVR a few 1702 // seconds before it is usable again. 1703 1704 // Tell it to start encoding, then wait for it to actually feed us 1705 // some data. 1706 QMutexLocker locker(&start_stop_encoding_lock); 1707 1708 struct v4l2_encoder_cmd command; 1709 struct pollfd polls; 1710 int idx; 1711 1712 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 1713 command.cmd = V4L2_ENC_CMD_START; 1714 1715 for (idx = 0; idx < 20; ++idx) 1716 { 1717 if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) 1718 break; 1719 usleep(100 * 1000); 1720 } 1721 1722 if (idx == 20) 1723 return false; 1724 1725 polls.fd = readfd; 1726 polls.events = POLLIN; 1727 polls.revents = 0; 1728 1729 for (idx = 0; idx < 10; ++idx) 1730 { 1731 if (poll(&polls, 1, 250) > 0) 1732 break; 1733 } 1734 1735 if (idx == 10) 1736 return false; 1737 1738 // HD-PVR should now be "ready" 1739 command.cmd = V4L2_ENC_CMD_STOP; 1740 1741 for (idx = 0; idx < 20; ++idx) 1742 { 1743 if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) 1744 return true; 1745 usleep(100 * 1000); 1746 } 1747 1748 return false; 1749 } 1750 1616 1751 void MpegRecorder::HandleResolutionChanges(void) 1617 1752 { 1618 1753 VERBOSE(VB_RECORD, LOC + "Checking Resolution"); … … 1620 1755 memset(&vfmt, 0, sizeof(vfmt)); 1621 1756 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1622 1757 1758 if (driver == "hdpvr") 1759 WaitFor_HDPVR(); 1760 1761 uint idx; 1623 1762 uint pix = 0; 1763 1764 for (idx = 0; idx < 20; ++idx) 1765 { 1624 1766 if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 1625 1767 { 1626 1768 VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") 1627 1769 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); 1628 1770 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height; 1771 break; 1772 } 1773 // Typically takes 0.9 seconds after a resolution change 1774 usleep(100 * 1000); 1629 1775 } 1630 1776 1631 1777 if (!pix) 1778 { 1779 VERBOSE(VB_RECORD, LOC + "Giving up detecting resolution"); 1632 1780 return; // nothing to do, we don't have a resolution yet 1781 } 1633 1782 1634 1783 int old_max = maxbitrate, old_avg = bitrate; 1635 1784 if (pix <= 768*568) … … 1687 1836 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 1688 1837 maxbitrate * 1000); 1689 1838 1690 set_ctrls(readfd, ext_ctrls, ioctl_recovery); 1839 set_ctrls(readfd, ext_ctrls); 1840 1691 1841 } 1692 1842 }