MythTV  master
NuppelVideoRecorder.h
Go to the documentation of this file.
1 #ifndef NUPPELVIDEORECORDER
2 #define NUPPELVIDEORECORDER
3 
4 // C headers
5 #include <sys/time.h>
6 #ifdef MMX
7 #undef MMX
8 #define MMXBLAH
9 #endif
10 #include <lame/lame.h>
11 #ifdef MMXBLAH
12 #define MMX
13 #endif
14 
15 #include "mythconfig.h"
16 
17 #undef HAVE_AV_CONFIG_H
18 extern "C" {
19 #include "libavcodec/avcodec.h"
20 }
21 
22 // C++ std headers
23 #include <cstdint>
24 #include <ctime>
25 #include <vector>
26 
27 // Qt headers
28 #include <QString>
29 
30 // MythTV headers
31 #include "v4lrecorder.h"
32 #include "format.h"
33 #include "captions/cc608decoder.h"
34 #include "lzo/lzo1x.h"
35 #include "mthread.h"
36 #include "mythframe.h"
37 
38 #include "mythtvexp.h"
39 
40 #define KEYFRAMEDIST 30
41 
42 struct video_audio;
43 class RTjpeg;
44 class MythMediaBuffer;
45 class ChannelBase;
46 class AudioInput;
48 
49 class NVRWriteThread : public MThread
50 {
51  public:
52  explicit NVRWriteThread(NuppelVideoRecorder *parent) :
53  MThread("NVRWrite"), m_parent(parent) {}
54  ~NVRWriteThread() override { wait(); m_parent = nullptr; }
55  void run(void) override; // MThread
56  private:
58 };
59 
60 class NVRAudioThread : public MThread
61 {
62  public:
63  explicit NVRAudioThread(NuppelVideoRecorder *parent) :
64  MThread("NVRAudio"), m_parent(parent) {}
65  ~NVRAudioThread() override { wait(); m_parent = nullptr; }
66  void run(void) override; // MThread
67  private:
69 };
70 
72 {
73  friend class NVRWriteThread;
74  friend class NVRAudioThread;
75  public:
77  ~NuppelVideoRecorder() override;
78 
79  void SetOption(const QString &opt, int value) override; // DTVRecorder
80  void SetOption(const QString &name, const QString &value) override; // DTVRecorder
81 
83  const QString &videodev,
84  const QString &audiodev,
85  const QString &vbidev) override; // DTVRecorder
86 
87  void Initialize(void) override; // DTVRecorder
88  void run(void) override; // RecorderBase
89 
90  void Pause(bool clear = true) override; // RecorderBase
91  bool IsPaused(bool holding_lock = false) const override; // RecorderBase
92 
93  bool IsRecording(void) override; // RecorderBase
94 
95  long long GetFramesWritten(void) override; // DTVRecorder
96 
97  bool Open(void);
98  int GetVideoFd(void) override; // DTVRecorder
99  void Reset(void) override; // DTVRecorder
100 
101  void SetVideoFilters(QString &filters) override; // DTVRecorder
102  void SetTranscoding(bool value) { m_transcoding = value; };
103 
104  void ResetForNewFile(void) override; // DTVRecorder
105  void FinishRecording(void) override; // DTVRecorder
106  void StartNewFile(void) override; // RecorderBase
107 
108  // reencode stuff
109  void StreamAllocate(void);
110  void WriteHeader(void);
111  void WriteSeekTable(void);
112  void WriteKeyFrameAdjustTable(
113  const std::vector<struct kfatable_entry> &kfa_table);
114  void UpdateSeekTable(int frame_num, long offset = 0);
115 
116  bool SetupAVCodecVideo(void);
117  void SetupRTjpeg(void);
118  int AudioInit(bool skipdevice = false);
119  void SetVideoAspect(float newAspect) {m_videoAspect = newAspect; };
120  void WriteVideo(MythVideoFrame *frame, bool skipsync = false,
121  bool forcekey = false);
122  void WriteAudio(unsigned char *buf, int fnum, int timecode);
123  void WriteText(unsigned char *buf, int len, int timecode, int pagenr);
124 
125  void SetNewVideoParams(double newaspect);
126 
127  protected:
128  void doWriteThread(void);
129  void doAudioThread(void);
130 
131  private:
132  inline void WriteFrameheader(rtframeheader *fh);
133 
134  void WriteFileHeader(void);
135 
136  void InitBuffers(void);
137  void ResizeVideoBuffers(void);
138 
139  bool MJPEGInit(void);
140 
141  void KillChildren(void);
142 
143  void BufferIt(unsigned char *buf, int len = -1, bool forcekey = false);
144 
145  int CreateNuppelFile(void);
146 
147  void ProbeV4L2(void);
148  bool SetFormatV4L2(void);
149  void DoV4L1(void);
150  void DoV4L2(void);
151  void DoMJPEG(void);
152 
153  void FormatTT(struct VBIData *vbidata) override; // V4LRecorder
154  void FormatCC(uint code1, uint code2) override; // V4LRecorder
155  void AddTextData(unsigned char*buf, int len, int64_t timecode, char type) override; // CC608Input
156 
157  void UpdateResolutions(void);
158 
159  int m_fd {-1}; // v4l input file handle
160  signed char *m_strm {nullptr};
161  unsigned int m_lf {0};
162  int m_tf {0};
163  int m_m1 {0};
164  int m_m2 {0};
165  int m_q {255};
166  int m_width {352};
167  int m_height {240};
168  int m_pipMode {0};
169  int m_compression {1};
170  bool m_compressAudio {true};
171  AudioInput *m_audioDevice {nullptr};
172  unsigned long long m_audioBytes {0};
173  int m_audioChannels {2};
174  int m_audioBits {16};
175  int m_audioBytesPerSample {m_audioChannels * m_audioBits / 8};
176  int m_audioSampleRate {44100}; // rate we request from sounddevice
177  int m_effectiveDsp {0}; // actual measured rate
178 
179  int m_useBttv {1};
180  float m_videoAspect {1.33333F};
181 
182  bool m_transcoding {false};
183 
184  int m_mp3Quality {3};
185  char *m_mp3Buf {nullptr};
186  int m_mp3BufSize {0};
187  lame_global_flags *m_gf {nullptr};
188 
189  RTjpeg *m_rtjc {nullptr};
190 
191 #define OUT_LEN (1024*1024 + 1024*1024 / 64 + 16 + 3)
192  std::array<lzo_byte,OUT_LEN> m_out {};
193 #define HEAP_ALLOC(var,size) \
194  std::array<long,((size) + (sizeof(long) - 1)) / sizeof(long)> __LZO_MMODEL var
195  HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS) {};
196 
197  std::vector<struct vidbuffertype *> m_videoBuffer;
198  std::vector<struct audbuffertype *> m_audioBuffer;
199  std::vector<struct txtbuffertype *> m_textBuffer;
200 
201  int m_actVideoEncode {0};
202  int m_actVideoBuffer {0};
203 
204  int m_actAudioEncode {0};
205  int m_actAudioBuffer {0};
206  long long m_actAudioSample {0};
207 
208  int m_actTextEncode {0};
209  int m_actTextBuffer {0};
210 
211  int m_videoBufferCount {0};
212  int m_audioBufferCount {0};
213  int m_textBufferCount {0};
214 
215  long m_videoBufferSize {0};
216  long m_audioBufferSize {0};
217  long m_textBufferSize {0};
218 
219  struct timeval m_stm {0,0};
220  struct timezone m_tzone {0,0};
221 
222  NVRWriteThread *m_writeThread {nullptr};
223  NVRAudioThread *m_audioThread {nullptr};
224 
225  bool m_recording {false};
226 
227  int m_keyframeDist {KEYFRAMEDIST};
228  std::vector<struct seektable_entry> *m_seekTable {nullptr};
229  long long m_lastPositionMapPos {0};
230 
231  long long m_extendedDataOffset {0};
232 
233  long long m_framesWritten {0};
234 
235  bool m_livetv {false};
236  bool m_writePaused {false};
237  bool m_audioPaused {false};
238  bool m_mainPaused {false};
239 
240  double m_frameRateMultiplier {1.0};
241  double m_heightMultiplier {1.0};
242 
243  int m_lastBlock {0};
244  int m_firstTc {0};
245  long int m_oldTc {0};
246  int m_startNum {0};
247  int m_frameOfGop {0};
248  int m_lastTimecode {0};
249  int m_audioBehind {0};
250 
251  bool m_useAvCodec {false};
252 
253  AVCodec *m_mpaVidCodec {nullptr};
254  AVCodecContext *m_mpaVidCtx {nullptr};
255 
256  int m_targetBitRate {2200};
257  int m_scaleBitRate {1};
258  int m_maxQuality {2};
259  int m_minQuality {31};
260  int m_qualDiff {3};
261  int m_mp4Opts {0};
262  int m_mbDecision {FF_MB_DECISION_SIMPLE};
264  int m_encodingThreadCount {1};
265 
266  VideoFrameType m_inPixFmt {FMT_YV12};
267  AVPixelFormat m_pictureFormat {AV_PIX_FMT_YUV420P};
268 #ifdef USING_V4L2
269  uint32_t m_v4l2PixelFormat {0};
270 #endif
271  int m_wOut {0};
272  int m_hOut {0};
273 
274  bool m_hardwareEncode {false};
275  int m_hmjpgQuality {80};
276  int m_hmjpgHDecimation {2};
277  int m_hmjpgVDecimation {2};
278  int m_hmjpgMaxW {640};
279 
280  bool m_clearTimeOnPause {false};
281 
282  bool m_usingV4l2 {false};
283  int m_channelFd {-1};
284 
285  ChannelBase *m_channelObj {nullptr};
286 
287  bool m_skipBtAudio {false};
288 
289 #ifdef USING_V4L2
290  bool m_correctBttv {false};
291 #endif
292 
293  int m_volume {100};
294 
295  CC608Decoder *m_ccd {nullptr};
296 
297  bool m_go7007 {false};
298  bool m_resetCapture {false};
299 };
300 
301 #endif
rtframeheader
Definition: format.h:35
channel
QDomElement channel
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:501
NVRWriteThread::NVRWriteThread
NVRWriteThread(NuppelVideoRecorder *parent)
Definition: NuppelVideoRecorder.h:52
DTVRecorder::GetVideoFd
int GetVideoFd(void) override
Returns file descriptor of recorder device.
Definition: dtvrecorder.h:53
NVRWriteThread::~NVRWriteThread
~NVRWriteThread() override
Definition: NuppelVideoRecorder.h:54
NuppelVideoRecorder::m_videoBuffer
std::vector< struct vidbuffertype * > m_videoBuffer
Definition: NuppelVideoRecorder.h:195
DTVRecorder::ResetForNewFile
void ResetForNewFile(void) override
Definition: dtvrecorder.cpp:140
V4LRecorder
Abstract base class for Video4Linux based recorders.
Definition: v4lrecorder.h:25
CC608Input::AddTextData
virtual void AddTextData(unsigned char *buf, int len, int64_t timecode, char type)=0
DTVRecorder::SetVideoFilters
void SetVideoFilters(QString &) override
Tells recorder which filters to use.
Definition: dtvrecorder.h:51
NuppelVideoRecorder::m_textBuffer
std::vector< struct txtbuffertype * > m_textBuffer
Definition: NuppelVideoRecorder.h:199
mythtvexp.h
CC608Decoder
Definition: cc608decoder.h:47
format.h
NuppelVideoRecorder::HEAP_ALLOC
HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS)
Definition: NuppelVideoRecorder.h:195
DTVRecorder::SetOptionsFromProfile
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
Definition: dtvrecorder.cpp:112
DTVRecorder::Reset
void Reset(void) override
Reset the recorder to the startup state.
Definition: dtvrecorder.cpp:198
MythMediaBuffer
Definition: mythmediabuffer.h:50
mythframe.h
CC608Input
Definition: cc608decoder.h:24
NVRWriteThread::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: NuppelVideoRecorder.cpp:70
DTVRecorder::FinishRecording
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
Definition: dtvrecorder.cpp:126
RecorderBase::Pause
virtual void Pause(bool clear=true)
Pause tells recorder to pause, it should not block.
Definition: recorderbase.cpp:264
NVRWriteThread
Definition: NuppelVideoRecorder.h:50
V4LRecorder::SetOption
void SetOption(const QString &name, const QString &value) override
Set an specific option.
Definition: v4lrecorder.cpp:59
NuppelVideoRecorder::m_audioBuffer
std::vector< struct audbuffertype * > m_audioBuffer
Definition: NuppelVideoRecorder.h:198
NVRAudioThread::~NVRAudioThread
~NVRAudioThread() override
Definition: NuppelVideoRecorder.h:65
NuppelVideoRecorder::SetVideoAspect
void SetVideoAspect(float newAspect)
Definition: NuppelVideoRecorder.h:119
NVRAudioThread
Definition: NuppelVideoRecorder.h:61
AudioInput
Definition: audioinput.h:28
cc608decoder.h
NVRAudioThread::m_parent
NuppelVideoRecorder * m_parent
Definition: NuppelVideoRecorder.h:68
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:32
hardwareprofile.scan.profile
profile
Definition: scan.py:99
FMT_YV12
@ FMT_YV12
Definition: mythframe.h:19
v4lrecorder.h
NVRWriteThread::m_parent
NuppelVideoRecorder * m_parent
Definition: NuppelVideoRecorder.h:57
DTVRecorder::GetFramesWritten
long long GetFramesWritten(void) override
Returns number of frames written to disk.
Definition: dtvrecorder.h:48
DTVRecorder::Initialize
void Initialize(void) override
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
Definition: dtvrecorder.h:52
clear
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:844
RecorderBase::IsRecording
virtual bool IsRecording(void)
Tells whether the StartRecorder() loop is running.
Definition: recorderbase.cpp:244
NVRAudioThread::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: NuppelVideoRecorder.cpp:77
uint
unsigned int uint
Definition: compat.h:140
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RTjpeg
Definition: RTjpegN.h:68
NVRAudioThread::NVRAudioThread
NVRAudioThread(NuppelVideoRecorder *parent)
Definition: NuppelVideoRecorder.h:63
KEYFRAMEDIST
#define KEYFRAMEDIST
Definition: NuppelVideoRecorder.h:40
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:274
VBIData
Definition: v4lrecorder.h:17
NuppelVideoRecorder::m_stm
Definition: NuppelVideoRecorder.h:219
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:143
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:49
mthread.h
V4LRecorder::FormatCC
virtual void FormatCC(uint, uint)
Definition: v4lrecorder.h:43
VideoFrameType
VideoFrameType
Definition: mythframe.h:16
V4LRecorder::FormatTT
virtual void FormatTT(struct VBIData *)
Definition: v4lrecorder.h:42
RecordingProfile
Definition: recordingprofile.h:40
MythVideoFrame
Definition: mythframe.h:83
MThread::wait
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:305
NuppelVideoRecorder::SetTranscoding
void SetTranscoding(bool value)
Definition: NuppelVideoRecorder.h:102
NuppelVideoRecorder::m_tzone
Definition: NuppelVideoRecorder.h:220
RecorderBase::IsPaused
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
Definition: recorderbase.cpp:283
NuppelVideoRecorder
Definition: NuppelVideoRecorder.h:72