⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_transcoder_con_threads.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_transcoder_con.h"

// start threads
UMC::Status Transcoder::Run(void)
{
    if (!m_bInit)
        return UMC::UMC_ERR_NOT_INITIALIZED;

    // run working thread(s)
    // start video thread(s)
    if (m_TranscoderParams.video_stream_type != UMC::UNDEF_VIDEO)
        if (0 == vm_thread_create(&m_hVideoTranscoding, VideoTranscodingThreadRoutine, this))
            return UMC::UMC_ERR_FAILED;

    // start audio thread(s)
    if (m_TranscoderParams.audio_stream_type != UMC::UNDEF_AUDIO)
    {
        if (0 == vm_thread_create(&m_hAudioDecoding, AudioDecodingThreadRoutine, this))
            return UMC::UMC_ERR_FAILED;

        if (0 == vm_thread_create(&m_hAudioEncoding, AudioEncodingThreadRoutine, this))
            return UMC::UMC_ERR_FAILED;
    }
    return UMC::UMC_OK;
} //UMC::Status Transcoder::Run(void)


Ipp32u VM_THREAD_CALLCONVENTION VideoTranscodingThreadRoutine(void *lpvParam)
{
    Transcoder *lpTrans = reinterpret_cast<Transcoder*>(lpvParam);
    if (!lpTrans)
        return 0;

    return lpTrans->VideoTranscoding();
}//Ipp32u VM_THREAD_CALLCONVENTION VideoTranscodingThreadRoutine(void *lpvParam)

//video transcoding routine
Ipp32u Transcoder::VideoTranscoding()
{
    if (!m_bInit)
    {
        vm_debug_message(VM_STRING("Transcoder isn't initialized\n"));
        error_status = true;
        return 0;
    }

    UMC::MediaData MediaSrc;
    UMC::VideoData MediaDst;
    UMC::MediaData MediaEncoded;

    UMC::Status umcRes = UMC::UMC_OK;

    Ipp64f cpu_tick_time = 1.0/(Ipp64f)(Ipp64s)vm_time_get_frequency();
    vm_tick tStart, tEnd;
    vm_tick t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;

    UMC::VideoEncoderParams *lpEncoderParams = DynamicCast<UMC::VideoEncoderParams>(m_lpVideoEncoderParams);

    Ipp32u fsize = m_video_info.clip_info.width *
                   m_video_info.clip_info.height * 4;

    Ipp8u* b_ptr = new Ipp8u[fsize];

    MediaDst.Init(m_video_info.clip_info.width,
                  m_video_info.clip_info.height,
                  UMC::YUV420);
    MediaDst.Alloc();

    // get start tick
    tStart = vm_time_get_tick();

    UMC::MediaData mux_data;

    bool spl_end_of_stream = false,
         dec_end_of_stream = false;

    // main working cycle
    while (false == m_bExit)
    {
        t0 = vm_time_get_tick();

        if (!dec_end_of_stream)
        {
            if (!spl_end_of_stream)
            {
                // decompress
                // get new video position
                if (4 > MediaSrc.GetDataSize() || umcRes == UMC::UMC_ERR_NOT_ENOUGH_DATA)
                    umcRes = m_lpVideoSplitter->GetNextData(&MediaSrc, video_track_num);
                else
                    umcRes = UMC::UMC_OK;

                // check error(s)
                if (umcRes != UMC::UMC_OK)
                {
                    if (umcRes == UMC::UMC_ERR_NOT_ENOUGH_DATA || umcRes == UMC::UMC_WRN_REPOSITION_INPROGRESS)
                    {
                        vm_time_sleep(TIME_TO_SLEEP);
                        continue;
                    }
                    else if (umcRes == UMC::UMC_ERR_END_OF_STREAM)
                    {
                        spl_end_of_stream = true;
                        continue;
                    }

                    vm_debug_message(VM_STRING("m_lpVideoSplitter->GetNextVideoData: %d\n"), umcRes);
                    break;
                }
            }

            // decompress frame
            umcRes = m_lpVideoDecoder->GetFrame(spl_end_of_stream ? NULL : &MediaSrc, &MediaDst);
            if (umcRes != UMC::UMC_OK)
            {
                if ((umcRes == UMC::UMC_ERR_NOT_ENOUGH_DATA || umcRes == UMC::UMC_ERR_SYNC ||
                    umcRes == UMC::UMC_WRN_INVALID_STREAM) && !spl_end_of_stream)
                {
                    vm_time_sleep(TIME_TO_SLEEP);
                    continue;
                }

                else if (umcRes == UMC::UMC_ERR_NOT_ENOUGH_DATA && spl_end_of_stream)
                {
                    dec_end_of_stream = true;
                    continue;
                }

                vm_debug_message(VM_STRING("m_lpVideoDecoder->GetFrame: %d\n"), umcRes);
                break;
            }

            t3 = t1 = vm_time_get_tick();

            MediaEncoded.SetBufferPointer(b_ptr, fsize);
            MediaEncoded.SetDataSize(0);

            //do not confuse encoder with scecific frame type
            MediaDst.SetFrameType(UMC::NONE_PICTURE);
        }

        // encode frame
        umcRes = m_lpVideoEncoder->GetFrame(dec_end_of_stream ? NULL : &MediaDst, &MediaEncoded);

        // check error(s)
        if (UMC::UMC_OK != umcRes)
        {
            if (umcRes == UMC::UMC_WRN_INVALID_STREAM)
                continue;

            vm_debug_message(VM_STRING("m_lpVideoEncoder->GetFrame: %d\n"), umcRes);
            break;
        }

        t4 = vm_time_get_tick();

        mux_data.SetBufferPointer((Ipp8u*)MediaEncoded.GetBufferPointer(), MediaEncoded.GetDataSize());
        memcpy(mux_data.GetDataPointer(), MediaEncoded.GetDataPointer(), MediaEncoded.GetDataSize());
        mux_data.SetDataSize(MediaEncoded.GetDataSize());
        mux_data.SetTime(MediaEncoded.GetTime());

        // write to muxer
        do
        {
            umcRes = m_lpMuxer->PutVideoData(&mux_data);
            if (UMC::UMC_ERR_NOT_ENOUGH_BUFFER == umcRes)
                vm_time_sleep(TIME_TO_SLEEP);

        } while ((false == m_bExit) && (UMC::UMC_ERR_NOT_ENOUGH_BUFFER == umcRes));

        // check error(s)
        if (UMC::UMC_OK != umcRes)
        {
            vm_debug_message(VM_STRING("m_lpMuxer->PutVideoData: %d\n"), umcRes);
            break;
        }
         // inc encoded frame(s)
         m_lEncodedFrames ++;

         // get end tick
         tEnd = vm_time_get_tick();
         t5 = tEnd;

         // inc elapsed time
         m_dElapsedTime = (Ipp64s)(tEnd - tStart)*cpu_tick_time;
         time_counter1 += (Ipp64s)(t1 - t0)*cpu_tick_time;
         time_counter2 += (Ipp64s)(t2 - t1)*cpu_tick_time;
         time_counter3 += (Ipp64s)(t3 - t2)*cpu_tick_time;
         time_counter4 += (Ipp64s)(t4 - t3)*cpu_tick_time;
         time_counter5 += (Ipp64s)(t5 - t4)*cpu_tick_time;

         vm_time_sleep(TIME_TO_SWITCH_THREAD);
    }

    for (Ipp32s track = number_of_audio_tracks; track < number_of_video_tracks + number_of_audio_tracks; track ++)
        m_lpMuxer->PutEndOfStream(track);

    delete [] b_ptr;

    bool video_errs = !(UMC::UMC_OK == umcRes || UMC::UMC_ERR_NOT_ENOUGH_DATA == umcRes || UMC::UMC_ERR_END_OF_STREAM == umcRes);
    error_status |= video_errs;

    return video_errs;
} //unsigned Ipp32u Transcoder::VideoTranscodingThreadRoutine(void *lpvParam)

Ipp32u VM_THREAD_CALLCONVENTION AudioDecodingThreadRoutine(void *lpvParam)
{
    Transcoder *lpTrans = reinterpret_cast<Transcoder*>(lpvParam);
    if (!lpTrans)
        return 0;

    return lpTrans->AudioDecoding();
}//Ipp32u VM_THREAD_CALLCONVENTION AudioDecodingThreadRoutine(void *lpvParam)

Ipp32u VM_THREAD_CALLCONVENTION AudioEncodingThreadRoutine(void *lpvParam)
{
    Transcoder *lpTrans = reinterpret_cast<Transcoder*>(lpvParam);
    if (!lpTrans)
        return 0;

    return lpTrans->AudioEncoding();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -