7 #include "mythconfig.h"
8 #if HAVE_SYS_SOUNDCARD_H
9 #include <sys/soundcard.h>
10 #elif HAVE_SOUNDCARD_H
11 #include <soundcard.h>
13 #include <sys/ioctl.h>
18 #include <QStringList>
43 #include "libswscale/swscale.h"
44 #include "libavutil/imgutils.h"
48 #include <linux/videodev2.h>
53 #include <linux/videodev.h>
56 #ifndef MJPIOC_S_PARAMS
68 #define LOC QString("NVR(%1): ").arg(m_videodevice)
88 m_seekTable =
new std::vector<struct seektable_entry>;
153 else if (opt ==
"height")
155 else if (opt ==
"rtjpegchromafilter")
157 else if (opt ==
"rtjpeglumafilter")
159 else if (opt ==
"rtjpegquality")
161 else if ((opt ==
"mpeg4bitrate") || (opt ==
"mpeg2bitrate"))
163 else if (opt ==
"scalebitrate")
165 else if (opt ==
"mpeg4maxquality")
172 else if (opt ==
"mpeg4minquality")
174 else if (opt ==
"mpeg4qualdiff")
176 else if (opt ==
"encodingthreadcount")
178 else if (opt ==
"mpeg4optionvhq")
185 else if (opt ==
"mpeg4option4mv")
192 else if (opt ==
"mpeg4optionidct")
195 m_mp4Opts |= AV_CODEC_FLAG_INTERLACED_DCT;
197 m_mp4Opts &= ~AV_CODEC_FLAG_INTERLACED_DCT;
199 else if (opt ==
"mpeg4optionime")
202 m_mp4Opts |= AV_CODEC_FLAG_INTERLACED_ME;
204 m_mp4Opts &= ~AV_CODEC_FLAG_INTERLACED_ME;
206 else if (opt ==
"hardwaremjpegquality")
208 else if (opt ==
"hardwaremjpeghdecimation")
210 else if (opt ==
"hardwaremjpegvdecimation")
212 else if (opt ==
"audiocompression")
214 else if (opt ==
"mp3quality")
216 else if (opt ==
"samplerate")
218 else if (opt ==
"audioframesize")
220 else if (opt ==
"pip_mode")
222 else if (opt ==
"inpixfmt")
224 else if (opt ==
"skipbtaudio")
226 else if (opt ==
"volume")
238 const QString &videodev,
239 const QString &audiodev,
240 const QString &vbidev)
251 setting =
tmp->getValue();
253 if (setting ==
"MPEG-4")
262 #ifdef USING_FFMPEG_THREADS
270 else if (setting ==
"MPEG-2")
276 #ifdef USING_FFMPEG_THREADS
280 else if (setting ==
"RTjpeg")
288 else if (setting ==
"Hardware MJPEG")
290 SetOption(
"videocodec",
"hardware-mjpeg");
298 LOG(VB_GENERAL, LOG_ERR,
LOC +
299 "Unknown video codec. "
300 "Please go into the TV Settings, Recording Profiles and "
301 "setup the four 'Software Encoders' profiles. "
302 "Assuming RTjpeg for now.");
313 setting =
tmp->getValue();
315 if (setting ==
"MP3")
321 else if (setting ==
"Uncompressed")
328 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown audio codec");
388 m_mpaVidCodec = avcodec_find_encoder_by_name(vcodec.constData());
392 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Video Codec not found: %1")
393 .
arg(vcodec.constData()));
401 case AV_PIX_FMT_YUV420P:
402 case AV_PIX_FMT_YUV422P:
403 case AV_PIX_FMT_YUVJ420P:
407 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unknown picture format: %1")
418 usebitrate = (int)(diff * usebitrate);
445 AVDictionary *
opts =
nullptr;
448 m_mpaVidCtx->bit_rate_tolerance = usebitrate * 100;
458 av_dict_set(&
opts,
"rc_strategy",
"2", 0);
459 av_dict_set(&
opts,
"b_strategy",
"0", 0);
465 av_dict_set(&
opts,
"rc_init_cplx",
"0", 0);
468 av_dict_set_int(&
opts,
"pred", FF_PRED_LEFT, 0);
470 m_mpaVidCtx->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
475 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unable to open FFMPEG/%1 codec")
502 double aspectnum =
m_wOut / (double)tot_height;
505 if (aspectnum == 0.0)
507 else if (fabs(aspectnum - 1.3333333333333333) < 0.001)
509 else if (fabs(aspectnum - 1.7777777777777777) < 0.001)
511 else if (fabs(aspectnum - 2.21) < 0.001)
514 aspect = aspectnum * 1000000;
522 if (
m_wOut && tot_height &&
538 case 2398: den = 24000;
542 case 2998: den = 30000;
546 case 5995: den = 60000;
555 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"NVR: frame rate = %1")
565 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to init audio input device");
599 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning, old RingBuffer creation");
605 m_error =
"Could not open RingBuffer";
626 LOG(VB_GENERAL, LOG_ERR,
LOC +
633 LOG(VB_GENERAL, LOG_ERR,
LOC +
641 LOG(VB_GENERAL, LOG_ERR,
LOC +
642 QString(
"Failed to determine audio block size on %1,"
651 LOG(VB_AUDIO, LOG_INFO,
LOC +
652 QString(
"Audio device %1 buffer size: %1 bytes")
659 lame_set_bWriteVbrTag(
m_gf, 0);
661 lame_set_compression_ratio(
m_gf, 11);
665 if ((
tmp = lame_init_params(
m_gf)) != 0)
667 LOG(VB_GENERAL, LOG_ERR,
LOC +
668 QString(
"AudioInit(): lame_init_params error %1").
arg(
tmp));
674 LOG(VB_GENERAL, LOG_ERR,
LOC +
675 "AudioInit(): lame support requires 16bit audio");
697 bool we_opened_fd =
false;
702 init_fd = open(vdevice.constData(), O_RDWR);
707 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device" +
ENO);
712 struct video_capability vc;
713 memset(&vc, 0,
sizeof(vc));
714 int ret = ioctl(init_fd, VIDIOCGCAP, &vc);
717 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't query V4L capabilities" +
ENO);
725 if (vc.maxwidth != 768 && vc.maxwidth != 640)
728 if (vc.type & VID_TYPE_MJPEG_ENCODER)
730 if (vc.maxwidth >= 768)
732 else if (vc.maxwidth >= 704)
740 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MJPEG not supported by device");
776 vidbuf->freeToEncode = 0;
777 vidbuf->freeToBuffer = 1;
778 vidbuf->bufferlen = 0;
779 vidbuf->forcekey =
false;
789 audbuf->freeToEncode = 0;
790 audbuf->freeToBuffer = 1;
799 txtbuf->freeToEncode = 0;
800 txtbuf->freeToBuffer = 1;
810 delete [] (vidbuf->buffer);
828 m_fd = open(vdevice.constData(), O_RDWR);
832 m_fd = open(vdevice.constData(), O_RDWR);
851 struct v4l2_capability vcap {};
853 if (ioctl(
m_channelFd, VIDIOC_QUERYCAP, &vcap) < 0)
858 if (
m_usingV4l2 && !(vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
860 LOG(VB_GENERAL, LOG_ERR,
LOC +
861 "Not a v4l2 capture device, falling back to v4l");
865 if (
m_usingV4l2 && !(vcap.capabilities & V4L2_CAP_STREAMING))
867 LOG(VB_GENERAL, LOG_ERR,
LOC +
868 "Won't work with the streaming interface, falling back");
872 if (vcap.card[0] ==
'B' && vcap.card[1] ==
'T' &&
873 vcap.card[2] ==
'8' && vcap.card[4] ==
'8')
876 QString driver = (
char *)vcap.driver;
877 if (driver ==
"go7007")
884 if (lzo_init() != LZO_E_OK)
886 LOG(VB_GENERAL, LOG_ERR,
LOC +
"lzo_init() failed, exiting");
887 m_error =
"lzo_init() failed, exiting";
894 m_error =
"Failed to open device";
903 m_error =
"Failed to set V4L2 format";
926 m_error = QString(
"Cannot open '%1' for writing")
934 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Children are already alive");
935 m_error =
"Children are already alive";
957 gettimeofday(&
m_stm,
nullptr);
982 struct video_capability vc;
983 struct video_mmap mm;
984 struct video_mbuf vm;
985 struct video_channel vchan;
986 struct video_audio va;
987 struct video_tuner vt;
989 memset(&mm, 0,
sizeof(mm));
990 memset(&vm, 0,
sizeof(vm));
991 memset(&vchan, 0,
sizeof(vchan));
992 memset(&va, 0,
sizeof(va));
993 memset(&vt, 0,
sizeof(vt));
994 memset(&vc, 0,
sizeof(vc));
996 if (ioctl(
m_fd, VIDIOCGCAP, &vc) < 0)
998 QString
tmp =
"VIDIOCGCAP: " +
ENO;
1000 LOG(VB_GENERAL, LOG_ERR,
tmp);
1005 int channelinput = 0;
1010 vchan.channel = channelinput;
1012 if (ioctl(
m_fd, VIDIOCGCHAN, &vchan) < 0)
1013 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCGCHAN: " +
ENO);
1021 if (ioctl(
m_fd, VIDIOCGAUDIO, &va) < 0)
1023 bool reports_audio = vchan.flags & VIDEO_VC_AUDIO;
1024 uint err_level = reports_audio ? VB_GENERAL : VB_AUDIO;
1026 LOG(err_level, LOG_ERR,
LOC +
"Failed to get audio" +
ENO);
1031 va.flags &= ~VIDEO_AUDIO_MUTE;
1032 va.volume =
m_volume * 65535 / 100;
1033 if (ioctl(
m_fd, VIDIOCSAUDIO, &va) < 0)
1034 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to set audio" +
ENO);
1041 m_error =
"MJPEG requested but not available.";
1049 if (ioctl(
m_fd, VIDIOCGMBUF, &vm) < 0)
1051 QString
tmp =
"VIDIOCGMBUF: " +
ENO;
1060 QString
tmp =
"need a minimum of 2 capture buffers";
1069 unsigned char *buf = (
unsigned char *)mmap(0, vm.size,
1070 PROT_READ|PROT_WRITE,
1073 if (buf == MAP_FAILED)
1075 QString
tmp =
"mmap: " +
ENO;
1085 mm.format = VIDEO_PALETTE_YUV422P;
1087 mm.format = VIDEO_PALETTE_YUV420P;
1090 if (ioctl(
m_fd, VIDIOCMCAPTURE, &mm)<0)
1091 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCMCAPTUREi0: " +
ENO);
1093 if (ioctl(
m_fd, VIDIOCMCAPTURE, &mm)<0)
1094 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCMCAPTUREi1: " +
ENO);
1102 if (m_request_pause)
1113 gettimeofday(&
m_stm,
nullptr);
1126 if (ioctl(
m_fd, VIDIOCSYNC, &frame)<0)
1129 if (syncerrors == 10)
1130 LOG(VB_GENERAL, LOG_ERR,
LOC +
1131 "Multiple bttv errors, further messages supressed");
1132 else if (syncerrors < 10)
1133 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCSYNC: " +
ENO);
1141 if (ioctl(
m_fd, VIDIOCMCAPTURE, &mm)<0)
1142 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCMCAPTURE0: " +
ENO);
1146 if (ioctl(
m_fd, VIDIOCSYNC, &frame)<0)
1149 if (syncerrors == 10)
1150 LOG(VB_GENERAL, LOG_ERR,
LOC +
1151 "Multiple bttv errors, further messages supressed");
1152 else if (syncerrors < 10)
1153 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCSYNC: " +
ENO);
1160 if (ioctl(
m_fd, VIDIOCMCAPTURE, &mm)<0)
1161 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VIDIOCMCAPTURE1: " +
ENO);
1164 munmap(buf, vm.size);
1172 #else // if !USING_V4L1
1174 #endif // !USING_V4L1
1179 struct v4l2_format vfmt {};
1181 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1185 vfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
1188 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1190 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
1192 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
1194 if (ioctl(
m_fd, VIDIOC_S_FMT, &vfmt) < 0)
1197 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1199 if (ioctl(
m_fd, VIDIOC_S_FMT, &vfmt) < 0)
1202 vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1203 if (ioctl(
m_fd, VIDIOC_S_FMT, &vfmt) < 0)
1205 LOG(VB_GENERAL, LOG_ERR,
LOC +
1206 "v4l2: Unable to set desired format");
1214 LOG(VB_GENERAL, LOG_ERR,
LOC +
1215 "v4l2: uyvy format supported, but yuv422 requested.");
1216 LOG(VB_GENERAL, LOG_ERR,
LOC +
1217 "v4l2: unfortunately, this converter hasn't been "
1218 "written yet, exiting");
1221 LOG(VB_RECORD, LOG_INFO,
LOC +
1222 "v4l2: format set, getting uyvy from v4l, converting");
1229 LOG(VB_GENERAL, LOG_ERR,
LOC +
1230 "v4l2: yuyv format supported, but yuv422 requested.");
1231 LOG(VB_GENERAL, LOG_ERR,
LOC +
1232 "v4l2: unfortunately, this converter hasn't been written "
1236 LOG(VB_RECORD, LOG_INFO,
LOC +
1237 "v4l2: format set, getting yuyv from v4l, converting");
1241 LOG(VB_RECORD, LOG_INFO,
LOC +
1242 "v4l2: format set, getting yuv420 from v4l");
1245 if (
m_width != (
int)vfmt.fmt.pix.width ||
1246 m_height != (
int)vfmt.fmt.pix.height)
1248 LOG(VB_RECORD, LOG_INFO,
LOC +
1249 QString(
"v4l2: resolution changed. requested %1x%2, using "
1252 .
arg(vfmt.fmt.pix.width) .arg(vfmt.fmt.pix.height));
1261 #else // if !USING_V4L2
1263 #endif // !USING_V4L2
1266 #define MAX_VIDEO_BUFFERS 5
1269 struct v4l2_buffer vbuf {};
1270 struct v4l2_requestbuffers vrbuf {};
1271 struct v4l2_control vc {};
1273 vc.id = V4L2_CID_AUDIO_MUTE;
1276 if (ioctl(
m_fd, VIDIOC_S_CTRL, &vc) < 0)
1277 LOG(VB_GENERAL, LOG_ERR,
LOC +
1278 "VIDIOC_S_CTRL:V4L2_CID_AUDIO_MUTE: " +
ENO);
1310 m_error =
"Unable to set compression params";
1322 m_error =
"Unable to set MPEG params";
1331 usebitrate = (int)(diff * usebitrate);
1336 m_error =
"Unable to set bitrate";
1346 vrbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1347 vrbuf.memory = V4L2_MEMORY_MMAP;
1348 vrbuf.count = numbuffers;
1350 if (ioctl(
m_fd, VIDIOC_REQBUFS, &vrbuf) < 0)
1352 m_error =
"Not able to get any capture buffers, exiting";
1357 if (vrbuf.count < numbuffers)
1359 LOG(VB_GENERAL, LOG_INFO,
LOC +
1360 QString(
"Requested %1 buffers, but only %2 are available. "
1361 "Proceeding anyway").
arg(numbuffers).
arg(vrbuf.count));
1364 numbuffers = vrbuf.count;
1366 std::array<uint8_t*,MAX_VIDEO_BUFFERS>
buffers {};
1367 std::array<int,MAX_VIDEO_BUFFERS> bufferlen {};
1369 for (
uint i = 0; i < numbuffers; i++)
1371 vbuf.type = vrbuf.type;
1374 if (ioctl(
m_fd, VIDIOC_QUERYBUF, &vbuf) < 0)
1376 LOG(VB_GENERAL, LOG_ERR,
LOC +
1377 QString(
"unable to query capture buffer %1").
arg(i));
1378 m_error =
"Unable to query capture buffer";
1382 buffers[i] = (
unsigned char *)mmap(
nullptr, vbuf.length,
1383 PROT_READ|PROT_WRITE, MAP_SHARED,
1384 m_fd, vbuf.m.offset);
1388 LOG(VB_GENERAL, LOG_ERR,
LOC +
"mmap: " +
ENO);
1389 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Memory map failed");
1390 m_error =
"Memory map failed";
1393 bufferlen[i] = vbuf.length;
1396 for (
uint i = 0; i < numbuffers; i++)
1398 memset(
buffers[i], 0, bufferlen[i]);
1399 vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1401 if (ioctl(
m_fd, VIDIOC_QBUF, &vbuf) < 0)
1402 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to enqueue capture buffer (VIDIOC_QBUF failed) " +
ENO);
1405 int turnon = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1406 if (ioctl(
m_fd, VIDIOC_STREAMON, &turnon) < 0)
1407 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to start capture (VIDIOC_STREAMON failed) " +
ENO);
1409 struct timeval tv {};
1412 bool forcekey =
false;
1417 uint8_t *output_buffer =
nullptr;
1418 struct SwsContext *convert_ctx =
nullptr;
1424 AV_PIX_FMT_YUYV422 :
1430 m_error =
"Cannot initialize image conversion buffer";
1435 convert_ctx = sws_getCachedContext(convert_ctx,
m_width,
m_height, in_pixfmt,
1437 SWS_FAST_BILINEAR,
nullptr,
nullptr,
nullptr);
1440 m_error =
"Cannot initialize image conversion context";
1441 av_free(output_buffer);
1446 av_image_fill_arrays(img_out.data, img_out.linesize,
1466 gettimeofday(&
m_stm,
nullptr);
1479 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Resetting and re-queueing");
1480 turnon = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1481 if (ioctl(
m_fd, VIDIOC_STREAMOFF, &turnon) < 0)
1482 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to stop capture (VIDIOC_STREAMOFF failed) " +
ENO);
1484 for (
uint i = 0; i < numbuffers; i++)
1486 memset(
buffers[i], 0, bufferlen[i]);
1487 vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1489 if (ioctl(
m_fd, VIDIOC_QBUF, &vbuf) < 0)
1490 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to enqueue capture buffer (VIDIOC_QBUF failed) " +
ENO);
1493 if (ioctl(
m_fd, VIDIOC_STREAMON, &turnon) < 0)
1494 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to start capture (VIDIOC_STREAMON failed) " +
ENO);
1501 FD_SET(
m_fd, &rdset);
1503 switch (select(
m_fd+1, &rdset,
nullptr,
nullptr, &tv))
1508 LOG(VB_GENERAL, LOG_ERR,
LOC +
"select: " +
ENO);
1511 LOG(VB_GENERAL, LOG_INFO,
LOC +
"select timeout");
1516 memset(&vbuf, 0,
sizeof(vbuf));
1517 vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1518 vbuf.memory = V4L2_MEMORY_MMAP;
1519 if (ioctl(
m_fd, VIDIOC_DQBUF, &vbuf) < 0)
1521 LOG(VB_GENERAL, LOG_ERR,
LOC +
"DQBUF ioctl failed." +
ENO);
1532 if (errno == EIO || errno == EINVAL)
1538 if (errno == EAGAIN)
1544 forcekey = ((vbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0U);
1549 (output_buffer !=
nullptr))
1552 av_image_fill_arrays(img_in.data, img_in.linesize,
1555 sws_scale(convert_ctx, img_in.data, img_in.linesize,
1556 0,
m_height, img_out.data, img_out.linesize);
1560 (output_buffer !=
nullptr))
1563 av_image_fill_arrays(img_in.data, img_in.linesize,
1566 sws_scale(convert_ctx, img_in.data, img_in.linesize,
1567 0,
m_height, img_out.data, img_out.linesize);
1577 vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1578 if (ioctl(
m_fd, VIDIOC_QBUF, &vbuf) < 0)
1579 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to enqueue capture buffer (VIDIOC_QBUF failed) " +
ENO);
1584 if (ioctl(
m_fd, VIDIOC_STREAMOFF, &turnon) < 0)
1585 LOG(VB_GENERAL, LOG_ERR,
LOC +
"unable to stop capture (VIDIOC_STREAMOFF failed) " +
ENO);
1587 for (
uint i = 0; i < numbuffers; i++)
1589 munmap(
buffers[i], bufferlen[i]);
1594 av_free(output_buffer);
1595 sws_freeContext(convert_ctx);
1600 #else // if !USING_V4L2
1602 #endif // !USING_V4L2
1611 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MJPIOC_G_PARAMS: " +
ENO);
1660 for (
int n = 0; n < bparm.
APP_len; n++)
1665 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"MJPIOC_S_PARAMS: " +
ENO);
1672 breq.
size = 256 * 1024;
1676 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"MJPIOC_REQBUFS: " +
ENO);
1680 uint8_t *MJPG_buff = (uint8_t *)mmap(0, breq.
count * breq.
size,
1681 PROT_READ|PROT_WRITE, MAP_SHARED,
m_fd,
1684 if (MJPG_buff == MAP_FAILED)
1686 LOG(VB_GENERAL, LOG_ERR,
LOC +
"mapping mjpeg buffers");
1692 for (
unsigned int count = 0; count < breq.
count; count++)
1695 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MJPIOC_QBUF_CAPT: " +
ENO);
1702 if (m_request_pause)
1713 gettimeofday(&
m_stm,
nullptr);
1736 m_error =
"MJPEG Capture error";
1741 munmap(MJPG_buff, breq.
count * breq.
size);
1748 #else // if !USING_V4L1
1750 #endif // !USING_V4L1
1785 struct timeval now {};
1793 gettimeofday(&now,
nullptr);
1795 auto tcres = durationFromTimevalDelta<std::chrono::milliseconds>(now,
m_stm);
1805 int fn = (tcres -
m_oldTc).count();
1824 LOG(VB_GENERAL, LOG_INFO,
LOC +
1825 "DROPPED frame due to full buffer in the recorder.");
1877 static const std::string kFinfo {
"MythTVVideo" };
1878 static const std::string kVers {
"0.07" };
1896 fileheader.
width = bswap_32(fileheader.
width);
1928 static std::array<uint32_t,128> s_tbls {};
1931 frameheader.
packetlength = s_tbls.size() *
sizeof(uint32_t);
1939 memset(&frameheader, 0,
sizeof(frameheader));
1954 case AV_CODEC_ID_MPEG4: vidfcc =
FOURCC_DIVX;
break;
1955 case AV_CODEC_ID_WMV1: vidfcc =
FOURCC_WMV1;
break;
1956 case AV_CODEC_ID_MSMPEG4V3: vidfcc =
FOURCC_DIV3;
break;
1957 case AV_CODEC_ID_MSMPEG4V2: vidfcc =
FOURCC_MP42;
break;
1958 case AV_CODEC_ID_MSMPEG4V1: vidfcc =
FOURCC_MPG4;
break;
1959 case AV_CODEC_ID_MJPEG: vidfcc =
FOURCC_MJPG;
break;
1960 case AV_CODEC_ID_H263:
1961 case AV_CODEC_ID_H263P: vidfcc =
FOURCC_H263;
break;
1962 case AV_CODEC_ID_H263I: vidfcc =
FOURCC_I263;
break;
1963 case AV_CODEC_ID_MPEG1VIDEO: vidfcc =
FOURCC_MPEG;
break;
1964 case AV_CODEC_ID_MPEG2VIDEO: vidfcc =
FOURCC_MPG2;
break;
1965 case AV_CODEC_ID_HUFFYUV: vidfcc =
FOURCC_HFYU;
break;
2042 memcpy(seekbuf + offset, (
const void *)&entry,
2061 const std::vector<struct kfatable_entry> &kfa_table)
2063 int numentries = kfa_table.size();
2076 for (
auto kfa : kfa_table)
2078 memcpy(kfa_buf + offset, &kfa,
2119 LOG(VB_GENERAL, LOG_ERR,
LOC +
2120 "No ringbuffer, recorder wasn't initialized.");
2126 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ringbuffer isn't open");
2187 LOG(VB_GENERAL, LOG_ERR,
LOC +
2194 LOG(VB_GENERAL, LOG_ERR,
LOC +
2201 LOG(VB_GENERAL, LOG_ERR,
LOC +
2206 struct timeval anow {};
2240 LOG(VB_GENERAL, LOG_ERR,
LOC +
2241 QString(
"Short read, %1 of %2 bytes from ")
2249 gettimeofday(&anow,
nullptr);
2256 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ran out of free AUDIO buffers :-(");
2266 durationFromTimevalDelta<std::chrono::milliseconds>(anow,
m_stm);
2294 struct timeval tnow {};
2295 gettimeofday(&tnow,
nullptr);
2300 LOG(VB_GENERAL, LOG_ERR,
LOC +
2301 QString(
"Teletext #%1: ran out of free TEXT buffers :-(").
arg(act));
2308 durationFromTimevalDelta<std::chrono::milliseconds>(tnow,
m_stm);
2316 std::vector<uint8_t> linebuf {};
2402 if ((c & 0xa0) == 0x20)
2405 c += (c & 0x40) ? 32 : -32;
2411 if (visible || (c !=
' '))
2422 linebuf.push_back(c);
2431 st.len = linebuf.size() + 1;
2433 int bufsize = ((outpos - m_textBuffer[act]->buffer + 1) + st.len);
2434 if (bufsize > maxlen)
2436 memcpy(outpos, &st,
sizeof(st));
2437 outpos +=
sizeof(st);
2438 int count = std::max(st.len,
static_cast<uint8_t
>(41));
2439 std::copy(linebuf.cbegin(), linebuf.cbegin() + count, outpos);
2445 m_textBuffer[act]->bufferlen = outpos - m_textBuffer[act]->buffer + 1;
2446 m_textBuffer[act]->freeToBuffer = 0;
2448 if (m_actTextBuffer >= m_textBufferCount)
2449 m_actTextBuffer = 0;
2450 m_textBuffer[act]->freeToEncode = 1;
2454 #endif // USING_V4L2
2458 struct timeval tnow {};
2459 gettimeofday (&tnow,
nullptr);
2463 auto tc = durationFromTimevalDelta<std::chrono::milliseconds>(tnow,
m_stm);
2468 std::chrono::milliseconds timecode,
char )
2473 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Teletext#%1").
arg(act) +
2474 " ran out of free TEXT buffers :-(");
2526 std::chrono::milliseconds firsttimecode = -1ms;
2536 (
action == ACTION_NONE ||
2545 (
action == ACTION_NONE ||
2580 LOG(VB_GENERAL, LOG_ERR,
LOC +
2581 "ACTION_AUDIO cannot be completed due to error.");
2661 std::array<uint8_t*,3> planes {
2666 std::chrono::milliseconds timecode = frame->
m_timecode;
2680 bool wantkeyframe = forcekey;
2682 bool writesync =
false;
2709 wantkeyframe =
true;
2725 mpa_picture->pict_type = AV_PICTURE_TYPE_I;
2727 mpa_picture->pict_type = AV_PICTURE_TYPE_NONE;
2732 av_init_packet(&packet);
2733 packet.data = (uint8_t *)
m_strm;
2737 tmp = avcodec_encode_video2(
m_mpaVidCtx, &packet, mpa_picture, &got_packet);
2739 if (
tmp < 0 || !got_packet)
2741 LOG(VB_GENERAL, LOG_ERR,
LOC +
2742 "WriteVideo : avcodec_encode_video() failed");
2784 m_out.data(), &out_len, wrkmem.data());
2789 &out_len, wrkmem.data());
2793 LOG(VB_GENERAL, LOG_ERR,
LOC +
"lzo compression failed");
2800 frameheader.
timecode = timecode.count();
2829 else if (compressthis == 0 || (
tmp < (
int)out_len))
2869 static void bswap_16_buf(
short int *buf,
int buf_cnt,
int audio_channels)
2870 __attribute__ ((unused));
2872 static void bswap_16_buf(
short int *buf,
int buf_cnt,
int audio_channels)
2874 for (
int i = 0; i < audio_channels * buf_cnt; i++)
2875 buf[i] = bswap_16(buf[i]);
2893 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"audio behind %1 %2").
2899 frameheader.
timecode = timecode.count();
2905 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
2918 auto mt = (double)timecode.count();
2928 std::array<uint8_t,7200> mp3gapless {};
2929 int compressedsize = 0;
2930 int gaplesssize = 0;
2941 lameret = lame_encode_buffer_interleaved(
2942 m_gf, (
short int*) buf, sample_cnt,
2947 lameret = lame_encode_buffer(
2948 m_gf, (
short int*) buf, (
short int*) buf, sample_cnt,
2954 LOG(VB_GENERAL, LOG_ERR,
LOC +
2955 QString(
"lame error '%1'").
arg(lameret));
2956 m_error = QString(
"Audio Encoding Error '%1'")
2960 compressedsize = lameret;
2962 lameret = lame_encode_flush_nogap(
m_gf, mp3gapless.data(), mp3gapless.size());
2965 LOG(VB_GENERAL, LOG_ERR,
LOC +
2966 QString(
"lame error '%1'").
arg(lameret));
2967 m_error = QString(
"Audio Encoding Error '%1'")
2971 gaplesssize = lameret;
2974 frameheader.
packetlength = compressedsize + gaplesssize;
2998 LOG(VB_RECORD, LOG_INFO,
LOC +
"audio behind");
3016 frameheader.
timecode = timecode.count();
3025 struct { int8_t m_a,m_b,m_c,m_d; } m_val8;