ref: 99faf1ec4a47c5362a6bde552d6097166e2fda16
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; }