www.pudn.com > w_ipp-sample-media_p_5.0.017.zip > video_enc_threading.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.
//
//
//
//
//
#include "vm_thread.h"
#include "vm_mmap.h"
#include "vm_time.h"
#include "umc_sys_info.h"
#include "vm_sys_info.h"
#include "ippcore.h"
#include "ippcc.h"
#include "umc_cyclic_buffer.h"
#include "umc_video_data.h"
#include "umc_mpeg2_video_encoder.h"
#include "umc_h264_video_encoder.h"
#include "umc_mpeg4_video_encoder.h"
#include "umc_h263_video_encoder.h"
#include "umc_h261_video_encoder.h"
using namespace UMC;
#include "utils.h"
#define GET_TICKS vm_time_get_tick()
typedef struct {
VideoEncoder *pEncoder;
VideoEncoderParams *Params;
UMCReadYUV *YUVReader;
SampleBuffer YUVFrames[1];
SampleBuffer CopressedFrames[1];
vm_char DstFName[256];
ColorFormat umcCFormat;
int m_FrameCount;
long m_EncodedSize;
double t_read_time;
double t_encode_time;
double t_write_time;
} EncodeInfo;
unsigned int ThreadLoadFrame(void* ptr)
{
int FrameCount;
vm_tick t_freq, t_start, t_end;
double curr_pts = 0, len_frame;
VideoData data;
VideoEncoder *pEncoder;
VideoEncoderParams *Params;
Status umcSts = UMC_OK;
assert(ptr);
EncodeInfo *Info = (EncodeInfo*)ptr;
pEncoder = Info->pEncoder;
Params = Info->Params;
data.SetVideoParameters(Params->src_width, Params->src_height, Info->umcCFormat);
len_frame = 1.0 / Info->Params->FrameRate;
t_freq = vm_time_get_frequency();
FrameCount = 0;
while ((umcSts == UMC_OK)&&(FrameCount < (int)Info->Params->numFramesToEncode))
{
do
{
umcSts = Info->YUVFrames->LockInputBuffer(&data);
if (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts);
if (UMC::UMC_OK != umcSts)
{
break;
}
t_start = vm_time_get_tick();
if (Info->YUVReader->LoadNextFrame(&data) != YUV_ERROR_NOERR) {
Info->YUVFrames->UnLockInputBuffer(&data);
break;
}
t_end = vm_time_get_tick();
data.SetTime(curr_pts);
//vm_string_printf(__VM_STRING("Load: %f\n"),data.GetTime());
curr_pts += len_frame;
Info->t_read_time +=(double)(vm_var64s)(t_end-t_start)/(vm_var64s)t_freq;
if(UMC_OK != (umcSts = Info->YUVFrames->UnLockInputBuffer(&data)))
{
break;
}
FrameCount++;
}
// set EOS
do
{
umcSts = Info->YUVFrames->LockInputBuffer(&data);
if (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts);
if (UMC::UMC_OK == umcSts)
{
data.SetDataSize(0);
data.SetTime(-1);
Info->YUVFrames->UnLockInputBuffer(&data, UMC::UMC_END_OF_STREAM);
}
return 0x0add;
}
unsigned int ThreadEncoding(void* ptr)
{
//int FrameCount;
vm_tick t_freq, t_start, t_end;
MediaData compressed_data;
VideoData yuv_data;
VideoEncoderParams *Params;
VideoEncoder *pEncoder;
Status umcSts = UMC_OK;
assert(ptr);
EncodeInfo *Info = (EncodeInfo*)ptr;
pEncoder = Info->pEncoder;
Params = Info->Params;
yuv_data.SetVideoParameters(Params->src_width, Params->src_height, Info->umcCFormat);
t_freq = vm_time_get_frequency();
Info->m_FrameCount = 0;
while(umcSts == UMC_OK)
{
// get destination buffer
do
{
umcSts = Info->CopressedFrames->LockInputBuffer(&compressed_data);
if (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts);
if(UMC_OK != umcSts)
{
break;
}
// get source buffer
do
{
umcSts = Info->YUVFrames->LockOutputBuffer(&yuv_data);
if (UMC::UMC_NOT_ENOUGH_DATA == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_DATA == umcSts);
if(UMC_OK != umcSts)
{
break;
}
// compress
vm_string_printf(VM_STRING("Encoding frame: %d ... "), Info->m_FrameCount);
t_start = GET_TICKS;
VideoData *p_yuv_data = (yuv_data.GetTime() >= 0) ? &yuv_data : NULL;
if(UMC_OK != (umcSts = pEncoder->GetFrame(p_yuv_data, &compressed_data)))
{
break;
}
t_end = GET_TICKS;
Info->t_encode_time += (double)(vm_var64s)(t_end-t_start)/(vm_var64s)t_freq;
vm_string_printf(VM_STRING(" done\n"));
//vm_string_printf(__VM_STRING("Enc: %f\n"),compressed_data.GetTime());
if(UMC_OK != (umcSts = Info->CopressedFrames->UnLockInputBuffer(&compressed_data)))
{
break;
}
yuv_data.SetDataSize(0);
if(UMC_OK != (umcSts = Info->YUVFrames->UnLockOutputBuffer(&yuv_data)))
{
break;
}
Info->m_FrameCount++;
}
// epilog
for(;;)
{
// get destination buffer
do
{
umcSts = Info->CopressedFrames->LockInputBuffer(&compressed_data);
if (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_BUFFER == umcSts);
if(UMC_OK != umcSts)
{
break;
}
// compress
t_start = GET_TICKS;
if(UMC_OK != (umcSts = pEncoder->GetFrame(NULL, &compressed_data)))
{
// put EOS and exit
compressed_data.SetDataSize(0);
compressed_data.SetTime(-1.0);
Info->CopressedFrames->UnLockInputBuffer(&compressed_data, UMC::UMC_END_OF_STREAM);
break;
}
t_end = GET_TICKS;
Info->t_encode_time += (double)(vm_var64s)(t_end-t_start)/(vm_var64s)t_freq;
if(UMC_OK != (umcSts = Info->CopressedFrames->UnLockInputBuffer(&compressed_data)))
{
break;
}
Info->m_FrameCount++;
}
//vm_string_printf("Encoded %d frames\n", Info->m_FrameCount);
return 0x0ecc;
}
unsigned int ThreadSaveFrame(void* ptr)
{
int FrameCount, size;
vm_tick t_freq, t_start, t_end;
double st,en;
VideoData data;
VideoEncoder *pEncoder;
VideoEncoderParams *Params;
FILE *out_file;
Status umcSts = UMC_OK;
assert(ptr);
EncodeInfo *Info = (EncodeInfo*)ptr;
pEncoder = Info->pEncoder;
Params = Info->Params;
out_file = vm_file_open(Info->DstFName, VM_STRING("wb"));
if(!out_file)
{
vm_string_printf( __VM_STRING("Cann't open out file\n"));
return 0;
}
t_freq = vm_time_get_frequency();
FrameCount = 0;
while(umcSts == UMC_OK)
{
do
{
umcSts = Info->CopressedFrames->LockOutputBuffer(&data);
if (UMC::UMC_NOT_ENOUGH_DATA == umcSts)
vm_time_sleep(5);
} while (UMC::UMC_NOT_ENOUGH_DATA == umcSts);
if(UMC_OK != umcSts)
{
break;
}
//vm_string_printf(__VM_STRING("Sav: %f\n"),data.GetTime());
data.GetTime(st,en);
size = (int)data.GetDataSize();
t_start = vm_time_get_tick();
if (1 != fwrite(data.GetDataPointer(), size, 1, out_file))
{
break;
}
Info->m_EncodedSize += size;
assert(size == (int)data.GetDataSize());
t_end = vm_time_get_tick();
Info->t_write_time += (double)(vm_var64s)(t_end-t_start)/(vm_var64s)t_freq;
data.SetDataSize(0);
if(UMC_OK != (umcSts = Info->CopressedFrames->UnLockOutputBuffer(&data)))
{
break;
}
FrameCount++;
}
fclose(out_file);
return 0x0123;
}
int encode_threaded(VideoEncoder *Encoder,
VideoEncoderParams *Params,
UMCReadYUV *YUVReader,
vm_char *DstFileName,
int *encoded_size,
double *enc_time)
{
EncodeInfo Info[1];
VideoBufferParams bufferPar;
int i = 1;
vm_thread m_hThreadLoad[1];
vm_thread m_hThreadEnc[1];
vm_thread m_hThreadSave[1];
Info->pEncoder = Encoder;
Info->Params = Params;
Info->YUVReader = YUVReader;
Info->umcCFormat = YUVReader->mColorFormat;
vm_string_strcpy(Info->DstFName, DstFileName);
Info->m_FrameCount = 0;
Info->m_EncodedSize = 0;
Info->t_read_time = 0;
Info->t_encode_time = 0;
Info->t_write_time = 0;
// Init YUVFrames
bufferPar.m_numberOfFrames = 16;
bufferPar.m_prefInputBufferSize =
bufferPar.m_prefOutputBufferSize = 2*YUVReader->mFrameSize;
if(UMC_OK != (Info->YUVFrames->Init(&bufferPar)))
{
vm_string_printf( __VM_STRING("Video Buffer for YUV creation failed\n"));
goto __exit_out;
}
// Init CopressedFrames
bufferPar.m_numberOfFrames = 4;
if(UMC_OK != (Info->CopressedFrames->Init(&bufferPar)))
{
vm_string_printf( __VM_STRING("Video Buffer for MPEG2 stream creation failed\n"));
goto __exit_out;
}
vm_thread_set_invalid(m_hThreadLoad);
if(!vm_thread_create(m_hThreadLoad, ThreadLoadFrame, Info))
{
vm_string_printf(__VM_STRING("ThreadLoadFrame creation failed\n"));
goto __exit_out;
}
vm_thread_set_priority(m_hThreadLoad, VM_THREAD_PRIORITY_HIGHEST);
vm_thread_set_invalid(m_hThreadEnc);
if(!vm_thread_create(m_hThreadEnc, ThreadEncoding, Info))
{
vm_string_printf(__VM_STRING("ThreadEncoding creation failed\n"));
goto __exit_out;
}
vm_thread_set_priority(m_hThreadEnc, VM_THREAD_PRIORITY_HIGH);
vm_thread_set_invalid(m_hThreadSave);
if(!vm_thread_create(m_hThreadSave, ThreadSaveFrame, Info))
{
vm_string_printf(__VM_STRING("ThreadSaveFrame creation failed\n"));
goto __exit_out;
}
vm_thread_set_priority(m_hThreadSave, VM_THREAD_PRIORITY_LOWEST);
vm_thread_wait(m_hThreadLoad);
vm_thread_wait(m_hThreadEnc);
vm_thread_wait(m_hThreadSave);
vm_thread_close(m_hThreadLoad);
vm_thread_close(m_hThreadEnc);
vm_thread_close(m_hThreadSave);
__exit_out:
Info->CopressedFrames->Close();
Info->YUVFrames->Close();
*encoded_size = Info->m_EncodedSize;
*enc_time = Info->t_encode_time;
return 0;
}