How to Render TriangleList and LineList in same frame in dx11 - direct3d

How to Render TriangleList and LineList in same frame in dx11.
I tried to bind two sets of buffers to GPU.
Each buffer set contains one index_buffer and one vertices buffer.
And use ID3D11Device::DrawIndexed Function to Render the vertices.
I thought that to decide what polygon to render just simply call the ID3D11DeviceContext::IASetPrimitiveTopology function real-timely.
But it seems won't work.
There would be only one single line rendered.
How can I render both the triangle and the line in same frame ?
My code is based on dxsdk tutorials03 in" dx11 area".The code is as follows.I simply add a ray render class to render a line .
#pragma once
//RayRenderClass.h
#include<D3D11.h>
#include<D3DX11.h>
#include<D3DX10math.h>
struct PointClass
{
float _XYZ[3];
};
struct VertexClass
{
PointClass pts;
float nor[3];
float tex[3];
};
class RayRenderClass
{
public:
RayRenderClass();
~RayRenderClass();
HRESULT Initialize(ID3D11Device* device, ID3D11DeviceContext* context);
HRESULT Shutdown();
HRESULT Render(ID3D11Device* device, ID3D11DeviceContext* context);
HRESULT UpdateStartPosition(D3DXVECTOR3 st);
HRESULT UpdateEndPosition(D3DXVECTOR3 ed);
D3DXVECTOR3 GetStartPosition();
D3DXVECTOR3 GetEndPosition();
private:
ULONG indices[2];
VertexClass pts[2];
ID3D11Buffer* m_indexBuffer;
ID3D11Buffer* m_vertices;
};
#include "RayRenderClass.h"
//RayRenderClass.cpp
#define SAFE_RELEASE(x) if((x)){(x)->Release(); x= nullptr;}
RayRenderClass::RayRenderClass()
{
ZeroMemory(pts, sizeof(pts));
//start point
pts[0].pts._XYZ[0] = 0.0f;
pts[0].pts._XYZ[1] = 0.0f;
pts[0].pts._XYZ[2] = 0.0f;
//end point
pts[1].pts._XYZ[0] = 1.0f;
pts[1].pts._XYZ[1] = 0.0f;
pts[1].pts._XYZ[2] = 0.0f;
}
RayRenderClass::~RayRenderClass()
{
}
HRESULT RayRenderClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* context)
{
HRESULT hr = E_FAIL;
D3D11_BUFFER_DESC verticesDesc;
D3D11_BUFFER_DESC indexDesc;
D3D11_SUBRESOURCE_DATA verticesData;
D3D11_SUBRESOURCE_DATA indexData;
ZeroMemory(&verticesDesc, sizeof(verticesDesc));
verticesDesc.Usage = D3D11_USAGE_DYNAMIC;
verticesDesc.ByteWidth = sizeof(VertexClass)* 2;
verticesDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
verticesDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
ZeroMemory(&verticesData, sizeof(verticesData));
verticesData.pSysMem = &pts[0].pts._XYZ[0];
hr = device->CreateBuffer(&verticesDesc, &verticesData, &m_vertices);
if (FAILED(hr))
return hr;
ZeroMemory(&indexDesc, sizeof(indexDesc));
indexDesc.Usage = D3D11_USAGE_DEFAULT;
indexDesc.ByteWidth = sizeof(ULONG)* 2;
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
ZeroMemory(&indexData, sizeof(indexData));
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
hr = device->CreateBuffer(&indexDesc, &indexData, &m_indexBuffer);
if (FAILED(hr))
{
return hr;
}
return S_OK;
}
HRESULT RayRenderClass::Shutdown()
{
SAFE_RELEASE(m_vertices);
SAFE_RELEASE(m_indexBuffer);
return S_OK;
}
HRESULT RayRenderClass::UpdateStartPosition(D3DXVECTOR3 st)
{
HRESULT hr = E_FAIL;
pts[0].pts._XYZ[0] = st.x;
pts[0].pts._XYZ[1] = st.y;
pts[0].pts._XYZ[2] = st.z;
return hr;
}
HRESULT RayRenderClass::UpdateEndPosition(D3DXVECTOR3 ed)
{
HRESULT hr = E_FAIL;
pts[1].pts._XYZ[0] = ed.x;
pts[1].pts._XYZ[1] = ed.y;
pts[1].pts._XYZ[2] = ed.z;
return hr;
}
D3DXVECTOR3 RayRenderClass::GetStartPosition()
{
D3DXVECTOR3 ret = { pts[0].pts._XYZ };
return ret;
}
D3DXVECTOR3 RayRenderClass::GetEndPosition()
{
D3DXVECTOR3 ret = { pts[1].pts._XYZ };
return ret;
}
HRESULT RayRenderClass::Render(ID3D11Device* device, ID3D11DeviceContext* context)
{
HRESULT hr = E_FAIL;
D3D11_MAPPED_SUBRESOURCE mappedResource;
VertexClass* verticesPtr;
UINT stride = sizeof(VertexClass);
UINT offset = 0;
hr = context->Map(m_vertices, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr))
return hr;
verticesPtr = (VertexClass*)mappedResource.pData;
memcpy(verticesPtr, (void*)pts, (sizeof(VertexClass)* 2));
context->Unmap(m_vertices, 0);
context->IASetVertexBuffers(0, 1, &m_vertices, &stride, &offset);
context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
//D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
context->DrawIndexed(2, 0, 0);
return hr;
}
//--------------------------------------------------------------------------------------
// File: Tutorial03.cpp
//
// This application displays a triangle using Direct3D 11
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include "resource.h"
#include "RayRenderClass.h"
//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct SimpleVertex
{
XMFLOAT3 Pos;
};
//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = NULL;
ID3D11DeviceContext* g_pImmediateContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;
ID3D11InputLayout* g_pVertexLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;
ID3D11Buffer* g_index = NULL;
RayRenderClass m_ray;
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
if( FAILED( InitDevice() ) )
{
CleanupDevice();
return 0;
}
// Main message loop
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
CleanupDevice();
return ( int )msg.wParam;
}
//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;
// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 3: Shaders",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
return S_OK;
}
//--------------------------------------------------------------------------------------
// Helper for compiling shaders with D3DX11
//--------------------------------------------------------------------------------------
HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
HRESULT hr = S_OK;
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pErrorBlob;
hr = D3DX11CompileFromFile( szFileName, NULL, NULL, szEntryPoint, szShaderModel,
dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
if( FAILED(hr) )
{
if( pErrorBlob != NULL )
OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
if( pErrorBlob ) pErrorBlob->Release();
return hr;
}
if( pErrorBlob ) pErrorBlob->Release();
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
HRESULT hr = S_OK;
RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE( driverTypes );
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE( featureLevels );
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
if( SUCCEEDED( hr ) )
break;
}
if( FAILED( hr ) )
return hr;
// Create a render target view
ID3D11Texture2D* pBackBuffer = NULL;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
if( FAILED( hr ) )
return hr;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return hr;
g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );
// Compile the vertex shader
ID3DBlob* pVSBlob = NULL;
hr = CompileShaderFromFile( L"Tutorial03.fx", "VS", "vs_4_0", &pVSBlob );
if( FAILED( hr ) )
{
MessageBox( NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the vertex shader
hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
if( FAILED( hr ) )
{
pVSBlob->Release();
return hr;
}
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE( layout );
// Create the input layout
hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
return hr;
// Set the input layout
g_pImmediateContext->IASetInputLayout( g_pVertexLayout );
// Compile the pixel shader
ID3DBlob* pPSBlob = NULL;
hr = CompileShaderFromFile( L"Tutorial03.fx", "PS", "ps_4_0", &pPSBlob );
if( FAILED( hr ) )
{
MessageBox( NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the pixel shader
hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
pPSBlob->Release();
if( FAILED( hr ) )
return hr;
// Create vertex buffer
SimpleVertex vertices[] =
{
XMFLOAT3( 0.0f, 0.5f, 0.5f ),
XMFLOAT3( 0.5f, -0.5f, 0.5f ),
XMFLOAT3( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
D3D11_BUFFER_DESC indexDesc;
D3D11_SUBRESOURCE_DATA indexData;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
UINT indices[] = {0,1,2};
ZeroMemory(&indexDesc, sizeof(indexDesc));
indexDesc.Usage = D3D11_USAGE_DEFAULT;
indexDesc.ByteWidth = sizeof(ULONG)* 3;
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
ZeroMemory(&indexData, sizeof(indexData));
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer(&indexDesc, &indexData, &g_index);
if (FAILED(hr))
{
return hr;
}
m_ray.Initialize(g_pd3dDevice, g_pImmediateContext);
return S_OK;
}
//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
if( g_pImmediateContext ) g_pImmediateContext->ClearState();
if( g_pVertexBuffer ) g_pVertexBuffer->Release();
if( g_pVertexLayout ) g_pVertexLayout->Release();
if( g_pVertexShader ) g_pVertexShader->Release();
if( g_pPixelShader ) g_pPixelShader->Release();
if( g_pRenderTargetView ) g_pRenderTargetView->Release();
if( g_pSwapChain ) g_pSwapChain->Release();
if( g_pImmediateContext ) g_pImmediateContext->Release();
if( g_pd3dDevice ) g_pd3dDevice->Release();
}
//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
switch( message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
// Clear the back buffer
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
g_pImmediateContext->IASetIndexBuffer(g_index, DXGI_FORMAT_R32_UINT, 0);
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Render a triangle
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->DrawIndexed( 3, 0 ,0);
// Present the information rendered to the back buffer to the front buffer (the screen)
m_ray.Render(g_pd3dDevice, g_pImmediateContext);
g_pSwapChain->Present(0, 0);
}

In your render method, you don't set the vertex buffer for your triangle (only on initialization), so by calling
m_ray.Render(g_pd3dDevice, g_pImmediateContext);
You permanently set the pipeline to use your line buffer instead.
Make sure that the following line is called within your render function, to properly assign your triangle before the draw:
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
For you ray, you should not even need an index buffer, you can get rid of it and use:
g_pImmediateContext->Draw(2,0);
For the same effect

Related

WCHAR* not compatible with "LPSTR" parameter. In wsprintf C++

Can't compile the following code in C++ with Visual Studio 2017 (Got it from: Source Code):
#include <Wincodec.h> // we use WIC for saving images
#include <d3d9.h> // DirectX 9 header
#pragma comment(lib, "d3d9.lib") // link to DirectX 9 library
#include <stdio.h>
#include <Windows.h>
#include <wchar.h>
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#define HRCHECK(__expr) {hr=(__expr);if(FAILED(hr)){wprintf(L"FAILURE 0x%08X (%i)\n\tline: %u file: '%s'\n\texpr: '" WIDEN(#__expr) L"'\n",hr, hr, __LINE__,__WFILE__);goto cleanup;}}
#define RELEASE(__p) {if(__p!=nullptr){__p->Release();__p=nullptr;}}
HRESULT SavePixelsToFile32bppPBGRA(UINT width, UINT height, UINT stride, LPBYTE pixels, LPWSTR filePath, const GUID &format)
{
if (!filePath || !pixels)
return E_INVALIDARG;
HRESULT hr = S_OK;
IWICImagingFactory *factory = nullptr;
IWICBitmapEncoder *encoder = nullptr;
IWICBitmapFrameEncode *frame = nullptr;
IWICStream *stream = nullptr;
GUID pf = GUID_WICPixelFormat32bppPBGRA;
BOOL coInit = CoInitialize(nullptr);
HRCHECK(CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)));
HRCHECK(factory->CreateStream(&stream));
HRCHECK(stream->InitializeFromFilename(filePath, GENERIC_WRITE));
HRCHECK(factory->CreateEncoder(format, nullptr, &encoder));
HRCHECK(encoder->Initialize(stream, WICBitmapEncoderNoCache));
HRCHECK(encoder->CreateNewFrame(&frame, nullptr)); // we don't use options here
HRCHECK(frame->Initialize(nullptr)); // we dont' use any options here
HRCHECK(frame->SetSize(width, height));
HRCHECK(frame->SetPixelFormat(&pf));
HRCHECK(frame->WritePixels(height, stride, stride * height, pixels));
HRCHECK(frame->Commit());
HRCHECK(encoder->Commit());
cleanup:
RELEASE(stream);
RELEASE(frame);
RELEASE(encoder);
RELEASE(factory);
if (coInit) CoUninitialize();
return hr;
}
HRESULT Direct3D9TakeScreenshots(UINT adapter, UINT count)
{
HRESULT hr = S_OK;
IDirect3D9 *d3d = nullptr;
IDirect3DDevice9 *device = nullptr;
IDirect3DSurface9 *surface = nullptr;
D3DPRESENT_PARAMETERS parameters = { 0 };
D3DDISPLAYMODE mode;
D3DLOCKED_RECT rc;
UINT pitch;
SYSTEMTIME st;
LPBYTE *shots = nullptr;
// init D3D and get screen size
d3d = Direct3DCreate9(D3D_SDK_VERSION);
HRCHECK(d3d->GetAdapterDisplayMode(adapter, &mode));
parameters.Windowed = TRUE;
parameters.BackBufferCount = 1;
parameters.BackBufferHeight = mode.Height;
parameters.BackBufferWidth = mode.Width;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.hDeviceWindow = NULL;
// create device & capture surface
HRCHECK(d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &device));
HRCHECK(device->CreateOffscreenPlainSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, nullptr));
// compute the required buffer size
HRCHECK(surface->LockRect(&rc, NULL, 0));
pitch = rc.Pitch;
HRCHECK(surface->UnlockRect());
// allocate screenshots buffers
shots = new LPBYTE[count];
for (UINT i = 0; i < count; i++)
{
shots[i] = new BYTE[pitch * mode.Height];
}
GetSystemTime(&st); // measure the time we spend doing <count> captures
wprintf(L"%i:%i:%i.%i\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
for (UINT i = 0; i < count; i++)
{
// get the data
HRCHECK(device->GetFrontBufferData(0, surface));
// copy it into our buffers
HRCHECK(surface->LockRect(&rc, NULL, 0));
CopyMemory(shots[i], rc.pBits, rc.Pitch * mode.Height);
HRCHECK(surface->UnlockRect());
}
GetSystemTime(&st);
wprintf(L"%i:%i:%i.%i\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
// save all screenshots
for (UINT i = 0; i < count; i++)
{
WCHAR file[100];
wsprintf(file, L"cap%i.png", i);
HRCHECK(SavePixelsToFile32bppPBGRA(mode.Width, mode.Height, pitch, shots[i], file, GUID_ContainerFormatPng));
}
cleanup:
if (shots != nullptr)
{
for (UINT i = 0; i < count; i++)
{
delete shots[i];
}
delete[] shots;
}
RELEASE(surface);
RELEASE(device);
RELEASE(d3d);
return hr;
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = Direct3D9TakeScreenshots(D3DADAPTER_DEFAULT, 10);
return 0;
}
Gives error at:
// save all screenshots
for (UINT i = 0; i < count; i++)
{
WCHAR file[100];
wsprintf(file, L"cap%i.png", i);
HRCHECK(SavePixelsToFile32bppPBGRA(mode.Width, mode.Height, pitch, shots[i], file, GUID_ContainerFormatPng));
}
Where:
"WCHAR file[100]" is not compatible with "LSPTR" on wsprintf.
L"cap%i.png" (const wchar_t) is not compatible with LPCSTR on wsprintf.
And in:
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = Direct3D9TakeScreenshots(D3DADAPTER_DEFAULT, 10);
return 0;
}
Where _TCHAR is not defined.
¡I'm new to C++ so please give me some hints!

Remote Code injection in Win 7 SP 1 using NtCreateThreadEx API

I am trying to learn how to inject code into a running process using NtCreateThreadEx. I found few tutorials online and tried the code shown below which basically tries to inject a piece of code to a a running notepad.exe. Code injection to notepad.exe was successful; however, this program crashes just after injection (i.e., after calling funNtCreateThreadEx) throwing following error:
Run-Time Check Failure #2 - Stack around the variable 'temp2' was corrupted.
Could someone help me explaining why I am getting this error? I tried to Google about this error and figured out its something related to memory overflow. However, I don't see any memory overflow in this following code. Please let me know what could be the reason for the above error. Thank you so much for your time.
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter);
typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx)
(
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN DWORD StackZeroBits,
IN DWORD SizeOfStackCommit,
IN DWORD SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
struct NtCreateThreadExBuffer
{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter) {
HMODULE modNtDll = LoadLibrary(L"ntdll.dll");
if (!modNtDll) {
std::cout << "Error loading ntdll.dll" << std::endl;
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)GetProcAddress(modNtDll, "NtCreateThreadEx");
if (!funNtCreateThreadEx) {
std::cout << "Error loading NtCreateThreadEx()" << std::endl;
return 0;
}
NtCreateThreadExBuffer ntbuffer;
memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
// ntbuffer.Unknown8 = 0;
HANDLE hThread;
NTSTATUS status = funNtCreateThreadEx(
&hThread,
0x1FFFFF,
NULL,
process,
(LPTHREAD_START_ROUTINE)Start,
lpParameter,
FALSE, //start instantly
0, //null
0, //null
0, //null
&ntbuffer
);
return hThread;
}
int main()
{
int res = -1;
res = privileges(); //get all required privileges
DWORD pid = getPid(L"notepad.exe");
if (pid == 0)
return PROCESS_NOT_FOUND; //error
HANDLE p;
p = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (p == NULL) return OPEN_PROCESS_FAILED; //error
char * mytext = "Hello by CodeCave!";
char * mycaption = "Injection result";
PARAMETERS data; //let's fill in a PARAMETERS struct
HMODULE user32 = LoadLibrary(L"User32.dll");
data.MessageBoxInj = (DWORD)GetProcAddress(user32, "MessageBoxA");
strcpy_s(data.text, mytext);
strcpy_s(data.caption, mycaption);
data.buttons = MB_OKCANCEL | MB_ICONQUESTION;
//Writing funtion to notepad memory
DWORD size_myFunc = 0x8000; //Creating more memory than required
LPVOID MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(p, MyFuncAddress, (void*)myFunc, 0x1000, NULL);
//Parameters to the function to notepad's memory
LPVOID DataAddress = VirtualAllocEx(p, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(p, DataAddress, &data, sizeof(PARAMETERS), NULL);
//invokes injected function
HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress);
if (thread != 0) {
//injection completed, not we can wait it to end and free the memory
}
return 0;
}
static DWORD myFunc(PARAMETERS * myparam) {
MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
switch (result) {
case IDOK:
//your code
break;
case IDCANCEL:
//your code
break;
}
return 0;
}
int privileges() {
HANDLE Token;
TOKEN_PRIVILEGES tp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL) == 0) {
return 1; //FAIL
}
else {
return 0; //SUCCESS
}
}
return 1;
}
typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);
struct PARAMETERS {
DWORD MessageBoxInj;
char text[50];
char caption[25];
int buttons;
};
DWORD myFunc(PARAMETERS * myparam);

how to read text file and show it on edit control in win 32 unicode character set?

i have been making a program to read the text from a text file on a button click and show it on the edit control. when the button is clicked, the dialog box opens to select the text file and clicking on ok, it should display on edit control but i am not getting the text in proper format.
this is the output : output image from visual studio
#include <windows.h>
const wchar_t g_szClassName[] = { L"myWindowClass" };
#define IDC_MAIN_EDIT 101
#define IDC_MAIN_BUTTON 102
#define IDC_MAIN_BUTTON1 103
BOOL LoadTextFileToEdit(HWND hEdit, LPTSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;
hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != 0xFFFFFFFF)
{
wchar_t* pszFileText;
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
if (pszFileText != NULL)
{
DWORD dwRead;
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
{
pszFileText[dwFileSize] = 0 ; // Add null terminator
if (SetWindowText(hEdit, (LPCWSTR)pszFileText))
bSuccess = TRUE; // It worked!
}
GlobalFree(pszFileText);
}
}
CloseHandle(hFile);
}
return bSuccess;
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
HFONT hfont;
HWND hedit,button,btnsave;
hedit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"My Own Window", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_MULTILINE
, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
button = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Open File", WS_CHILD | WS_VISIBLE|WS_BORDER|WS_TABSTOP
,CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON, GetModuleHandle(NULL), NULL);
btnsave = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Save File", WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE|WS_TABSTOP
, CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON1, GetModuleHandle(NULL), NULL);
if (hedit == NULL)
{
MessageBox(NULL, L"Could not create edit box", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hedit, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(FALSE, 0));
//SetWindowText(button, L"Open File");
//SetWindowText(btnsave, L"Save File");
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_MAIN_BUTTON:
{
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
{
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
LoadTextFileToEdit(hedit, szFileName);
}
}
break;
case IDC_MAIN_BUTTON1:
{
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
{
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
}
}
break;
default:
break;
}
break;
case WM_SIZE:
{
HWND hEdit,button,btnsave;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
button = GetDlgItem(hwnd, IDC_MAIN_BUTTON);
btnsave = GetDlgItem(hwnd, IDC_MAIN_BUTTON1);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom-120, SWP_NOZORDER);
SetWindowPos(button, NULL, rcClient.right-200, rcClient.bottom-30, 70, 30, SWP_NOZORDER);
SetWindowPos(btnsave, NULL, rcClient.right - 100, rcClient.bottom - 30, 70, 30, SWP_NOZORDER);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
//step 1: registering the window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
//step 2: Creating the Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
g_szClassName, L"The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300,
NULL, NULL, hinstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
//Step-3: the message loop
while (GetMessage(&msg, NULL, 0, 0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
i got the answer to my question. Actually in unicode wide string a character is of 2 bytes so we need to allocate twice the memory. so replace :
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
with
pszFileText = (wchar_t*)GlobalAlloc(GPTR, 2*(dwFileSize + 1));
and
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
with
if (ReadFile(hFile, (LPVOID)pszFileText, 2*(dwFileSize+1), &dwRead, NULL))

Multithread decoding of Video PID of Mpeg2Ts using FFMPEG

I'm working on an app in VC++ to display video frames of a video Pid of mpeg2ts stream using FFMPEG and need to do the same, for other mpeg2stream simultaneously by using multi thread process,my source code is:
int main (int argc, char* argv[])
{
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("Couldn't open input stream.\n");
return -1;
}
if(avformat_find_stream_info(pFormatCtx,NULL)<0){
printf("Couldn't find stream information.\n");
return -1;
}
videoindex=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
videoindex=i;
break;
}
if(videoindex==-1){
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
printf("Codec not found.\n");
return -1;
}
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
printf("Could not open codec.\n");
return -1;
}
pFrame=av_frame_alloc();
pFrameYUV=av_frame_alloc();
out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
packet=(AVPacket *)av_malloc(sizeof(AVPacket));
//Output Info-----------------------------
printf("--------------- File Information ----------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
#if OUTPUT_YUV420P
fp_yuv=fopen("output.yuv","wb+");
#endif
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
//SDL 2.0 Support for multiple windows
screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h, SDL_WINDOW_OPENGL);
if(!screen) {
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());
return -1;
}
sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
//IYUV: Y + U + V (3 planes)
//YV12: Y + V + U (3 planes)
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);
sdlRect.x=0;
sdlRect.y=0;
sdlRect.w=screen_w;
sdlRect.h=screen_h;
//SDL End----------------------
BYTE buffer [4] ;
int nSize = 0 ;
int nByteCnt = 0 ;
int nPreviuosPos = 0 ;
mpgfile = fopen ("D:\\00_Projects\\Farzan II\\SampleData\\Yahsat1996V_N_PID(2101).pes", "rb");
while(av_read_frame(pFormatCtx, packet)>=0 /*&& nSize > 0*/)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0)
{
printf("Decode Error.\n");
return -1;
}
if(got_picture)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
#if 0
SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );
#else
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
pFrameYUV->data[0], pFrameYUV->linesize[0],
pFrameYUV->data[1], pFrameYUV->linesize[1],
pFrameYUV->data[2], pFrameYUV->linesize[2]);
#endif
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
}
av_free_packet(packet);
}
//flush decoder
//FIX: Flush Frames remained in Codec
while (1) {
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
break;
if (!got_picture)
break;
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
int y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
sws_freeContext(img_convert_ctx);
#if OUTPUT_YUV420P
fclose(fp_yuv);
#endif
SDL_Quit();
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
it works well when i call it in One thread but,after calling this function in multi thread ,the error of access violation occurred , is there anyone to guide me to solution?

GetOutputAvailableType() returns MF_E_TRANSFORM_TYPE_NOT_SET

I am trying to decode h264 video from my camera I have configured the decoder as follows.
I am not able to figure out why GetOutputAvailableType() function returns MF_E_TRANSFORM_TYPE_NOT_SET.I have also noticed that GetStreamIDs() returns E_NOTIMPL. I have checked in msdn it is given "MFT has a fixed number of streams, and \n the stream identifiers are consecutive starting from zero.".Can some body also explain what does this means?
HRESULT CH264_decodingDlg::ConfugureDecoder(IMFTransform *pDecoder)
{
HRESULT hr = S_OK;
IMFMediaType* pMediaTypeInput = NULL;
//Creating Input Media Type
hr = MFCreateMediaType(&pMediaTypeInput);
if (FAILED(hr)) return hr;
DWORD dwIn = 0,dwOut = 0;
hr = pDecoder->GetStreamCount(&dwIn,&dwOut);
if (FAILED(hr)) return hr;
if (dwIn)
{
DWORD dwInputID[2] ={0} ;
DWORD dwOutputID[2]= {0};
hr = pDecoder->GetStreamIDs(dwIn,dwInputID,dwOut,dwOutputID);
//if (FAILED(hr)) return hr;
GUID guidCurrent;
GUID guidMajor;
for (int i = 0; i< 8; i++)
{
hr = pDecoder->GetInputAvailableType(0,i,&pMediaTypeInput);
hr = pMediaTypeInput->GetGUID(MF_MT_MAJOR_TYPE, &guidMajor);
if (guidMajor == MFMediaType_Video) //safety check
{
if (hr == MF_E_NO_MORE_TYPES)
{
break;
}
hr = pMediaTypeInput->GetGUID( MF_MT_SUBTYPE, &guidCurrent );
if ( guidCurrent == MFVideoFormat_H264 ) //m_pVideoSubtype = MEDIASUBTYPE_WVC1
{
break;
}
}
}
// Set MF_MT_MAJOR_TYPE
hr = pMediaTypeInput->SetGUID(MF_MT_MAJOR_TYPE ,MFMediaType_Video);
if (FAILED(hr)) return hr;
// Set MF_MT_SUBTYPE
hr = pMediaTypeInput->SetGUID(MF_MT_SUBTYPE ,MFVideoFormat_H264);
if (FAILED(hr)) return hr;
// Set MF_MT_FRAME_RATE
UINT32 nNumerator = 30;
UINT32 nDenominator = 1;
hr = MFSetAttributeRatio(pMediaTypeInput,MF_MT_FRAME_RATE ,nNumerator,nDenominator);
if (FAILED(hr)) return hr;
// Set MF_MT_FRAME_SIZE
UINT32 nWidth = 640 ;
UINT32 nHeight = 480;
hr = MFSetAttributeSize(pMediaTypeInput, MF_MT_FRAME_SIZE, nWidth, nHeight);
if (FAILED(hr)) return hr;
// Set MF_MT_MPEG2_PROFILE
hr = pMediaTypeInput->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Base);
if (FAILED(hr)) return hr;
// Set MF_MT_INTERLACE_MODE
hr = pMediaTypeInput->SetUINT32(MF_MT_INTERLACE_MODE ,MFVideoInterlace_Progressive);
if (FAILED(hr)) return hr;
// Set MF_MT_PIXEL_ASPECT_RATIO
hr = MFSetAttributeRatio(pMediaTypeInput,MF_MT_PIXEL_ASPECT_RATIO,1,1);
if (FAILED(hr)) return hr;
//Set Input Media Type
hr = pDecoder->SetInputType(0,pMediaTypeInput,MFT_SET_TYPE_TEST_ONLY);
if (FAILED(hr)) return hr;
//Creating Output Media Type
IMFMediaType* pMediaTypeOutput = NULL;
hr = MFCreateMediaType(&pMediaTypeOutput);
if (FAILED(hr)) return hr;
hr = pDecoder->GetOutputAvailableType(0,0,&pMediaTypeOutput);
if (FAILED(hr)) return hr;`
Before you can get output media type, you have to set input media type. I don't see you are doing this (SetInputType is called with MFT_SET_TYPE_TEST_ONLY).

Resources