Ticket #5866: mpegrecorder-hdpvr.patch
File mpegrecorder-hdpvr.patch, 13.5 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/mpegrecorder.h
80 80 uint GetFilteredAudioLayer(void) const; 81 81 uint GetFilteredAudioBitRate(uint audio_layer) const; 82 82 83 void RestartEncoding(void); 83 84 bool StartEncoding(int fd); 84 85 bool StopEncoding(int fd); 85 86 … … 91 92 92 93 bool deviceIsMpegFile; 93 94 int bufferSize; 95 useconds_t ioctl_recovery; 94 96 95 97 // Driver info 96 98 QString card; … … 104 106 // State 105 107 bool recording; 106 108 bool encoding; 107 bool needs_resolution;108 109 mutable QMutex start_stop_encoding_lock; 109 110 QMutex recording_wait_lock; 110 111 QWaitCondition recording_wait; … … 113 114 bool cleartimeonpause; 114 115 115 116 // Encoding info 116 int width, height;117 uint width, height; 117 118 int bitrate, maxbitrate, streamtype, aspectratio; 118 119 int audtype, audsamplerate, audbitratel1, audbitratel2, audbitratel3; 119 120 int audvolume; -
libs/libmythtv/mpegrecorder.cpp
86 86 requires_special_pause(false), 87 87 // State 88 88 recording(false), encoding(false), 89 needs_resolution(false),start_stop_encoding_lock(QMutex::Recursive),89 start_stop_encoding_lock(QMutex::Recursive), 90 90 recording_wait_lock(), recording_wait(), 91 91 // Pausing state 92 92 cleartimeonpause(false), … … 389 389 has_buggy_vbi = true; 390 390 requires_special_pause = 391 391 (version >= IVTV_KERNEL_VERSION(0, 10, 0)); 392 ioctl_recovery = 0; 392 393 } 393 394 else if (driver == "pvrusb2") 394 395 { … … 397 398 has_v4l2_vbi = true; 398 399 has_buggy_vbi = true; 399 400 requires_special_pause = true; 401 ioctl_recovery = 0; 400 402 } 401 403 else if (driver == "hdpvr") 402 404 { … … 407 409 bzero(_stream_id, sizeof(_stream_id)); 408 410 bzero(_pid_status, sizeof(_pid_status)); 409 411 memset(_continuity_counter, 0xff, sizeof(_continuity_counter)); 412 ioctl_recovery = 1000; 410 413 } 411 414 else 412 415 { … … 414 417 bufferSize = 4096; 415 418 usingv4l2 = has_v4l2_vbi = true; 416 419 has_buggy_vbi = requires_special_pause = false; 420 ioctl_recovery = 0; 417 421 } 418 422 } 419 423 … … 497 501 VERBOSE(VB_IMPORTANT, LOC_ERR + "Error getting format" + ENO); 498 502 return false; 499 503 } 504 usleep(ioctl_recovery); 500 505 501 506 vfmt.fmt.pix.width = width; 502 507 vfmt.fmt.pix.height = height; … … 506 511 VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO); 507 512 return false; 508 513 } 514 usleep(ioctl_recovery); 509 515 510 516 return true; 511 517 } … … 520 526 VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO); 521 527 return false; 522 528 } 529 usleep(ioctl_recovery); 523 530 524 531 switch (language) 525 532 { … … 554 561 VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO); 555 562 success = false; 556 563 } 564 usleep(ioctl_recovery); 557 565 558 566 return success; 559 567 } … … 571 579 qctrl.maximum = 65535; 572 580 qctrl.minimum = 0; 573 581 } 582 usleep(ioctl_recovery); 574 583 575 584 // calculate volume in card units. 576 585 int range = qctrl.maximum - qctrl.minimum; … … 589 598 "If you are using an AverMedia M179 card this is normal."); 590 599 return false; 591 600 } 601 usleep(ioctl_recovery); 592 602 593 603 return true; 594 604 } … … 736 746 ctrl_list.push_back(tmp_ctrl); 737 747 } 738 748 739 static void set_ctrls(int fd, vector<struct v4l2_ext_control> &ext_ctrls) 749 static void set_ctrls(int fd, vector<struct v4l2_ext_control> &ext_ctrls, 750 useconds_t ioctl_recovery) 740 751 { 741 752 static QMutex control_description_lock; 742 753 static QMap<uint32_t,QString> control_description; … … 782 793 .arg(control_description[ext_ctrls[i].id]).arg(value) + 783 794 ENO); 784 795 } 796 usleep(ioctl_recovery); 785 797 } 786 798 } 787 799 … … 814 826 { 815 827 maxbitrate = high_mpeg4peakbitrate; 816 828 bitrate = high_mpeg4avgbitrate; 829 830 // query supported audio codecs and prefer AC3 831 struct v4l2_queryctrl qctrl; 832 qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; 833 if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) 834 { 835 VERBOSE(VB_IMPORTANT, LOC_WARN + 836 "Unable to get supported audio codecs." + ENO); 837 } 838 else 839 { 840 usleep(ioctl_recovery); 841 if (qctrl.minimum != qctrl.maximum) 842 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, 843 qctrl.maximum); 844 } 817 845 } 818 846 maxbitrate = std::max(maxbitrate, bitrate); 819 847 … … 831 859 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 832 860 maxbitrate * 1000); 833 861 834 set_ctrls(chanfd, ext_ctrls );862 set_ctrls(chanfd, ext_ctrls, ioctl_recovery); 835 863 836 864 bool ok; 837 865 int audioinput = audiodevice.toUInt(&ok); … … 847 875 } 848 876 else 849 877 { 878 usleep(ioctl_recovery); 850 879 ain.index = audioinput; 851 880 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0) 852 881 { 853 882 VERBOSE(VB_IMPORTANT, LOC_WARN + 854 883 "Unable to set audio input."); 855 884 } 885 usleep(ioctl_recovery); 856 886 } 857 887 } 858 888 … … 1036 1066 if (deviceIsMpegFile) 1037 1067 elapsedTimer.start(); 1038 1068 else if (_device_read_buffer) 1039 _device_read_buffer->Start(); 1069 { 1070 VERBOSE(VB_RECORD, LOC + "Initial startup of recorder"); 1040 1071 1041 needs_resolution = (driver == "hdpvr"); 1072 if (StartEncoding(readfd)) 1073 _device_read_buffer->Start(); 1074 else 1075 { 1076 VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to start recording"); 1077 recording = false; 1078 QMutexLocker locker(&recording_wait_lock); 1079 recording_wait.wakeAll(); 1080 _error = true; 1081 } 1082 } 1042 1083 1043 1084 QByteArray vdevice = videodevice.toAscii(); 1044 1085 while (encoding && !_error) 1045 1086 { 1046 1087 if (PauseAndWait(100)) 1047 1088 continue; 1048 1049 HandleResolutionChanges();1050 1089 1051 1090 if (deviceIsMpegFile) 1052 1091 { … … 1090 1129 { 1091 1130 VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected"); 1092 1131 1093 _device_read_buffer->Stop(); 1094 1095 QMutexLocker locker(&start_stop_encoding_lock); 1096 1097 StopEncoding(readfd); 1098 1099 // Make sure the next things in the file are a PAT & PMT 1100 if (_stream_data->PATSingleProgram() && 1101 _stream_data->PMTSingleProgram()) 1102 { 1103 bool tmp = _wait_for_keyframe_option; 1104 _wait_for_keyframe_option = false; 1105 HandleSingleProgramPAT(_stream_data->PATSingleProgram()); 1106 HandleSingleProgramPMT(_stream_data->PMTSingleProgram()); 1107 _wait_for_keyframe_option = tmp; 1108 } 1109 1110 if (StartEncoding(readfd)) 1111 { 1112 _device_read_buffer->Start(); 1113 } 1114 else 1115 { 1116 if (0 != close(readfd)) 1117 VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); 1118 1119 // Force card to be reopened on next iteration.. 1120 readfd = -1; 1121 } 1132 RestartEncoding(); 1122 1133 } 1123 1134 else if (_device_read_buffer->IsEOF()) 1124 1135 { … … 1216 1227 } 1217 1228 } 1218 1229 1230 VERBOSE(VB_RECORD, LOC + "StartRecording finishing up"); 1231 1219 1232 if (_device_read_buffer) 1220 1233 { 1221 1234 if (_device_read_buffer->IsRunning()) … … 1224 1237 delete _device_read_buffer; 1225 1238 _device_read_buffer = NULL; 1226 1239 } 1240 1227 1241 StopEncoding(readfd); 1228 1242 1229 1243 FinishRecording(); … … 1373 1387 1374 1388 if (!paused) 1375 1389 { 1390 VERBOSE(VB_RECORD, LOC + "PauseAndWait pause"); 1391 1392 // Some drivers require streaming to be disabled before 1393 // an input switch and other channel format setting. 1394 if (requires_special_pause) 1395 StopEncoding(readfd); 1396 1376 1397 if (_device_read_buffer) 1377 1398 { 1378 1399 QMutex drb_lock; 1379 1400 drb_lock.lock(); 1380 1381 1401 _device_read_buffer->SetRequestPause(true); 1382 1383 1402 pauseWait.wait(&drb_lock, timeout); 1384 1403 } 1385 1404 else 1386 {1387 paused = true;1388 1405 pauseWait.wakeAll(); 1389 }1390 1406 1391 // Some drivers require streaming to be disabled before 1392 // an input switch and other channel format setting. 1393 if (requires_special_pause) 1394 StopEncoding(readfd); 1395 1407 paused = true; 1396 1408 if (tvrec) 1397 1409 tvrec->RecorderPaused(); 1398 1410 } 1399 1411 1400 1412 unpauseWait.wait(&waitlock, timeout); 1401 1413 } 1402 if (!request_pause) 1414 1415 if (!request_pause && paused) 1403 1416 { 1404 if (paused) 1405 { 1406 // Some drivers require streaming to be disabled before 1407 // an input switch and other channel format setting. 1408 if (requires_special_pause) 1409 StartEncoding(readfd); 1417 VERBOSE(VB_RECORD, LOC + "PauseAndWait unpause"); 1418 // Some drivers require streaming to be disabled before 1419 // an input switch and other channel format setting. 1420 if (requires_special_pause) 1421 StartEncoding(readfd); 1422 1423 if (_device_read_buffer) 1424 _device_read_buffer->SetRequestPause(false); 1425 1426 if (_stream_data) 1427 _stream_data->Reset(_stream_data->DesiredProgram()); 1410 1428 1411 if (_device_read_buffer)1412 _device_read_buffer->SetRequestPause(false);1413 1414 if (_stream_data)1415 _stream_data->Reset(_stream_data->DesiredProgram());1416 }1417 1429 paused = false; 1418 1430 } 1431 1419 1432 return paused; 1420 1433 } 1421 1434 1435 void MpegRecorder::RestartEncoding(void) 1436 { 1437 VERBOSE(VB_RECORD, LOC + "RestartEncoding"); 1438 1439 _device_read_buffer->Stop(); 1440 1441 QMutexLocker locker(&start_stop_encoding_lock); 1442 1443 StopEncoding(readfd); 1444 1445 // Make sure the next things in the file are a PAT & PMT 1446 if (_stream_data->PATSingleProgram() && 1447 _stream_data->PMTSingleProgram()) 1448 { 1449 _wait_for_keyframe_option = false; 1450 HandleSingleProgramPAT(_stream_data->PATSingleProgram()); 1451 HandleSingleProgramPMT(_stream_data->PMTSingleProgram()); 1452 } 1453 1454 _wait_for_keyframe_option = true; 1455 if (StartEncoding(readfd)) 1456 { 1457 _device_read_buffer->Start(); 1458 } 1459 else 1460 { 1461 if (0 != close(readfd)) 1462 VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); 1463 1464 readfd = -1; 1465 } 1466 } 1467 1422 1468 bool MpegRecorder::StartEncoding(int fd) 1423 1469 { 1424 1470 QMutexLocker locker(&start_stop_encoding_lock); … … 1427 1473 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 1428 1474 command.cmd = V4L2_ENC_CMD_START; 1429 1475 1476 if (driver == "hdpvr") 1477 HandleResolutionChanges(); 1478 1430 1479 VERBOSE(VB_RECORD, LOC + "StartEncoding"); 1431 needs_resolution = (driver == "hdpvr");1432 1480 1433 1481 for (int idx = 0; idx < 10; ++idx) 1434 1482 { 1435 1483 if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) 1436 1484 { 1437 1485 VERBOSE(VB_RECORD, LOC + "Encoding started"); 1486 usleep(ioctl_recovery); 1438 1487 return true; 1439 1488 } 1440 1489 … … 1463 1512 1464 1513 for (int idx = 0; idx < 10; ++idx) 1465 1514 { 1466 1467 1515 if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) 1468 1516 { 1517 usleep(ioctl_recovery); 1469 1518 VERBOSE(VB_RECORD, LOC + "Encoding stopped"); 1470 1519 return true; 1471 1520 } … … 1566 1615 1567 1616 void MpegRecorder::HandleResolutionChanges(void) 1568 1617 { 1569 if (!needs_resolution)1570 return;1571 1572 1618 VERBOSE(VB_RECORD, LOC + "Checking Resolution"); 1573 1619 struct v4l2_format vfmt; 1574 1620 memset(&vfmt, 0, sizeof(vfmt)); … … 1580 1626 VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") 1581 1627 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); 1582 1628 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height; 1583 needs_resolution = false;1584 1629 } 1585 1630 1586 1631 if (!pix) … … 1609 1654 if (old_max == old_avg) 1610 1655 { 1611 1656 VERBOSE(VB_RECORD, LOC + 1612 QString("Old bitrate %1 CBR").arg(old_avg)); 1657 QString("Old bitrate %1 CBR for %2x%3") 1658 .arg(old_avg).arg(width).arg(height)); 1613 1659 } 1614 1660 else 1615 1661 { 1616 1662 VERBOSE(VB_RECORD, LOC + 1617 QString("Old bitrate %1/%2 VBR ")1618 .arg(old_avg).arg(old_max) );1663 QString("Old bitrate %1/%2 VBR for %3x%4") 1664 .arg(old_avg).arg(old_max).arg(width).arg(height)); 1619 1665 } 1620 1666 1621 1667 if (maxbitrate == bitrate) … … 1641 1687 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 1642 1688 maxbitrate * 1000); 1643 1689 1644 set_ctrls(readfd, ext_ctrls );1690 set_ctrls(readfd, ext_ctrls, ioctl_recovery); 1645 1691 } 1646 1647 // Restart streaming. Shouldn't be needed? seems to be with current driver.1648 QMutexLocker locker(&start_stop_encoding_lock);1649 StopEncoding(readfd);1650 StartEncoding(readfd);1651 1652 needs_resolution = false;1653 1692 }