|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "avicodecrestrictions.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <windows.h></windows.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <vfw.h></vfw.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
HIC getCodec(const std::wstring &codecName, int &bpp) {
|
|
Shinya Kitaoka |
120a6e |
HIC hic = 0;
|
|
Shinya Kitaoka |
120a6e |
ICINFO icinfo;
|
|
Shinya Kitaoka |
120a6e |
memset(&icinfo, 0, sizeof(ICINFO));
|
|
Shinya Kitaoka |
120a6e |
bool found = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
char descr[2048], name[2048];
|
|
Shinya Kitaoka |
120a6e |
DWORD fccType = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BITMAPINFO inFmt;
|
|
Shinya Kitaoka |
120a6e |
memset(&inFmt, 0, sizeof(BITMAPINFO));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biWidth = inFmt.bmiHeader.biHeight = 100;
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biPlanes = 1;
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biCompression = BI_RGB;
|
|
Shinya Kitaoka |
120a6e |
for (bpp = 32; (bpp >= 24) && !found; bpp -= 8) {
|
|
Shinya Kitaoka |
120a6e |
// find the codec.
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biBitCount = bpp;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; ICInfo(fccType, i, &icinfo); i++) {
|
|
Shinya Kitaoka |
120a6e |
hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_COMPRESS);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ICGetInfo(hic, &icinfo, sizeof(ICINFO)); // Find out the compressor name
|
|
Shinya Kitaoka |
120a6e |
WideCharToMultiByte(CP_ACP, 0, icinfo.szDescription, -1, descr,
|
|
Shinya Kitaoka |
120a6e |
sizeof(descr), 0, 0);
|
|
Shinya Kitaoka |
120a6e |
WideCharToMultiByte(CP_ACP, 0, icinfo.szName, -1, name, sizeof(name), 0,
|
|
Shinya Kitaoka |
120a6e |
0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string compressorName;
|
|
Shinya Kitaoka |
120a6e |
compressorName = std::string(name) + " '" + std::to_string(bpp) + "' " +
|
|
Shinya Kitaoka |
120a6e |
std::string(descr);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (hic) {
|
|
Shinya Kitaoka |
120a6e |
if (ICCompressQuery(hic, &inFmt, NULL) != ICERR_OK) {
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
continue; // Skip this compressor if it can't handle the format.
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (::to_wstring(compressorName) == codecName) {
|
|
Shinya Kitaoka |
120a6e |
found = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (found) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return hic;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool canWork(const HIC &hic, const TDimension &resolution, int bpp) {
|
|
Shinya Kitaoka |
120a6e |
int lx = resolution.lx, ly = resolution.ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BITMAPINFO bi;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biPlanes = 1;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biCompression = BI_RGB;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biXPelsPerMeter = 80;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biYPelsPerMeter = 72;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biClrUsed = 0;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biClrImportant = 0;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biBitCount = bpp;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biWidth = lx;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biHeight = ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return ICERR_OK == ICCompressQuery(hic, &bi.bmiHeader, NULL);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void AviCodecRestrictions::getRestrictions(const std::wstring &codecName,
|
|
Shinya Kitaoka |
120a6e |
QString &restrictions) {
|
|
Shinya Kitaoka |
120a6e |
restrictions.clear();
|
|
Shinya Kitaoka |
120a6e |
if (codecName == L"Uncompressed") {
|
|
Shinya Kitaoka |
120a6e |
restrictions = QObject::tr("No restrictions for uncompressed avi video");
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// find the codec
|
|
Shinya Kitaoka |
120a6e |
int bpp;
|
|
Shinya Kitaoka |
120a6e |
HIC hic = getCodec(codecName, bpp);
|
|
Shinya Kitaoka |
120a6e |
if (!hic) {
|
|
Shinya Kitaoka |
120a6e |
restrictions = QObject::tr(
|
|
Shinya Kitaoka |
120a6e |
"It is not possible to communicate with the codec.\n Probably the "
|
|
Shinya Kitaoka |
120a6e |
"codec cannot work correctly.");
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BITMAPINFO bi;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biPlanes = 1;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biCompression = BI_RGB;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biXPelsPerMeter = 80;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biYPelsPerMeter = 72;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biClrUsed = 0;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biClrImportant = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int lx = 640, ly = 480;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biWidth = lx;
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biHeight = ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Loop until we can find a width, height, and depth that works!
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
|
|
MCCCS |
a0ce32 |
// check the x length
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biBitCount = bpp;
|
|
Shinya Kitaoka |
120a6e |
for (i = 3; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biWidth = lx + (1 << i);
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biSizeImage =
|
|
Shinya Kitaoka |
120a6e |
((bi.bmiHeader.biWidth * bi.bmiHeader.biBitCount + 31) / 32) * 4 * ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL)) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (i >= 0)
|
|
Shinya Kitaoka |
120a6e |
restrictions = QObject::tr("video width must be a multiple of %1")
|
|
Shinya Kitaoka |
120a6e |
.arg(QString::number(1 << (i + 1)));
|
|
Shinya Kitaoka |
120a6e |
|
|
MCCCS |
a0ce32 |
// check the y length
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biWidth = 640;
|
|
Shinya Kitaoka |
120a6e |
for (i = 3; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biHeight = ly + (1 << i);
|
|
Shinya Kitaoka |
120a6e |
bi.bmiHeader.biSizeImage =
|
|
Shinya Kitaoka |
120a6e |
((lx * bi.bmiHeader.biBitCount + 31) / 32) * 4 * bi.bmiHeader.biHeight;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ICERR_OK != ICCompressQuery(hic, &bi.bmiHeader, NULL)) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (i >= 0)
|
|
Shinya Kitaoka |
120a6e |
restrictions = restrictions + "\n" +
|
|
MCCCS |
a0ce32 |
QObject::tr("video length must be a multiple of %1")
|
|
Shinya Kitaoka |
120a6e |
.arg(QString::number(1 << (i + 1)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (restrictions.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
restrictions = QObject::tr("No restrictions for this codec");
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
restrictions.prepend(QObject::tr("Resolution restrictions:") + "\n");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool AviCodecRestrictions::canWriteMovie(const std::wstring &codecName,
|
|
Shinya Kitaoka |
120a6e |
const TDimension &resolution) {
|
|
Shinya Kitaoka |
120a6e |
if (codecName == L"Uncompressed") {
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// find the codec
|
|
Shinya Kitaoka |
120a6e |
int bpp;
|
|
Shinya Kitaoka |
120a6e |
HIC hic = getCodec(codecName, bpp);
|
|
Shinya Kitaoka |
120a6e |
if (!hic) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool test = canWork(hic, resolution, bpp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
return test;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool AviCodecRestrictions::canBeConfigured(const std::wstring &codecName) {
|
|
Shinya Kitaoka |
120a6e |
if (codecName == L"Uncompressed") return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// find the codec
|
|
Shinya Kitaoka |
120a6e |
int bpp;
|
|
Shinya Kitaoka |
120a6e |
HIC hic = getCodec(codecName, bpp);
|
|
Shinya Kitaoka |
120a6e |
if (!hic) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool test = ICQueryConfigure(hic);
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
return test;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void AviCodecRestrictions::openConfiguration(const std::wstring &codecName,
|
|
Shinya Kitaoka |
120a6e |
void *winId) {
|
|
Shinya Kitaoka |
120a6e |
if (codecName == L"Uncompressed") return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// find the codec
|
|
Shinya Kitaoka |
120a6e |
int bpp;
|
|
Shinya Kitaoka |
120a6e |
HIC hic = getCodec(codecName, bpp);
|
|
Shinya Kitaoka |
120a6e |
if (!hic) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ICConfigure(hic, winId);
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMap<std::wstring, bool=""> AviCodecRestrictions::getUsableCodecs(</std::wstring,>
|
|
Shinya Kitaoka |
120a6e |
const TDimension &resolution) {
|
|
Shinya Kitaoka |
120a6e |
QMap<std::wstring, bool=""> codecs;</std::wstring,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
HIC hic = 0;
|
|
Shinya Kitaoka |
120a6e |
ICINFO icinfo;
|
|
Shinya Kitaoka |
120a6e |
memset(&icinfo, 0, sizeof(ICINFO));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
char descr[2048], name[2048];
|
|
Shinya Kitaoka |
120a6e |
DWORD fccType = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BITMAPINFO inFmt;
|
|
Shinya Kitaoka |
120a6e |
memset(&inFmt, 0, sizeof(BITMAPINFO));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biWidth = inFmt.bmiHeader.biHeight = 100;
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biPlanes = 1;
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biCompression = BI_RGB;
|
|
Shinya Kitaoka |
120a6e |
int bpp;
|
|
Shinya Kitaoka |
120a6e |
for (bpp = 32; (bpp >= 24); bpp -= 8) {
|
|
Shinya Kitaoka |
120a6e |
// find the codec.
|
|
Shinya Kitaoka |
120a6e |
inFmt.bmiHeader.biBitCount = bpp;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; ICInfo(fccType, i, &icinfo); i++) {
|
|
Shinya Kitaoka |
120a6e |
hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_COMPRESS);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ICGetInfo(hic, &icinfo, sizeof(ICINFO)); // Find out the compressor name
|
|
Shinya Kitaoka |
120a6e |
WideCharToMultiByte(CP_ACP, 0, icinfo.szDescription, -1, descr,
|
|
Shinya Kitaoka |
120a6e |
sizeof(descr), 0, 0);
|
|
Shinya Kitaoka |
120a6e |
WideCharToMultiByte(CP_ACP, 0, icinfo.szName, -1, name, sizeof(name), 0,
|
|
Shinya Kitaoka |
120a6e |
0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::wstring compressorName;
|
|
Shinya Kitaoka |
120a6e |
compressorName =
|
|
Shinya Kitaoka |
120a6e |
::to_wstring(std::string(name) + " '" + std::to_string(bpp) + "' " +
|
|
Shinya Kitaoka |
120a6e |
std::string(descr));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (hic) {
|
|
Shinya Kitaoka |
120a6e |
if (ICCompressQuery(hic, &inFmt, NULL) != ICERR_OK) {
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
continue; // Skip this compressor if it can't handle the format.
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
codecs[compressorName] = canWork(hic, resolution, bpp);
|
|
Shinya Kitaoka |
120a6e |
ICClose(hic);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return codecs;
|
|
Toshihiro Shimizu |
890ddd |
}
|