-
-
Save roxlu/e7ef81b14d285069c719 to your computer and use it in GitHub Desktop.
CoCreateInstance for Intel Quick Sync MFT fails.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1. Download these files | |
2. Make sure you have Visual Studio installed (I'm testing with 2015 community edition) | |
3. Make sure you have CMake installed | |
4. Open an Command Prompt, go to the directory with the downloaded files: | |
mkdir build | |
cd build | |
cmake -DCMAKE_INSTALL_PREFIX=../install .. | |
cmake --build . --target install | |
5. Then execute the created file 'install/test_h264_encoding.exe' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 2.8) | |
project(h264encoding) | |
set(bd ${CMAKE_CURRENT_LIST_DIR}) | |
set(sd ${bd}) | |
set(id ${bd}) | |
include_directories( | |
${id} | |
) | |
set(lib_sources | |
${sd}/VideoEncoderMediaFoundation.cpp | |
${sd}/Log.cpp | |
) | |
set(app_libs | |
Mfplat.lib | |
Mfuuid.lib | |
) | |
add_library(encoding ${lib_sources}) | |
add_executable(test_h264_encoding ${sd}/test_h264_encoding.cpp) | |
target_link_libraries(test_h264_encoding encoding ${app_libs}) | |
add_dependencies(test_h264_encoding encoding) | |
install(TARGETS test_h264_encoding DESTINATION bin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Log.h> | |
#include <sstream> | |
#if defined(_WIN32) | |
# include <stdarg.h> | |
# include <time.h> | |
# include <Winsock2.h> | |
#elif defined(__linux) | |
# include <stdarg.h> | |
# include <sys/time.h> | |
#else | |
# include <sys/time.h> | |
#endif | |
#if defined(__APPLE__) | |
# include <TargetConditionals.h> | |
#endif | |
namespace poly { | |
Log poly_log; | |
int poly_log_initialized_flag = -1; | |
/* --------------------------------------------------------------------------------- */ | |
/* @todo - cleanup the if()s around the ofs file writes. */ | |
Log::Log() | |
:write_to_stdout(true) | |
,write_to_file(true) | |
,use_colors(true) | |
,level(SX_LOG_LEVEL_ALL) | |
{ | |
#if defined(_WIN32) | |
console_handle = GetStdHandle(STD_OUTPUT_HANDLE); | |
#endif | |
} | |
Log::~Log() { | |
if (ofs.is_open()) { | |
ofs.close(); | |
} | |
write_to_stdout = false; | |
write_to_file = false; | |
use_colors = false; | |
} | |
int Log::open(std::string filep) { | |
if (false == write_to_file) { | |
return 0; | |
} | |
if (0 != filepath.size()) { | |
printf("Error: trying to open the log file but it's already open? Calling poly_log_init() twice?\n"); | |
return -1; | |
} | |
filepath = filep; | |
if (0 == filepath.size()) { | |
printf("Error: cannot open the log filepath because the string is empty.\n"); | |
return -2; | |
} | |
ofs.open(filepath.c_str(), std::ios::out | std::ios::app); | |
if (!ofs.is_open()) { | |
printf("Error: cannot open the log file. No permission? %s\n", filepath.c_str()); | |
return -3; | |
} | |
return 0; | |
} | |
void Log::log(int inlevel, int line, const char* function, const char* fmt, va_list args) { | |
if (inlevel > level) { | |
return; | |
} | |
static char buffer[1024 * 8]; /* should be big enough ;-) */ | |
std::string slevel; | |
std::stringstream ss_stdout; | |
std::string color_msg_open; | |
std::string color_info_open; | |
std::string color_close; | |
if (true == write_to_file) { | |
if (false == ofs.is_open()) { | |
printf("Error: cannot log because the file hasn't been opened. Did you call poly_log_init()?\n"); | |
return; | |
} | |
} | |
/* Get the date-time string. */ | |
#if defined(_WIN32) | |
int milli = (int)GetTickCount(); | |
#else | |
timeval miltime; | |
gettimeofday(&miltime, NULL); | |
int milli = miltime.tv_usec / 1000; | |
#endif | |
time_t t; | |
struct tm* info; | |
char time_buf[256]; | |
time(&t); | |
info = localtime(&t); | |
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", info); | |
sprintf(time_buf, "%s.%03d", time_buf, milli); | |
std::string time_str(time_buf); | |
/* default colors. */ | |
#if defined(_WIN32) || TARGET_OS_IPHONE | |
color_close = ""; | |
color_info_open = ""; | |
#else | |
if (true == use_colors) { | |
color_close = "\e[0m"; | |
color_info_open = "\e[90m"; | |
} | |
#endif | |
vsprintf(buffer, fmt, args); | |
if (write_to_file) { | |
ofs << time_str << " " ; | |
} | |
if (inlevel == SX_LOG_LEVEL_DEBUG) { | |
slevel = " debug "; | |
#if !defined(_WIN32) && !TARGET_OS_IPHONE | |
if (true == use_colors) { | |
color_msg_open = "\e[36m"; | |
} | |
#endif | |
if (write_to_file) { | |
ofs << slevel; | |
} | |
} | |
else if (inlevel == SX_LOG_LEVEL_VERBOSE) { | |
slevel = " verbose "; | |
if (write_to_file) { | |
ofs << slevel; | |
} | |
#if !defined(_WIN32) && !TARGET_OS_IPHONE | |
if (true == use_colors) { | |
color_msg_open = "\e[92m"; | |
} | |
#endif | |
} | |
else if (inlevel == SX_LOG_LEVEL_WARNING) { | |
slevel = " warning "; | |
#if !defined(_WIN32) && !TARGET_OS_IPHONE | |
if (true == use_colors) { | |
color_msg_open = "\e[93m"; | |
} | |
#endif | |
if (write_to_file) { | |
ofs << slevel; | |
} | |
} | |
else if (inlevel == SX_LOG_LEVEL_ERROR) { | |
slevel = " <<ERROR>> "; | |
#if !defined(_WIN32) && !TARGET_OS_IPHONE | |
if (true == use_colors) { | |
color_msg_open = "\e[31m"; | |
} | |
#endif | |
if (write_to_file) { | |
ofs << slevel; | |
} | |
} | |
if (write_to_file) { | |
ofs << " [" << function << ":" << line << "] = " << buffer << "\n"; | |
} | |
if (write_to_stdout) { | |
#if 0 | |
ss << time_str << ":" | |
<< slevel | |
<< "[" << function << ":" << line << "]" | |
<< " = " << buffer | |
<< std::endl; | |
#endif | |
#if defined(_WIN32) | |
SetConsoleTextAttribute(console_handle, 8); | |
printf("%s%10.10s[%90.90s:%03d]: ", | |
time_str.c_str(), | |
slevel.c_str(), | |
function, | |
line); | |
if (SX_LOG_LEVEL_DEBUG == inlevel) { | |
SetConsoleTextAttribute(console_handle, 11); | |
} | |
else if (SX_LOG_LEVEL_VERBOSE == inlevel) { | |
SetConsoleTextAttribute(console_handle, 10); | |
} | |
else if (SX_LOG_LEVEL_WARNING == inlevel) { | |
SetConsoleTextAttribute(console_handle, 14); | |
} | |
else if (SX_LOG_LEVEL_ERROR == inlevel) { | |
SetConsoleTextAttribute(console_handle, 12); | |
} | |
else { | |
SetConsoleTextAttribute(console_handle, 11);; | |
} | |
printf("%s\n", buffer); | |
SetConsoleTextAttribute(console_handle, 7); | |
#else | |
printf("%s %s %15s [%80.80s : %03d]: %s %s %s\n", | |
color_info_open.c_str(), | |
time_str.c_str(), | |
slevel.c_str(), | |
function, | |
line, | |
color_msg_open.c_str(), | |
buffer, | |
color_close.c_str()); | |
/* | |
ss_stdout << color_info_open | |
<< time_str << ":" | |
<< slevel | |
<< "[" << function << ":" << line << "]" | |
<< " = " | |
<< color_msg_open | |
<< buffer | |
<< color_close | |
<< std::endl; | |
*/ | |
//printf("%s", ss_stdout.str().c_str()); | |
#endif | |
} | |
if (write_to_file) { | |
ofs.flush(); | |
} | |
} | |
/* --------------------------------------------------------------------------------- */ | |
int poly_log_init(std::string path) { | |
std::stringstream ss; | |
std::string filepath = ""; | |
char buf[4096]; | |
time_t t; | |
struct tm* info; | |
time(&t); | |
info = localtime(&t); | |
strftime(buf, 4096, "%Y.%m.%d", info); | |
if (0 == path.size()) { | |
filepath = "./"; | |
} | |
else { | |
filepath = path +"/"; | |
} | |
ss << filepath << "log-" << buf << ".log"; | |
filepath = ss.str(); | |
poly_log_initialized_flag = poly_log.open(filepath); | |
return poly_log_initialized_flag; | |
} | |
int poly_log_is_initialized() { | |
return poly_log_initialized_flag; | |
} | |
void poly_log_disable_stdout() { | |
poly_log.write_to_stdout = false; | |
} | |
void poly_log_enable_stdout() { | |
poly_log.write_to_stdout = false; | |
} | |
void poly_log_enable_colors() { | |
poly_log.use_colors = true; | |
} | |
void poly_log_disable_colors() { | |
poly_log.use_colors = false; | |
} | |
void poly_log_disable_log_to_file() { | |
poly_log.write_to_file = false; | |
} | |
void poly_log_enable_log_to_file() { | |
poly_log.write_to_file = true; | |
} | |
void poly_log_set_level(int level) { | |
poly_log.level = level; | |
} | |
int poly_log_get_level() { | |
return poly_log.level; | |
} | |
void poly_debug(int line, const char* function, const char* fmt, ...) { | |
va_list args; | |
va_start(args, fmt); | |
poly_log.log(SX_LOG_LEVEL_DEBUG, line, function, fmt, args); | |
va_end(args); | |
} | |
void poly_verbose(int line, const char* function, const char* fmt, ...) { | |
va_list args; | |
va_start(args, fmt); | |
poly_log.log(SX_LOG_LEVEL_VERBOSE, line, function, fmt, args); | |
va_end(args); | |
} | |
void poly_warning(int line, const char* function, const char* fmt, ...) { | |
va_list args; | |
va_start(args, fmt); | |
poly_log.log(SX_LOG_LEVEL_WARNING, line, function, fmt, args); | |
va_end(args); | |
} | |
void poly_error(int line, const char* function, const char* fmt, ...) { | |
va_list args; | |
va_start(args, fmt); | |
poly_log.log(SX_LOG_LEVEL_ERROR, line, function, fmt, args); | |
va_end(args); | |
} | |
} /* namespace poly */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -*-c++-*- */ | |
/* | |
Log | |
=== | |
A simple logger which can write into a file and/or to | |
the console. Supports colored output on all major platforms | |
Window, Mac and Linux. | |
To remove all logs features you can define `SX_DISABLE_LOG` | |
when compiling. This will add a couple of nop macros for | |
SX_DEBUG, SX_VERBOSE, SX_WARNING and SX_ERROR. | |
On Windows we can use 0-255 different colors, 0-14 define colors | |
with a black background that we prefer, these colors are: | |
- 0 Black | |
- 1 Dark blue | |
- 2 Dark green | |
- 3 Dark cyan | |
- 4 Dark red | |
- 5 Dark purple | |
- 6 Dark brown | |
- 7 White | |
- 8 Gray | |
- 9 Blue | |
- 10 Green | |
- 11 Cyan | |
- 12 Red | |
- 13 Purple | |
- 14 Yellow | |
*/ | |
#ifndef POLY_LOG_H | |
#define POLY_LOG_H | |
#include <string> | |
#include <fstream> | |
#if defined(_WIN32) | |
# define WIN32_LEAN_AND_MEAN | |
# include <windows.h> | |
#endif | |
#define SX_LOG_LEVEL_ALL 5 | |
#define SX_LOG_LEVEL_ERROR 1 | |
#define SX_LOG_LEVEL_WARNING 2 | |
#define SX_LOG_LEVEL_VERBOSE 3 | |
#define SX_LOG_LEVEL_DEBUG 4 | |
#if defined(SX_DISABLE_LOG) | |
# define SX_DEBUG(fmt, ...) { } | |
# define SX_VERBOSE(fmt, ...) { } | |
# define SX_WARNING(fmt, ...) { } | |
# define SX_ERROR(fmt, ...) { } | |
#else | |
# if defined(_MSC_VER) | |
# define SX_DEBUG(fmt, ...) { poly::poly_debug(__LINE__, __FUNCSIG__, fmt, ##__VA_ARGS__); } | |
# define SX_VERBOSE(fmt, ...) { poly::poly_verbose(__LINE__, __FUNCSIG__, fmt, ##__VA_ARGS__); } | |
# define SX_WARNING(fmt, ...) { poly::poly_warning(__LINE__, __FUNCSIG__, fmt, ##__VA_ARGS__); } | |
# define SX_ERROR(fmt, ...) { poly::poly_error(__LINE__, __FUNCSIG__, fmt, ##__VA_ARGS__); } | |
# else | |
# define SX_DEBUG(fmt, ...) { poly::poly_debug(__LINE__, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__); } | |
# define SX_VERBOSE(fmt, ...) { poly::poly_verbose(__LINE__, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__); } | |
# define SX_WARNING(fmt, ...) { poly::poly_warning(__LINE__, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__); } | |
# define SX_ERROR(fmt, ...) { poly::poly_error(__LINE__, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__); } | |
# endif | |
#endif | |
/* --------------------------------------------------------------------------------- */ | |
namespace poly { | |
/* Debug control */ | |
int poly_log_init(std::string path = ""); | |
int poly_log_is_initialized(); | |
void poly_log_disable_stdout(); | |
void poly_log_enable_stdout(); | |
void poly_log_disable_log_to_file(); | |
void poly_log_enable_log_to_file(); | |
void poly_log_disable_colors(); | |
void poly_log_enable_colors(); | |
void poly_log_set_level(int level); | |
int poly_log_get_level(); | |
/* Debug wrappers. */ | |
void poly_debug(int line, const char* function, const char* fmt, ...); | |
void poly_verbose(int line, const char* function, const char* fmt, ...); | |
void poly_warning(int line, const char* function, const char* fmt, ...); | |
void poly_error(int line, const char* function, const char* fmt, ...); | |
/* --------------------------------------------------------------------------------- */ | |
class Log { | |
public: | |
Log(); | |
~Log(); | |
int open(std::string filepath); /* Open the log with the give filepath. */ | |
void log(int level, /* Log something at the given level. */ | |
int line, /* Refers to the line in the source code. */ | |
const char* function, /* Funcion that logged the message. */ | |
const char* fmt, /* We use printf() like formats. */ | |
va_list args); /* Variable arguments. */ | |
public: | |
bool write_to_stdout; /* Write output also to stdout. */ | |
bool write_to_file; /* Write log to file. */ | |
bool use_colors; /* Use colored output. */ | |
int level; /* What level we should log. */ | |
private: | |
std::string filepath; /* Filepath where we save the log file. */ | |
std::ofstream ofs; /* The output file stream */ | |
#if defined(_WIN32) | |
HANDLE console_handle; /* On Windows we get a handle to the console, so we can change the colors of the output. */ | |
#endif | |
}; | |
/* --------------------------------------------------------------------------------- */ | |
extern Log poly_log; | |
extern int poly_log_initialized_flag; | |
} /* namespace poly */ | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
if [ ! -d build.release ] ; then | |
mkdir build.release | |
fi | |
cd build.release | |
cmake -DCMAKE_INSTALL_PREFIX=${PWD}/../install \ | |
-DPOLY_DIR=${PWD}/../../../polytrope/ \ | |
../ | |
if [ $? -ne 0 ] ; then | |
exit | |
fi | |
cmake --build . --target install | |
if [ $? -ne 0 ] ; then | |
exit | |
fi | |
cd ../install/bin | |
./test_h264_encoding | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <Log.h> | |
#include <VideoEncoderMediaFoundation.h> | |
using namespace poly; | |
int main() { | |
poly_log_init(); | |
SX_VERBOSE("test h264 encoding."); | |
VideoEncoderMediaFoundation mft; | |
mft.init(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <VideoEncoderMediaFoundation.h> | |
#include <Log.h> | |
namespace poly { | |
static std::string hresult_to_string(HRESULT hr); | |
VideoEncoderMediaFoundation::VideoEncoderMediaFoundation() | |
:transform(NULL) | |
{ | |
} | |
VideoEncoderMediaFoundation::~VideoEncoderMediaFoundation() { | |
} | |
int VideoEncoderMediaFoundation::init() { | |
int r = 0; | |
HRESULT hr = S_OK; | |
GUID clsid = { 0 } ; | |
DWORD num_in_streams = 0; | |
DWORD num_out_streams = 0; | |
if (NULL != transform) { | |
SX_ERROR("Cannot initialize, transform is not NULL."); | |
return -1; | |
} | |
/* Initialize COM and create the transform object. */ | |
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to initialize COM."); | |
r = -1; | |
goto error; | |
} | |
if (0 != findHardwareEncoder(clsid)) { | |
r = -2; | |
goto error; | |
} | |
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&transform)); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to create the transform object: %s, err: %08X", hresult_to_string(hr).c_str(), hr); | |
r = -3; | |
goto error; | |
} | |
hr = transform->GetStreamCount(&num_in_streams, &num_out_streams); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to retrieve the standard num in/out streams."); | |
r = -4; | |
goto error; | |
} | |
if (1 != num_in_streams) { | |
SX_ERROR("Number of input stream is not 1. This should be 1."); | |
r = -5; | |
goto error; | |
} | |
error: | |
if (r < 0) { | |
shutdown(); | |
} | |
return r; | |
} | |
int VideoEncoderMediaFoundation::shutdown() { | |
if (NULL != transform) { | |
SX_ERROR("Releaes the transformm."); | |
} | |
return 0; | |
} | |
/* Set to 1 to print the name of the found encoder. */ | |
#define VEMF_PRINT_NAME 1 | |
int VideoEncoderMediaFoundation::findHardwareEncoder(GUID& guid) { | |
bool is_async = false; | |
int r = 0; | |
HRESULT hr = S_OK; | |
UINT32 flags = 0; | |
UINT32 count = 0; | |
UINT32 i = 0; | |
IMFActivate** result = NULL; | |
IMFActivate* activate = NULL; | |
IMFActivate* found_activate = NULL; | |
MFT_REGISTER_TYPE_INFO info = { MFMediaType_Video, MFVideoFormat_H264 }; | |
#if VEMF_PRINT_NAME | |
WCHAR guid_str[40] = { 0 } ; | |
UINT32 name_len = 0; | |
LPWSTR friendly_name = NULL; | |
#endif | |
flags |= MFT_ENUM_FLAG_LOCALMFT; | |
flags |= MFT_ENUM_FLAG_TRANSCODE_ONLY; | |
flags |= MFT_ENUM_FLAG_SYNCMFT; | |
flags |= MFT_ENUM_FLAG_ASYNCMFT; | |
flags |= MFT_ENUM_FLAG_HARDWARE; | |
hr = MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, flags, NULL, &info, &result, &count); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to enumerate video encoders. None present?"); | |
return -1; | |
} | |
if (NULL == result) { | |
SX_ERROR("Result is NULL. Not supposed to happen."); | |
return -2; | |
} | |
SX_VERBOSE("Found %lu encoders.", count); | |
for (i = 0; i < count; ++i) { | |
activate = result[i]; | |
flags = 0; | |
hr = activate->GetUINT32(MF_TRANSFORM_FLAGS_Attribute, &flags); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Activation Object %u does not expose flags.", i); | |
continue; | |
} | |
#if VEMF_PRINT_NAME | |
hr = activate->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &friendly_name, &name_len); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to retrieve the friendly name."); | |
} | |
else { | |
SX_VERBOSE("Got a name: %S len: %lu", friendly_name, name_len); | |
CoTaskMemFree(friendly_name); | |
} | |
#endif | |
if ( (flags & MFT_ENUM_FLAG_HARDWARE) == MFT_ENUM_FLAG_HARDWARE) { | |
SX_VERBOSE("%lu supports hardware encoding.", i); | |
found_activate = activate; | |
break; | |
} | |
#if 0 | |
if ( (flags & MFT_ENUM_FLAG_ASYNCMFT) == MFT_ENUM_FLAG_ASYNCMFT) { | |
SX_VERBOSE("%u is async.", i); | |
is_async = true; | |
} | |
if ( (flags & MFT_ENUM_FLAG_SYNCMFT) == MFT_ENUM_FLAG_SYNCMFT) { | |
SX_VERBOSE("%u is sync.", i); | |
is_async = false; | |
} | |
#endif | |
} | |
if (NULL == found_activate) { | |
SX_ERROR("We did not find an suitable activation object."); | |
r = -3; | |
goto error; | |
} | |
hr = found_activate->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guid); | |
if (false == SUCCEEDED(hr)) { | |
SX_ERROR("Failed to retreive the CLSID attribute from the activation object."); | |
r = -5; | |
goto error; | |
} | |
#if VEMF_PRINT_NAME | |
if (0 == StringFromGUID2(guid, guid_str, 40)) { | |
SX_ERROR("Buffer to small."); | |
} | |
else { | |
SX_VERBOSE("Found GUID: %S", guid_str); | |
} | |
#endif | |
error: | |
for (i = 0; i < count; ++i) { | |
result[i]->Release(); | |
} | |
CoTaskMemFree(result); | |
result = NULL; | |
return r; | |
} | |
static std::string hresult_to_string(HRESULT hr) { | |
switch(hr) { | |
case S_OK: { return "S_OK"; } | |
case E_FAIL: { return "E_FAIL"; } | |
case REGDB_E_CLASSNOTREG: { return "REGDB_E_CLASSNOTREG"; } | |
case CLASS_E_NOAGGREGATION: { return "CLASS_E_NOAGGREGATION"; } | |
case E_NOINTERFACE: { return "E_NOINTERFACE"; } | |
case E_POINTER: { return "E_POINTER"; } | |
default: { return "UNKNOWN"; } | |
} | |
} | |
} /* namespace poly */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Windows Media Transform H264 Encoder | |
===================================== | |
0: https://msdn.microsoft.com/en-us/library/windows/desktop/aa965264(v=vs.85).aspx "Basic Processing Model" | |
1: https://msdn.microsoft.com/en-us/library/windows/desktop/ms698983(v=vs.85).aspx "Activation Objects" | |
2: https://msdn.microsoft.com/en-us/library/windows/desktop/dd940330(v=vs.85).aspx "Hardware MFTs - info on async data processing." | |
*/ | |
#ifndef POLY_VIDEO_ENCODER_MEDIA_FOUNDATION_H | |
#define POLY_VIDEO_ENCODER_MEDIA_FOUNDATION_H | |
#include <Objbase.h> /* CoInitialize(), CoCreateInstance(). */ | |
#include <Mftransform.h> /* IMFTransform */ | |
#include <Mfapi.h> /* MFTEnumEx(). */ | |
#include <Codecapi.h> | |
namespace poly { | |
class VideoEncoderMediaFoundation { | |
public: | |
VideoEncoderMediaFoundation(); | |
~VideoEncoderMediaFoundation(); | |
int init(); | |
int shutdown(); | |
private: | |
int findHardwareEncoder(GUID& result); | |
public: | |
IMFTransform* transform; | |
}; | |
} /* namespace poly */ | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment