MythTV  0.26-pre
recorderbase.h
Go to the documentation of this file.
00001 // -*- Mode: c++ -*-
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" // for MarkTypes, frm_pos_map_t
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; // for access to SetIntOption(), SetStrOption()
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     // pausing interface
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; // AspectRatio
00274 
00275     uint           m_videoHeight;
00276     uint           m_videoWidth;
00277     double         m_frameRate;
00278 
00279     ProgramInfo   *curRecording;
00280 
00281     // For handling pausing + stop recording
00282     mutable QMutex pauseLock; // also used for request_recording and recording
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     // For RingBuffer switching
00295     QMutex         nextRingBufferLock;
00296     RingBuffer    *nextRingBuffer;
00297     ProgramInfo   *nextRecording;
00298 
00299     // Seektable  support
00300     MarkTypes      positionMapType;
00301     mutable QMutex positionMapLock;
00302     frm_pos_map_t  positionMap;
00303     frm_pos_map_t  positionMapDelta;
00304     MythTimer      positionMapTimer;
00305 
00306     // Statistics
00307     // Note: Once we enter RecorderBase::run(), only that thread can
00308     // update these values safely. These values are read in that thread
00309     // without locking and updated with the lock held. Outside that
00310     // thread these values are only read, and only with the lock held.
00311     mutable QMutex statisticsLock;
00312     QAtomicInt     timeOfFirstDataIsSet; // doesn't need locking
00313     QDateTime      timeOfFirstData;
00314     QAtomicInt     timeOfLatestDataCount; // doesn't need locking
00315     QAtomicInt     timeOfLatestDataPacketInterval; // doesn't need locking
00316     QDateTime      timeOfLatestData;
00317     MythTimer      timeOfLatestDataTimer;
00318     RecordingGaps  recordingGaps;
00320     static const uint kTimeOfLatestDataIntervalTarget;
00321 };
00322 
00323 #endif
00324 
00325 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends