|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 00003 #include <map> 00004 #include <iostream> 00005 #include <algorithm> 00006 using namespace std; 00007 00008 #include "mythcontext.h" 00009 #include "videoout_d3d.h" 00010 #include "osd.h" 00011 #include "filtermanager.h" 00012 #include "fourcc.h" 00013 #include "videodisplayprofile.h" 00014 #include "mythmainwindow.h" 00015 #include "myth_imgconvert.h" 00016 #include "mythplayer.h" 00017 00018 #include "mmsystem.h" 00019 #include "tv.h" 00020 00021 #undef UNICODE 00022 00023 extern "C" { 00024 #include "libavcodec/avcodec.h" 00025 } 00026 00027 const int kNumBuffers = 31; 00028 const int kNeedFreeFrames = 1; 00029 const int kPrebufferFramesNormal = 10; 00030 const int kPrebufferFramesSmall = 4; 00031 const int kKeepPrebuffer = 2; 00032 00033 #define NUM_DXVA2_BUFS 30 00034 00035 #define LOC QString("VideoOutputD3D: ") 00036 00037 void VideoOutputD3D::GetRenderOptions(render_opts &opts, 00038 QStringList &cpudeints) 00039 { 00040 opts.renderers->append("direct3d"); 00041 opts.deints->insert("direct3d", cpudeints); 00042 (*opts.osds)["direct3d"].append("direct3d"); 00043 (*opts.safe_renderers)["dummy"].append("direct3d"); 00044 (*opts.safe_renderers)["nuppel"].append("direct3d"); 00045 if (opts.decoders->contains("ffmpeg")) 00046 (*opts.safe_renderers)["ffmpeg"].append("direct3d"); 00047 if (opts.decoders->contains("crystalhd")) 00048 (*opts.safe_renderers)["crystalhd"].append("direct3d"); 00049 opts.priorities->insert("direct3d", 70); 00050 00051 #ifdef USING_DXVA2 00052 if (opts.decoders->contains("dxva2")) 00053 (*opts.safe_renderers)["dxva2"].append("direct3d"); 00054 #endif 00055 } 00056 00057 VideoOutputD3D::VideoOutputD3D(void) 00058 : VideoOutput(), m_lock(QMutex::Recursive), 00059 m_hWnd(NULL), m_render(NULL), 00060 m_video(NULL), 00061 m_render_valid(false), m_render_reset(false), m_pip_active(NULL), 00062 m_osd_painter(NULL) 00063 { 00064 m_pauseFrame.buf = NULL; 00065 #ifdef USING_DXVA2 00066 m_decoder = NULL; 00067 #endif 00068 m_pause_surface = NULL; 00069 } 00070 00071 VideoOutputD3D::~VideoOutputD3D() 00072 { 00073 TearDown(); 00074 } 00075 00076 void VideoOutputD3D::TearDown(void) 00077 { 00078 QMutexLocker locker(&m_lock); 00079 vbuffers.DiscardFrames(true); 00080 vbuffers.Reset(); 00081 vbuffers.DeleteBuffers(); 00082 if (m_pauseFrame.buf) 00083 { 00084 delete [] m_pauseFrame.buf; 00085 m_pauseFrame.buf = NULL; 00086 } 00087 00088 delete m_osd_painter; 00089 m_osd_painter = NULL; 00090 00091 DeleteDecoder(); 00092 DestroyContext(); 00093 } 00094 00095 void VideoOutputD3D::DestroyContext(void) 00096 { 00097 QMutexLocker locker(&m_lock); 00098 m_render_valid = false; 00099 m_render_reset = false; 00100 00101 while (!m_pips.empty()) 00102 { 00103 delete *m_pips.begin(); 00104 m_pips.erase(m_pips.begin()); 00105 } 00106 m_pip_ready.clear(); 00107 00108 if (m_video) 00109 { 00110 delete m_video; 00111 m_video = NULL; 00112 } 00113 00114 if (m_render) 00115 { 00116 delete m_render; 00117 m_render = NULL; 00118 } 00119 } 00120 00121 void VideoOutputD3D::WindowResized(const QSize &new_size) 00122 { 00123 // FIXME this now requires the context to be re-created 00124 /* 00125 QMutexLocker locker(&m_lock); 00126 window.SetDisplayVisibleRect(QRect(QPoint(0, 0), new_size)); 00127 window.SetDisplayAspect( 00128 ((float)new_size.width()) / new_size.height()); 00129 00130 MoveResize(); 00131 */ 00132 } 00133 00134 bool VideoOutputD3D::InputChanged(const QSize &input_size, 00135 float aspect, 00136 MythCodecID av_codec_id, 00137 void *codec_private, 00138 bool &aspect_only) 00139 { 00140 QMutexLocker locker(&m_lock); 00141 00142 QSize cursize = window.GetActualVideoDim(); 00143 00144 LOG(VB_PLAYBACK, LOG_INFO, LOC + 00145 QString("InputChanged from %1: %2x%3 aspect %4 to %5: %6x%7 aspect %9") 00146 .arg(toString(video_codec_id)).arg(cursize.width()) 00147 .arg(cursize.height()).arg(window.GetVideoAspect()) 00148 .arg(toString(av_codec_id)).arg(input_size.width()) 00149 .arg(input_size.height()).arg(aspect)); 00150 00151 00152 bool cid_changed = (video_codec_id != av_codec_id); 00153 bool res_changed = input_size != cursize; 00154 bool asp_changed = aspect != window.GetVideoAspect(); 00155 00156 if (!res_changed && !cid_changed) 00157 { 00158 if (asp_changed) 00159 { 00160 aspect_only = true; 00161 VideoAspectRatioChanged(aspect); 00162 MoveResize(); 00163 } 00164 return true; 00165 } 00166 00167 TearDown(); 00168 QRect disp = window.GetDisplayVisibleRect(); 00169 if (Init(input_size.width(), input_size.height(), 00170 aspect, m_hWnd, disp, av_codec_id)) 00171 { 00172 BestDeint(); 00173 return true; 00174 } 00175 00176 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to re-initialise video output."); 00177 errorState = kError_Unknown; 00178 00179 return false; 00180 } 00181 00182 bool VideoOutputD3D::SetupContext() 00183 { 00184 QMutexLocker locker(&m_lock); 00185 DestroyContext(); 00186 QSize size = window.GetVideoDim(); 00187 m_render = new MythRenderD3D9(); 00188 if (!(m_render && m_render->Create(window.GetDisplayVisibleRect().size(), 00189 m_hWnd))) 00190 return false; 00191 00192 m_video = new D3D9Image(m_render, size, true); 00193 if (!(m_video && m_video->IsValid())) 00194 return false; 00195 00196 LOG(VB_PLAYBACK, LOG_INFO, LOC + 00197 "Direct3D device successfully initialized."); 00198 m_render_valid = true; 00199 return true; 00200 } 00201 00202 bool VideoOutputD3D::Init(int width, int height, float aspect, WId winid, 00203 const QRect &win_rect,MythCodecID codec_id) 00204 { 00205 MythPainter *painter = GetMythPainter(); 00206 if (painter) 00207 painter->FreeResources(); 00208 00209 QMutexLocker locker(&m_lock); 00210 m_hWnd = winid; 00211 window.SetAllowPreviewEPG(true); 00212 00213 VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id); 00214 00215 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Init with codec: %1") 00216 .arg(toString(codec_id))); 00217 SetProfile(); 00218 00219 bool success = true; 00220 success &= SetupContext(); 00221 InitDisplayMeasurements(width, height, false); 00222 00223 if (codec_is_dxva2(video_codec_id)) 00224 { 00225 if (!CreateDecoder()) 00226 return false; 00227 } 00228 00229 success &= CreateBuffers(); 00230 success &= InitBuffers(); 00231 success &= CreatePauseFrame(); 00232 00233 MoveResize(); 00234 00235 if (!success) 00236 TearDown(); 00237 else 00238 { 00239 m_osd_painter = new MythD3D9Painter(m_render); 00240 if (m_osd_painter) 00241 { 00242 m_osd_painter->SetSwapControl(false); 00243 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created D3D9 osd painter."); 00244 } 00245 else 00246 LOG(VB_GENERAL, LOG_ERR, LOC + 00247 "Failed to create D3D9 osd painter."); 00248 } 00249 return success; 00250 } 00251 00252 void VideoOutputD3D::SetProfile(void) 00253 { 00254 if (db_vdisp_profile) 00255 db_vdisp_profile->SetVideoRenderer("direct3d"); 00256 } 00257 00258 bool VideoOutputD3D::CreateBuffers(void) 00259 { 00260 if (codec_is_dxva2(video_codec_id)) 00261 { 00262 vbuffers.Init(NUM_DXVA2_BUFS, false, 2, 1, 4, 1); 00263 LOG(VB_PLAYBACK, LOG_INFO, LOC + 00264 QString("Created %1 empty DXVA2 buffers.") .arg(NUM_DXVA2_BUFS)); 00265 return true; 00266 } 00267 00268 vbuffers.Init(kNumBuffers, true, kNeedFreeFrames, 00269 kPrebufferFramesNormal, kPrebufferFramesSmall, 00270 kKeepPrebuffer); 00271 return true; 00272 00273 } 00274 00275 bool VideoOutputD3D::InitBuffers(void) 00276 { 00277 #ifdef USING_DXVA2 00278 if ((codec_is_dxva2(video_codec_id)) && m_decoder) 00279 { 00280 QMutexLocker locker(&m_lock); 00281 const QSize video_dim = window.GetVideoDim(); 00282 bool ok = true; 00283 for (int i = 0; i < NUM_DXVA2_BUFS; i++) 00284 { 00285 ok &= vbuffers.CreateBuffer(video_dim.width(), 00286 video_dim.height(), i, 00287 m_decoder->GetSurface(i), FMT_DXVA2); 00288 } 00289 if (ok) 00290 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialised DXVA2 buffers."); 00291 return ok; 00292 } 00293 #endif 00294 return vbuffers.CreateBuffers(FMT_YV12, 00295 window.GetVideoDim().width(), 00296 window.GetVideoDim().height()); 00297 } 00298 00299 bool VideoOutputD3D::CreatePauseFrame(void) 00300 { 00301 if (codec_is_dxva2(video_codec_id)) 00302 return true; 00303 00304 init(&m_pauseFrame, FMT_YV12, 00305 new unsigned char[vbuffers.GetScratchFrame()->size + 128], 00306 vbuffers.GetScratchFrame()->width, 00307 vbuffers.GetScratchFrame()->height, 00308 vbuffers.GetScratchFrame()->size); 00309 00310 m_pauseFrame.frameNumber = vbuffers.GetScratchFrame()->frameNumber; 00311 return true; 00312 } 00313 00314 void VideoOutputD3D::PrepareFrame(VideoFrame *buffer, FrameScanType t, 00315 OSD *osd) 00316 { 00317 (void)osd; 00318 if (IsErrored()) 00319 { 00320 LOG(VB_GENERAL, LOG_ERR, LOC + 00321 "PrepareFrame() called while IsErrored is true."); 00322 return; 00323 } 00324 00325 if (!buffer && codec_is_std(video_codec_id)) 00326 buffer = vbuffers.GetScratchFrame(); 00327 00328 bool dummy = false; 00329 if (buffer) 00330 { 00331 dummy = buffer->dummy; 00332 framesPlayed = buffer->frameNumber + 1; 00333 } 00334 00335 if (!m_render || !m_video) 00336 return; 00337 00338 m_render_valid = m_render->Test(m_render_reset); 00339 if (m_render_valid) 00340 { 00341 QRect dvr = vsz_enabled ? vsz_desired_display_rect : 00342 window.GetDisplayVideoRect(); 00343 bool ok = m_render->ClearBuffer(); 00344 if (ok && !dummy) 00345 ok = m_video->UpdateVertices(dvr, window.GetVideoRect(), 00346 255, true); 00347 00348 if (ok) 00349 { 00350 ok = m_render->Begin(); 00351 if (ok) 00352 { 00353 if (!dummy) 00354 m_video->Draw(); 00355 QMap<MythPlayer*,D3D9Image*>::iterator it = m_pips.begin(); 00356 for (; it != m_pips.end(); ++it) 00357 { 00358 if (m_pip_ready[it.key()]) 00359 { 00360 if (m_pip_active == *it) 00361 { 00362 QRect rect = (*it)->GetRect(); 00363 if (!rect.isNull()) 00364 { 00365 rect.adjust(-10, -10, 10, 10); 00366 m_render->DrawRect(rect, QColor(128,0,0,255), 255); 00367 } 00368 } 00369 (*it)->Draw(); 00370 } 00371 } 00372 00373 if (m_visual) 00374 m_visual->Draw(GetTotalOSDBounds(), m_osd_painter, NULL); 00375 00376 if (osd && m_osd_painter && !window.IsEmbedding()) 00377 osd->DrawDirect(m_osd_painter, GetTotalOSDBounds().size(), 00378 true); 00379 m_render->End(); 00380 } 00381 } 00382 00383 } 00384 } 00385 00386 void VideoOutputD3D::Show(FrameScanType ) 00387 { 00388 if (IsErrored()) 00389 { 00390 LOG(VB_GENERAL, LOG_ERR, LOC + 00391 "Show() called while IsErrored is true."); 00392 return; 00393 } 00394 00395 if (!m_render) 00396 return; 00397 00398 m_render_valid = m_render->Test(m_render_reset); 00399 if (m_render_valid) 00400 m_render->Present(window.IsEmbedding() ? m_hEmbedWnd : NULL); 00401 } 00402 00403 void VideoOutputD3D::EmbedInWidget(const QRect &rect) 00404 { 00405 if (window.IsEmbedding()) 00406 return; 00407 00408 VideoOutput::EmbedInWidget(rect); 00409 // TODO: Initialise m_hEmbedWnd? 00410 } 00411 00412 void VideoOutputD3D::StopEmbedding(void) 00413 { 00414 if (!window.IsEmbedding()) 00415 return; 00416 00417 VideoOutput::StopEmbedding(); 00418 } 00419 00420 void VideoOutputD3D::Zoom(ZoomDirection direction) 00421 { 00422 QMutexLocker locker(&m_lock); 00423 VideoOutput::Zoom(direction); 00424 MoveResize(); 00425 } 00426 00427 void VideoOutputD3D::UpdatePauseFrame(int64_t &disp_timecode) 00428 { 00429 QMutexLocker locker(&m_lock); 00430 VideoFrame *used_frame = vbuffers.head(kVideoBuffer_used); 00431 00432 if (codec_is_std(video_codec_id)) 00433 { 00434 if (!used_frame) 00435 used_frame = vbuffers.GetScratchFrame(); 00436 CopyFrame(&m_pauseFrame, used_frame); 00437 disp_timecode = m_pauseFrame.disp_timecode; 00438 } 00439 else if (codec_is_dxva2(video_codec_id)) 00440 { 00441 if (used_frame) 00442 { 00443 m_pause_surface = used_frame->buf; 00444 disp_timecode = used_frame->disp_timecode; 00445 } 00446 else 00447 LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Failed to update pause frame"); 00448 } 00449 } 00450 00451 void VideoOutputD3D::UpdateFrame(VideoFrame *frame, D3D9Image *img) 00452 { 00453 if (codec_is_dxva2(video_codec_id)) 00454 return; 00455 00456 // TODO - add a size check 00457 bool hardware_conv = false; 00458 uint pitch = 0; 00459 uint8_t *buf = img->GetBuffer(hardware_conv, pitch); 00460 if (buf && hardware_conv) 00461 { 00462 int i; 00463 uint8_t *dst = buf; 00464 uint8_t *src = frame->buf; 00465 int chroma_width = frame->width >> 1; 00466 int chroma_height = frame->height >> 1; 00467 int chroma_pitch = pitch >> 1; 00468 for (i = 0; i < frame->height; i++) 00469 { 00470 memcpy(dst, src, frame->width); 00471 dst += pitch; 00472 src += frame->width; 00473 } 00474 00475 dst = buf + (frame->height * pitch); 00476 src = frame->buf + (frame->height * frame->width * 5/4); 00477 for (i = 0; i < chroma_height; i++) 00478 { 00479 memcpy(dst, src, chroma_width); 00480 dst += chroma_pitch; 00481 src += chroma_width; 00482 } 00483 00484 dst = buf + (frame->height * pitch * 5/4); 00485 src = frame->buf + (frame->height * frame->width); 00486 for (i = 0; i < chroma_height; i++) 00487 { 00488 memcpy(dst, src, chroma_width); 00489 dst += chroma_pitch; 00490 src += chroma_width; 00491 } 00492 } 00493 else if (buf && !hardware_conv) 00494 { 00495 AVPicture image_in, image_out; 00496 avpicture_fill(&image_out, (uint8_t*)buf, 00497 PIX_FMT_RGB32, frame->width, frame->height); 00498 image_out.linesize[0] = pitch; 00499 avpicture_fill(&image_in, frame->buf, 00500 PIX_FMT_YUV420P, frame->width, frame->height); 00501 myth_sws_img_convert(&image_out, PIX_FMT_RGB32, &image_in, 00502 PIX_FMT_YUV420P, frame->width, frame->height); 00503 } 00504 img->ReleaseBuffer(); 00505 } 00506 00507 void VideoOutputD3D::ProcessFrame(VideoFrame *frame, OSD *osd, 00508 FilterChain *filterList, 00509 const PIPMap &pipPlayers, 00510 FrameScanType scan) 00511 { 00512 if (!m_render || !m_video) 00513 return; 00514 00515 QMutexLocker locker(&m_lock); 00516 if (IsErrored()) 00517 { 00518 LOG(VB_GENERAL, LOG_ERR, LOC + 00519 "ProcessFrame() called while IsErrored is true."); 00520 return; 00521 } 00522 00523 bool gpu = codec_is_dxva2(video_codec_id); 00524 00525 if (gpu && frame && frame->codec != FMT_DXVA2) 00526 { 00527 LOG(VB_GENERAL, LOG_ERR, LOC + "Wrong frame format"); 00528 return; 00529 } 00530 00531 bool dummy = false; 00532 bool pauseframe = false; 00533 if (!frame) 00534 { 00535 if (!gpu) 00536 { 00537 frame = vbuffers.GetScratchFrame(); 00538 CopyFrame(vbuffers.GetScratchFrame(), &m_pauseFrame); 00539 } 00540 pauseframe = true; 00541 } 00542 00543 if (frame) 00544 dummy = frame->dummy; 00545 bool deint_proc = m_deinterlacing && (m_deintFilter != NULL) && 00546 !dummy; 00547 00548 if (filterList && !gpu && !dummy) 00549 filterList->ProcessFrame(frame); 00550 00551 bool safepauseframe = pauseframe && !IsBobDeint() && !gpu; 00552 if (deint_proc && m_deinterlaceBeforeOSD && 00553 (!pauseframe || safepauseframe)) 00554 { 00555 m_deintFilter->ProcessFrame(frame, scan); 00556 } 00557 00558 if (!window.IsEmbedding()) 00559 ShowPIPs(frame, pipPlayers); 00560 00561 if ((!pauseframe || safepauseframe) && 00562 deint_proc && !m_deinterlaceBeforeOSD) 00563 { 00564 m_deintFilter->ProcessFrame(frame, scan); 00565 } 00566 00567 // Test the device 00568 m_render_valid |= m_render->Test(m_render_reset); 00569 if (m_render_reset) 00570 SetupContext(); 00571 00572 // Update a software decoded frame 00573 if (m_render_valid && !gpu && !dummy) 00574 UpdateFrame(frame, m_video); 00575 00576 // Update a GPU decoded frame 00577 if (m_render_valid && gpu && !dummy) 00578 { 00579 m_render_valid = m_render->Test(m_render_reset); 00580 if (m_render_reset) 00581 CreateDecoder(); 00582 00583 if (m_render_valid && frame) 00584 { 00585 m_render->CopyFrame(frame->buf, m_video); 00586 } 00587 else if (m_render_valid && pauseframe) 00588 { 00589 m_render->CopyFrame(m_pause_surface, m_video); 00590 } 00591 } 00592 } 00593 00594 void VideoOutputD3D::ShowPIP(VideoFrame *frame, 00595 MythPlayer *pipplayer, 00596 PIPLocation loc) 00597 { 00598 if (!pipplayer) 00599 return; 00600 00601 int pipw, piph; 00602 VideoFrame *pipimage = pipplayer->GetCurrentFrame(pipw, piph); 00603 const float pipVideoAspect = pipplayer->GetVideoAspect(); 00604 const QSize pipVideoDim = pipplayer->GetVideoBufferSize(); 00605 const bool pipActive = pipplayer->IsPIPActive(); 00606 const bool pipVisible = pipplayer->IsPIPVisible(); 00607 const uint pipVideoWidth = pipVideoDim.width(); 00608 const uint pipVideoHeight = pipVideoDim.height(); 00609 00610 if ((pipVideoAspect <= 0) || !pipimage || 00611 !pipimage->buf || (pipimage->codec != FMT_YV12) || !pipVisible) 00612 { 00613 pipplayer->ReleaseCurrentFrame(pipimage); 00614 return; 00615 } 00616 00617 QRect position = GetPIPRect(loc, pipplayer); 00618 QRect dvr = window.GetDisplayVisibleRect(); 00619 00620 m_pip_ready[pipplayer] = false; 00621 D3D9Image *m_pip = m_pips[pipplayer]; 00622 if (!m_pip) 00623 { 00624 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Initialise PiP."); 00625 m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight), 00626 true); 00627 m_pips[pipplayer] = m_pip; 00628 if (!m_pip->IsValid()) 00629 { 00630 pipplayer->ReleaseCurrentFrame(pipimage); 00631 return; 00632 } 00633 } 00634 00635 QSize current = m_pip->GetSize(); 00636 if ((uint)current.width() != pipVideoWidth || 00637 (uint)current.height() != pipVideoHeight) 00638 { 00639 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Re-initialise PiP."); 00640 delete m_pip; 00641 m_pip = new D3D9Image(m_render, QSize(pipVideoWidth, pipVideoHeight), 00642 true); 00643 m_pips[pipplayer] = m_pip; 00644 if (!m_pip->IsValid()) 00645 { 00646 pipplayer->ReleaseCurrentFrame(pipimage); 00647 return; 00648 } 00649 } 00650 m_pip->UpdateVertices(position, QRect(0, 0, pipVideoWidth, pipVideoHeight), 00651 255, true); 00652 UpdateFrame(pipimage, m_pip); 00653 m_pip_ready[pipplayer] = true; 00654 if (pipActive) 00655 m_pip_active = m_pip; 00656 00657 pipplayer->ReleaseCurrentFrame(pipimage); 00658 } 00659 00660 void VideoOutputD3D::RemovePIP(MythPlayer *pipplayer) 00661 { 00662 if (!m_pips.contains(pipplayer)) 00663 return; 00664 00665 QMutexLocker locker(&m_lock); 00666 00667 D3D9Image *m_pip = m_pips[pipplayer]; 00668 if (m_pip) 00669 delete m_pip; 00670 m_pip_ready.remove(pipplayer); 00671 m_pips.remove(pipplayer); 00672 } 00673 00674 QStringList VideoOutputD3D::GetAllowedRenderers( 00675 MythCodecID myth_codec_id, const QSize &video_dim) 00676 { 00677 QStringList list; 00678 if (codec_is_std(myth_codec_id) || (codec_is_dxva2_hw(myth_codec_id) && 00679 !getenv("NO_DXVA2"))) 00680 { 00681 list += "direct3d"; 00682 } 00683 return list; 00684 } 00685 00686 MythPainter *VideoOutputD3D::GetOSDPainter(void) 00687 { 00688 return m_osd_painter; 00689 } 00690 00691 bool VideoOutputD3D::ApproveDeintFilter(const QString& filtername) const 00692 { 00693 if (codec_is_std(video_codec_id)) 00694 { 00695 return !filtername.contains("bobdeint") && 00696 !filtername.contains("opengl") && 00697 !filtername.contains("vdpau"); 00698 } 00699 00700 return false; 00701 } 00702 00703 MythCodecID VideoOutputD3D::GetBestSupportedCodec( 00704 uint width, uint height, const QString &decoder, 00705 uint stream_type, bool no_acceleration, 00706 PixelFormat &pix_fmt) 00707 { 00708 #ifdef USING_DXVA2 00709 QSize size(width, height); 00710 bool use_cpu = no_acceleration; 00711 MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_DXVA2 + (stream_type - 1)); 00712 use_cpu |= !codec_is_dxva2_hw(test_cid); 00713 pix_fmt = PIX_FMT_DXVA2_VLD; 00714 if ((decoder == "dxva2") && !getenv("NO_DXVA2") && !use_cpu) 00715 return test_cid; 00716 #endif 00717 return (MythCodecID)(kCodec_MPEG1 + (stream_type - 1)); 00718 } 00719 00720 00721 void* VideoOutputD3D::GetDecoderContext(unsigned char* buf, uint8_t*& id) 00722 { 00723 (void)buf; 00724 (void)id; 00725 #ifdef USING_DXVA2 00726 if (m_decoder) 00727 return (void*)&m_decoder->m_context; 00728 #endif 00729 return NULL; 00730 } 00731 00732 bool VideoOutputD3D::CreateDecoder(void) 00733 { 00734 #ifdef USING_DXVA2 00735 QMutexLocker locker(&m_lock); 00736 if (m_decoder) 00737 DeleteDecoder(); 00738 QSize video_dim = window.GetVideoDim(); 00739 m_decoder = new DXVA2Decoder(NUM_DXVA2_BUFS, video_codec_id, 00740 video_dim.width(), video_dim.height()); 00741 return (m_decoder && m_decoder->Init(m_render)); 00742 #else 00743 return false; 00744 #endif 00745 } 00746 00747 void VideoOutputD3D::DeleteDecoder(void) 00748 { 00749 #ifdef USING_DXVA2 00750 QMutexLocker locker(&m_lock); 00751 delete m_decoder; 00752 m_decoder = NULL; 00753 #endif 00754 } 00755 00756 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1