00001
00002 #ifndef RECORDERBASE_H_
00003 #define RECORDERBASE_H_
00004
00005 #include <stdint.h>
00006
00007 #include <QWaitCondition>
00008 #include <QAtomicInt>
00009 #include <QDateTime>
00010 #include <QRunnable>
00011 #include <QString>
00012 #include <QMutex>
00013 #include <QMap>
00014
00015 #include "recordingquality.h"
00016 #include "programtypes.h"
00017 #include "mythtimer.h"
00018 #include "mythtvexp.h"
00019
00020 class FireWireDBOptions;
00021 class GeneralDBOptions;
00022 class RecordingProfile;
00023 class DVBDBOptions;
00024 class RecorderBase;
00025 class ChannelBase;
00026 class ProgramInfo;
00027 class RingBuffer;
00028 class TVRec;
00029
00042 class MTV_PUBLIC RecorderBase : public QRunnable
00043 {
00044 friend class Transcode;
00045
00046 public:
00047 RecorderBase(TVRec *rec);
00048 virtual ~RecorderBase();
00049
00051 void SetFrameRate(double rate)
00052 {
00053 video_frame_rate = rate;
00054 ntsc_framerate = (29.96 <= rate && 29.98 >= rate);
00055 }
00056
00066 void SetRecording(const ProgramInfo *pginfo);
00067
00074 void SetRingBuffer(RingBuffer *rbuf);
00075
00082 virtual void SetOption(const QString &opt, const QString &value);
00083
00088 virtual void SetOption(const QString &opt, int value);
00089
00096 virtual void SetVideoFilters(QString &filters) = 0;
00097
00104 virtual void SetOptionsFromProfile(RecordingProfile *profile,
00105 const QString &videodev,
00106 const QString &audiodev,
00107 const QString &vbidev) = 0;
00108
00119 virtual void SetNextRecording(const ProgramInfo*, RingBuffer*) = 0;
00120
00124 virtual void Initialize(void) = 0;
00125
00130 virtual void run(void) = 0;
00131
00137 virtual void Reset(void) = 0;
00138
00140 virtual bool IsErrored(void) = 0;
00141
00147 virtual long long GetFramesWritten(void) = 0;
00148
00157 virtual int GetVideoFd(void) = 0;
00158
00173 int64_t GetKeyframePosition(uint64_t desired) const;
00174 bool GetKeyframePositions(
00175 int64_t start, int64_t end, frm_pos_map_t&) const;
00176
00177 virtual void StopRecording(void);
00178 virtual bool IsRecording(void);
00179 virtual bool IsRecordingRequested(void);
00180
00182 virtual RecordingQuality *GetRecordingQuality(void) const;
00183
00184
00185 virtual void Pause(bool clear = true);
00186 virtual void Unpause(void);
00187 virtual bool IsPaused(bool holding_lock = false) const;
00188 virtual bool WaitForPause(int timeout = 1000);
00189
00196 double GetFrameRate(void) { return video_frame_rate; }
00197
00200 virtual void CheckForRingBufferSwitch(void);
00201
00204 void SavePositionMap(bool force = false);
00205
00206 enum AspectRatio {
00207 ASPECT_UNKNOWN = 0x00,
00208 ASPECT_1_1 = 0x01,
00209 ASPECT_4_3 = 0x02,
00210 ASPECT_16_9 = 0x03,
00211 ASPECT_2_21_1 = 0x04,
00212 ASPECT_CUSTOM = 0x05,
00213 };
00214
00215 static RecorderBase *CreateRecorder(
00216 TVRec *tvrec,
00217 ChannelBase *channel,
00218 const RecordingProfile &profile,
00219 const GeneralDBOptions &genOpt,
00220 const DVBDBOptions &dvbOpt);
00221
00222 protected:
00226 void SetIntOption(RecordingProfile *profile, const QString &name);
00230 void SetStrOption(RecordingProfile *profile, const QString &name);
00231 virtual bool PauseAndWait(int timeout = 100);
00232
00233 virtual void ResetForNewFile(void) = 0;
00234 virtual void ClearStatistics(void);
00235 virtual void FinishRecording(void) = 0;
00236 virtual void StartNewFile(void) { }
00237
00240 void SetPositionMapType(MarkTypes type) { positionMapType = type; }
00241
00244 void AspectChange(uint ratio, long long frame);
00245
00248 void ResolutionChange(uint width, uint height, long long frame);
00249
00252 void FrameRateChange(uint framerate, long long frame);
00253
00256 void SetDuration(uint64_t duration);
00257
00260 void SetTotalFrames(uint64_t total_frames);
00261
00262 TVRec *tvrec;
00263 RingBuffer *ringBuffer;
00264 bool weMadeBuffer;
00265
00266 QString videocodec;
00267 QString videodevice;
00268
00269 bool ntsc;
00270 bool ntsc_framerate;
00271 double video_frame_rate;
00272
00273 uint m_videoAspect;
00274
00275 uint m_videoHeight;
00276 uint m_videoWidth;
00277 double m_frameRate;
00278
00279 ProgramInfo *curRecording;
00280
00281
00282 mutable QMutex pauseLock;
00283 bool request_pause;
00284 bool paused;
00285 QWaitCondition pauseWait;
00286 QWaitCondition unpauseWait;
00288 bool request_recording;
00290 bool recording;
00291 QWaitCondition recordingWait;
00292
00293
00294
00295 QMutex nextRingBufferLock;
00296 RingBuffer *nextRingBuffer;
00297 ProgramInfo *nextRecording;
00298
00299
00300 MarkTypes positionMapType;
00301 mutable QMutex positionMapLock;
00302 frm_pos_map_t positionMap;
00303 frm_pos_map_t positionMapDelta;
00304 MythTimer positionMapTimer;
00305
00306
00307
00308
00309
00310
00311 mutable QMutex statisticsLock;
00312 QAtomicInt timeOfFirstDataIsSet;
00313 QDateTime timeOfFirstData;
00314 QAtomicInt timeOfLatestDataCount;
00315 QAtomicInt timeOfLatestDataPacketInterval;
00316 QDateTime timeOfLatestData;
00317 MythTimer timeOfLatestDataTimer;
00318 RecordingGaps recordingGaps;
00320 static const uint kTimeOfLatestDataIntervalTarget;
00321 };
00322
00323 #endif
00324
00325