HRESULT CLAVSplitterSettingsProp::LoadData() { HRESULT hr = S_OK; // Free old strings SAFE_CO_FREE(m_pszPrefLang); SAFE_CO_FREE(m_pszPrefSubLang); SAFE_CO_FREE(m_pszAdvSubConfig); // Query current settings CHECK_HR(hr = m_pLAVF->GetPreferredLanguages(&m_pszPrefLang)); CHECK_HR(hr = m_pLAVF->GetPreferredSubtitleLanguages(&m_pszPrefSubLang)); CHECK_HR(hr = m_pLAVF->GetAdvancedSubtitleConfig(&m_pszAdvSubConfig)); m_subtitleMode = m_pLAVF->GetSubtitleMode(); m_PGSForcedStream = m_pLAVF->GetPGSForcedStream(); m_PGSOnlyForced = m_pLAVF->GetPGSOnlyForced(); m_VC1Mode = m_pLAVF->GetVC1TimestampMode(); m_substreams = m_pLAVF->GetSubstreamsEnabled(); m_MKVExternal = m_pLAVF->GetLoadMatroskaExternalSegments(); m_StreamSwitchRemoveAudio = m_pLAVF->GetStreamSwitchRemoveAudio(); m_PreferHighQualityAudio = m_pLAVF->GetPreferHighQualityAudioStreams(); m_ImpairedAudio = m_pLAVF->GetUseAudioForHearingVisuallyImpaired(); m_QueueMaxMem = m_pLAVF->GetMaxQueueMemSize(); m_QueueMaxPackets = m_pLAVF->GetMaxQueueSize(); m_NetworkAnalysisDuration = m_pLAVF->GetNetworkStreamAnalysisDuration(); m_TrayIcon = m_pLAVF->GetTrayIcon(); done: return hr; }
CLAVSplitterSettingsProp::~CLAVSplitterSettingsProp(void) { SAFE_CO_FREE(m_pszPrefLang); SAFE_CO_FREE(m_pszPrefSubLang); SAFE_CO_FREE(m_pszAdvSubConfig); SafeRelease(&m_pLAVF); }
CLAVSubtitleFrame::~CLAVSubtitleFrame(void) { for (int i = 0; i < m_NumBitmaps; i++) { m_Bitmaps[i]->Release(); } SAFE_CO_FREE(m_Bitmaps); }
STDMETHODIMP CDecDXVA2::DestroyDecoder(bool bFull, bool bNoAVCodec) { SafeRelease(&m_pDecoder); m_pCallback->ReleaseAllDXVAResources(); for (int i = 0; i < m_NumSurfaces; i++) { SafeRelease(&m_pSurfaces[i].d3d); } m_NumSurfaces = 0; for (int i = 0; i < DXVA2_QUEUE_SURFACES; i++) { SAFE_CO_FREE(m_FrameQueue[i]); } if (!bNoAVCodec) { if (m_pAVCtx) { av_freep(&m_pAVCtx->hwaccel_context); } CDecAvcodec::DestroyDecoder(); } if (bFull) { FreeD3DResources(); } return S_OK; }
HRESULT CLAVAudio::ShutdownBitstreaming() { if (m_avioBitstream) { SAFE_CO_FREE(m_avioBitstream->buffer); av_freep(&m_avioBitstream); } return S_OK; }
HRESULT CopyLAVFrameInPlace(LAVFrame *pFrame) { LAVFrame *tmpFrame = nullptr; CopyLAVFrame(pFrame, &tmpFrame); FreeLAVFrameBuffers(pFrame); *pFrame = *tmpFrame; SAFE_CO_FREE(tmpFrame); return S_OK; }
STDMETHODIMP CBDDemuxer::SetTitle(int idx) { HRESULT hr = S_OK; int ret; // return values if (m_pTitle) { bd_free_title_info(m_pTitle); } // Init Event Queue bd_get_event(m_pBD, nullptr); // Select title m_pTitle = bd_get_title_info(m_pBD, idx, 0); ret = bd_select_title(m_pBD, idx); if (ret == 0) { return E_FAIL; } if (m_pb) { av_free(m_pb->buffer); av_free(m_pb); } uint8_t *buffer = (uint8_t *)av_mallocz(BD_READ_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); m_pb = avio_alloc_context(buffer, BD_READ_BUFFER_SIZE, 0, this, BDByteStreamRead, nullptr, BDByteStreamSeek); SafeRelease(&m_lavfDemuxer); SAFE_CO_FREE(m_rtOffset); m_lavfDemuxer = new CLAVFDemuxer(m_pLock, m_pSettings); m_lavfDemuxer->AddRef(); m_lavfDemuxer->SetBluRay(this); if (FAILED(hr = m_lavfDemuxer->OpenInputStream(m_pb, nullptr, "mpegts", TRUE))) { SafeRelease(&m_lavfDemuxer); return hr; } m_lavfDemuxer->SeekByte(0, 0); // Process any events that occured during opening ProcessBDEvents(); // Reset EOS protection m_EndOfStreamPacketFlushProtection = FALSE; // space for storing stream offsets m_rtOffset = (REFERENCE_TIME *)CoTaskMemAlloc(sizeof(REFERENCE_TIME) * m_lavfDemuxer->GetNumStreams()); if (!m_rtOffset) return E_OUTOFMEMORY; memset(m_rtOffset, 0, sizeof(REFERENCE_TIME) * m_lavfDemuxer->GetNumStreams()); DbgLog((LOG_TRACE, 20, L"Opened BD title with %d clips and %d chapters", m_pTitle->clip_count, m_pTitle->chapter_count)); return S_OK; }
HRESULT FreeLAVFrameBuffers(LAVFrame *pFrame) { CheckPointer(pFrame, E_POINTER); if (pFrame->destruct) { pFrame->destruct(pFrame); pFrame->destruct = nullptr; pFrame->priv_data = nullptr; } memset(pFrame->data, 0, sizeof(pFrame->data)); memset(pFrame->stereo, 0, sizeof(pFrame->stereo)); memset(pFrame->stride, 0, sizeof(pFrame->stride)); for (int i = 0; i < pFrame->side_data_count; i++) { SAFE_CO_FREE(pFrame->side_data[i].data); } SAFE_CO_FREE(pFrame->side_data); pFrame->side_data_count = 0; return S_OK; }
CBDDemuxer::~CBDDemuxer(void) { CloseMVCExtensionDemuxer(); if (m_pTitle) { bd_free_title_info(m_pTitle); m_pTitle = nullptr; } if (m_pBD) { bd_close(m_pBD); m_pBD = nullptr; } if (m_pb) { av_free(m_pb->buffer); av_free(m_pb); } SafeRelease(&m_lavfDemuxer); SAFE_CO_FREE(m_StreamClip); SAFE_CO_FREE(m_rtOffset); }
HRESULT CLAVAudio::InitBitstreaming() { // Alloc buffer for the AVIO context BYTE *buffer = (BYTE *)CoTaskMemAlloc(LAV_BITSTREAM_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if(!buffer) return E_OUTOFMEMORY; // Create AVIO context m_avioBitstream = avio_alloc_context(buffer, LAV_BITSTREAM_BUFFER_SIZE, 1, this, NULL, BSWriteBuffer, NULL); if(!m_avioBitstream) { SAFE_CO_FREE(buffer); return E_FAIL; } return S_OK; }
HRESULT CDecDXVA2::FindDecoderConfiguration(const GUID &input, const DXVA2_VideoDesc *pDesc, DXVA2_ConfigPictureDecode *pConfig) { CheckPointer(pConfig, E_INVALIDARG); CheckPointer(pDesc, E_INVALIDARG); HRESULT hr = S_OK; UINT cfg_count = 0; DXVA2_ConfigPictureDecode *cfg_list = NULL; hr = m_pDXVADecoderService->GetDecoderConfigurations(input, pDesc, NULL, &cfg_count, &cfg_list); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> GetDecoderConfigurations failed with hr: %X", hr)); return E_FAIL; } DbgLog((LOG_TRACE, 10, L"-> We got %d decoder configurations", cfg_count)); int best_score = 0; DXVA2_ConfigPictureDecode best_cfg; for (unsigned i = 0; i < cfg_count; i++) { DXVA2_ConfigPictureDecode *cfg = &cfg_list[i]; int score; if (cfg->ConfigBitstreamRaw == 1) score = 1; else if (m_pAVCtx->codec_id == AV_CODEC_ID_H264 && cfg->ConfigBitstreamRaw == 2) score = 2; else continue; if (IsEqualGUID(cfg->guidConfigBitstreamEncryption, DXVA2_NoEncrypt)) score += 16; if (score > best_score) { best_score = score; best_cfg = *cfg; } } SAFE_CO_FREE(cfg_list); if (best_score <= 0) { DbgLog((LOG_TRACE, 10, L"-> No matching configuration available")); return E_FAIL; } *pConfig = best_cfg; return S_OK; }
CBDDemuxer::~CBDDemuxer(void) { if (m_pTitle) { bd_free_title_info(m_pTitle); m_pTitle = NULL; } if (m_pBD) { bd_close(m_pBD); m_pBD = NULL; } if (m_pb) { av_free(m_pb->buffer); av_free(m_pb); } SafeRelease(&m_lavfDemuxer); SAFE_CO_FREE(m_rtOffset); }
HRESULT CLAVSplitterFormatsProp::OnActivate() { HRESULT hr = S_OK; INITCOMMONCONTROLSEX icc; icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_BAR_CLASSES | ICC_STANDARD_CLASSES; if (InitCommonControlsEx(&icc) == FALSE) { return E_FAIL; } ASSERT(m_pLAVF != nullptr); memset(stringBuffer, 0, sizeof(stringBuffer)); const char *pszInput = m_pLAVF->GetInputFormat(); if (pszInput) { _snwprintf_s(stringBuffer, _TRUNCATE, L"%S", pszInput); } SendDlgItemMessage(m_Dlg, IDC_CUR_INPUT, WM_SETTEXT, 0, (LPARAM)stringBuffer); m_Formats = m_pLAVF->GetInputFormats(); // Setup ListView control for format configuration SendDlgItemMessage(m_Dlg, IDC_FORMATS, CCM_DPISCALE, TRUE, 0); HWND hlv = GetDlgItem(m_Dlg, IDC_FORMATS); ListView_SetExtendedListViewStyle(hlv, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); int nCol = 1; LVCOLUMN lvc = {LVCF_WIDTH, 0, 20, 0}; ListView_InsertColumn(hlv, 0, &lvc); ListView_AddCol(hlv, nCol, 75, L"Format", false); ListView_AddCol(hlv, nCol, 210, L"Description", false); ListView_DeleteAllItems(hlv); ListView_SetItemCount(hlv, m_Formats.size()); SAFE_CO_FREE(m_bFormats); m_bFormats = (BOOL *)CoTaskMemAlloc(sizeof(BOOL) * m_Formats.size()); if (!m_bFormats) return E_OUTOFMEMORY; memset(m_bFormats, 0, sizeof(BOOL) * m_Formats.size()); // Create entries for the formats LVITEM lvi; memset(&lvi, 0, sizeof(lvi)); lvi.mask = LVIF_TEXT|LVIF_PARAM; int nItem = 0; std::set<FormatInfo>::const_iterator it; for (it = m_Formats.begin(); it != m_Formats.end(); ++it) { // Create main entry lvi.iItem = nItem + 1; ListView_InsertItem(hlv, &lvi); // Set sub item texts _snwprintf_s(stringBuffer, _TRUNCATE, L"%S", it->strName); ListView_SetItemText(hlv, nItem, 1, (LPWSTR)stringBuffer); _snwprintf_s(stringBuffer, _TRUNCATE, L"%S", it->strDescription); ListView_SetItemText(hlv, nItem, 2, (LPWSTR)stringBuffer); m_bFormats[nItem] = m_pLAVF->IsFormatEnabled(it->strName); ListView_SetCheckState(hlv, nItem, m_bFormats[nItem]); nItem++; } return hr; }
HRESULT CDecDXVA2::FindVideoServiceConversion(AVCodecID codec, GUID *input, D3DFORMAT *output) { HRESULT hr = S_OK; UINT count = 0; GUID *input_list = NULL; /* Gather the format supported by the decoder */ hr = m_pDXVADecoderService->GetDecoderDeviceGuids(&count, &input_list); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> GetDecoderDeviceGuids failed with hr: %X", hr)); goto done; } DbgLog((LOG_TRACE, 10, L"-> Enumerating supported DXVA2 modes (count: %d)", count)); for(unsigned i = 0; i < count; i++) { const GUID *g = &input_list[i]; const dxva2_mode_t *mode = DXVA2FindMode(g); if (mode) { DbgLog((LOG_TRACE, 10, L" -> %S", mode->name)); } else { DbgLog((LOG_TRACE, 10, L" -> Unknown GUID (%s)", WStringFromGUID(*g).c_str())); } } /* Iterate over our priority list */ for (unsigned i = 0; dxva2_modes[i].name; i++) { const dxva2_mode_t *mode = &dxva2_modes[i]; if (!mode->codec || mode->codec != codec) continue; BOOL supported = FALSE; for (const GUID *g = &input_list[0]; !supported && g < &input_list[count]; g++) { supported = IsEqualGUID(*mode->guid, *g); } if (!supported) continue; DbgLog((LOG_TRACE, 10, L"-> Trying to use '%S'", mode->name)); UINT out_count = 0; D3DFORMAT *out_list = NULL; hr = m_pDXVADecoderService->GetDecoderRenderTargets(*mode->guid, &out_count, &out_list); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> Retrieving render targets failed with hr: %X", hr)); continue; } BOOL hasNV12 = FALSE; DbgLog((LOG_TRACE, 10, L"-> Enumerating render targets (count: %d)", out_count)); for (unsigned j = 0; j < out_count; j++) { const D3DFORMAT f = out_list[j]; DbgLog((LOG_TRACE, 10, L" -> %d is supported (%4.4S)", f, (const char *)&f)); if (f == FOURCC_NV12) { hasNV12 = TRUE; } } if (hasNV12) { DbgLog((LOG_TRACE, 10, L"-> Found NV12, finished setup")); *input = *mode->guid; *output = (D3DFORMAT)FOURCC_NV12; SAFE_CO_FREE(out_list); SAFE_CO_FREE(input_list); return S_OK; } SAFE_CO_FREE(out_list); } done: SAFE_CO_FREE(input_list); return E_FAIL; }
STDMETHODIMP CBDDemuxer::SetTitle(int idx) { HRESULT hr = S_OK; int ret; // return values if (m_pTitle) { bd_free_title_info(m_pTitle); } // Init Event Queue bd_get_event(m_pBD, nullptr); // Select title m_pTitle = bd_get_title_info(m_pBD, idx, 0); ret = bd_select_title(m_pBD, idx); if (ret == 0) { return E_FAIL; } MPLS_PL * mpls = bd_get_title_mpls(m_pBD); if (mpls) { for (int i = 0; i < mpls->ext_sub_count; i++) { if (mpls->ext_sub_path[i].type == 8 && mpls->ext_sub_path[i].sub_playitem_count == mpls->list_count) { DbgLog((LOG_TRACE, 20, L"CBDDemuxer::SetTitle(): Enabling BD3D MVC demuxing")); DbgLog((LOG_TRACE, 20, L" -> MVC_Base_view_R_flag: %d", m_pTitle->mvc_base_view_r_flag)); m_MVCPlayback = TRUE; m_MVCExtensionSubPathIndex = i; break; } } } CloseMVCExtensionDemuxer(); if (m_pb) { av_free(m_pb->buffer); av_free(m_pb); } uint8_t *buffer = (uint8_t *)av_mallocz(BD_READ_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); m_pb = avio_alloc_context(buffer, BD_READ_BUFFER_SIZE, 0, this, BDByteStreamRead, nullptr, BDByteStreamSeek); SafeRelease(&m_lavfDemuxer); SAFE_CO_FREE(m_StreamClip); SAFE_CO_FREE(m_rtOffset); m_lavfDemuxer = new CLAVFDemuxer(m_pLock, m_pSettings); m_lavfDemuxer->AddRef(); m_lavfDemuxer->SetBluRay(this); if (FAILED(hr = m_lavfDemuxer->OpenInputStream(m_pb, nullptr, "mpegts", TRUE))) { SafeRelease(&m_lavfDemuxer); return hr; } if (m_MVCPlayback && !m_lavfDemuxer->m_bH264MVCCombine) { DbgLog((LOG_TRACE, 10, L"CBDDemuxer::SetTitle(): MVC demuxing was requested, but main demuxer did not activate MVC mode, disabling.")); CloseMVCExtensionDemuxer(); m_MVCPlayback = FALSE; } m_lavfDemuxer->SeekByte(0, 0); // Process any events that occured during opening ProcessBDEvents(); // Reset EOS protection m_EndOfStreamPacketFlushProtection = FALSE; // space for storing stream offsets m_StreamClip = (uint16_t *)CoTaskMemAlloc(sizeof(*m_StreamClip) * m_lavfDemuxer->GetNumStreams()); if (!m_StreamClip) return E_OUTOFMEMORY; memset(m_StreamClip, -1, sizeof(*m_StreamClip) * m_lavfDemuxer->GetNumStreams()); m_rtOffset = (REFERENCE_TIME *)CoTaskMemAlloc(sizeof(*m_rtOffset) * m_lavfDemuxer->GetNumStreams()); if (!m_rtOffset) return E_OUTOFMEMORY; memset(m_rtOffset, 0, sizeof(*m_rtOffset) * m_lavfDemuxer->GetNumStreams()); DbgLog((LOG_TRACE, 20, L"Opened BD title with %d clips and %d chapters", m_pTitle->clip_count, m_pTitle->chapter_count)); return S_OK; }
static void lav_free_lavframe(void *opaque, uint8_t *data) { LAVFrame *frame = (LAVFrame *)opaque; FreeLAVFrameBuffers(frame); SAFE_CO_FREE(opaque); }
CLAVSplitterFormatsProp::~CLAVSplitterFormatsProp(void) { SAFE_CO_FREE(m_bFormats); SafeRelease(&m_pLAVF); }