MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
videoout_null.cpp
Go to the documentation of this file.
1 #include <map>
2 #include <iostream>
3 using namespace std;
4 
5 #include "mythlogging.h"
6 #include "videoout_null.h"
7 #include "videodisplayprofile.h"
8 
9 const int kNumBuffers = 31;
10 const int kNeedFreeFrames = 1;
11 const int kPrebufferFramesNormal = 12;
12 const int kPrebufferFramesSmall = 4;
13 const int kKeepPrebuffer = 2;
14 
16  QStringList &cpudeints)
17 {
18  opts.renderers->append("null");
19  opts.deints->insert("null", cpudeints);
20  (*opts.osds)["null"].append("softblend");
21  (*opts.safe_renderers)["dummy"].append("null");
22  (*opts.safe_renderers)["nuppel"].append("null");
23  if (opts.decoders->contains("ffmpeg"))
24  (*opts.safe_renderers)["ffmpeg"].append("null");
25  if (opts.decoders->contains("crystalhd"))
26  (*opts.safe_renderers)["crystalhd"].append("null");
27 
28  opts.priorities->insert("null", 10);
29 }
30 
32  VideoOutput(), global_lock(QMutex::Recursive)
33 {
34  LOG(VB_PLAYBACK, LOG_INFO, "VideoOutputNull()");
35  memset(&av_pause_frame, 0, sizeof(av_pause_frame));
36 }
37 
39 {
40  LOG(VB_PLAYBACK, LOG_INFO, "~VideoOutputNull()");
41  QMutexLocker locker(&global_lock);
42 
43  if (av_pause_frame.buf)
44  {
45  delete [] av_pause_frame.buf;
46  memset(&av_pause_frame, 0, sizeof(av_pause_frame));
47  }
48 
50 }
51 
52 // this is documented in videooutbase.cpp
54 {
55  QMutexLocker locker(&global_lock);
56  VideoOutput::Zoom(direction);
57  MoveResize();
58 }
59 
61 {
62  if (av_pause_frame.buf)
63  {
64  delete [] av_pause_frame.buf;
65  av_pause_frame.buf = NULL;
66  }
67 
69  new unsigned char[vbuffers.GetScratchFrame()->size + 128],
73 
75 
77 }
78 
79 bool VideoOutputNull::InputChanged(const QSize &video_dim_buf,
80  const QSize &video_dim_disp,
81  float aspect,
82  MythCodecID av_codec_id,
83  void *codec_private,
84  bool &aspect_only)
85 {
86  LOG(VB_PLAYBACK, LOG_INFO,
87  QString("InputChanged(WxH = %1x%2, aspect = %3)")
88  .arg(video_dim_disp.width())
89  .arg(video_dim_disp.height()).arg(aspect));
90 
91  if (!codec_is_std(av_codec_id))
92  {
93  LOG(VB_GENERAL, LOG_ERR, QString("VideoOutputNull::InputChanged(): "
94  "new video codec is not supported."));
96  return false;
97  }
98 
99  QMutexLocker locker(&global_lock);
100 
101  if (video_dim_disp == window.GetActualVideoDim())
102  {
103  vbuffers.Clear();
104  MoveResize();
105  return true;
106  }
107 
108  VideoOutput::InputChanged(video_dim_buf, video_dim_disp,
109  aspect, av_codec_id, codec_private,
110  aspect_only);
112 
113  MoveResize();
114 
115  const QSize video_dim = window.GetVideoDim();
116 
117  bool ok = vbuffers.CreateBuffers(FMT_YV12, video_dim.width(),
118  video_dim.height());
119  if (!ok)
120  {
121  LOG(VB_GENERAL, LOG_ERR, "VideoOutputNull::InputChanged(): "
122  "Failed to recreate buffers");
124  }
125  else
126  {
128  }
129 
130  if (db_vdisp_profile)
132 
133  return ok;
134 }
135 
136 bool VideoOutputNull::Init(const QSize &video_dim_buf,
137  const QSize &video_dim_disp,
138  float aspect, WId winid,
139  const QRect &win_rect, MythCodecID codec_id)
140 {
141  if ((video_dim_disp.width() <= 0) || (video_dim_disp.height() <= 0))
142  return false;
143 
144  if (!codec_is_std(codec_id))
145  {
146  LOG(VB_GENERAL, LOG_ERR,
147  QString("Cannot create VideoOutputNull for codec %1")
148  .arg(toString(codec_id)));
149  return false;
150  }
151 
152  QMutexLocker locker(&global_lock);
153 
154  VideoOutput::Init(video_dim_buf, video_dim_disp,
155  aspect, winid, win_rect, codec_id);
156 
160 
161  // XXX should this be GetActualVideoDim() ?
162  const QSize video_dim = window.GetVideoDim();
163 
164  if (!vbuffers.CreateBuffers(FMT_YV12, video_dim.width(), video_dim.height()))
165  return false;
166 
168 
169  if (db_vdisp_profile)
171 
172  MoveResize();
173 
174  return true;
175 }
176 
177 void VideoOutputNull::EmbedInWidget(const QRect &rect)
178 {
179  QMutexLocker locker(&global_lock);
180  if (!window.IsEmbedding())
182 }
183 
185 {
186  QMutexLocker locker(&global_lock);
187  if (window.IsEmbedding())
189 }
190 
192  OSD *osd)
193 {
194  (void)osd;
195  (void)t;
196 
197  if (!buffer)
198  buffer = vbuffers.GetScratchFrame();
199 
200  framesPlayed = buffer->frameNumber + 1;
201 }
202 
204 {
205 }
206 
208 {
209 }
210 
211 void VideoOutputNull::UpdatePauseFrame(int64_t &disp_timecode)
212 {
213  QMutexLocker locker(&global_lock);
214 
215  // Try used frame first, then fall back to scratch frame.
217  VideoFrame *used_frame = NULL;
219  used_frame = vbuffers.Head(kVideoBuffer_used);
220 
221  if (used_frame)
222  CopyFrame(&av_pause_frame, used_frame);
223  vbuffers.end_lock();
224 
225  if (!used_frame)
226  {
229  }
230 
231  disp_timecode = av_pause_frame.disp_timecode;
232 }
233 
235  FilterChain *filterList,
236  const PIPMap &pipPlayers,
238 {
239  (void)frame;
240  (void)osd;
241  (void)filterList;
242  (void)pipPlayers;
243  (void)scan;
244 }