diff --git a/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp b/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
index debd75b..17481c2 100644
|
a
|
b
|
NuppelVideoRecorder::NuppelVideoRecorder(TVRec *rec, ChannelBase *channel) :
|
| 87 | 87 | { |
| 88 | 88 | channelObj = channel; |
| 89 | 89 | |
| 90 | | encoding = false; |
| 91 | 90 | fd = -1; |
| 92 | 91 | channelfd = -1; |
| 93 | 92 | lf = tf = 0; |
| … |
… |
NuppelVideoRecorder::NuppelVideoRecorder(TVRec *rec, ChannelBase *channel) :
|
| 130 | 129 | text_buffer_count = 0; |
| 131 | 130 | text_buffer_size = 0; |
| 132 | 131 | |
| 133 | | childrenLive = false; |
| 134 | | errored = false; |
| 135 | | |
| 136 | | recording = false; |
| 137 | | |
| 138 | 132 | writepaused = false; |
| 139 | 133 | audiopaused = false; |
| 140 | 134 | mainpaused = false; |
| … |
… |
bool NuppelVideoRecorder::IsRecording(void)
|
| 491 | 485 | return recording; |
| 492 | 486 | } |
| 493 | 487 | |
| 494 | | bool NuppelVideoRecorder::IsErrored(void) |
| 495 | | { |
| 496 | | return errored; |
| 497 | | } |
| 498 | | |
| 499 | 488 | long long NuppelVideoRecorder::GetFramesWritten(void) |
| 500 | 489 | { |
| 501 | 490 | return framesWritten; |
| … |
… |
void NuppelVideoRecorder::Initialize(void)
|
| 748 | 737 | livetv = false; |
| 749 | 738 | if (!ringBuffer->IsOpen()) |
| 750 | 739 | { |
| 751 | | LOG(VB_GENERAL, LOG_ERR, LOC + "Could not open RingBuffer"); |
| 752 | | errored = true; |
| | 740 | _error = "Could not open RingBuffer"; |
| | 741 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 753 | 742 | return; |
| 754 | 743 | } |
| 755 | 744 | } |
| … |
… |
void NuppelVideoRecorder::ResizeVideoBuffers(void)
|
| 992 | 981 | } |
| 993 | 982 | } |
| 994 | 983 | |
| 995 | | void NuppelVideoRecorder::StopRecording(void) |
| 996 | | { |
| 997 | | encoding = false; |
| 998 | | V4LRecorder::StopRecording(); |
| 999 | | } |
| 1000 | | |
| 1001 | 984 | void NuppelVideoRecorder::StreamAllocate(void) |
| 1002 | 985 | { |
| 1003 | 986 | strm = new signed char[width * height * 2 + 10]; |
| … |
… |
bool NuppelVideoRecorder::Open(void)
|
| 1017 | 1000 | fd = open(vdevice.constData(), O_RDWR); |
| 1018 | 1001 | if (retries++ > 5) |
| 1019 | 1002 | { |
| 1020 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 1021 | | QString("Can't open video device: %1").arg(videodevice)); |
| 1022 | | LOG(VB_GENERAL, LOG_ERR, LOC + "open video: " + ENO); |
| | 1003 | _error = QString("Can't open video device: %1").arg(videodevice); |
| | 1004 | LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO); |
| 1023 | 1005 | KillChildren(); |
| 1024 | | errored = true; |
| 1025 | 1006 | return false; |
| 1026 | 1007 | } |
| 1027 | 1008 | } |
| … |
… |
void NuppelVideoRecorder::run(void)
|
| 1072 | 1053 | if (lzo_init() != LZO_E_OK) |
| 1073 | 1054 | { |
| 1074 | 1055 | LOG(VB_GENERAL, LOG_ERR, LOC + "lzo_init() failed, exiting"); |
| 1075 | | errored = true; |
| | 1056 | _error = "lzo_init() failed, exiting"; |
| | 1057 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1076 | 1058 | return; |
| 1077 | 1059 | } |
| 1078 | 1060 | |
| 1079 | 1061 | if (!Open()) |
| 1080 | 1062 | { |
| 1081 | | errored = true; |
| | 1063 | _error = "Failed to open device"; |
| | 1064 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1082 | 1065 | return; |
| 1083 | 1066 | } |
| 1084 | 1067 | |
| … |
… |
void NuppelVideoRecorder::run(void)
|
| 1086 | 1069 | |
| 1087 | 1070 | if (usingv4l2 && !SetFormatV4L2()) |
| 1088 | 1071 | { |
| 1089 | | errored = true; |
| | 1072 | _error = "Failed to set V4L2 format"; |
| | 1073 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1090 | 1074 | return; |
| 1091 | 1075 | } |
| 1092 | 1076 | |
| … |
… |
void NuppelVideoRecorder::run(void)
|
| 1112 | 1096 | |
| 1113 | 1097 | if (CreateNuppelFile() != 0) |
| 1114 | 1098 | { |
| 1115 | | LOG(VB_GENERAL, LOG_ERR, LOC + QString("Cannot open '%1' for writing") |
| 1116 | | .arg(ringBuffer->GetFilename())); |
| 1117 | | errored = true; |
| | 1099 | _error = QString("Cannot open '%1' for writing") |
| | 1100 | .arg(ringBuffer->GetFilename()); |
| | 1101 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1118 | 1102 | return; |
| 1119 | 1103 | } |
| 1120 | 1104 | |
| 1121 | | if (childrenLive) |
| | 1105 | if (IsHelperRequested()) |
| 1122 | 1106 | { |
| 1123 | 1107 | LOG(VB_GENERAL, LOG_ERR, LOC + "Children are already alive"); |
| 1124 | | errored = true; |
| | 1108 | _error = "Children are already alive"; |
| 1125 | 1109 | return; |
| 1126 | 1110 | } |
| 1127 | 1111 | |
| 1128 | | if (!SpawnChildren()) |
| 1129 | 1112 | { |
| 1130 | | LOG(VB_GENERAL, LOG_ERR, LOC + "Couldn't spawn children"); |
| 1131 | | errored = true; |
| 1132 | | return; |
| | 1113 | QMutexLocker locker(&pauseLock); |
| | 1114 | request_recording = true; |
| | 1115 | request_helper = true; |
| | 1116 | recording = true; |
| | 1117 | recordingWait.wakeAll(); |
| 1133 | 1118 | } |
| 1134 | 1119 | |
| | 1120 | write_thread = new NVRWriteThread(this); |
| | 1121 | write_thread->start(); |
| | 1122 | |
| | 1123 | audio_thread = new NVRAudioThread(this); |
| | 1124 | audio_thread->start(); |
| | 1125 | |
| | 1126 | if ((vbimode != VBIMode::None) && (OpenVBIDevice() >= 0)) |
| | 1127 | vbi_thread = new VBIThread(this); |
| | 1128 | |
| 1135 | 1129 | // save the start time |
| 1136 | 1130 | gettimeofday(&stm, &tzone); |
| 1137 | 1131 | |
| … |
… |
void NuppelVideoRecorder::run(void)
|
| 1143 | 1137 | inpixfmt = FMT_NONE; |
| 1144 | 1138 | InitFilters(); |
| 1145 | 1139 | DoV4L2(); |
| 1146 | | return; |
| 1147 | 1140 | } |
| 1148 | 1141 | else |
| 1149 | 1142 | DoV4L1(); |
| | 1143 | |
| | 1144 | { |
| | 1145 | QMutexLocker locker(&pauseLock); |
| | 1146 | request_recording = false; |
| | 1147 | request_helper = false; |
| | 1148 | recording = false; |
| | 1149 | recordingWait.wakeAll(); |
| | 1150 | } |
| 1150 | 1151 | } |
| 1151 | 1152 | |
| 1152 | 1153 | #ifdef USING_V4L1 |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1168 | 1169 | |
| 1169 | 1170 | if (ioctl(fd, VIDIOCGCAP, &vc) < 0) |
| 1170 | 1171 | { |
| 1171 | | LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCGCAP: " + ENO); |
| | 1172 | QString tmp = "VIDIOCGCAP: " + ENO; |
| 1172 | 1173 | KillChildren(); |
| 1173 | | errored = true; |
| | 1174 | LOG(VB_GENERAL, LOG_ERR, tmp); |
| | 1175 | _error = tmp; |
| 1174 | 1176 | return; |
| 1175 | 1177 | } |
| 1176 | 1178 | |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1210 | 1212 | if ((vc.type & VID_TYPE_MJPEG_ENCODER) && hardware_encode) |
| 1211 | 1213 | { |
| 1212 | 1214 | DoMJPEG(); |
| 1213 | | errored = true; |
| | 1215 | _error = "MJPEG requested but not available."; |
| | 1216 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1214 | 1217 | return; |
| 1215 | 1218 | } |
| 1216 | 1219 | |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1219 | 1222 | |
| 1220 | 1223 | if (ioctl(fd, VIDIOCGMBUF, &vm) < 0) |
| 1221 | 1224 | { |
| 1222 | | LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCGMBUF: " +ENO); |
| | 1225 | QString tmp = "VIDIOCGMBUF: " + ENO; |
| 1223 | 1226 | KillChildren(); |
| 1224 | | errored = true; |
| | 1227 | LOG(VB_GENERAL, LOG_ERR, LOC + tmp); |
| | 1228 | _error = tmp; |
| 1225 | 1229 | return; |
| 1226 | 1230 | } |
| 1227 | 1231 | |
| 1228 | 1232 | if (vm.frames < 2) |
| 1229 | 1233 | { |
| 1230 | | LOG(VB_GENERAL, LOG_ERR, LOC + "need a minimum of 2 capture buffers"); |
| | 1234 | QString tmp = "need a minimum of 2 capture buffers"; |
| 1231 | 1235 | KillChildren(); |
| 1232 | | errored = true; |
| | 1236 | LOG(VB_GENERAL, LOG_ERR, LOC + tmp); |
| | 1237 | _error = tmp; |
| 1233 | 1238 | return; |
| 1234 | 1239 | } |
| 1235 | 1240 | |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1241 | 1246 | fd, 0); |
| 1242 | 1247 | if (buf <= 0) |
| 1243 | 1248 | { |
| 1244 | | LOG(VB_GENERAL, LOG_ERR, LOC + "mmap: " + ENO); |
| | 1249 | QString tmp = "mmap: " + ENO; |
| 1245 | 1250 | KillChildren(); |
| 1246 | | errored = true; |
| | 1251 | LOG(VB_GENERAL, LOG_ERR, LOC + tmp); |
| | 1252 | _error = tmp; |
| 1247 | 1253 | return; |
| 1248 | 1254 | } |
| 1249 | 1255 | |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1261 | 1267 | if (ioctl(fd, VIDIOCMCAPTURE, &mm)<0) |
| 1262 | 1268 | LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCMCAPTUREi1: " + ENO); |
| 1263 | 1269 | |
| 1264 | | encoding = true; |
| 1265 | | recording = true; |
| 1266 | | |
| 1267 | 1270 | int syncerrors = 0; |
| 1268 | 1271 | |
| 1269 | | while (encoding) |
| | 1272 | while (IsRecordingRequested() && !IsErrored()) |
| 1270 | 1273 | { |
| 1271 | 1274 | { |
| 1272 | 1275 | QMutexLocker locker(&pauseLock); |
| … |
… |
void NuppelVideoRecorder::DoV4L1(void)
|
| 1338 | 1341 | |
| 1339 | 1342 | FinishRecording(); |
| 1340 | 1343 | |
| 1341 | | recording = false; |
| 1342 | 1344 | close(fd); |
| 1343 | 1345 | } |
| 1344 | 1346 | #else // if !USING_V4L1 |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1487 | 1489 | comp.flags |= GO7007_COMP_CLOSED_GOP; |
| 1488 | 1490 | if (ioctl(fd, GO7007IOC_S_COMP_PARAMS, &comp) < 0) |
| 1489 | 1491 | { |
| 1490 | | LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set compression params"); |
| 1491 | | errored = true; |
| | 1492 | _error = "Unable to set compression params"; |
| | 1493 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1492 | 1494 | return; |
| 1493 | 1495 | } |
| 1494 | 1496 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1501 | 1503 | |
| 1502 | 1504 | if (ioctl(fd, GO7007IOC_S_MPEG_PARAMS, &mpeg) < 0) |
| 1503 | 1505 | { |
| 1504 | | LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set MPEG params"); |
| 1505 | | errored = true; |
| | 1506 | _error = "Unable to set MPEG params"; |
| | 1507 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1506 | 1508 | return; |
| 1507 | 1509 | } |
| 1508 | 1510 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1515 | 1517 | |
| 1516 | 1518 | if (ioctl(fd, GO7007IOC_S_BITRATE, &usebitrate) < 0) |
| 1517 | 1519 | { |
| 1518 | | LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set bitrate"); |
| 1519 | | errored = true; |
| | 1520 | _error = "Unable to set bitrate"; |
| | 1521 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1520 | 1522 | return; |
| 1521 | 1523 | } |
| 1522 | 1524 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1531 | 1533 | |
| 1532 | 1534 | if (ioctl(fd, VIDIOC_REQBUFS, &vrbuf) < 0) |
| 1533 | 1535 | { |
| 1534 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 1535 | | "Not able to get any capture buffers, exiting"); |
| 1536 | | errored = true; |
| | 1536 | _error = "Not able to get any capture buffers, exiting"; |
| | 1537 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1537 | 1538 | return; |
| 1538 | 1539 | } |
| 1539 | 1540 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1558 | 1559 | { |
| 1559 | 1560 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 1560 | 1561 | QString("unable to query capture buffer %1").arg(i)); |
| 1561 | | errored = true; |
| | 1562 | _error = "Unable to query capture buffer"; |
| 1562 | 1563 | return; |
| 1563 | 1564 | } |
| 1564 | 1565 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1569 | 1570 | if (buffers[i] == MAP_FAILED) |
| 1570 | 1571 | { |
| 1571 | 1572 | LOG(VB_GENERAL, LOG_ERR, LOC + "mmap: " + ENO); |
| 1572 | | LOG(VB_GENERAL, LOG_ERR, LOC + QString("Memory map failed")); |
| 1573 | | errored = true; |
| | 1573 | LOG(VB_GENERAL, LOG_ERR, LOC + "Memory map failed"); |
| | 1574 | _error = "Memory map failed"; |
| 1574 | 1575 | return; |
| 1575 | 1576 | } |
| 1576 | 1577 | bufferlen[i] = vbuf.length; |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1592 | 1593 | int frame = 0; |
| 1593 | 1594 | bool forcekey = false; |
| 1594 | 1595 | |
| 1595 | | encoding = true; |
| 1596 | | recording = true; |
| 1597 | 1596 | resetcapture = false; |
| 1598 | 1597 | |
| 1599 | 1598 | // setup pixel format conversions for YUYV and UYVY |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1610 | 1609 | output_buffer = (uint8_t*)av_malloc(height * width * 3 / 2); |
| 1611 | 1610 | if (!output_buffer) |
| 1612 | 1611 | { |
| 1613 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 1614 | | "Cannot initialize image conversionbuffer"); |
| 1615 | | errored = true; |
| | 1612 | _error = "Cannot initialize image conversion buffer"; |
| | 1613 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1616 | 1614 | return; |
| 1617 | 1615 | } |
| 1618 | 1616 | |
| … |
… |
void NuppelVideoRecorder::DoV4L2(void)
|
| 1621 | 1619 | SWS_FAST_BILINEAR, NULL, NULL, NULL); |
| 1622 | 1620 | if (!convert_ctx) |
| 1623 | 1621 | { |
| 1624 | | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 1625 | | "Cannot initialize image conversion context"); |
| 1626 | | errored = true; |
| | 1622 | _error = "Cannot initialize image conversion context"; |
| | 1623 | LOG(VB_GENERAL, LOG_ERR, LOC + _error); |
| 1627 | 1624 | return; |
| 1628 | 1625 | } |
| 1629 | 1626 | |
| 1630 | 1627 | avpicture_fill(&img_out, output_buffer, PIX_FMT_YUV420P, width, height); |
| 1631 | 1628 | } |
| 1632 | 1629 | |
| 1633 | | while (encoding) { |
| | 1630 | while (IsRecordingRequested() && !IsErrored()) |
| | 1631 | { |
| 1634 | 1632 | again: |
| 1635 | 1633 | { |
| 1636 | 1634 | QMutexLocker locker(&pauseLock); |
| … |
… |
again:
|
| 1765 | 1763 | av_free(output_buffer); |
| 1766 | 1764 | sws_freeContext(convert_ctx); |
| 1767 | 1765 | |
| 1768 | | recording = false; |
| 1769 | 1766 | close(fd); |
| 1770 | 1767 | close(channelfd); |
| 1771 | 1768 | } |
| … |
… |
void NuppelVideoRecorder::DoMJPEG(void)
|
| 1867 | 1864 | LOG(VB_GENERAL, LOG_ERR, LOC + "MJPIOC_QBUF_CAPT: " + ENO); |
| 1868 | 1865 | } |
| 1869 | 1866 | |
| 1870 | | encoding = true; |
| 1871 | | recording = true; |
| 1872 | | |
| 1873 | | while (encoding) |
| | 1867 | while (IsRecordingRequested() && !IsErrored()) |
| 1874 | 1868 | { |
| 1875 | 1869 | { |
| 1876 | 1870 | QMutexLocker locker(&pauseLock); |
| … |
… |
void NuppelVideoRecorder::DoMJPEG(void)
|
| 1897 | 1891 | } |
| 1898 | 1892 | |
| 1899 | 1893 | if (ioctl(fd, MJPIOC_SYNC, &bsync) < 0) |
| 1900 | | encoding = false; |
| | 1894 | { |
| | 1895 | _error = "MJPEG sync error"; |
| | 1896 | LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO); |
| | 1897 | break; |
| | 1898 | } |
| 1901 | 1899 | |
| 1902 | 1900 | BufferIt((unsigned char *)(MJPG_buff + bsync.frame * breq.size), |
| 1903 | 1901 | bsync.length); |
| 1904 | 1902 | |
| 1905 | 1903 | if (ioctl(fd, MJPIOC_QBUF_CAPT, &(bsync.frame)) < 0) |
| 1906 | | encoding = false; |
| | 1904 | { |
| | 1905 | _error = "MJPEG Capture error"; |
| | 1906 | LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO); |
| | 1907 | } |
| 1907 | 1908 | } |
| 1908 | 1909 | |
| 1909 | 1910 | munmap(MJPG_buff, breq.count * breq.size); |
| … |
… |
void NuppelVideoRecorder::DoMJPEG(void)
|
| 1911 | 1912 | |
| 1912 | 1913 | FinishRecording(); |
| 1913 | 1914 | |
| 1914 | | recording = false; |
| 1915 | 1915 | close(fd); |
| 1916 | 1916 | } |
| 1917 | 1917 | #else // if !USING_V4L1 |
| 1918 | 1918 | void NuppelVideoRecorder::DoMJPEG(void) {} |
| 1919 | 1919 | #endif // !USING_V4L1 |
| 1920 | 1920 | |
| 1921 | | bool NuppelVideoRecorder::SpawnChildren(void) |
| 1922 | | { |
| 1923 | | childrenLive = true; |
| 1924 | | |
| 1925 | | write_thread = new NVRWriteThread(this); |
| 1926 | | write_thread->start(); |
| 1927 | | |
| 1928 | | audio_thread = new NVRAudioThread(this); |
| 1929 | | audio_thread->start(); |
| 1930 | | |
| 1931 | | if ((vbimode != VBIMode::None) && (OpenVBIDevice() >= 0)) |
| 1932 | | vbi_thread = new VBIThread(this); |
| 1933 | | |
| 1934 | | return true; |
| 1935 | | } |
| 1936 | | |
| 1937 | 1921 | void NuppelVideoRecorder::KillChildren(void) |
| 1938 | 1922 | { |
| 1939 | | childrenLive = false; |
| 1940 | 1923 | { |
| 1941 | 1924 | QMutexLocker locker(&pauseLock); |
| | 1925 | request_helper = false; |
| 1942 | 1926 | unpauseWait.wakeAll(); |
| 1943 | 1927 | } |
| 1944 | 1928 | |
| … |
… |
void NuppelVideoRecorder::doAudioThread(void)
|
| 2409 | 2393 | int act = 0, lastread = 0; |
| 2410 | 2394 | audio_bytes_per_sample = audio_channels * audio_bits / 8; |
| 2411 | 2395 | |
| 2412 | | while (childrenLive) |
| | 2396 | while (IsHelperRequested() && !IsErrored()) |
| 2413 | 2397 | { |
| 2414 | 2398 | { |
| 2415 | 2399 | QMutexLocker locker(&pauseLock); |
| … |
… |
void NuppelVideoRecorder::doAudioThread(void)
|
| 2433 | 2417 | } |
| 2434 | 2418 | } |
| 2435 | 2419 | |
| | 2420 | if (!IsHelperRequested() || IsErrored()) |
| | 2421 | break; |
| | 2422 | |
| 2436 | 2423 | lastread = audio_device->GetSamples(buffer, audio_buffer_size); |
| 2437 | 2424 | if (audio_buffer_size != lastread) |
| 2438 | 2425 | { |
| … |
… |
void NuppelVideoRecorder::AddTextData(unsigned char *buf, int len,
|
| 2696 | 2683 | |
| 2697 | 2684 | void NuppelVideoRecorder::doWriteThread(void) |
| 2698 | 2685 | { |
| 2699 | | while (childrenLive && !IsErrored()) |
| | 2686 | while (IsHelperRequested() && !IsErrored()) |
| 2700 | 2687 | { |
| 2701 | 2688 | { |
| 2702 | 2689 | QMutexLocker locker(&pauseLock); |
| … |
… |
void NuppelVideoRecorder::doWriteThread(void)
|
| 2720 | 2707 | } |
| 2721 | 2708 | } |
| 2722 | 2709 | |
| | 2710 | if (!IsHelperRequested() || IsErrored()) |
| | 2711 | break; |
| | 2712 | |
| 2723 | 2713 | CheckForRingBufferSwitch(); |
| 2724 | 2714 | |
| 2725 | 2715 | enum |
| … |
… |
void NuppelVideoRecorder::WriteAudio(unsigned char *buf, int fnum, int timecode)
|
| 3182 | 3172 | { |
| 3183 | 3173 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 3184 | 3174 | QString("lame error '%1'").arg(lameret)); |
| 3185 | | errored = true; |
| | 3175 | _error = QString("Audio Encoding Error '%1'") |
| | 3176 | .arg(lameret); |
| 3186 | 3177 | return; |
| 3187 | 3178 | } |
| 3188 | 3179 | compressedsize = lameret; |
| … |
… |
void NuppelVideoRecorder::WriteAudio(unsigned char *buf, int fnum, int timecode)
|
| 3193 | 3184 | { |
| 3194 | 3185 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 3195 | 3186 | QString("lame error '%1'").arg(lameret)); |
| 3196 | | errored = true; |
| | 3187 | _error = QString("Audio Encoding Error '%1'") |
| | 3188 | .arg(lameret); |
| 3197 | 3189 | return; |
| 3198 | 3190 | } |
| 3199 | 3191 | gaplesssize = lameret; |
diff --git a/mythtv/libs/libmythtv/NuppelVideoRecorder.h b/mythtv/libs/libmythtv/NuppelVideoRecorder.h
index 860571d..67b7d67 100644
|
a
|
b
|
class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input
|
| 86 | 86 | |
| 87 | 87 | void Initialize(void); |
| 88 | 88 | void run(void); |
| 89 | | void StopRecording(void); |
| 90 | 89 | |
| 91 | 90 | virtual void Pause(bool clear = true); |
| 92 | 91 | virtual bool IsPaused(bool holding_lock = false) const; |
| 93 | 92 | |
| 94 | 93 | bool IsRecording(void); |
| 95 | | bool IsErrored(void); |
| 96 | 94 | |
| 97 | 95 | long long GetFramesWritten(void); |
| 98 | 96 | |
| … |
… |
class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input
|
| 142 | 140 | |
| 143 | 141 | bool MJPEGInit(void); |
| 144 | 142 | |
| 145 | | bool SpawnChildren(void); |
| 146 | 143 | void KillChildren(void); |
| 147 | 144 | |
| 148 | 145 | void BufferIt(unsigned char *buf, int len = -1, bool forcekey = false); |
| … |
… |
class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input
|
| 161 | 158 | |
| 162 | 159 | void UpdateResolutions(void); |
| 163 | 160 | |
| 164 | | bool encoding; |
| 165 | | |
| 166 | 161 | int fd; // v4l input file handle |
| 167 | 162 | signed char *strm; |
| 168 | 163 | unsigned int lf, tf; |
| … |
… |
class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input
|
| 224 | 219 | struct timeval stm; |
| 225 | 220 | struct timezone tzone; |
| 226 | 221 | |
| 227 | | volatile bool childrenLive; |
| 228 | | |
| 229 | 222 | NVRWriteThread *write_thread; |
| 230 | 223 | NVRAudioThread *audio_thread; |
| 231 | 224 | |
| 232 | 225 | bool recording; |
| 233 | | bool errored; |
| 234 | 226 | |
| 235 | 227 | int keyframedist; |
| 236 | 228 | vector<struct seektable_entry> *seektable; |
diff --git a/mythtv/libs/libmythtv/mpegrecorder.cpp b/mythtv/libs/libmythtv/mpegrecorder.cpp
index 36e33c7..ced08fb 100644
|
a
|
b
|
void MpegRecorder::run(void)
|
| 933 | 933 | { |
| 934 | 934 | QMutexLocker locker(&pauseLock); |
| 935 | 935 | request_recording = true; |
| | 936 | request_helper = true; |
| 936 | 937 | recording = true; |
| 937 | 938 | recordingWait.wakeAll(); |
| 938 | 939 | } |
| … |
… |
void MpegRecorder::run(void)
|
| 1145 | 1146 | |
| 1146 | 1147 | StopEncoding(readfd); |
| 1147 | 1148 | |
| | 1149 | { |
| | 1150 | QMutexLocker locker(&pauseLock); |
| | 1151 | request_helper = false; |
| | 1152 | } |
| | 1153 | |
| | 1154 | if (vbi_thread) |
| | 1155 | { |
| | 1156 | vbi_thread->wait(); |
| | 1157 | delete vbi_thread; |
| | 1158 | vbi_thread = NULL; |
| | 1159 | CloseVBIDevice(); |
| | 1160 | } |
| | 1161 | |
| 1148 | 1162 | FinishRecording(); |
| 1149 | 1163 | |
| 1150 | 1164 | delete[] buffer; |
| … |
… |
void MpegRecorder::run(void)
|
| 1157 | 1171 | } |
| 1158 | 1172 | |
| 1159 | 1173 | QMutexLocker locker(&pauseLock); |
| | 1174 | request_recording = false; |
| 1160 | 1175 | recording = false; |
| 1161 | 1176 | recordingWait.wakeAll(); |
| 1162 | 1177 | } |
diff --git a/mythtv/libs/libmythtv/v4lrecorder.cpp b/mythtv/libs/libmythtv/v4lrecorder.cpp
index 40042b1..7a665da 100644
|
a
|
b
|
V4LRecorder::V4LRecorder(TVRec *tv) :
|
| 33 | 33 | ntsc_vbi_width(0), ntsc_vbi_start_line(0), |
| 34 | 34 | ntsc_vbi_line_count(0), |
| 35 | 35 | vbi608(NULL), |
| 36 | | vbi_thread(NULL), vbi_fd(-1) |
| | 36 | vbi_thread(NULL), vbi_fd(-1), |
| | 37 | request_helper(false) |
| 37 | 38 | { |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | 41 | V4LRecorder::~V4LRecorder() |
| 41 | 42 | { |
| | 43 | { |
| | 44 | QMutexLocker locker(&pauseLock); |
| | 45 | request_helper = false; |
| | 46 | unpauseWait.wakeAll(); |
| | 47 | } |
| | 48 | |
| 42 | 49 | if (vbi_thread) |
| 43 | 50 | { |
| | 51 | vbi_thread->wait(); |
| 44 | 52 | delete vbi_thread; |
| 45 | 53 | vbi_thread = NULL; |
| | 54 | CloseVBIDevice(); |
| 46 | 55 | } |
| 47 | 56 | } |
| 48 | 57 | |
| … |
… |
void V4LRecorder::StopRecording(void)
|
| 53 | 62 | vbi_thread->wait(); |
| 54 | 63 | } |
| 55 | 64 | |
| | 65 | bool V4LRecorder::IsHelperRequested(void) const |
| | 66 | { |
| | 67 | QMutexLocker locker(&pauseLock); |
| | 68 | return request_helper && request_recording; |
| | 69 | } |
| | 70 | |
| 56 | 71 | void V4LRecorder::SetOption(const QString &name, const QString &value) |
| 57 | 72 | { |
| 58 | 73 | if (name == "audiodevice") |
| … |
… |
void V4LRecorder::RunVBIDevice(void)
|
| 252 | 267 | ptr_end = buf + sz; |
| 253 | 268 | } |
| 254 | 269 | |
| 255 | | while (IsRecordingRequested() && !IsErrored()) |
| | 270 | while (IsHelperRequested() && !IsErrored()) |
| 256 | 271 | { |
| 257 | 272 | if (PauseAndWait()) |
| 258 | 273 | continue; |
| 259 | 274 | |
| 260 | | if (!IsRecordingRequested()) |
| | 275 | if (!IsHelperRequested() || IsErrored()) |
| 261 | 276 | break; |
| 262 | 277 | |
| 263 | 278 | struct timeval tv; |
diff --git a/mythtv/libs/libmythtv/v4lrecorder.h b/mythtv/libs/libmythtv/v4lrecorder.h
index 64de6fe..7835d3b 100644
|
a
|
b
|
class MTV_PUBLIC V4LRecorder : public DTVRecorder
|
| 38 | 38 | void CloseVBIDevice(void); |
| 39 | 39 | void RunVBIDevice(void); |
| 40 | 40 | |
| | 41 | virtual bool IsHelperRequested(void) const; |
| 41 | 42 | virtual void FormatTT(struct VBIData *vbidata) {} |
| 42 | 43 | virtual void FormatCC(uint code1, uint code2) {} |
| 43 | 44 | |
| … |
… |
class MTV_PUBLIC V4LRecorder : public DTVRecorder
|
| 54 | 55 | VBIThread *vbi_thread; |
| 55 | 56 | QList<struct txtbuffertype*> textbuffer; |
| 56 | 57 | int vbi_fd; |
| | 58 | volatile bool request_helper; |
| 57 | 59 | }; |
| 58 | 60 | |
| 59 | 61 | class VBIThread : public MThread |