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

📄 umc_mpeg2_dec.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 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-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_mpeg2_dec_base.h"#include "umc_mpeg2_dec.h"#include "umc_mpeg2_dec_tbl.h"#include "umc_media_data_ex.h"#include "umc_video_data.h"#include "vm_sys_info.h"#include "vm_time.h"using namespace UMC;bool MPEG2VideoDecoderBase::InitColorConverter(BaseCodecParams *pInit){    VideoDecoderParams *init = DynamicCast<VideoDecoderParams, BaseCodecParams>(pInit);    if(!init)        return false;    memset(&m_Convert, 0, sizeof(ColorConversionParams));    memset(&m_ConvertPreview, 0, sizeof(ColorConversionParams));    m_lpConverter = NULL;    m_maxThreads  = 1;    m_decodedFrameNum = 0;    m_lpConverter = init->lpConverter;    if(init->lpConvertInit)    {        // initialize convertion param(s)        m_Convert.ConversionInit = *(init->lpConvertInit);        init->lFlags &= ~FLAG_VDEC_UVMERGED;        m_Convert.ConversionInit.FormatSource = YUV420;        // if second picture desired        if (NULL != init->lpConvertInitPreview)        {            m_bTwoPictures = true;            m_ConvertPreview.ConversionInit = *(init->lpConvertInitPreview);            m_ConvertPreview.ConversionInit.FormatSource = YUV420;        } else {            m_bTwoPictures = false;        }    }    return true;}static IppStatus mp2_HuffmanTableInitAlloc(Ipp32s *tbl, int bits_table0, mp2_VLCTable *vlc){  Ipp32s *ptbl;  Ipp16s bad_value = 0;  int max_bits;  int num_tbl;  int i, j, k, m, n;  int bits, code, value;  int bits0, bits1;  int min_value, max_value, spec_value;  int min_code0, min_code1;  int max_code0, max_code1;  int prefix_code1 = -1;  int bits_table1 = 0;  int *buffer = NULL;  int *codes;  int *cbits;  int *values;  Ipp16s *table0 = NULL;  Ipp16s *table1 = NULL;  /* get number of entries (n) */  max_bits = *tbl++;  num_tbl = *tbl++;  for (i = 0; i < num_tbl; i++) {    *tbl++;  }  n = 0;  ptbl = tbl;  for (bits = 1; bits <= max_bits; bits++) {    m = *ptbl;    if (m < 0) break;    n += m;    ptbl += 2*m + 1;  }  /* alloc internal table */  buffer = new int[3*n];  if (!buffer) return ippStsErr;  codes = buffer;  cbits = buffer + n;  values = buffer + 2*n;  /* read VLC to internal table */  min_value = 0x7fffffff;  max_value = 0;  spec_value = 0;  ptbl = tbl;  k = 0;  for (bits = 1; bits <= max_bits; bits++) {    if (*ptbl < 0) break;    m = *ptbl++;    for (i = 0; i < m; i++) {      code = *ptbl++;      value = *ptbl++;      code &= ((1 << bits) - 1);      if (value < min_value) min_value = value;      if (value > max_value) {        if (!spec_value && value >= 0xffff) {          spec_value = value;        } else {          max_value = value;        }      }      codes[k] = code << (30 - bits);      cbits[k] = bits;      values[k] = value;      k++;    }  }  if (!bits_table0) {    bits_table0 = max_bits;    bits_table1 = 0;    vlc->threshold_table0 = 0;  }  bits0 = bits_table0;  if (bits0 > 0 && bits0 < max_bits) {    min_code0 = min_code1 = 0x7fffffff;    max_code0 = max_code1 = 0;    for (i = 0; i < n; i++) {      code = codes[i];      bits = cbits[i];      if (bits <= bits0) {        if (code > max_code0) max_code0 = code;        if (code < min_code0) min_code0 = code;      } else {        if (code > max_code1) max_code1 = code;        if (code < min_code1) min_code1 = code;      }    }    if ((max_code0 < min_code1) || (max_code1 < min_code0)) {      for (j = 0; j < 29; j++) {        if ((min_code1 ^ max_code1) & (1 << (29 - j))) break;      }      bits1 = max_bits - j;      if (bits0 == bits_table0) {        bits_table1 = bits1;        prefix_code1 = min_code1 >> (30 - bits0);        vlc->threshold_table0 = min_code0 >> (30 - max_bits);      }    }  }  if (bits_table0 > 0 && bits_table0 < max_bits && !bits_table1) {    if (buffer) delete[] buffer;    return ippStsErr;  }  bad_value = (bad_value << 8) | VLC_BAD;  table0 = ippsMalloc_16s(1 << bits_table0);  ippsSet_16s(bad_value, table0, 1 << bits_table0);  if (bits_table1) {    table1 = ippsMalloc_16s(1 << bits_table1);    ippsSet_16s(bad_value, table1, 1 << bits_table1);  }  for (i = 0; i < n; i++) {    code = codes[i];    bits = cbits[i];    value = values[i];    if (bits <= bits_table0) {      code = code >> (30 - bits_table0);      for (j = 0; j < (1 << (bits_table0 - bits)); j++) {        table0[code + j] = (Ipp16s)((value << 8) | bits);      }    } else {      code = code >> (30 - max_bits);      code = code & ((1 << bits_table1) - 1);      for (j = 0; j < (1 << (max_bits - bits)); j++) {        table1[code + j] = (Ipp16s)((value << 8) | bits);      }    }  }  if (bits_table1) { // fill VLC_NEXTTABLE    if (prefix_code1 == -1) {      if (buffer) delete[] buffer;      return ippStsErr;    }    bad_value = (bad_value &~ 255) | VLC_NEXTTABLE;    for (j = 0; j < (1 << ((bits_table0 - (max_bits - bits_table1)))); j++) {      table0[prefix_code1 + j] = bad_value;    }  }  vlc->max_bits = max_bits;  vlc->bits_table0 = bits_table0;  vlc->bits_table1 = bits_table1;  vlc->table0 = table0;  vlc->table1 = table1;  if (buffer) delete[] buffer;  return ippStsNoErr;}static void mp2_HuffmanTableFree(mp2_VLCTable *vlc) {  if (vlc->table0) {    ippsFree(vlc->table0);    vlc->table0 = NULL;  }  if (vlc->table1) {    ippsFree(vlc->table1);    vlc->table1 = NULL;  }}bool MPEG2VideoDecoderBase::InitTables(){  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(MBAdressing, 5, &vlcMBAdressing))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(IMBType, 0, &vlcMBType[0]))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(PMBType, 0, &vlcMBType[1]))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(BMBType, 0, &vlcMBType[2]))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(MBPattern, 5, &vlcMBPattern))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(MotionVector, 5, &vlcMotionVector))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(dct_dc_size_luma, 5, &vlcDctDcSizeLuma))    return false;  if (ippStsNoErr != mp2_HuffmanTableInitAlloc(dct_dc_size_chroma, 5, &vlcDctDcSizeChroma))    return false;    memset(&vlcTables, 0, sizeof(vlcTables));    if (ippStsNoErr != ippiHuffmanTableInitAlloc_32s(dct_dc_size_luma, &vlcTables.ippTableB5a))        return false;    if (ippStsNoErr != ippiHuffmanTableInitAlloc_32s(dct_dc_size_chroma, &vlcTables.ippTableB5b))        return false;    return true;}bool MPEG2VideoDecoderBase::DeleteTables(){    // release tools    if(Video)    {#ifdef KEEP_HISTORY        if(Video[0].frame_buffer.frame_p_c_n[0].frame_history)        {            ippsFree(Video[0].frame_buffer.frame_p_c_n[0].frame_history);            Video[0].frame_buffer.frame_p_c_n[0].frame_history = NULL;        }        if(Video[0].frame_buffer.frame_p_c_n[1].frame_history)        {            ippsFree(Video[0].frame_buffer.frame_p_c_n[1].frame_history);            Video[0].frame_buffer.frame_p_c_n[1].frame_history = NULL;        }        if(Video[0].frame_buffer.frame_p_c_n[2].frame_history)        {            ippsFree(Video[0].frame_buffer.frame_p_c_n[2].frame_history);            Video[0].frame_buffer.frame_p_c_n[2].frame_history = NULL;        }#endif        for(int i = 0; i < m_nNumberOfAllocatedThreads; i++)        {            if(Video[i].block.idct)            {                ippsFree((void*)Video[i].block.idct);                Video[i].block.idct = NULL;            }            if(Video[i].block.dq)            {                ippsFree((void*)Video[i].block.dq);                Video[i].block.dq = NULL;            }        }        ippsFree(Video);        Video = NULL;    }    if(sequenceHeader.ptr_context_data)    {        ippsFree(sequenceHeader.ptr_context_data);        sequenceHeader.ptr_context_data = NULL;    }    // release tables    mp2_HuffmanTableFree(&vlcMBAdressing);    mp2_HuffmanTableFree(&vlcMBType[0]);    mp2_HuffmanTableFree(&vlcMBType[1]);    mp2_HuffmanTableFree(&vlcMBType[2]);    mp2_HuffmanTableFree(&vlcMBPattern);    mp2_HuffmanTableFree(&vlcMotionVector);    mp2_HuffmanTableFree(&vlcDctDcSizeLuma);    mp2_HuffmanTableFree(&vlcDctDcSizeChroma);    if(vlcTables.ippTableB5a)    {        ippiHuffmanTableFree_32s(vlcTables.ippTableB5a);        vlcTables.ippTableB5a = NULL;    }    if(vlcTables.ippTableB5b)    {        ippiHuffmanTableFree_32s(vlcTables.ippTableB5b);        vlcTables.ippTableB5b = NULL;    }    return UMC_OK;}unsigned int MPEG2VideoDecoderBase::ThreadWorkingRoutine(void *lpv){    THREAD_ID *             lpThreadId;    MPEG2VideoDecoderBase * lpOwner;    // check error(s)    if (NULL == lpv)        return 0xbaadf00d;    lpThreadId  = reinterpret_cast<THREAD_ID *> (lpv);    lpOwner     = reinterpret_cast<MPEG2VideoDecoderBase *> (lpThreadId->m_lpOwner);    // wait for start    vm_event_wait(lpOwner->m_lpStartEvent + lpThreadId->m_nNumber);    while (VM_TIMEOUT == vm_event_timed_wait(&(lpOwner->m_lpQuit[lpThreadId->m_nNumber]), 0))    {        lpOwner->DecodeSlices(lpThreadId->m_nNumber);        // set finish        vm_event_signal(lpOwner->m_lpStopEvent + lpThreadId->m_nNumber);        // wait for start        vm_event_wait(lpOwner->m_lpStartEvent + lpThreadId->m_nNumber);    }    return lpThreadId->m_nNumber;}Status MPEG2VideoDecoderBase::ThreadingSetup(){    int i;    Video = (IppVideoContext*)ippsMalloc_8u(m_nNumberOfThreads*sizeof(IppVideoContext));    if(!Video) return UMC_ALLOC;    memset(Video, 0, m_nNumberOfThreads*sizeof(IppVideoContext));    for(i = 0; i < m_nNumberOfThreads; i++)    {        Video[i].block.idct = ippsMalloc_16s(128*12);        if(!Video[i].block.idct) return UMC_ALLOC;        Video[i].block.dq   = ippsMalloc_16s(128);        if(!Video[i].block.dq) return UMC_ALLOC;    }    // create threading tools    if (1 < m_nNumberOfThreads)    {        // create exit event(s)        m_lpQuit = new vm_event[m_nNumberOfThreads];        if (NULL == m_lpQuit)            return UMC_FAILED_TO_ALLOCATE_BUFFER;        for (i = 1; i < m_nNumberOfThreads; i++)        {            vm_event_set_invalid(m_lpQuit + i);            if (VM_OK != vm_event_init(m_lpQuit + i, 0, 0))                return UMC_FAILED_TO_INITIALIZE;        }        // create start event(s)        m_lpStartEvent = new vm_event[m_nNumberOfThreads];        if (NULL == m_lpStartEvent)            return UMC_FAILED_TO_ALLOCATE_BUFFER;        for (i = 1; i < m_nNumberOfThreads; i++)        {            vm_event_set_invalid(m_lpStartEvent + i);            if (VM_OK != vm_event_init(m_lpStartEvent + i, 0, 0))                return UMC_FAILED_TO_INITIALIZE;        }        // create stop event(s)        m_lpStopEvent = new vm_event[m_nNumberOfThreads];        if (NULL == m_lpStopEvent)            return UMC_FAILED_TO_ALLOCATE_BUFFER;        for (i = 1;i < m_nNumberOfThreads;i += 1)        {            vm_event_set_invalid(m_lpStopEvent + i);            if (VM_OK != vm_event_init(m_lpStopEvent + i, 0, 0))                return UMC_FAILED_TO_INITIALIZE;        }        // allocate thread ID(s)        m_lpThreadsID = new THREAD_ID[m_nNumberOfThreads];        if (NULL == m_lpThreadsID)            return UMC_FAILED_TO_ALLOCATE_BUFFER;        // starting thread(s)        m_lpThreads = new vm_thread[m_nNumberOfThreads];        if (NULL == m_lpThreads)            return UMC_FAILED_TO_ALLOCATE_BUFFER;        for (i = 1;i < m_nNumberOfThreads;i += 1)        {            vm_thread_set_invalid(m_lpThreads + i);            m_lpThreadsID[i].m_nNumber = i;            m_lpThreadsID[i].m_lpOwner = this;            if (0 == vm_thread_create(m_lpThreads + i, ThreadWorkingRoutine, m_lpThreadsID + i))                return UMC_FAILED_TO_INITIALIZE;        }    }    m_nNumberOfAllocatedThreads = m_nNumberOfThreads;    return UMC_OK;}Status MPEG2VideoDecoderBase::Init(BaseCodecParams *pInit){    MediaData *data;    if((m_lFlags & FLAG_VSPL_4BYTE_ACCESS) != 0)      return UMC_UNSUPPORTED;    decodeIntraSpec = (IppiDecodeIntraSpec_MPEG2*)(intraBuff + ((16 - (int)intraBuff) & 15));    decodeInterSpec = (IppiDecodeInterSpec_MPEG2*)(interBuff + ((16 - (int)interBuff) & 15));    ippiDecodeInterInit_MPEG2(NULL, IPPVC_MPEG1_STREAM, decodeInterSpec);    decodeIntraSpec->intraVLCFormat = PictureHeader.intra_vlc_format = 0;    decodeIntraSpec->intraShiftDC = PictureHeader.curr_intra_dc_multi = intra_dc_multi[0];    VideoDecoderParams *init = DynamicCast<VideoDecoderParams, BaseCodecParams>(pInit);    if(!init)        return UMC_FAILED_TO_INITIALIZE;    m_pConverter = init->lpConverter;    if (false == InitColorConverter(init))        return UMC_FAILED_TO_INITIALIZE;    if (false == InitTables())        return UMC_FAILED_TO_INITIALIZE;    data = init->m_pData;    m_bNoBframes   = false;    m_bNoPframes   = false;    m_ccCurrData.SetBufferPointer(NULL, 0);    m_pCCData = new SampleBuffer;    if(m_pCCData)    {        Status res = UMC_OK;        MediaBufferParams initPar;        initPar.m_prefInputBufferSize = initPar.m_prefOutputBufferSize = 1024;        initPar.m_numberOfFrames = 20;        res = m_pCCData->Init(&initPar);        if(res != UMC_OK)        {            m_pCCData->Close();            delete m_pCCData;            m_pCCData = NULL;        }    }    m_ClipInfo = init->info;    if(!init->lpConvertInit)      ulResized = 1;    else    switch(init->lpConvertInit->lFlags)    {    case FLAG_CCNV_NONE:    case FLAG_CCNV_CONVERT:        ulResized = 1;        break;    case FLAG_CCNV_RESIZE_2S:        ulResized = 2;        break;    case FLAG_CCNV_RESIZE_4S:        ulResized = 4;        break;    case FLAG_CCNV_RESIZE_8S:        ulResized = 8;        break;    case FLAG_CCNV_RESIZE_CUSTOM:    default:        ulResized = 0;        break;    }    m_lFlags = init->lFlags;    if(init->uiLimitThreads == 0)        m_nNumberOfThreads = vm_sys_info_get_cpu_num();    else        m_nNumberOfThreads = init->uiLimitThreads;    if (0 >= m_nNumberOfThreads)        m_nNumberOfThreads = 1;    else if (8 < m_nNumberOfThreads)        m_nNumberOfThreads = 8;    if(UMC_OK != ThreadingSetup())        return UMC_ALLOC;    sequenceHeader.frame_rate_extension_d = 0;    sequenceHeader.frame_rate_extension_n = 0;    if(data)    {        sequenceHeader.first_i_occure = 0;        sequenceHeader.first_p_occure = 0;        sequenceHeader.continues_pts  = 1;        sequenceHeader.stream_type = UNDEF_VIDEO;        sequenceHeader.broken_link = 0;        sequenceHeader.closed_gop  = 0;        sequenceHeader.gop_picture = 0;        sequenceHeader.gop_second  = 0;        m_decodedFrameNum          = 0;        PrepareBuffer(data);        if(UMC_OK > DecodeBegin(data->GetTime(), &init->info)) {            return UMC_NULL_PTR;        }        FlushBuffer(data, false);        m_ClipInfo.clip_info.width  = sequenceHeader.horizontal_size;        m_ClipInfo.clip_info.height = sequenceHeader.vertical_size;        m_ClipInfo.framerate        = 1.0 / sequenceHeader.delta_frame_time;        return UMC_OK;    }    else        return UMC_NULL_PTR;}Status MPEG2VideoDecoderBase::FlushBuffer(MediaData* data, bool threaded){    if((m_lFlags & FLAG_VDEC_COMPATIBLE)) {      IppVideoContext *video = &Video[0]; // it decodes tail of frame      Ipp8u* plast = GET_BYTE_PTR(video->bs);      Ipp8u* pend = GET_END_PTR(video->bs);      Ipp8u* plasta = plast - ((int)plast & 3);      if (plasta > pend) {         plasta = pend;      }      return data->MoveDataPointer(plasta - (Ipp8u*)data->GetDataPointer());    }    /* else if not m_lFlags & FLAG_VDEC_COMPATIBLE */    Status umcRes = UMC_OK;    unsigned int code;    int stDataLeft = 0;    IppVideoContext* video = 0;

⌨️ 快捷键说明

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