www.pudn.com > w_ipp-sample-media_p_5.0.017.zip > video_enc_con.cpp
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2005 Intel Corporation. All Rights Reserved.
//
//ipp
#include "ipp.h"
//mpeg2
#include "umc_mpeg2_video_encoder.h"
//h264
#include "umc_h264_video_encoder.h"
//mpeg4
#include "umc_mpeg4_video_encoder.h"
//h263
#include "umc_h263_video_encoder.h"
//h261
#include "umc_h261_video_encoder.h"
//vm
#include "vm_time.h"
using namespace UMC;
#include "utils.h"
#define MAX_FILELEN 1024
int encode(VideoEncoder *p_vidEncoder,
VideoEncoderParams *p_vidEncoderParams,
UMCReadYUV *YUVReader,
vm_char *DstFileName,
int *encoded_size,
double *enc_time)
{
VideoData *p_dataIn = NULL;
MediaData *p_dataOut = NULL;
int mFrameCount = 0, err_code = 0;
int mWidth, mHeight, mSize, mTotalFrames;
int mCompSize, mRetval;
size_t len;
FILE *outFile = NULL;
vm_tick tf, ts, te;
double time = 0.0;
Ipp8u *pY = NULL, *pU = NULL, *pV = NULL, *pBS = NULL;
mWidth = p_vidEncoderParams->src_width;
mHeight = p_vidEncoderParams->src_height;
mTotalFrames = p_vidEncoderParams->numFramesToEncode;
mSize = mWidth * mHeight;
p_dataIn = new VideoData;
p_dataOut = new MediaData;
if ((!p_dataIn) || (!p_dataOut)) {
fprintf(stderr,"Error: Can't allocate Media Data objects \n");
err_code=7; goto free_memories;
}
outFile = vm_file_open(DstFileName, VM_STRING("wb"));
if (!outFile) {
fprintf(stderr,"Error: Can't open output file '%s'\n", DstFileName);
err_code=9; goto free_memories;
}
pY = pU = pV = pBS = NULL;
pY = new Ipp8u[mSize];
pU = new Ipp8u[mSize];
pV = new Ipp8u[mSize];
pBS = new Ipp8u[2*mSize];
if (( !pY ) || ( !pU ) || ( !pV )|| ( !pBS )) {
fprintf(stderr,"Error: Can't allocate data buffers! \n");
err_code=10; goto free_memories;
}
p_dataIn->SetDest(pY, pU, pV);
p_dataIn->SetPitch(YUVReader->mWidth, YUVReader->mWidthChroma, YUVReader->mWidthChroma);
p_dataIn->SetColorFormat(YUVReader->mColorFormat);
p_dataOut->SetBufferPointer(pBS, 2*mSize);
tf = vm_time_get_frequency();
time = 0;
mCompSize = 0;
while (mFrameCount < mTotalFrames) {
printf("Encoding frame: %d ... ",mFrameCount);
if (YUVReader->LoadNextFrame(p_dataIn) != YUV_ERROR_NOERR) {
fprintf(stderr,"Error: Can't read next %d source frame!\n", mFrameCount);
break;
}
ts = vm_time_get_tick();
mRetval = p_vidEncoder->GetFrame(p_dataIn, p_dataOut);
te = vm_time_get_tick();
time += (double)(vm_var64s)(te - ts) / (double)(vm_var64s)tf;
if(mRetval != UMC_OK && mRetval != UMC_NOT_ENOUGH_DATA){
fprintf(stderr,"Error: encoding failed at %d source frame (exit with %d)!\n", mFrameCount, mRetval);
err_code = 13;
break;
}
len = fwrite(p_dataOut->GetDataPointer(), 1, p_dataOut->GetDataSize(), outFile);
mCompSize += (int)len;
if (len != p_dataOut->GetDataSize()) {
fprintf(stderr,"Error: Couldn't write to output file '%s'\n", DstFileName);
err_code=11; goto free_memories;
}
printf(" done\n" );
mFrameCount ++;
}
while ((mRetval == UMC_OK )&&(p_dataOut->GetDataSize()>0)) {
ts = vm_time_get_tick();
mRetval = p_vidEncoder->GetFrame(NULL, p_dataOut);
te = vm_time_get_tick();
time += (double)(vm_var64s)(te - ts) / (double)(vm_var64s)tf;
if(mRetval != UMC_OK && mRetval != UMC_END_OF_STREAM){
fprintf(stderr,"Error: encoding failed at outputing buffered frames (exit with %d)!\n", mRetval);
err_code = 13; // Incorrectly processed buffered frames encoding request!!!
break;
}
len = fwrite(p_dataOut->GetDataPointer(), 1, p_dataOut->GetDataSize(), outFile);
mCompSize += (int)len;
if (len != p_dataOut->GetDataSize()) {
fprintf(stderr,"Error: Couldn't write to output file '%s'\n", DstFileName);
err_code=12; goto free_memories;
}
mFrameCount++;
}
free_memories:
if (p_dataIn) delete p_dataIn;
if (p_dataOut) delete p_dataOut;
if (pY) delete [] pY;
if (pV) delete [] pV;
if (pU) delete [] pU;
if (pBS) delete [] pBS;
if (outFile) fclose(outFile);
*enc_time = time;
*encoded_size = mCompSize;
return err_code;
}
void PrintHelp(vm_char *prog_name)
{
vm_string_printf(VM_STRING("Usage: %s [Options] [m2|m4|h264|h263|h261] InputParFile OutputEncodedFile\n\n"), prog_name);
vm_string_printf(VM_STRING("Options: \n"));
vm_string_printf(VM_STRING(" [-t num] - number of threads for encoding\n"));
vm_string_printf(VM_STRING(" [-r] - enables threading of read/encode/write\n"));
vm_string_printf(VM_STRING(" [-y dir] - directory of YUV files\n"));
vm_string_printf(VM_STRING(" [-u file] - file for dumping perfomance info\n"));
vm_string_printf(VM_STRING("\n"));
}
int main(int argc, vm_char *argv[])
{
vm_char SrcFileName[MAX_FILELEN];
vm_char *ParFileName = NULL;
vm_char *DstFileName = NULL;
UMCReadYUV YUVReader[1];
VideoEncoder *p_vidEncoder = NULL;
VideoEncoderParams *p_vidEncoderParams = NULL;
ColorFormat mColorFormat = YV12;
FILE *perf_file = NULL;
vm_char *p;
int encoded_size;
double enc_time, ov_time;
vm_tick tf, ts, te;
int numThreads = 1;
int rw_threading = 0;
int codec_number = 0;
int err_code = 0;
int i;
int mWidth;
int mHeight;
int mTotalFrames;
double size_ratio;
*SrcFileName = 0;
for (i = 1; i < argc; i++)
{
if (vm_string_strcmp(argv[i], VM_STRING("m2")) == 0) {
codec_number = 2;
} else
if (vm_string_strcmp(argv[i], VM_STRING("m4")) == 0) {
codec_number = 4;
} else
if (vm_string_strcmp(argv[i], VM_STRING("h264")) == 0) {
codec_number = 264;
} else
if (vm_string_strcmp(argv[i], VM_STRING("h263")) == 0) {
codec_number = 263;
} else
if (vm_string_strcmp(argv[i], VM_STRING("h261")) == 0) {
codec_number = 261;
} else
if ('-' != argv[i][0]) {
if (NULL == ParFileName) {
ParFileName = argv[i];
} else {
DstFileName = argv[i];
}
} else
switch (argv[i][1])
{
case 'y':
i++;
vm_string_strcpy(SrcFileName, argv[i]);
p = SrcFileName + vm_string_strlen(SrcFileName) - 1;
if (*p != '\\' && *p != '/') {
vm_string_strcat(SrcFileName, VM_STRING("\\"));
}
break;
case 't':
if (2 == vm_string_strlen(argv[i])) {
i++;
if (argv[i][0]=='-') {
PrintHelp(argv[0]);
return 1;
} else {
numThreads = (int)vm_string_atol(argv[i]);
}
} else {
numThreads = (int)vm_string_atol(argv[i] + 2);
}
break;
case 'r':
rw_threading = 1;
break;
case 'u':
i++;
perf_file = vm_file_open(argv[i], VM_STRING("w"));
break;
case 'h':
case '?':
default:
PrintHelp(argv[0]);
return 1;
}
}
if (!ParFileName || !DstFileName || !codec_number) {
PrintHelp(argv[0]);
return 1;
}
switch (codec_number) {
case 2:
p_vidEncoder = createMPEG2VideoEncoder();
p_vidEncoderParams = new MPEG2EncoderParams;
if (ReadMPEG2EncoderParams(ParFileName,(MPEG2EncoderParams*)(p_vidEncoderParams),
SrcFileName, MAX_FILELEN ))
{
fprintf(stderr,"Error: Can't read par file %s \n", ParFileName);
err_code=3; goto exit;
}
{
int chroma_format = ((MPEG2EncoderParams*)p_vidEncoderParams)->chroma_format;
if (chroma_format == CHROMA422) mColorFormat = YUV422; else
if (chroma_format == CHROMA444) mColorFormat = YUV444;
}
((MPEG2EncoderParams*)p_vidEncoderParams)->numThreads = numThreads;
break;
case 4:
p_vidEncoder = createMPEG4VideoEncoder();
p_vidEncoderParams = new MPEG4EncoderParams;
if (ReadMPEG4EncoderParams(ParFileName,(MPEG4EncoderParams*)(p_vidEncoderParams),
SrcFileName, MAX_FILELEN )) {
fprintf(stderr,"Error: Can't read par file %s \n", ParFileName);
err_code=3; goto exit;
}
break;
case 264:
p_vidEncoder = createH264VideoEncoder();
p_vidEncoderParams = new H264EncoderParams;
if (ReadH264EncoderParams(ParFileName,(H264EncoderParams*)(p_vidEncoderParams),
SrcFileName, MAX_FILELEN )){
fprintf(stderr,"Error: Can't par file %s \n", ParFileName);
err_code=3; goto exit;
}
break;
case 263:
p_vidEncoder = createH263VideoEncoder();
p_vidEncoderParams = new H263EncoderParams;
if (ReadH263EncoderParams(ParFileName,(H263EncoderParams*)(p_vidEncoderParams),
SrcFileName, MAX_FILELEN )){
fprintf(stderr,"Error: Can't par file %s \n", ParFileName);
err_code=3; goto exit;
}
break;
case 261:
p_vidEncoder = createH261VideoEncoder();
p_vidEncoderParams = new H261EncoderParams;
if (ReadH261EncoderParams(ParFileName,(H261EncoderParams*)(p_vidEncoderParams),
SrcFileName, MAX_FILELEN )){
fprintf(stderr,"Error: Can't par file %s \n", ParFileName);
err_code=3; goto exit;
}
break;
}
if (ippStaticInit() < ippStsNoErr) {
fprintf(stderr,"Error: Can't initialize ipp libs! \n");
err_code=5; goto exit;
}
if (p_vidEncoder->Init(p_vidEncoderParams) != UMC_OK) {
fprintf(stderr,"Error: Video encoder initialization failed\n");
err_code=6; goto exit;
}
mWidth = p_vidEncoderParams->src_width;
mHeight = p_vidEncoderParams->src_height;
mTotalFrames = p_vidEncoderParams->numFramesToEncode;
if (YUVReader->Init(SrcFileName, mWidth, mHeight, mColorFormat) != YUV_ERROR_NOERR){
fprintf(stderr,"Error: Can't initalize yuv data reader for file %s \n",SrcFileName );
err_code=8; goto exit;
}
printf("\n");
printf("Starting encoding %s to file %s\n", SrcFileName, DstFileName);
printf("Source video width=%d, height=%d, frames to encode=%d\n\n",
mWidth, mHeight, mTotalFrames);
ts = vm_time_get_tick();
if (!rw_threading) {
encode(p_vidEncoder, p_vidEncoderParams, YUVReader, DstFileName, &encoded_size, &enc_time);
} else {
printf("Enabled threading of read/encode/write!\n\n");
encode_threaded(p_vidEncoder, p_vidEncoderParams, YUVReader, DstFileName, &encoded_size, &enc_time);
}
te = vm_time_get_tick();
tf = vm_time_get_frequency();
ov_time = (double)(vm_var64s)(te - ts) / (double)(vm_var64s)tf;
printf("Summary:\n" );
printf(" Encoding Time = %.2f sec, %.2f fps\n", enc_time, mTotalFrames/enc_time);
printf(" Overall Time = %.2f sec, %.2f fps\n", ov_time, mTotalFrames/ov_time);
printf(" Encoded Size = %d bytes\n", encoded_size);
printf(" Compression Ratio = %.2f\n", ((double)mTotalFrames*YUVReader->mFrameSize)/encoded_size);
size_ratio = 0;
if (p_vidEncoderParams->FrameRate != 0 && p_vidEncoderParams->BitRate != 0) {
size_ratio = encoded_size/(((double)mTotalFrames/p_vidEncoderParams->FrameRate)*(p_vidEncoderParams->BitRate/8));
printf(" EncodedSize/ExpectedSize = %.2f\n", size_ratio);
}
if (codec_number == 2) {
p_vidEncoder->GetInfo(p_vidEncoderParams);
printf(" MPEG2 internal performance = %6.2lf fps\n", ((MPEG2EncoderParams*)p_vidEncoderParams)->performance);
}
printf("\n");
if (perf_file != NULL) {
vm_string_fprintf(perf_file, VM_STRING("Performance = %.2f fps"), mTotalFrames/enc_time);
vm_string_fprintf(perf_file, VM_STRING(", EncodedSize/ExpectedSize = %.2f"), size_ratio);
fclose(perf_file);
}
exit:
if (p_vidEncoder) delete p_vidEncoder;
if (p_vidEncoderParams) delete p_vidEncoderParams;
return err_code;
}