|
MythTV
0.26-pre
|
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 }
1.7.6.1