MythTV  0.26-pre
videoout_null.cpp
Go to the documentation of this file.
00001 #include <map>
00002 #include <iostream>
00003 using namespace std;
00004 
00005 #include "mythlogging.h"
00006 #include "videoout_null.h"
00007 #include "videodisplayprofile.h"
00008 
00009 const int kNumBuffers = 31;
00010 const int kNeedFreeFrames = 1;
00011 const int kPrebufferFramesNormal = 12;
00012 const int kPrebufferFramesSmall = 4;
00013 const int kKeepPrebuffer = 2;
00014 
00015 void VideoOutputNull::GetRenderOptions(render_opts &opts,
00016                                        QStringList &cpudeints)
00017 {
00018     opts.renderers->append("null");
00019     opts.deints->insert("null", cpudeints);
00020     (*opts.osds)["null"].append("softblend");
00021     (*opts.safe_renderers)["dummy"].append("null");
00022     (*opts.safe_renderers)["nuppel"].append("null");
00023     if (opts.decoders->contains("ffmpeg"))
00024         (*opts.safe_renderers)["ffmpeg"].append("null");
00025     if (opts.decoders->contains("crystalhd"))
00026         (*opts.safe_renderers)["crystalhd"].append("null");
00027 
00028     opts.priorities->insert("null", 10);
00029 }
00030 
00031 VideoOutputNull::VideoOutputNull() :
00032     VideoOutput(), global_lock(QMutex::Recursive)
00033 {
00034     LOG(VB_PLAYBACK, LOG_INFO, "VideoOutputNull()");
00035     memset(&av_pause_frame, 0, sizeof(av_pause_frame));
00036 }
00037 
00038 VideoOutputNull::~VideoOutputNull()
00039 {
00040     LOG(VB_PLAYBACK, LOG_INFO, "~VideoOutputNull()");
00041     QMutexLocker locker(&global_lock);
00042 
00043     if (av_pause_frame.buf)
00044     {
00045         delete [] av_pause_frame.buf;
00046         memset(&av_pause_frame, 0, sizeof(av_pause_frame));
00047     }
00048 
00049     vbuffers.DeleteBuffers();
00050 }
00051 
00052 // this is documented in videooutbase.cpp
00053 void VideoOutputNull::Zoom(ZoomDirection direction)
00054 {
00055     QMutexLocker locker(&global_lock);
00056     VideoOutput::Zoom(direction);
00057     MoveResize();
00058 }
00059 
00060 void VideoOutputNull::CreatePauseFrame(void)
00061 {
00062     if (av_pause_frame.buf)
00063     {
00064         delete [] av_pause_frame.buf;
00065         av_pause_frame.buf = NULL;
00066     }
00067 
00068     init(&av_pause_frame, FMT_YV12,
00069          new unsigned char[vbuffers.GetScratchFrame()->size + 128],
00070          vbuffers.GetScratchFrame()->width,
00071          vbuffers.GetScratchFrame()->height,
00072          vbuffers.GetScratchFrame()->size);
00073 
00074     av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
00075 
00076     clear(&av_pause_frame);
00077 }
00078 
00079 bool VideoOutputNull::InputChanged(const QSize &input_size,
00080                                    float        aspect,
00081                                    MythCodecID  av_codec_id,
00082                                    void        *codec_private,
00083                                    bool        &aspect_only)
00084 {
00085     LOG(VB_PLAYBACK, LOG_INFO,
00086         QString("InputChanged(WxH = %1x%2, aspect = %3)")
00087             .arg(input_size.width())
00088             .arg(input_size.height()).arg(aspect));
00089 
00090     if (!codec_is_std(av_codec_id))
00091     {
00092         LOG(VB_GENERAL, LOG_ERR, QString("VideoOutputNull::InputChanged(): "
00093                                          "new video codec is not supported."));
00094         errorState = kError_Unknown;
00095         return false;
00096     }
00097 
00098     QMutexLocker locker(&global_lock);
00099 
00100     if (input_size == window.GetActualVideoDim())
00101     {
00102         vbuffers.Clear();
00103         MoveResize();
00104         return true;
00105     }
00106 
00107     VideoOutput::InputChanged(input_size, aspect, av_codec_id, codec_private,
00108                               aspect_only);
00109     vbuffers.DeleteBuffers();
00110 
00111     MoveResize();
00112 
00113     const QSize video_dim = window.GetVideoDim();
00114 
00115     bool ok = vbuffers.CreateBuffers(FMT_YV12, video_dim.width(),
00116                                      video_dim.height());
00117     if (!ok)
00118     {
00119         LOG(VB_GENERAL, LOG_ERR, "VideoOutputNull::InputChanged(): "
00120                                  "Failed to recreate buffers");
00121         errorState = kError_Unknown;
00122     }
00123     else
00124     {
00125         CreatePauseFrame();
00126     }
00127 
00128     if (db_vdisp_profile)
00129         db_vdisp_profile->SetVideoRenderer("null");
00130 
00131     return ok;
00132 }
00133 
00134 bool VideoOutputNull::Init(int width, int height, float aspect, WId winid,
00135                            const QRect &win_rect, MythCodecID codec_id)
00136 {
00137     if ((width <= 0) || (height <= 0))
00138         return false;
00139 
00140     if (!codec_is_std(codec_id))
00141     {
00142         LOG(VB_GENERAL, LOG_ERR,
00143             QString("Cannot create VideoOutputNull for codec %1")
00144             .arg(toString(codec_id)));
00145         return false;
00146     }
00147 
00148     QMutexLocker locker(&global_lock);
00149 
00150     VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id);
00151 
00152     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
00153                   kPrebufferFramesNormal, kPrebufferFramesSmall,
00154                   kKeepPrebuffer);
00155 
00156     const QSize video_dim = window.GetVideoDim();
00157 
00158     if (!vbuffers.CreateBuffers(FMT_YV12, video_dim.width(), video_dim.height()))
00159         return false;
00160 
00161     CreatePauseFrame();
00162 
00163     if (db_vdisp_profile)
00164         db_vdisp_profile->SetVideoRenderer("null");
00165 
00166     MoveResize();
00167 
00168     return true;
00169 }
00170 
00171 void VideoOutputNull::EmbedInWidget(const QRect &rect)
00172 {
00173     QMutexLocker locker(&global_lock);
00174     if (!window.IsEmbedding())
00175         VideoOutput::EmbedInWidget(rect);
00176 }
00177 
00178 void VideoOutputNull::StopEmbedding(void)
00179 {
00180     QMutexLocker locker(&global_lock);
00181     if (window.IsEmbedding())
00182         VideoOutput::StopEmbedding();
00183 }
00184 
00185 void VideoOutputNull::PrepareFrame(VideoFrame *buffer, FrameScanType t,
00186                                    OSD *osd)
00187 {
00188     (void)osd;
00189     (void)t;
00190 
00191     if (!buffer)
00192         buffer = vbuffers.GetScratchFrame();
00193 
00194     framesPlayed = buffer->frameNumber + 1;
00195 }
00196 
00197 void VideoOutputNull::Show(FrameScanType )
00198 {
00199 }
00200 
00201 void VideoOutputNull::DrawUnusedRects(bool)
00202 {
00203 }
00204 
00205 void VideoOutputNull::UpdatePauseFrame(int64_t &disp_timecode)
00206 {
00207     QMutexLocker locker(&global_lock);
00208 
00209     // Try used frame first, then fall back to scratch frame.
00210     vbuffers.begin_lock(kVideoBuffer_used);
00211     VideoFrame *used_frame = NULL;
00212     if (vbuffers.size(kVideoBuffer_used) > 0)
00213         used_frame = vbuffers.head(kVideoBuffer_used);
00214 
00215     if (used_frame)
00216         CopyFrame(&av_pause_frame, used_frame);
00217     vbuffers.end_lock();
00218 
00219     if (!used_frame)
00220     {
00221         vbuffers.GetScratchFrame()->frameNumber = framesPlayed - 1;
00222         CopyFrame(&av_pause_frame, vbuffers.GetScratchFrame());
00223     }
00224 
00225     disp_timecode = av_pause_frame.disp_timecode;
00226 }
00227 
00228 void VideoOutputNull::ProcessFrame(VideoFrame *frame, OSD *osd,
00229                                    FilterChain *filterList,
00230                                    const PIPMap &pipPlayers,
00231                                    FrameScanType scan)
00232 {
00233     (void)frame;
00234     (void)osd;
00235     (void)filterList;
00236     (void)pipPlayers;
00237     (void)scan;
00238 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends