ref: 8bb82769679bf274f4d53e0153099c5091274e09
dir: /processing/src/testbed/WelsVideoProcessor.cpp/
/*!
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
// WelsVideoProcessor.cpp : Defines the entry point for the console application.
//
#include <tchar.h>
#include "stdafx.h"
#include "wels_process.h"
//////////////////////////////////////////////////////////////////////////
typedef struct
{
FILE *srcfile;
FILE *dstfile;
vPixMap src;
vPixMap dst;
vMethods methods[vMethods_Mask];
} VpConfigure;
//////////////////////////////////////////////////////////////////////////
void PrintHelp(TCHAR *strAppName, TCHAR *strError)
{
if (strError)
{
_tprintf(_T("Error: %s\n"), strError);
}
else
{
_tprintf(_T("Welsvp Sample Console\n"));
}
_tprintf(_T("Usage1: %s [Options] -i InputFile -o OutputFile -w 640 -h 480\n"), strAppName);
_tprintf(_T("Options: \n"));
_tprintf(_T(" [-sx x] - cropX of src video (def: 0)\n"));
_tprintf(_T(" [-sy y] - cropY of src video (def: 0)\n"));
_tprintf(_T(" [-sw width] - cropW of src video (def: width)\n"));
_tprintf(_T(" [-sh height] - cropH of src video (def: height)\n"));
_tprintf(_T(" [-scc format] - format (FourCC) of src video (def: support yv12|yuy2|rgb3|rgb4)\n"));
_tprintf(_T(" [-dx x] - cropX of dst video (def: 0)\n"));
_tprintf(_T(" [-dy y] - cropY of dst video (def: 0)\n"));
_tprintf(_T(" [-dw width] - cropW of dst video (def: width)\n"));
_tprintf(_T(" [-dh height] - cropH of dst video (def: height)\n"));
_tprintf(_T(" [-dcc format] - format (FourCC) of dst video (def: nv12. support nv12|yuy2)\n"));
_tprintf(_T(" Video Processing Algorithms\n"));
_tprintf(_T(" [-vaa] - enable video analysis algorithm \n"));
_tprintf(_T(" [-bgd] - enable background detection algorithm \n"));
_tprintf(_T(" [-scd] - enable scene change detection algorithm \n"));
_tprintf(_T(" [-denoise] - enable denoise algorithm \n"));
_tprintf(_T(" [-downsample] - enable downsample algorithm \n"));
_tprintf(_T(" [-n frames] - number of frames to VP process\n\n"));
_tprintf(_T("\n"));
_tprintf(_T("Usage2: %s -sw 640 -sh 480 -scc rgb3 -dw 320 -dh 240 -dcc i420 -denoise -vaa -i in.rgb -o out.yuv\n"), strAppName);
_tprintf(_T("\n"));
}
vVideoFormat Str2FourCC( TCHAR* strInput )
{
vVideoFormat format = vVideoFormat_I420; // as default
if ( 0 == _tcscmp(strInput, _T("yv12")) )
{
format = vVideoFormat_YV12;
}
else if ( 0 == _tcscmp(strInput, _T("i420")) )
{
format = vVideoFormat_I420;
}
else if ( 0 == _tcscmp(strInput, _T("rgb24")) )
{
format = vVideoFormat_RGB24;
}
else if ( 0 == _tcscmp(strInput, _T("rgb32")) )
{
format = vVideoFormat_RGB32;
}
else if ( 0 == _tcscmp(strInput, _T("yuy2")) )
{
format = vVideoFormat_YUY2;
}
else if ( 0 == _tcscmp(strInput, _T("nv12")) )
{
format = vVideoFormat_NV12;
}
return format;
}
int ReadFile(vPixMap &pixmap, FILE *fp)
{
int ret = 0;
int size = pixmap.Rect.width * pixmap.Rect.height;
switch (pixmap.eFormat)
{
case vVideoFormat_I420:
case vVideoFormat_YV12:
{
if ( fread(pixmap.pPixel[0], pixmap.nSizeInBits/8, (3*size)>>1, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_YUY2:
{
if ( fread(pixmap.pPixel[0], pixmap.nSizeInBits/8, 2*size, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_RGB24:
{
if ( fread(pixmap.pPixel[0], pixmap.nSizeInBits/8, 3*size, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_RGB32:
{
if ( fread(pixmap.pPixel[0], pixmap.nSizeInBits/8, 4*size, fp) <= 0 )
ret = 1;
}
break;
default:
ret = 1;
break;
}
return ret;
}
int WriteFile(vPixMap &pixmap, FILE *fp)
{
int ret = 0;
int size = pixmap.Rect.width * pixmap.Rect.height;
switch (pixmap.eFormat)
{
case vVideoFormat_I420:
case vVideoFormat_YV12:
{
if ( fwrite(pixmap.pPixel[0], pixmap.nSizeInBits/8, (3*size)>>1, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_YUY2:
{
if ( fwrite(pixmap.pPixel[0], pixmap.nSizeInBits/8, 2*size, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_RGB24:
{
if ( fwrite(pixmap.pPixel[0], pixmap.nSizeInBits/8, 3*size, fp) <= 0 )
ret = 1;
}
break;
case vVideoFormat_RGB32:
{
if ( fwrite(pixmap.pPixel[0], pixmap.nSizeInBits/8, 4*size, fp) <= 0 )
ret = 1;
}
break;
default:
ret = 1;
break;
}
return ret;
}
int AllocPixMap(vPixMap &pixmap)
{
pixmap.nSizeInBits = sizeof(unsigned char) * 8;
switch (pixmap.eFormat)
{
case vVideoFormat_I420:
case vVideoFormat_YV12:
{
pixmap.nStride[0] = pixmap.Rect.width;
pixmap.nStride[1] = pixmap.nStride[2] = pixmap.Rect.width / 2;
pixmap.pPixel[0] = new void *[pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8 * 3 / 2];
pixmap.pPixel[1] = (unsigned char *)pixmap.pPixel[0] + pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8;
pixmap.pPixel[2] = (unsigned char *)pixmap.pPixel[0] + pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8 * 5 / 4;
}
break;
case vVideoFormat_YUY2:
{
pixmap.nStride[0] = pixmap.nStride[1] = pixmap.nStride[2] = pixmap.Rect.width * 2;
pixmap.pPixel[0] = new void *[pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8 * 2];
pixmap.pPixel[1] = pixmap.pPixel[2] = NULL;
}
break;
case vVideoFormat_RGB24:
{
pixmap.nStride[0] = pixmap.nStride[1] = pixmap.nStride[2] = pixmap.Rect.width * 3;
pixmap.pPixel[0] = new void *[pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8 * 3];
pixmap.pPixel[1] = pixmap.pPixel[2] = NULL;
}
break;
case vVideoFormat_RGB32:
{
pixmap.nStride[0] = pixmap.nStride[1] = pixmap.nStride[2] = pixmap.Rect.width * 4;
pixmap.pPixel[0] = new void *[pixmap.nStride[0] * pixmap.Rect.height * pixmap.nSizeInBits / 8 * 4];
pixmap.pPixel[1] = pixmap.pPixel[2] = NULL;
}
break;
default:
return 1;
}
return (pixmap.pPixel[0]) ? 0 : 1;
}
void FreePixMap(vPixMap &pixmap)
{
if (pixmap.pPixel[0])
{
free(pixmap.pPixel[0]);
pixmap.pPixel[0] = pixmap.pPixel[1] = pixmap.pPixel[2] = NULL;
}
}
int InitResource(TCHAR *strAppName, VpConfigure &cfg)
{
if (0 == cfg.srcfile)
{
PrintHelp(strAppName, _T("Source file can not found!\n"));
goto exit;
};
if (0 == cfg.dstfile)
{
PrintHelp(strAppName, _T("Destination file name not found"));
goto exit;
};
if (cfg.dst.Rect.width == 0)
cfg.dst.Rect.width = cfg.src.Rect.width;
if (cfg.dst.Rect.height == 0)
cfg.dst.Rect.height = cfg.src.Rect.height;
cfg.methods[vMethods_ColorSpaceConvert] = vMethods_ColorSpaceConvert;
if (AllocPixMap(cfg.src))
goto exit;
if (AllocPixMap(cfg.dst))
goto exit;
return 0;
exit:
FreePixMap(cfg.src);
FreePixMap(cfg.dst);
return 1;
}
int ParseCommond(TCHAR* strInput[], int nArgNum, VpConfigure &cfg)
{
if (nArgNum < 9)
{
PrintHelp(strInput[0], _T("please specify all necessary parameters!"));
return 1;
}
int width = 0, height = 0;
for (int i = 1; i < nArgNum; i++ )
{
if (strInput[i])
{
if ( 0 == _tcscmp(strInput[i], _T("-i")) )
{
i++;
_tfopen_s(&cfg.srcfile, strInput[i], _T("rb"));
}
else if (0 == _tcscmp(strInput[i], _T("-o")))
{
i++;
_tfopen_s(&cfg.dstfile, strInput[i], _T("wb"));
}
else if (0 == _tcscmp(strInput[i], _T("-w")))
{
i++;
_stscanf_s(strInput[i], _T("%d"), &width);
}
else if (0 == _tcscmp(strInput[i], _T("-h")))
{
i++;
_stscanf_s(strInput[i], _T("%d"), &height);
}
//-----------------------------------------------------------------------------------
else if (0 == _tcscmp(strInput[i], _T("-sx")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.src.Rect.top);
}
else if (0 == _tcscmp(strInput[i], _T("-sy")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.src.Rect.left);
}
else if (0 == _tcscmp(strInput[i], _T("-sw")))
{
i++;
TCHAR *a = strInput[i];
_stscanf_s(strInput[i], _T("%hd"), &cfg.src.Rect.width);
}
else if (0 == _tcscmp(strInput[i], _T("-sh")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.src.Rect.height);
}
else if (0 == _tcscmp(strInput[i], _T("-scc")))
{
i++;
cfg.src.eFormat = Str2FourCC( strInput[i] );
}
//-----------------------------------------------------------------------------------
else if (0 == _tcscmp(strInput[i], _T("-dx")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.dst.Rect.top);
}
else if (0 == _tcscmp(strInput[i], _T("-dy")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.dst.Rect.left);
}
else if (0 == _tcscmp(strInput[i], _T("-dw")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.dst.Rect.width);
}
else if (0 == _tcscmp(strInput[i], _T("-dh")))
{
i++;
_stscanf_s(strInput[i], _T("%hd"), &cfg.dst.Rect.height);
}
else if (0 == _tcscmp(strInput[i], _T("-dcc")))
{
i++;
cfg.dst.eFormat = Str2FourCC( strInput[i] );
}
//-----------------------------------------------------------------------------------
else if (0 == _tcscmp(strInput[i], _T("-denoise")))
{
cfg.methods[vMethods_Denoise] = vMethods_Denoise;
}
else if (0 == _tcscmp(strInput[i], _T("-scd")))
{
cfg.methods[vMethods_SceneChangeDetection] = vMethods_SceneChangeDetection;
}
else if (0 == _tcscmp(strInput[i], _T("-downsample")))
{
}
else if (0 == _tcscmp(strInput[i], _T("-vaa")))
{
}
else if (0 == _tcscmp(strInput[i], _T("-bgd")))
{
}
else if (0 == _tcscmp(strInput[i], _T("-aq")))
{
}
}
}
if (cfg.src.Rect.width == 0) cfg.src.Rect.width = width;
if (cfg.src.Rect.height == 0) cfg.src.Rect.height = height;
if (cfg.dst.Rect.width == 0) cfg.dst.Rect.width = width;
if (cfg.dst.Rect.height == 0) cfg.dst.Rect.height = height;
return InitResource(strInput[0], cfg);
}
int _tmain(int argc, _TCHAR* argv[])
{
int ret = 0;
VpConfigure cfg = {0};
IWelsVpPlugin *pVpp = NULL;
ret = ParseCommond(argv, argc, cfg);
if (ret)
goto exit;
pVpp = new IWelsVpPlugin(ret);
if (pVpp && ret == 0)
{
vResult vret = vRet_Success;
while (1)
{
if (feof(cfg.srcfile))
break;
if (ReadFile(cfg.src, cfg.srcfile))
break;
vret = pVpp->Process(cfg.methods[vMethods_ColorSpaceConvert], &cfg.src, &cfg.dst);
if (vret)
break;
vret = pVpp->Process(cfg.methods[vMethods_Denoise], &cfg.dst, NULL);
if (vret)
break;
if (WriteFile(cfg.dst, cfg.dstfile))
break;
}
}
exit:
if (pVpp)
{
delete pVpp;
pVpp = NULL;
}
if (cfg.srcfile)
fclose(cfg.srcfile);
if (cfg.dstfile)
fclose(cfg.dstfile);
FreePixMap(cfg.src);
FreePixMap(cfg.dst);
return 0;
}