📄 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -