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

📄 umc_mpeg2_dec.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    frame_buffer.retrieve   = -1;
    frame_buffer.ind_his_p = 0;
    frame_buffer.ind_his_b = 1;
    frame_buffer.ind_his_free = 2;
    frame_buffer.frame_p_c_n[0].frame_time = -1;
    frame_buffer.frame_p_c_n[1].frame_time = -1;
    frame_buffer.frame_p_c_n[0].duration = 0;
    frame_buffer.frame_p_c_n[1].duration = 0;

    sequenceHeader.stream_time_temporal_reference = -1;
    sequenceHeader.stream_time = 0;

    return UMC_OK;
}


Status MPEG2VideoDecoderBase::FlushBuffer(MediaData* data, bool threaded)
{
    IppVideoContext *video = Video[0]; // it decodes tail of frame
    Ipp8u* plast = GET_BYTE_PTR(video->bs);
    Ipp8u* pend = GET_END_PTR(video->bs);
    if (plast > pend)
        plast = pend;
    return data->MoveDataPointer(plast - (Ipp8u*)data->GetDataPointer());
}

Status MPEG2VideoDecoderBase::PrepareBuffer(MediaData* data)
{
    IppVideoContext *video = Video[0];
    Ipp8u  *ptr;
    Ipp32s size;

    if (data == 0) {
      return UMC_OK;
    }
    ptr = (Ipp8u*)data->GetDataPointer();
    size = data->GetDataSize();

    INIT_BITSTREAM(video->bs, ptr, ptr + size);

    return UMC_OK;
}

bool MPEG2VideoDecoderBase::IsPictureToSkip()
{
  if (NONE_PICTURE >= PictureHeader.picture_coding_type ||
      B_PICTURE < PictureHeader.picture_coding_type)
  {
    if(!(PictureHeader.picture_coding_type == D_PICTURE &&
         m_ClipInfo.stream_type == MPEG1_VIDEO))
    {
      return true;
    }
  }

  if(frame_buffer.field_buffer_index == 0) // not for second field
  {
    sequenceHeader.stream_time_temporal_reference++;
    if(PictureHeader.picture_coding_type == I_PICTURE)
    {
      sequenceHeader.bdied = 0;
      if(sequenceHeader.first_i_occure)
        sequenceHeader.first_p_occure = 1;
      sequenceHeader.first_i_occure = 1;
    }
    else if(!sequenceHeader.first_i_occure) {
      return true;
    }
    else if(PictureHeader.picture_coding_type == P_PICTURE) {
      sequenceHeader.bdied = 0;
      sequenceHeader.first_p_occure = 1;
    }
    else if(PictureHeader.picture_coding_type == B_PICTURE) {
      if(!sequenceHeader.first_p_occure &&
        (!sequenceHeader.closed_gop || sequenceHeader.broken_link )) {
          return true;
        }
    }
  }

  if(PictureHeader.picture_coding_type == 3 && sequenceHeader.is_skipped_b ||
    !sequenceHeader.first_p_occure ||
    ((PictureHeader.picture_coding_type == 3) && m_bNoBframes) ||
    ((PictureHeader.picture_coding_type == 2) && m_bNoPframes))
  {
    if(sequenceHeader.bdied && sequenceHeader.first_p_occure &&
      !(((PictureHeader.picture_coding_type == 3) && m_bNoBframes) ||
      ((PictureHeader.picture_coding_type == 2) && m_bNoPframes)))
    {
      sequenceHeader.bdied = 0;
    } else {
      if(sequenceHeader.is_skipped_b > 0)
        sequenceHeader.is_skipped_b--;

      if(sequenceHeader.first_p_occure)
      {
        sequenceHeader.num_of_skipped++;
        sequenceHeader.bdied = 1;
        return true;
      }
    }
  }

  return false;
}

Status MPEG2VideoDecoderBase::GetFrame(MediaData* input, MediaData* output)
{
  Status umcRes;

  if ((NULL == input) || (NULL == input->GetDataPointer()))
  {
    Ipp64f dTime;
    if (output == 0) {
      return UMC_ERR_NULL_PTR;
    }
    if (m_decodedFrameNum <= 0) {
      return UMC_ERR_NOT_ENOUGH_DATA;
    }
    CalculateFrameTime(frame_buffer.frame_p_c_n[frame_buffer.next_index].frame_time, &dTime);
    m_decodedFrameNum--;
    frame_buffer.retrieve = frame_buffer.next_index;
    return SaveFrame(frame_buffer.next_index,
                     dTime,
                     output);
  }

  if (NULL == output) {
    return UMC_ERR_NULL_PTR;
  }

  PrepareBuffer(input);

  umcRes = DecodeFrame(Video[0], input->GetTime(), output);

  FlushBuffer(input, m_ClipInfo.stream_type == MPEG2_VIDEO); // ?

  return umcRes;
}

Status MPEG2VideoDecoderBase::DecodeFrame(IppVideoContext  *video,
                                          Ipp64f           currentTime,
                                          MediaData        *output)
{
  Status umcRes = UMC_OK;
  Ipp32u code;

  if (!sequenceHeader.is_decoded) {
    if(UMC_OK != FindSequenceHeader(Video[0]))
      return (UMC_ERR_NOT_ENOUGH_DATA);
    umcRes = DecodeSequenceHeader(Video[0]);
    if(UMC_OK != umcRes)
      return umcRes;
  }

  SHOW_BITS(video->bs, 32, code);
  do {
    GET_START_CODE(video->bs, code);
    // some headers are possible here
    if(code == (Ipp32u)UMC_ERR_NOT_ENOUGH_DATA)
      if(GET_OFFSET(video->bs) > 0) // some data was decoded
        return UMC_ERR_NOT_ENOUGH_DATA;
      else                          // no start codes found
        return UMC_ERR_SYNC;
    if(code == SEQUENCE_END_CODE)
      continue;
    if(code != PICTURE_START_CODE) {
      if (DecodeHeader(code, video) == UMC_ERR_NOT_ENOUGH_DATA) {
        return (UMC_ERR_NOT_ENOUGH_DATA);
      }
    }
  } while (code != PICTURE_START_CODE);

  umcRes = DecodeHeader(PICTURE_START_CODE, video);
  if(umcRes != UMC_OK)
    return (umcRes);

  //  We don't advance PTS for input data - we don't want to guess it
  //  without decoding.
  Ipp64f dTime;
  CalculateFrameTime(currentTime, &dTime);

  if (IsPictureToSkip()) {
    return UMC_ERR_NOT_ENOUGH_DATA;
  }

  umcRes = DecodePicture();

  if (UMC_OK != umcRes)
  { // Error in DecodePicture()

    return umcRes;
  }

  if (PictureHeader.picture_structure != IPPVC_FRAME_PICTURE &&
      frame_buffer.field_buffer_index == 1)
  {
    return UMC_ERR_NOT_ENOUGH_DATA;
  }
  m_decodedFrameNum++; // full frame decoded

  if (frame_buffer.retrieve < 0) {
    return UMC_ERR_NOT_ENOUGH_DATA;
  }
  m_decodedFrameNum--; // frame retrieved

  return SaveFrame(frame_buffer.retrieve, dTime, output);
}

// Close decoding
Status MPEG2VideoDecoderBase::Close()
{
    Ipp32s i;

    DeleteTables();

    m_dPlaybackRate = 1;

    if (m_lpThreads)
    {
        for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
            vm_event_signal(m_lpQuit + i);

        for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
            vm_event_signal(m_lpStartEvent + i);

        for (i = 1; i < m_nNumberOfAllocatedThreads;i += 1)
        {
            if (vm_thread_is_valid(m_lpThreads + i))
                vm_thread_wait(m_lpThreads + i);
        }
    }

    // delete all threading tools
    if (m_lpQuit)
    {
        for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
        {
            if (vm_event_is_valid(m_lpQuit + i))
            {
                vm_event_destroy(m_lpQuit + i);
                vm_event_set_invalid(m_lpQuit + i);
            }
        }

        delete [] m_lpQuit;
        m_lpQuit = NULL;
    }

    if (m_lpThreads)
    {
        for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
            vm_thread_set_invalid(m_lpThreads + i);

        delete [] m_lpThreads;
        m_lpThreads = NULL;
    }

    if (m_lpStartEvent)
    {
        for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
        {
            if (vm_event_is_valid(m_lpStartEvent + i))
            {
                vm_event_destroy(m_lpStartEvent + i);
                vm_event_set_invalid(m_lpStartEvent + i);
            }
        }

        delete [] m_lpStartEvent;
        m_lpStartEvent = NULL;
    }

    if (m_lpStopEvent)
    {
        for (i = 1;i < m_nNumberOfAllocatedThreads;i += 1)
        {
            if (vm_event_is_valid(m_lpStopEvent + i))
            {
                vm_event_destroy(m_lpStopEvent + i);
                vm_event_set_invalid(m_lpStopEvent + i);
            }
        }
        delete [] m_lpStopEvent;
        m_lpStopEvent = NULL;
    }

    if (m_lpThreadsID)
    {
        delete [] m_lpThreadsID;
        m_lpThreadsID = NULL;
    }
    if (m_pCCData)
    {
        delete m_pCCData;
        m_pCCData = NULL;
    }

    return UMC_OK;
}


MPEG2VideoDecoderBase::MPEG2VideoDecoderBase()
{
    Video                      = NULL;
    m_decodedFrameNum          = 0;
    m_lFlags                   = 0;
    m_ClipInfo.framerate       = 0;
    m_ClipInfo.clip_info.width =
    m_ClipInfo.clip_info.height= 100;

    memset(&sequenceHeader, 0, sizeof(sequenceHeader));
    memset(&PictureHeader, 0, sizeof(PictureHeader));
    memset(&frame_buffer, 0, sizeof(frame_buffer));

    m_ClipInfo.stream_type = UNDEF_VIDEO;
    sequenceHeader.profile = MPEG2_PROFILE_MAIN;
    sequenceHeader.level = MPEG2_LEVEL_MAIN;
    frame_buffer.allocated_mb_width = 0;
    frame_buffer.allocated_mb_height = 0;
    frame_buffer.allocated_cformat = NONE;
    frame_buffer.mid_context_data = MID_INVALID;
    frame_buffer.ptr_context_data = NULL; // internal buffer not allocated

    m_nNumberOfThreads  = 1;
    m_nNumberOfAllocatedThreads  = 1;
    m_lpQuit            = NULL;
    m_lpThreads         = NULL;
    m_lpStartEvent      = NULL;
    m_lpStopEvent       = NULL;
    m_lpThreadsID       = NULL;
    //m_pStartCodesData   = NULL;
    m_pCCData           = NULL;

    m_dPlaybackRate     = 1;

    vlcMBAdressing.table0 = vlcMBAdressing.table1 = NULL;
    vlcMBType[0].table0 = vlcMBType[0].table1 = NULL;
    vlcMBType[1].table0 = vlcMBType[1].table1 = NULL;
    vlcMBType[2].table0 = vlcMBType[2].table1 = NULL;
    vlcMBPattern.table0 = vlcMBPattern.table1 = NULL;
    vlcMotionVector.table0 = vlcMotionVector.table1 = NULL;

}

MPEG2VideoDecoderBase::~MPEG2VideoDecoderBase()
{
    Close();
}


Status    MPEG2VideoDecoderBase::ResetSkipCount()
{
    AdjustSpeed(-10);
    return UMC_OK;
}


Status    MPEG2VideoDecoderBase::SkipVideoFrame(Ipp32s count)
{
    AdjustSpeed(count);
    return UMC_OK;
}


bool MPEG2VideoDecoderBase::AdjustSpeed(Ipp32s nframe)
{
    if (nframe>0) IncreaseSpeedN(nframe);
    if (nframe<0) DecreaseSpeed(-(Ipp64f)nframe/
                                (Ipp64f)m_ClipInfo.framerate);
    return true;
}

Ipp32s MPEG2VideoDecoderBase::IncreaseSpeedN (Ipp32s numoffr)
{
    sequenceHeader.is_skipped_b+=numoffr;

    return numoffr;
}

Ipp32s MPEG2VideoDecoderBase::DecreaseSpeed(Ipp64f delta)
{
    Ipp32s num_skipp_frames = (Ipp32s)(delta * m_ClipInfo.framerate);

    if(num_skipp_frames <= 3)
        num_skipp_frames = 1;

    if(!num_skipp_frames)
        return 0;

    if(sequenceHeader.is_skipped_b > 0)
        sequenceHeader.is_skipped_b-=num_skipp_frames;

    if(sequenceHeader.is_skipped_b < 0)
        sequenceHeader.is_skipped_b = 0;
    return num_skipp_frames;

}


Ipp32s MPEG2VideoDecoderBase::IncreaseSpeed(Ipp64f delta)
{
//    IppVideoContext* video = &pContext->Video[0];
    Ipp32s num_skipp_frames = (Ipp32s)(delta * m_ClipInfo.framerate);

    if(num_skipp_frames <= 3)
        num_skipp_frames = 1;

    if(num_skipp_frames > 5)
        num_skipp_frames = 5;

    sequenceHeader.is_skipped_b+=num_skipp_frames;

    return num_skipp_frames;

}
bool MPEG2VideoDecoderBase::AdjustSpeed(Ipp64f delta)
{
    if (delta>0) IncreaseSpeed(delta);
    if (delta<0) DecreaseSpeed(-delta);
    return true;
}


Ipp32u MPEG2VideoDecoderBase::GetNumOfSkippedFrames()
{
    return sequenceHeader.num_of_skipped;
}

Status MPEG2VideoDecoderBase::Reset()
{
    sequenceHeader.first_i_occure  = 0;
    sequenceHeader.first_p_occure  = 0;
    sequenceHeader.bdied           = 0;
    sequenceHeader.broken_link = 0;
    sequenceHeader.closed_gop  = 0;
    sequenceHeader.gop_picture = 0;
    sequenceHeader.gop_second  = 0;
    sequenceHeader.stream_time = 0; //-sequenceHeader.delta_frame_time;
    sequenceHeader.frame_rate_extension_d = 0;
    sequenceHeader.frame_rate_extension_n = 0;

    PictureHeader.intra_vlc_format    = 0;
    PictureHeader.curr_intra_dc_multi = intra_dc_multi[0];

    m_decodedFrameNum          = 0;
    m_bNoBframes               = false;
    m_bNoPframes               = false;
    m_bOwnAllocator            = false;


    frame_buffer.prev_index = 0;
    frame_buffer.curr_index = 0;
    frame_buffer.next_index = 1;
    frame_buffer.retrieve   = -1;
    frame_buffer.ind_his_p  = 0;
    frame_buffer.ind_his_b  = 1;
    frame_buffer.ind_his_free = 2;
    frame_buffer.frame_p_c_n[0].frame_time = -1;
    frame_buffer.frame_p_c_n[1].frame_time = -1;
    frame_buffer.frame_p_c_n[0].duration = 0;
    frame_buffer.frame_p_c_n[1].duration = 0;
    frame_buffer.field_buffer_index  = 0;

    if (m_pCCData)
    {
      m_ccCurrData.SetBufferPointer(0,0);
      m_pCCData->Reset();
    }
    return UMC_OK;
}

⌨️ 快捷键说明

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