コード例 #1
0
ファイル: OMXClock.cpp プロジェクト: Bengt/omxplayer
OMXClock::OMXClock()
{
  m_dllAvFormat.Load();

  m_video_clock = DVD_NOPTS_VALUE;
  m_audio_clock = DVD_NOPTS_VALUE;
  m_has_video   = false;
  m_has_audio   = false;
  m_play_speed  = 1;
  m_pause       = false;
  m_iCurrentPts = DVD_NOPTS_VALUE;

  m_systemFrequency = CurrentHostFrequency();
  m_systemUsed = m_systemFrequency;
  m_pauseClock = 0;
  m_bReset = true;
  m_iDisc = 0;
  m_maxspeedadjust = 0.0;
  m_speedadjust = false;
  m_ismasterclock = true;
  m_ClockOffset = 0;
  m_fps = 25.0f;

  pthread_mutex_init(&m_lock, NULL);

  CheckSystemClock();

  OMXReset();
}
コード例 #2
0
void CVideoSyncDRM::EventHandler(int fd, unsigned int frame, unsigned int sec,
                                 unsigned int usec, void *data)
{
  drmVBlank vbl;
  VblInfo *info = (VblInfo*)data;
  int crtc = g_Windowing.GetCrtc();

  vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT);
  if (crtc == 1)
  {
    vbl.request.type = (drmVBlankSeqType)(vbl.request.type | DRM_VBLANK_SECONDARY);
  }
  else if (crtc > 1)
  {
    vbl.request.type = (drmVBlankSeqType)(vbl.request.type |
                       ((crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK));
  }
  vbl.request.sequence = 1;
  vbl.request.signal = (unsigned long)data;

  drmWaitVBlank(info->videoSync->m_fd, &vbl);

  uint64_t now = CurrentHostCounter();
  float diff = (float)(now - info->start)/CurrentHostFrequency();
  int vblanks = MathUtils::round_int(diff * info->videoSync->m_fps);
  info->start = now;

  info->videoSync->UpdateClock(vblanks, now);
}
コード例 #3
0
ファイル: OMXClock.cpp プロジェクト: mikecernio/omxplayer
OMXClock::OMXClock()
{
  m_dllAvFormat.Load();

  m_video_clock = DVD_NOPTS_VALUE;
  m_audio_clock = DVD_NOPTS_VALUE;
  m_has_video   = false;
  m_has_audio   = false;
  m_play_speed  = 1 * OMX_SLOMO_MULTIPLIER;     // Adjusting initial speed for normal video playback, so it can accomodate the new slow motion range
  m_pause       = false;
  m_iCurrentPts = DVD_NOPTS_VALUE;

  m_systemFrequency = CurrentHostFrequency();
  m_systemUsed = m_systemFrequency;
  m_pauseClock = 0;
  m_bReset = true;
  m_iDisc = 0;
  m_maxspeedadjust = 0.0;
  m_speedadjust = false;
  m_ismasterclock = true;
  m_ClockOffset = 0;
  m_fps = 25.0f;

  pthread_mutex_init(&m_lock, NULL);

  CheckSystemClock();

  OMXReset();
}
コード例 #4
0
ファイル: DVDVideoCodecVDA.cpp プロジェクト: bobo1on1/xbmc
int CDVDVideoCodecVDA::Decode(BYTE* pData, int iSize, double dts, double pts)
{
  CCocoaAutoPool pool;
  //
  if (pData)
  {
    OSStatus status;
    double sort_time;
    uint32_t avc_flags = 0;
    CFDataRef avc_demux;
    CFDictionaryRef avc_time;

    if (m_convert_bytestream)
    {
      // convert demuxer packet from bytestream (AnnexB) to bitstream
      ByteIOContext *pb;
      int demuxer_bytes;
      uint8_t *demuxer_content;

      if(m_dllAvFormat->url_open_dyn_buf(&pb) < 0)
      {
        return VC_ERROR;
      }
      demuxer_bytes = avc_parse_nal_units(m_dllAvFormat, pb, pData, iSize);
      demuxer_bytes = m_dllAvFormat->url_close_dyn_buf(pb, &demuxer_content);
      avc_demux = CFDataCreate(kCFAllocatorDefault, demuxer_content, demuxer_bytes);
      m_dllAvUtil->av_free(demuxer_content);
    }
    else
    {
      avc_demux = CFDataCreate(kCFAllocatorDefault, pData, iSize);
    }
    sort_time = (CurrentHostCounter() * 1000.0) / CurrentHostFrequency();
    avc_time = CreateDictionaryWithDisplayTime(sort_time - m_sort_time_offset, dts, pts);

    if (m_DropPictures)
      avc_flags = kVDADecoderDecodeFlags_DontEmitFrame;

    status = m_dll->VDADecoderDecode((VDADecoder)m_vda_decoder, avc_flags, avc_demux, avc_time);
    CFRelease(avc_time);
    CFRelease(avc_demux);
    if (status != kVDADecoderNoErr)
    {
      CLog::Log(LOGNOTICE, "%s - VDADecoderDecode failed, status(%d)", __FUNCTION__, (int)status);
      return VC_ERROR;
    }
  }

  // TODO: queue depth is related to the number of reference frames in encoded h.264.
  // so we need to buffer until we get N ref frames + 1.
  if (m_queue_depth < 4)
  {
    return VC_BUFFER;
  }

  return VC_PICTURE | VC_BUFFER;
}
コード例 #5
0
ファイル: DVDVideoCodecVDA.cpp プロジェクト: RoboSK/xbmc
void CDVDVideoCodecVDA::Reset(void)
{
  CCocoaAutoPool pool;
  m_dll->VDADecoderFlush((VDADecoder)m_vda_decoder, 0);

  while (m_queue_depth)
    DisplayQueuePop();

  m_sort_time_offset = (CurrentHostCounter() * 1000.0) / CurrentHostFrequency();
}
コード例 #6
0
ファイル: AEUtil.cpp プロジェクト: Arcko/xbmc
double AEDelayStatus::GetDelay()
{
  double d = 0;
  if (tick)
    d = (double)(CurrentHostCounter() - tick) / CurrentHostFrequency();
  if (d > maxcorrection)
    d = maxcorrection;

  return delay - d;
}
コード例 #7
0
ファイル: VideoSyncD3D.cpp プロジェクト: ssfdre38/xbmc
void CVideoSyncD3D::Run(CEvent& stopEvent)
{
  int64_t Now;
  int64_t LastVBlankTime;
  int NrVBlanks;
  double VBlankTime;
  int64_t systemFrequency = CurrentHostFrequency();

  // init the vblanktime
  Now = CurrentHostCounter();
  LastVBlankTime = Now;
  m_lastUpdateTime = Now - systemFrequency;
  while (!stopEvent.Signaled() && !m_displayLost && !m_displayReset)
  {
    // sleep until vblank
    Microsoft::WRL::ComPtr<IDXGIOutput> pOutput;
    DX::DeviceResources::Get()->GetOutput(&pOutput);
    HRESULT hr = pOutput->WaitForVBlank();

    // calculate how many vblanks happened
    Now = CurrentHostCounter();
    VBlankTime = (double)(Now - LastVBlankTime) / (double)systemFrequency;
    NrVBlanks = MathUtils::round_int(VBlankTime * m_fps);

    // update the vblank timestamp, update the clock and send a signal that we got a vblank
    UpdateClock(NrVBlanks, Now, m_refClock);

    // save the timestamp of this vblank so we can calculate how many vblanks happened next time
    LastVBlankTime = Now;

    if ((Now - m_lastUpdateTime) >= systemFrequency)
    {
      float fps = m_fps;
      if (fps != GetFps())
        break;
    }

    // because we had a vblank, sleep until half the refreshrate period because i think WaitForVBlank block any rendering stuf
    // without sleeping we have freeze rendering
    int SleepTime = (int)((LastVBlankTime + (systemFrequency / MathUtils::round_int(m_fps) / 2) - Now) * 1000 / systemFrequency);
    if (SleepTime > 50)
      SleepTime = 50; //failsafe
    if (SleepTime > 0)
      ::Sleep(SleepTime);
  }

  m_lostEvent.Set();
  while (!stopEvent.Signaled() && m_displayLost && !m_displayReset)
  {
    Sleep(10);
  }
}
コード例 #8
0
void CRenderSystemGLES::SetVSync(bool enable)
{
  if (m_bVSync==enable && m_bVsyncInit == true)
    return;

  if (!m_bRenderCreated)
    return;
  
  if (enable)
    CLog::Log(LOGINFO, "GLES: Enabling VSYNC");
  else
    CLog::Log(LOGINFO, "GLES: Disabling VSYNC");

  m_iVSyncMode   = 0;
  m_iVSyncErrors = 0;
  m_iSwapRate    = 0;
  m_bVSync       = enable;
  m_bVsyncInit   = true;

  SetVSyncImpl(enable);
  
  if (!enable)
    return;

  if (g_advancedSettings.m_ForcedSwapTime != 0.0)
  {
    /* some hardware busy wait on swap/glfinish, so we must manually sleep to avoid 100% cpu */
    double rate = g_graphicsContext.GetFPS();
    if (rate <= 0.0 || rate > 1000.0)
    {
      CLog::Log(LOGWARNING, "Unable to determine a valid horizontal refresh rate, vsync workaround disabled %.2g", rate);
      m_iSwapRate = 0;
    }
    else
    {
      int64_t freq;
      freq = CurrentHostFrequency();
      m_iSwapRate   = (int64_t)((double)freq / rate);
      m_iSwapTime   = (int64_t)(0.001 * g_advancedSettings.m_ForcedSwapTime * freq);
      m_iSwapStamp  = 0;
      CLog::Log(LOGINFO, "GLES: Using artificial vsync sleep with rate %f", rate);
      if(!m_iVSyncMode)
        m_iVSyncMode = 1;
    }
  }
    
  if (!m_iVSyncMode)
    CLog::Log(LOGERROR, "GLES: Vertical Blank Syncing unsupported");
  else
    CLog::Log(LOGINFO, "GLES: Selected vsync mode %d", m_iVSyncMode);
}
コード例 #9
0
ファイル: Stopwatch.cpp プロジェクト: CEikermann/xbmc
CStopWatch::CStopWatch(bool useFrameTime /*=false*/)
{
  m_timerPeriod      = 0.0f;
  m_startTick        = 0;
  m_isRunning        = false;
  m_useFrameTime     = useFrameTime;

#ifdef TARGET_POSIX
  m_timerPeriod = 1.0f / 1000.0f; // we want seconds
#else
  if (m_useFrameTime)
    m_timerPeriod = 1.0f / 1000.0f; //frametime is in milliseconds
  else
    m_timerPeriod = 1.0f / (float)CurrentHostFrequency();
#endif
}
コード例 #10
0
ファイル: VideoSyncAndroid.cpp プロジェクト: AchimTuran/xbmc
void CVideoSyncAndroid::FrameCallback(int64_t frameTimeNanos)
{
  int           NrVBlanks;
  double        VBlankTime;
  int64_t       nowtime = CurrentHostCounter();
  
  //calculate how many vblanks happened
  VBlankTime = (double)(nowtime - m_LastVBlankTime) / (double)CurrentHostFrequency();
  NrVBlanks = MathUtils::round_int(VBlankTime * m_fps);

  //save the timestamp of this vblank so we can calculate how many happened next time
  m_LastVBlankTime = nowtime;
  
  //update the vblank timestamp, update the clock and send a signal that we got a vblank
  UpdateClock(NrVBlanks, nowtime, m_refClock);
}
コード例 #11
0
CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock")
{
  m_SystemFrequency = CurrentHostFrequency();
  m_ClockSpeed = 1.0;
  m_TotalMissedVblanks = 0;
  m_UseVblank = false;

  m_CurrTime = 0;
  m_LastIntTime = 0;
  m_CurrTimeFract = 0.0;
  m_RefreshRate = 0.0;
  m_MissedVblanks = 0;
  m_VblankTime = 0;

  Start();
}
コード例 #12
0
CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock")
{
  m_SystemFrequency = CurrentHostFrequency();
  m_ClockSpeed = 1.0;
  m_ClockOffset = 0;
  m_TotalMissedVblanks = 0;
  m_UseVblank = false;

  m_CurrTime = 0;
  m_LastIntTime = 0;
  m_CurrTimeFract = 0.0;
  m_fineadjust = 0.0;
  m_RefreshRate = 0.0;
  m_MissedVblanks = 0;
  m_VblankTime = 0;

  m_pVideoSync = nullptr;
}
コード例 #13
0
ファイル: RenderSystemGL.cpp プロジェクト: Dukeboys/xbmc
bool CRenderSystemGL::PresentRender(const CDirtyRegionList& dirty)
{
  if (!m_bRenderCreated)
    return false;

  if (m_iVSyncMode != 0 && m_iSwapRate != 0)
  {
    int64_t curr, diff, freq;
    curr = CurrentHostCounter();
    freq = CurrentHostFrequency();

    if(m_iSwapStamp == 0)
      m_iSwapStamp = curr;

    /* calculate our next swap timestamp */
    diff = curr - m_iSwapStamp;
    diff = m_iSwapRate - diff % m_iSwapRate;
    m_iSwapStamp = curr + diff;

    /* sleep as close as we can before, assume 1ms precision of sleep *
     * this should always awake so that we are guaranteed the given   *
     * m_iSwapTime to do our swap                                     */
    diff = (diff - m_iSwapTime) * 1000 / freq;
    if (diff > 0)
      Sleep((DWORD)diff);
  }

  bool result = PresentRenderImpl(dirty);
  m_latencyCounter++;

  if (m_iVSyncMode && m_iSwapRate != 0)
  {
    int64_t curr, diff;
    curr = CurrentHostCounter();

    diff = curr - m_iSwapStamp;
    m_iSwapStamp = curr;

    if (MathUtils::abs(diff - m_iSwapRate) < MathUtils::abs(diff))
      CLog::Log(LOGDEBUG, "%s - missed requested swap",__FUNCTION__);
  }

  return result;
}
コード例 #14
0
ファイル: DVDClock.cpp プロジェクト: Kahlzarg/xbmc
CDVDClock::CDVDClock()
{
  CSingleLock lock(m_systemsection);

  m_pauseClock = 0;
  m_bReset = true;
  m_iDisc = 0;
  m_maxspeedadjust = 0.0;
  m_systemAdjust = 0;
  m_speedAdjust = 0;
  m_startClock = 0;
  m_vSyncAdjust = 0;
  m_frameTime = DVD_TIME_BASE / 60.0;

  m_videoRefClock.reset(new CVideoReferenceClock());
  m_lastSystemTime = m_videoRefClock->GetTime();
  m_systemOffset = m_videoRefClock->GetTime();
  m_systemFrequency = CurrentHostFrequency();
  m_systemUsed = m_systemFrequency;
}
コード例 #15
0
ファイル: VideoSyncDRM.cpp プロジェクト: 69thelememt/xbmc
void CVideoSyncDRM::EventHandler(int fd, unsigned int frame, unsigned int sec,
                                 unsigned int usec, void *data)
{
  drmVBlank vbl;
  VblInfo *info = (VblInfo*)data;
  drmVBlankSeqType crtcSel = CrtcSel();

  vbl.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT | crtcSel);
  vbl.request.sequence = 1;
  vbl.request.signal = (unsigned long)data;

  drmWaitVBlank(info->videoSync->m_fd, &vbl);

  uint64_t now = CurrentHostCounter();
  float diff = (float)(now - info->start)/CurrentHostFrequency();
  int vblanks = MathUtils::round_int(diff * info->videoSync->m_fps);
  info->start = now;

  info->videoSync->UpdateClock(vblanks, now);
}
コード例 #16
0
ファイル: OMXPlayerAudio.cpp プロジェクト: ojp5/xbmc
OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent)
: CThread("OMXPlayerAudio")
, m_messageQueue("audio")
, m_messageParent(parent)
{
  m_av_clock      = av_clock;
  m_pAudioCodec   = NULL;
  m_speed         = DVD_PLAYSPEED_NORMAL;
  m_started       = false;
  m_stalled       = false;
  m_audioClock    = 0;
  m_buffer_empty  = false;
  m_nChannels     = 0;
  m_DecoderOpen   = false;
  m_freq          = CurrentHostFrequency();
  m_send_eos      = false;
  m_bad_state     = false;
  m_hints_current.Clear();

  m_av_clock->SetMasterClock(false);

  m_messageQueue.SetMaxDataSize(3 * 1024 * 1024);
  m_messageQueue.SetMaxTimeSize(8.0);
  m_use_passthrough = false;
  m_passthrough = false;
  m_use_hw_decode = false;
  m_hw_decode = false;
  m_silence = false;
  m_error = 0.0;
  m_errorbuff = 0.0;
  m_errorcount = 0;
  m_syncclock = false;
  m_integral = 0.0;
  m_skipdupcount = 0;
  m_prevskipped = false;
  m_flush = false;  
  m_synctype = 0;

}
コード例 #17
0
OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock,
                               CDVDMessageQueue& parent)
: CThread("COMXPlayerAudio")
, m_messageQueue("audio")
, m_messageParent(parent)
{
  m_av_clock      = av_clock;
  m_pAudioCodec   = NULL;
  m_speed         = DVD_PLAYSPEED_NORMAL;
  m_started       = false;
  m_stalled       = false;
  m_audioClock    = 0;
  m_buffer_empty  = false;
  m_nChannels     = 0;
  m_DecoderOpen   = false;
  m_freq          = CurrentHostFrequency();
  m_hints_current.Clear();

  m_av_clock->SetMasterClock(false);

  m_messageQueue.SetMaxDataSize(3 * 1024 * 1024);
  m_messageQueue.SetMaxTimeSize(8.0);
}
コード例 #18
0
ファイル: TextureManager.cpp プロジェクト: Karlson2k/xbmc
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */)
{
  std::string strPath;
  static CTextureArray emptyTexture;
  int bundle = -1;
  int size = 0;
  if (!HasTexture(strTextureName, &strPath, &bundle, &size))
    return emptyTexture;

  if (size) // we found the texture
  {
    for (int i = 0; i < (int)m_vecTextures.size(); ++i)
    {
      CTextureMap *pMap = m_vecTextures[i];
      if (pMap->GetName() == strTextureName)
      {
        //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
        return pMap->GetTexture();
      }
    }
    // Whoops, not there.
    return emptyTexture;
  }

  for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i)
  {
    CTextureMap* pMap = i->first;
    if (pMap->GetName() == strTextureName && i->second > 0)
    {
      m_vecTextures.push_back(pMap);
      m_unusedTextures.erase(i);
      return pMap->GetTexture();
    }
  }

  if (checkBundleOnly && bundle == -1)
    return emptyTexture;

  //Lock here, we will do stuff that could break rendering
  CSingleLock lock(g_graphicsContext);

#ifdef _DEBUG_TEXTURES
  int64_t start;
  start = CurrentHostCounter();
#endif

  if (StringUtils::EndsWithNoCase(strPath, ".gif"))
  {
    CTextureMap* pMap = nullptr;

    if (bundle >= 0)
    {
      CBaseTexture **pTextures;
      int nLoops = 0, width = 0, height = 0;
      int* Delay;
      int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay);
      if (!nImages)
      {
        CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
        delete [] pTextures;
        delete [] Delay;
        return emptyTexture;
      }

      pMap = new CTextureMap(strTextureName, width, height, nLoops);
      for (int iImage = 0; iImage < nImages; ++iImage)
      {
        pMap->Add(pTextures[iImage], Delay[iImage]);
      }

      delete [] pTextures;
      delete [] Delay;
    }
    else
    {
#if defined(HAS_GIFLIB)
      Gif gif;
      if(!gif.LoadGif(strPath.c_str()))
      {
        if (StringUtils::StartsWith(strPath, g_SkinInfo->Path()))
          CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str());
        return emptyTexture;
      }

      pMap = new CTextureMap(strTextureName, gif.Width(), gif.Height(), gif.GetNumLoops());

      for (auto frame : gif.GetFrames())
      {
        CTexture *glTexture = new CTexture();
        if (glTexture)
        {
          glTexture->LoadFromMemory(gif.Width(), gif.Height(), gif.GetPitch(), XB_FMT_A8R8G8B8, false, frame->m_pImage);
          pMap->Add(glTexture, frame->m_delay);
        }
      }
#endif//HAS_GIFLIB
    }

    if (pMap)
    {
      m_vecTextures.push_back(pMap);
      return pMap->GetTexture();
    }
  } // of if (strPath.Right(4).ToLower()==".gif")

  CBaseTexture *pTexture = NULL;
  int width = 0, height = 0;
  if (bundle >= 0)
  {
    if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height))
    {
      CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
      return emptyTexture;
    }
  }
  else
  {
    pTexture = CBaseTexture::LoadFromFile(strPath);
    if (!pTexture)
      return emptyTexture;
    width = pTexture->GetWidth();
    height = pTexture->GetHeight();
  }

  if (!pTexture) return emptyTexture;

  CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0);
  pMap->Add(pTexture, 100);
  m_vecTextures.push_back(pMap);

#ifdef _DEBUG_TEXTURES
  int64_t end, freq;
  end = CurrentHostCounter();
  freq = CurrentHostFrequency();
  char temp[200];
  sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
  OutputDebugString(temp);
#endif

  return pMap->GetTexture();
}
コード例 #19
0
ファイル: DVDVideoCodecVDA.cpp プロジェクト: RoboSK/xbmc
bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
{
  if (g_guiSettings.GetBool("videoplayer.usevda") && !hints.software)
  {
    CCocoaAutoPool pool;
    int32_t width, height, profile, level;
    CFDataRef avcCData;
    uint8_t *extradata; // extra data for codec to use
    unsigned int extrasize; // size of extra data

    //
    width  = hints.width;
    height = hints.height;
    level  = hints.level;
    profile = hints.profile;
    extrasize = hints.extrasize;
    extradata = (uint8_t*)hints.extradata;
 
    if (Cocoa_GPUForDisplayIsNvidiaPureVideo3() && !CDVDCodecUtils::IsVP3CompatibleWidth(width))
    {
      CLog::Log(LOGNOTICE, "%s - Nvidia 9400 GPU hardware limitation, cannot decode a width of %d", __FUNCTION__, width);
      return false;
    }

    switch (hints.codec)
    {
      case CODEC_ID_H264:
        // TODO: need to quality h264 encoding (profile, level and number of reference frame)
        // source must be H.264 with valid avcC atom data in extradata
        if (extrasize < 7 || extradata == NULL)
        {
          CLog::Log(LOGNOTICE, "%s - avcC atom too data small or missing", __FUNCTION__);
          return false;
        }
        // valid avcC atom data always starts with the value 1 (version)
        if ( *extradata != 1 )
        {
          if (extradata[0] == 0 && extradata[1] == 0 && extradata[2] == 0 && extradata[3] == 1)
          {
            // video content is from x264 or from bytestream h264 (AnnexB format)
            // NAL reformating to bitstream format needed
            m_dllAvUtil = new DllAvUtil;
            m_dllAvFormat = new DllAvFormat;
            if (!m_dllAvUtil->Load() || !m_dllAvFormat->Load())
            {
              return false;
            }

            ByteIOContext *pb;
            if (m_dllAvFormat->url_open_dyn_buf(&pb) < 0)
            {
              return false;
            }

            m_convert_bytestream = true;
            // create a valid avcC atom data from ffmpeg's extradata
            isom_write_avcc(m_dllAvUtil, m_dllAvFormat, pb, extradata, extrasize);
            // unhook from ffmpeg's extradata
            extradata = NULL;
            // extract the avcC atom data into extradata then write it into avcCData for VDADecoder
            extrasize = m_dllAvFormat->url_close_dyn_buf(pb, &extradata);
            // CFDataCreate makes a copy of extradata contents
            avcCData = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)extradata, extrasize);
            // done with the converted extradata, we MUST free using av_free
            m_dllAvUtil->av_free(extradata);
          }
          else
          {
            CLog::Log(LOGNOTICE, "%s - invalid avcC atom data", __FUNCTION__);
            return false;
          }
        }
        else
        {
          if (extradata[4] == 0xFE)
          {
            // video content is from so silly encoder that think 3 byte NAL sizes
            // are valid, setup to convert 3 byte NAL sizes to 4 byte.
            m_dllAvUtil = new DllAvUtil;
            m_dllAvFormat = new DllAvFormat;
            if (!m_dllAvUtil->Load() || !m_dllAvFormat->Load())
              return false;

            extradata[4] = 0xFF;
            m_convert_3byteTo4byteNALSize = true;
          }
          // CFDataCreate makes a copy of extradata contents
          avcCData = CFDataCreate(kCFAllocatorDefault, (const uint8_t*)extradata, extrasize);
        }

        m_format = 'avc1';
        m_pFormatName = "vda-h264";
      break;
      default:
        return false;
      break;
    }

    // input stream is qualified, now we can load dlls.
    m_dllSwScale = new DllSwScale;
    if (!m_dllSwScale->Load())
    {
      CFRelease(avcCData);
      return false;
    }

    // setup the decoder configuration dict
    CFMutableDictionaryRef decoderConfiguration = CFDictionaryCreateMutable(
      kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef avcWidth  = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
    CFNumberRef avcHeight = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
    CFNumberRef avcFormat = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &m_format);

    CFDictionarySetValue(decoderConfiguration, m_dll->Get_kVDADecoderConfiguration_Height(), avcHeight);
    CFDictionarySetValue(decoderConfiguration, m_dll->Get_kVDADecoderConfiguration_Width(),  avcWidth);
    CFDictionarySetValue(decoderConfiguration, m_dll->Get_kVDADecoderConfiguration_SourceFormat(), avcFormat);
    CFDictionarySetValue(decoderConfiguration, m_dll->Get_kVDADecoderConfiguration_avcCData(), avcCData);

    // release the retained object refs, decoderConfiguration owns them now
    CFRelease(avcWidth);
    CFRelease(avcHeight);
    CFRelease(avcFormat);
    CFRelease(avcCData);

    // setup the destination image buffer dict, vda will output this pict format
    CFMutableDictionaryRef destinationImageBufferAttributes = CFDictionaryCreateMutable(
      kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    OSType cvPixelFormatType = kCVPixelFormatType_422YpCbCr8;
    CFNumberRef pixelFormat  = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &cvPixelFormatType);
    CFDictionarySetValue(destinationImageBufferAttributes, kCVPixelBufferPixelFormatTypeKey, pixelFormat);

    // create the VDADecoder object
    OSStatus status;
    try
    {
      status = m_dll->VDADecoderCreate(decoderConfiguration, destinationImageBufferAttributes,
        (VDADecoderOutputCallback *)VDADecoderCallback, this, (VDADecoder*)&m_vda_decoder);
    }
    catch (...)
    {
      CLog::Log(LOGERROR, "%s - exception",__FUNCTION__);
      status = kVDADecoderDecoderFailedErr;
    }
    CFRelease(decoderConfiguration);
    CFRelease(destinationImageBufferAttributes);
    if (status != kVDADecoderNoErr)
    {
	  if (status == kVDADecoderDecoderFailedErr)
        CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, currently in use by another process",
          __FUNCTION__);
	  else
        CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, status(%d), profile(%d), level(%d)",
          __FUNCTION__, (int)status, profile, level);
      return false;
    }

    // allocate a YV12 DVDVideoPicture buffer.
    // first make sure all properties are reset.
    memset(&m_videobuffer, 0, sizeof(DVDVideoPicture));
    unsigned int iPixels = width * height;
    unsigned int iChromaPixels = iPixels/4;

    m_videobuffer.pts = DVD_NOPTS_VALUE;
    m_videobuffer.iFlags = DVP_FLAG_ALLOCATED;
    m_videobuffer.format = DVDVideoPicture::FMT_YUV420P;
    m_videobuffer.color_range  = 0;
    m_videobuffer.color_matrix = 4;
    m_videobuffer.iWidth  = width;
    m_videobuffer.iHeight = height;
    m_videobuffer.iDisplayWidth  = width;
    m_videobuffer.iDisplayHeight = height;

    m_videobuffer.iLineSize[0] = width;   //Y
    m_videobuffer.iLineSize[1] = width/2; //U
    m_videobuffer.iLineSize[2] = width/2; //V
    m_videobuffer.iLineSize[3] = 0;

    m_videobuffer.data[0] = (BYTE*)malloc(iPixels);       //Y
    m_videobuffer.data[1] = (BYTE*)malloc(iChromaPixels); //U
    m_videobuffer.data[2] = (BYTE*)malloc(iChromaPixels); //V
    m_videobuffer.data[3] = NULL;

    // set all data to 0 for less artifacts.. hmm.. what is black in YUV??
    memset(m_videobuffer.data[0], 0, iPixels);
    memset(m_videobuffer.data[1], 0, iChromaPixels);
    memset(m_videobuffer.data[2], 0, iChromaPixels);

    m_DropPictures = false;
    m_sort_time_offset = (CurrentHostCounter() * 1000.0) / CurrentHostFrequency();

    return true;
  }

  return false;
}
コード例 #20
0
ファイル: AESinkPULSE.cpp プロジェクト: krattai/sht_tv
void CAESinkPULSE::GetDelay(AEDelayStatus& status)
{
  if (!m_IsAllocated)
  {
    status.SetDelay(0);
    return;
  }

  pa_threaded_mainloop_lock(m_MainLoop);
  const pa_timing_info* pti = pa_stream_get_timing_info(m_Stream);
  // only incorporate local sink delay + internal PA transport delay
  double sink_delay = (pti->configured_sink_usec / 1000000.0);
  double transport_delay = pti->transport_usec / 1000000.0;

  uint64_t diff = CurrentHostCounter() - m_lastPackageStamp;
  unsigned int bytes_played = (unsigned int) ((double) diff * (double) m_BytesPerSecond  / (double) CurrentHostFrequency() + 0.5);

  int buffer_delay = m_filled_bytes - bytes_played;
  if (buffer_delay < 0)
    buffer_delay = 0;

  pa_threaded_mainloop_unlock(m_MainLoop);

  double delay = buffer_delay / (double) m_BytesPerSecond + sink_delay + transport_delay;
  status.SetDelay(delay);
}
コード例 #21
0
int main(int argc, char * const argv[])
{
	int ret = CODEC_ERROR_NONE;
  std::string input_filename;

  if (argc > 1) {
    for (int i = 1; i < argc; i++) {
      if (strncasecmp(argv[i], "--input", 7) == 0) {
        // check the next arg with the proper value.
        int next = i + 1;
        if (next < argc) {
          input_filename = argv[next];
          i++;
        }
      } else if (strncasecmp(argv[i], "-h", 2) == 0 || strncasecmp(argv[i], "--help", 6) == 0) {
        printf("Usage: %s [OPTIONS]...\n", argv[0]);
        printf("Arguments:\n");
        printf("  --input <filename> \tInput video filename\n");
        exit(0);
      }
    }
  }
  if (input_filename.empty()) {
    printf("no input file specified\n");
    exit(0);
  }

  // install signal handlers
  signal(SIGINT, signal_handler);
  signal(SIGTERM, signal_handler);

  // initialize App contex.
  AVPacket avpkt;
  AppContext ctx;
  memset(&ctx, 0, sizeof(ctx));

  player_para_init(&ctx);
  am_packet_init(&ctx.am_pkt);

  ctx.am_pkt.avpkt = &avpkt;
  av_init_packet(ctx.am_pkt.avpkt);

  // create the ffmepg file reader/demuxer
  ctx.demuxer = new FFmpegFileReader(input_filename.c_str());
  if (!ctx.demuxer->Initialize()) {
    fprintf(stderr, "ERROR: Can't initialize FFmpegFileReader\n");
    goto fail;
  }
  
  ctx.codec_context = ctx.demuxer->GetCodecContext();
  ctx.format_context = ctx.demuxer->GetFormatContext();
  if (!ctx.codec_context) {
    fprintf(stderr, "ERROR: Invalid FFmpegFileReader Codec Context\n");
    goto fail;
  }

  dump_extradata(&ctx);

  printf("video width(%d), height(%d), extradata_size(%d)\n",
    (int)ctx.codec_context->width, (int)ctx.codec_context->height, ctx.codec_context->extradata_size);

  AVStream *pStream;
  pStream = ctx.format_context->streams[ctx.demuxer->GetVideoIndex()];
  //ctx.vstream_info.video_pid = (unsigned short)ctx.codec_context->id;
  if (pStream->time_base.den) {
    ctx.vstream_info.start_time     = pStream->start_time * pStream->time_base.num * PTS_FREQ / pStream->time_base.den;
    ctx.vstream_info.video_duration = ((float)pStream->time_base.num / pStream->time_base.den) * UNIT_FREQ;
    ctx.vstream_info.video_pts      = ((float)pStream->time_base.num / pStream->time_base.den) * PTS_FREQ;
  }
  ctx.vstream_info.video_width  = ctx.codec_context->width;
  ctx.vstream_info.video_height = ctx.codec_context->height;
  ctx.vstream_info.video_ratio  = (float)pStream->sample_aspect_ratio.num / pStream->sample_aspect_ratio.den;
  if (ctx.codec_context->time_base.den) {
    ctx.vstream_info.video_codec_rate = (int64_t)UNIT_FREQ * ctx.codec_context->time_base.num / ctx.codec_context->time_base.den;
  }
  if (pStream->r_frame_rate.num) {
    ctx.vstream_info.video_rate = (int64_t)UNIT_FREQ * pStream->r_frame_rate.den / pStream->r_frame_rate.num;
  }


  log_print("time_base.num(%d), pStream->time_base.den(%d)\n",
    pStream->time_base.num, pStream->time_base.den);
    ctx.vstream_info.video_duration = ((float)pStream->time_base.num / pStream->time_base.den) * UNIT_FREQ;
    ctx.vstream_info.video_pts      = ((float)pStream->time_base.num / pStream->time_base.den) * PTS_FREQ;

  printf("\n*********AMLOGIC CODEC PLAYER DEMO************\n\n");
	osd_blank("/sys/class/graphics/fb0/blank", 1);
	osd_blank("/sys/class/graphics/fb1/blank", 1);
	//osd_blank("/sys/class/tsync/enable", 1);
  osd_blank("/sys/class/tsync/enable", 0);

  switch(ctx.codec_context->codec_id)
  {
    case CODEC_ID_H264:
      printf("CODEC_ID_H264\n");

      ctx.vcodec.has_video = 1;
      ctx.vcodec.has_audio = 0;
      ctx.stream_type = STREAM_ES;
      //ctx.vcodec.video_pid = ctx.demuxer->GetVideoIndex();
      ctx.vcodec.video_type = VFORMAT_H264;
      ctx.vcodec.stream_type = STREAM_TYPE_ES_VIDEO;
      //ctx.vcodec.noblock = !!p_para->buffering_enable;
      ctx.vcodec.am_sysinfo.format = VIDEO_DEC_FORMAT_H264;
      ctx.vcodec.am_sysinfo.width  = ctx.vstream_info.video_width;
      ctx.vcodec.am_sysinfo.height = ctx.vstream_info.video_height;
      ctx.vcodec.am_sysinfo.rate   = ctx.vstream_info.video_rate;
      ctx.vcodec.am_sysinfo.ratio  = ctx.vstream_info.video_ratio;
      ctx.vcodec.am_sysinfo.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);

    break;
    case CODEC_ID_MPEG4:
      printf("CODEC_ID_MPEG4\n");
      ctx.vcodec.video_type = VFORMAT_MPEG4;
    break;
    case CODEC_ID_MPEG2VIDEO:
      printf("CODEC_ID_MPEG2VIDEO\n");
      ctx.vcodec.video_type = VFORMAT_MPEG12;
    break;
    default:
      fprintf(stderr, "ERROR: Invalid FFmpegFileReader Codec Format (not h264/mpeg4) = %d\n",
        ctx.codec_context->codec_id);
      goto fail;
    break;
  }

	ret = codec_init(&ctx.vcodec);
	if(ret != CODEC_ERROR_NONE)
	{
		printf("codec init failed, ret=-0x%x", -ret);
		return -1;
	}
	printf("video codec ok!\n");


	ret = codec_init_cntl(&ctx.vcodec);
	if( ret != CODEC_ERROR_NONE )
	{
		printf("codec_init_cntl error\n");
		return -1;
	}

	codec_set_cntl_avthresh(&ctx.vcodec, AV_SYNC_THRESH);
	codec_set_cntl_syncthresh(&ctx.vcodec, ctx.vcodec.has_audio);

  {
    int frame_count, total = 0;
    int64_t bgn_us, end_us;

    ctx.am_pkt.codec = &ctx.vcodec;

    pre_header_feeding(&ctx, &ctx.am_pkt);

    ctx.demuxer->Read(ctx.am_pkt.avpkt);
    printf("byte_count(%d), dts(%llu), pts(%llu)\n",
      ctx.am_pkt.avpkt->size, ctx.am_pkt.avpkt->dts, ctx.am_pkt.avpkt->pts);
    if (!ctx.am_pkt.avpkt->size) {
      fprintf(stderr, "ERROR: Zero bytes read from input\n");
      //goto fail;
    }
    ctx.am_pkt.type = CODEC_VIDEO;
    ctx.am_pkt.data = ctx.am_pkt.avpkt->data;
    ctx.am_pkt.data_size = ctx.am_pkt.avpkt->size;
    ctx.am_pkt.avpkt_newflag = 1;
    ctx.am_pkt.avpkt_isvalid = 1;

    frame_count = 0;
    bool done = false;
    struct buf_status vbuf;
    struct vdec_status vdec;
    float  vlevel;
    while (!g_signal_abort && !done && (frame_count < 5000)) {
      h264_update_frame_header(&ctx.am_pkt);
      
      bgn_us = CurrentHostCounter() * 1000 / CurrentHostFrequency();

      log_print("avpts(%lld), avdts(%lld)\n",
        ctx.am_pkt.avpkt->pts, ctx.am_pkt.avpkt->dts);

      ret = write_av_packet(&ctx, &ctx.am_pkt);

      end_us = CurrentHostCounter() * 1000 / CurrentHostFrequency();

      frame_count++;
      //fprintf(stdout, "decode time(%llu) us\n", end_us-bgn_us);
      check_vcodec_state(&ctx.vcodec, &vdec, &vbuf);
      vlevel = 100.0 * (float)vbuf.data_len / vbuf.size;
      //log_print("buffering_states,vlevel=%d,vsize=%d,level=%f\n", vbuf.data_len, vbuf.size, vlevel);
      usleep(vlevel * 5000);

      ctx.demuxer->Read(ctx.am_pkt.avpkt);
      ctx.am_pkt.type = CODEC_VIDEO;
      ctx.am_pkt.data = ctx.am_pkt.avpkt->data;
      ctx.am_pkt.data_size = ctx.am_pkt.avpkt->size;
      ctx.am_pkt.avpkt_newflag = 1;
      ctx.am_pkt.avpkt_isvalid = 1;

      if (!ctx.am_pkt.data_size) done = true;
      total += ctx.am_pkt.data_size;
    }
  }

fail:
	codec_close_cntl(&ctx.vcodec);
	codec_close(&ctx.vcodec);

  return 0;
}
コード例 #22
0
ファイル: TextureManager.cpp プロジェクト: deniscostadsc/xbmc
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */)
{
    std::string strPath;
    static CTextureArray emptyTexture;
    int bundle = -1;
    int size = 0;
    if (!HasTexture(strTextureName, &strPath, &bundle, &size))
        return emptyTexture;

    if (size) // we found the texture
    {
        for (int i = 0; i < (int)m_vecTextures.size(); ++i)
        {
            CTextureMap *pMap = m_vecTextures[i];
            if (pMap->GetName() == strTextureName)
            {
                //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage());
                return pMap->GetTexture();
            }
        }
        // Whoops, not there.
        return emptyTexture;
    }

    for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i)
    {
        CTextureMap* pMap = i->first;
        if (pMap->GetName() == strTextureName && i->second > 0)
        {
            m_vecTextures.push_back(pMap);
            m_unusedTextures.erase(i);
            return pMap->GetTexture();
        }
    }

    if (checkBundleOnly && bundle == -1)
        return emptyTexture;

    //Lock here, we will do stuff that could break rendering
    CSingleLock lock(g_graphicsContext);

#ifdef _DEBUG_TEXTURES
    int64_t start;
    start = CurrentHostCounter();
#endif

    if (bundle >= 0 && StringUtils::EndsWithNoCase(strPath, ".gif"))
    {
        CTextureMap* pMap = nullptr;
        CBaseTexture **pTextures = nullptr;
        int nLoops = 0, width = 0, height = 0;
        int* Delay = nullptr;
        int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay);
        if (!nImages)
        {
            CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
            delete[] pTextures;
            delete[] Delay;
            return emptyTexture;
        }

        unsigned int maxWidth = 0;
        unsigned int maxHeight = 0;
        pMap = new CTextureMap(strTextureName, width, height, nLoops);
        for (int iImage = 0; iImage < nImages; ++iImage)
        {
            pMap->Add(pTextures[iImage], Delay[iImage]);
            maxWidth = std::max(maxWidth, pTextures[iImage]->GetWidth());
            maxHeight = std::max(maxHeight, pTextures[iImage]->GetHeight());
        }

        pMap->SetWidth((int)maxWidth);
        pMap->SetHeight((int)maxHeight);

        delete[] pTextures;
        delete[] Delay;

        if (pMap)
        {
            m_vecTextures.push_back(pMap);
            return pMap->GetTexture();
        }
    }
    else if (StringUtils::EndsWithNoCase(strPath, ".gif") ||
             StringUtils::EndsWithNoCase(strPath, ".apng"))
    {
        CTextureMap* pMap = nullptr;

        std::string mimeType;
        if (StringUtils::EndsWithNoCase(strPath, ".gif"))
            mimeType = "image/gif";
        else if (StringUtils::EndsWithNoCase(strPath, ".apng"))
            mimeType = "image/apng";

        XFILE::CFile file;
        XFILE::auto_buffer buf;
        CFFmpegImage anim(mimeType);
        pMap = new CTextureMap(strTextureName, 0, 0, 0);

        if (file.LoadFile(strPath, buf) <= 0 ||
                !anim.Initialize((uint8_t*)buf.get(), buf.size()) || !pMap)
        {
            CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CURL::GetRedacted(strPath).c_str());
            file.Close();
            return emptyTexture;
        }

        unsigned int maxWidth = 0;
        unsigned int maxHeight = 0;
        uint64_t maxMemoryUsage = 91238400;// 1920*1080*4*11 bytes, i.e, a total of approx. 12 full hd frames

        auto frame = anim.ReadFrame();
        while (frame)
        {
            CTexture *glTexture = new CTexture();
            if (glTexture)
            {
                glTexture->LoadFromMemory(anim.Width(), anim.Height(), frame->GetPitch(), XB_FMT_A8R8G8B8, true, frame->m_pImage);
                pMap->Add(glTexture, frame->m_delay);
                maxWidth = std::max(maxWidth, glTexture->GetWidth());
                maxHeight = std::max(maxHeight, glTexture->GetHeight());
            }

            if (pMap->GetMemoryUsage() <= maxMemoryUsage)
            {
                frame = anim.ReadFrame();
            }
            else
            {
                CLog::Log(LOGDEBUG, "Memory limit (%" PRIu64 " bytes) exceeded, %i frames extracted from file : %s", (maxMemoryUsage/11)*12,pMap->GetTexture().size(), CURL::GetRedacted(strPath).c_str());
                break;
            }
        }

        pMap->SetWidth((int)maxWidth);
        pMap->SetHeight((int)maxHeight);

        file.Close();

        if (pMap)
        {
            m_vecTextures.push_back(pMap);
            return pMap->GetTexture();
        }
    }

    CBaseTexture *pTexture = NULL;
    int width = 0, height = 0;
    if (bundle >= 0)
    {
        if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height))
        {
            CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str());
            return emptyTexture;
        }
    }
    else
    {
        pTexture = CBaseTexture::LoadFromFile(strPath);
        if (!pTexture)
            return emptyTexture;
        width = pTexture->GetWidth();
        height = pTexture->GetHeight();
    }

    if (!pTexture) return emptyTexture;

    CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0);
    pMap->Add(pTexture, 100);
    m_vecTextures.push_back(pMap);

#ifdef _DEBUG_TEXTURES
    int64_t end, freq;
    end = CurrentHostCounter();
    freq = CurrentHostFrequency();
    char temp[200];
    sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : "");
    OutputDebugString(temp);
#endif

    return pMap->GetTexture();
}
コード例 #23
0
TEST(TestTimeUtils, CurrentHostFrequency)
{
  std::cout << "CurrentHostFrequency(): " <<
    testing::PrintToString(CurrentHostFrequency()) << std::endl;
}
コード例 #24
0
ファイル: GUIControlProfiler.cpp プロジェクト: A600/xbmc
CGUIControlProfiler::CGUIControlProfiler(void)
: m_ItemHead(NULL, NULL, NULL), m_pLastItem(NULL), m_iMaxFrameCount(200), m_iFrameCount(0)
// m_bIsRunning(false), no isRunning because it is static
{
  m_fPerfScale = 100000.0f / CurrentHostFrequency();
}