HRESULT CMpeg2DecoderDXVA2::CreateDecoder(IDirect3DSurface9 **ppSurface, int SurfaceCount) { DBG_TRACE(TEXT("CMpeg2DecoderDXVA2::CreateDecoder()")); if (!ppSurface) return E_POINTER; if (!m_pFilter || !m_pDecoderService) return E_UNEXPECTED; CloseDecoder(); HRESULT hr; GUID guidDecoder; if (!FindDecoder(&guidDecoder, nullptr, &m_SurfaceFormat, 1)) { DBG_ERROR(TEXT("Decoder not found")); return E_FAIL; } DXVA2_VideoDesc VideoDesc = {}; VideoDesc.SampleWidth = m_pFilter->GetAlignedWidth(); VideoDesc.SampleHeight = m_pFilter->GetAlignedHeight(); VideoDesc.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst; VideoDesc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_MPEG2; VideoDesc.SampleFormat.NominalRange = DXVA2_NominalRange_16_235; VideoDesc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709; VideoDesc.SampleFormat.VideoLighting = DXVA2_VideoLighting_dim; VideoDesc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT709; VideoDesc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_709; VideoDesc.Format = m_SurfaceFormat; UINT Count; DXVA2_ConfigPictureDecode *pConfigs; hr = m_pDecoderService->GetDecoderConfigurations( guidDecoder, &VideoDesc, nullptr, &Count, &pConfigs); if (FAILED(hr)) { DBG_ERROR(TEXT("GetDecoderConfigurations() failed (%x)"), hr); return hr; } int SelConfig = -1; for (UINT i = 0; i < Count; i++) { if (pConfigs[i].ConfigBitstreamRaw == 1) { SelConfig = i; break; } } if (SelConfig < 0) { ::CoTaskMemFree(pConfigs); return E_FAIL; } IDirectXVideoDecoder *pVideoDecoder; hr = m_pDecoderService->CreateVideoDecoder( guidDecoder, &VideoDesc, &pConfigs[SelConfig], ppSurface, SurfaceCount, &pVideoDecoder); ::CoTaskMemFree(pConfigs); if (FAILED(hr)) { DBG_ERROR(TEXT("CreateVideoDecoder() failed (%x)"), hr); return hr; } m_pVideoDecoder = pVideoDecoder; return hr; }
bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& options) { const AVCodec* pCodec = FindDecoder(hints); if (!pCodec) { CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::%s - unable to find decoder for codec %d", __FUNCTION__, hints.codec); return false; } CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - using decoder %s", __FUNCTION__, pCodec->long_name ? pCodec->long_name : pCodec->name); m_pCodecContext = avcodec_alloc_context3(pCodec); if (!m_pCodecContext) return false; const AVCodecHWConfig* pConfig = FindHWConfig(pCodec); if (pConfig && (pConfig->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) && pConfig->device_type == AV_HWDEVICE_TYPE_DRM) { CWinSystemGbm* winSystem = dynamic_cast<CWinSystemGbm*>(CServiceBroker::GetWinSystem()); if (av_hwdevice_ctx_create(&m_pCodecContext->hw_device_ctx, AV_HWDEVICE_TYPE_DRM, winSystem->GetDevicePath().c_str(), nullptr, 0) < 0) { CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unable to create hwdevice context", __FUNCTION__); avcodec_free_context(&m_pCodecContext); return false; } } m_pCodecContext->pix_fmt = AV_PIX_FMT_DRM_PRIME; m_pCodecContext->get_format = GetFormat; m_pCodecContext->codec_tag = hints.codec_tag; m_pCodecContext->coded_width = hints.width; m_pCodecContext->coded_height = hints.height; m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel; m_pCodecContext->time_base.num = 1; m_pCodecContext->time_base.den = DVD_TIME_BASE; if (hints.extradata && hints.extrasize > 0) { m_pCodecContext->extradata_size = hints.extrasize; m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + AV_INPUT_BUFFER_PADDING_SIZE); memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); } if (avcodec_open2(m_pCodecContext, pCodec, nullptr) < 0) { CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unable to open codec", __FUNCTION__); avcodec_free_context(&m_pCodecContext); return false; } if (m_pCodecContext->pix_fmt != AV_PIX_FMT_DRM_PRIME) { CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unexpected pix fmt %s", __FUNCTION__, av_get_pix_fmt_name(m_pCodecContext->pix_fmt)); avcodec_free_context(&m_pCodecContext); return false; } const char* pixFmtName = av_get_pix_fmt_name(m_pCodecContext->pix_fmt); m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); m_processInfo.SetVideoDimensions(hints.width, hints.height); m_processInfo.SetVideoDeintMethod("none"); m_processInfo.SetVideoDAR(hints.aspect); if (pCodec->name) m_name = std::string("ff-") + pCodec->name; else m_name = "ffmpeg"; m_processInfo.SetVideoDecoderName(m_name, true); return true; }
HRESULT CMpeg2DecoderDXVA2::CreateDecoderService(CTVTestVideoDecoder *pFilter) { DBG_TRACE(TEXT("CMpeg2DecoderDXVA2::CreateDecoderService()")); if (!pFilter) return E_POINTER; if (!pFilter->m_pD3DDeviceManager || !pFilter->m_hDXVADevice) return E_UNEXPECTED; CloseDecoderService(); m_pFilter = pFilter; m_pDeviceManager = pFilter->m_pD3DDeviceManager; m_pDeviceManager->AddRef(); HRESULT hr; IDirect3DDevice9 *pDevice; hr = m_pDeviceManager->LockDevice(m_pFilter->m_hDXVADevice, &pDevice, TRUE); if (SUCCEEDED(hr)) { D3DDEVICE_CREATION_PARAMETERS CreationParams; hr = pDevice->GetCreationParameters(&CreationParams); if (SUCCEEDED(hr)) { IDirect3D9 *pD3D; hr = pDevice->GetDirect3D(&pD3D); if (SUCCEEDED(hr)) { D3DADAPTER_IDENTIFIER9 AdapterID; hr = pD3D->GetAdapterIdentifier(CreationParams.AdapterOrdinal, 0, &AdapterID); if (SUCCEEDED(hr)) { WCHAR szDriver[MAX_DEVICE_IDENTIFIER_STRING]; WCHAR szDescription[MAX_DEVICE_IDENTIFIER_STRING]; WCHAR szDeviceName[32]; ::MultiByteToWideChar(CP_ACP, 0, AdapterID.Driver, -1, szDriver, _countof(szDriver)); ::MultiByteToWideChar(CP_ACP, 0, AdapterID.Description, -1, szDescription, _countof(szDescription)); ::MultiByteToWideChar(CP_ACP, 0, AdapterID.DeviceName, -1, szDeviceName, _countof(szDeviceName)); DBG_TRACE(TEXT("--- Adapter information ---")); DBG_TRACE(TEXT(" Driver : %s"), szDriver); DBG_TRACE(TEXT("Description : %s"), szDescription); DBG_TRACE(TEXT("Device name : %s"), szDeviceName); DBG_TRACE(TEXT(" Product : %08x"), HIWORD(AdapterID.DriverVersion.HighPart)); DBG_TRACE(TEXT(" Version : %d.%d.%d"), LOWORD(AdapterID.DriverVersion.HighPart), HIWORD(AdapterID.DriverVersion.LowPart), LOWORD(AdapterID.DriverVersion.LowPart)); DBG_TRACE(TEXT(" Vendor : %08x"), AdapterID.VendorId); DBG_TRACE(TEXT(" Device ID : %08x"), AdapterID.DeviceId); DBG_TRACE(TEXT(" Subsystem : %08x"), AdapterID.SubSysId); DBG_TRACE(TEXT(" Revision : %08x"), AdapterID.Revision); m_AdapterIdentifier = AdapterID; } pD3D->Release(); } } pDevice->Release(); m_pDeviceManager->UnlockDevice(m_pFilter->m_hDXVADevice, FALSE); } if (FAILED(hr)) { ::ZeroMemory(&m_AdapterIdentifier, sizeof(m_AdapterIdentifier)); } IDirectXVideoDecoderService *pDecoderService; hr = m_pDeviceManager->GetVideoService(m_pFilter->m_hDXVADevice, IID_PPV_ARGS(&pDecoderService)); if (FAILED(hr)) { DBG_ERROR(TEXT("GetVideoService() failed (%x)"), hr); CloseDecoderService(); return hr; } m_pDecoderService = pDecoderService; if (!FindDecoder(nullptr, &m_SurfaceFormat, SurfaceFormatList, _countof(SurfaceFormatList))) { CloseDecoderService(); return E_FAIL; } return S_OK; }