You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.0 KiB
175 lines
6.0 KiB
/*****************************************************************************
|
|
* d3d11_processor.c: D3D11 VideoProcessor helper
|
|
*****************************************************************************
|
|
* Copyright © 2017 VLC authors, VideoLAN and VideoLabs
|
|
*
|
|
* Authors: Steve Lhomme <robux4@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <vlc_filter.h>
|
|
#include <vlc_picture.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#define COBJMACROS
|
|
#include <initguid.h>
|
|
#include <d3d11.h>
|
|
|
|
#include "d3d11_processor.h"
|
|
|
|
#if defined(ID3D11VideoContext_VideoProcessorBlt)
|
|
#ifndef NDEBUG
|
|
static void LogProcessorSupport(vlc_object_t *o,
|
|
ID3D11VideoProcessorEnumerator *processorEnumerator)
|
|
{
|
|
UINT flags;
|
|
HRESULT hr;
|
|
for (int format = 0; format < 188; format++) {
|
|
hr = ID3D11VideoProcessorEnumerator_CheckVideoProcessorFormat(processorEnumerator, format, &flags);
|
|
if (FAILED(hr))
|
|
continue;
|
|
const char *name = DxgiFormatToStr(format);
|
|
const char *support = NULL;
|
|
if ((flags & (D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT|D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT))
|
|
== (D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT|D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT))
|
|
support = "input/output";
|
|
else if (flags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)
|
|
support = "input";
|
|
else if (flags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT)
|
|
support = "output";
|
|
if (support)
|
|
{
|
|
if (name)
|
|
msg_Dbg(o, "processor format %s is supported for %s", name, support);
|
|
else
|
|
msg_Dbg(o, "processor format (%d) is supported for %s", format, support);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#undef D3D11_CreateProcessor
|
|
int D3D11_CreateProcessor(vlc_object_t *o, d3d11_device_t *d3d_dev,
|
|
D3D11_VIDEO_FRAME_FORMAT srcFields,
|
|
const video_format_t *fmt_in, const video_format_t *fmt_out,
|
|
d3d11_processor_t *out)
|
|
{
|
|
HRESULT hr;
|
|
void *pv;
|
|
*out = (d3d11_processor_t) { 0 };
|
|
|
|
hr = ID3D11Device_QueryInterface(d3d_dev->d3ddevice, &IID_ID3D11VideoDevice, &pv);
|
|
if (FAILED(hr)) {
|
|
msg_Err(o, "Could not Query ID3D11VideoDevice Interface. (hr=0x%lX)", hr);
|
|
goto error;
|
|
}
|
|
out->d3dviddev = pv;
|
|
|
|
hr = ID3D11DeviceContext_QueryInterface(d3d_dev->d3dcontext, &IID_ID3D11VideoContext, &pv);
|
|
if (FAILED(hr)) {
|
|
msg_Err(o, "Could not Query ID3D11VideoContext Interface. (hr=0x%lX)", hr);
|
|
goto error;
|
|
}
|
|
out->d3dvidctx = pv;
|
|
|
|
D3D11_VIDEO_PROCESSOR_CONTENT_DESC processorDesc = {
|
|
.InputFrameFormat = srcFields,
|
|
.InputFrameRate = {
|
|
.Numerator = fmt_in->i_frame_rate_base ? fmt_in->i_frame_rate : 0,
|
|
.Denominator = fmt_in->i_frame_rate_base,
|
|
},
|
|
.InputWidth = fmt_in->i_width,
|
|
.InputHeight = fmt_in->i_height,
|
|
.OutputWidth = fmt_out->i_width,
|
|
.OutputHeight = fmt_out->i_height,
|
|
.OutputFrameRate = {
|
|
.Numerator = fmt_out->i_frame_rate_base ? fmt_out->i_frame_rate : 0,
|
|
.Denominator = fmt_out->i_frame_rate_base,
|
|
},
|
|
.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL,
|
|
};
|
|
hr = ID3D11VideoDevice_CreateVideoProcessorEnumerator(out->d3dviddev, &processorDesc, &out->procEnumerator);
|
|
if ( FAILED(hr) || out->procEnumerator == NULL )
|
|
{
|
|
msg_Dbg(o, "Can't get a video processor for the video.");
|
|
goto error;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
LogProcessorSupport(o, out->procEnumerator);
|
|
#endif
|
|
|
|
return VLC_SUCCESS;
|
|
error:
|
|
D3D11_ReleaseProcessor(out);
|
|
return VLC_ENOTSUP;
|
|
}
|
|
|
|
void D3D11_ReleaseProcessor(d3d11_processor_t *out)
|
|
{
|
|
if (out->videoProcessor)
|
|
{
|
|
ID3D11VideoProcessor_Release(out->videoProcessor);
|
|
out->videoProcessor = NULL;
|
|
}
|
|
if (out->procEnumerator)
|
|
{
|
|
ID3D11VideoProcessorEnumerator_Release(out->procEnumerator);
|
|
out->procEnumerator = NULL;
|
|
}
|
|
if (out->d3dviddev)
|
|
{
|
|
ID3D11VideoDevice_Release(out->d3dviddev);
|
|
out->d3dviddev = NULL;
|
|
}
|
|
if (out->d3dvidctx)
|
|
{
|
|
ID3D11VideoContext_Release(out->d3dvidctx);
|
|
out->d3dvidctx = NULL;
|
|
}
|
|
}
|
|
|
|
#undef D3D11_Assert_ProcessorInput
|
|
HRESULT D3D11_Assert_ProcessorInput(vlc_object_t *o, d3d11_processor_t *d3d_proc, picture_sys_d3d11_t *p_sys)
|
|
{
|
|
if (p_sys->processorInput)
|
|
return S_OK;
|
|
|
|
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inDesc = {
|
|
.FourCC = 0,
|
|
.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D,
|
|
.Texture2D.MipSlice = 0,
|
|
.Texture2D.ArraySlice = p_sys->slice_index,
|
|
};
|
|
HRESULT hr;
|
|
|
|
hr = ID3D11VideoDevice_CreateVideoProcessorInputView(d3d_proc->d3dviddev,
|
|
p_sys->resource[KNOWN_DXGI_INDEX],
|
|
d3d_proc->procEnumerator,
|
|
&inDesc,
|
|
&p_sys->processorInput);
|
|
#ifndef NDEBUG
|
|
if (FAILED(hr))
|
|
msg_Dbg(o,"Failed to create processor input for slice %d. (hr=0x%lX)", p_sys->slice_index, hr);
|
|
#endif
|
|
return hr;
|
|
}
|
|
#endif
|
|
|