Esempio n. 1
0
void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double dts, double pts)
{
  // mpeg2 handling
  if (m_mpeg2_sequence)
  {
    // probe demux for sequence_header_code NAL and
    // decode aspect ratio and frame rate.
    if (CBitstreamConverter::mpeg2_sequence_header(pData, iSize, m_mpeg2_sequence))
    {
      m_mpeg2_sequence_pts = pts;
      if (m_mpeg2_sequence_pts == DVD_NOPTS_VALUE)
        m_mpeg2_sequence_pts = dts;

      m_framerate = m_mpeg2_sequence->rate;
      m_video_rate = (int)(0.5 + (96000.0 / m_framerate));

      CLog::Log(LOGDEBUG, "%s: detected mpeg2 aspect ratio(%f), framerate(%f), video_rate(%d)",
        __MODULE_NAME__, m_mpeg2_sequence->ratio, m_framerate, m_video_rate);

      // update m_hints for 1st frame fixup.
      switch(m_mpeg2_sequence->rate_info)
      {
        default:
        case 0x01:
          m_hints.fpsrate = 24000.0;
          m_hints.fpsscale = 1001.0;
          break;
        case 0x02:
          m_hints.fpsrate = 24000.0;
          m_hints.fpsscale = 1000.0;
          break;
        case 0x03:
          m_hints.fpsrate = 25000.0;
          m_hints.fpsscale = 1000.0;
          break;
        case 0x04:
          m_hints.fpsrate = 30000.0;
          m_hints.fpsscale = 1001.0;
          break;
        case 0x05:
          m_hints.fpsrate = 30000.0;
          m_hints.fpsscale = 1000.0;
          break;
        case 0x06:
          m_hints.fpsrate = 50000.0;
          m_hints.fpsscale = 1000.0;
          break;
        case 0x07:
          m_hints.fpsrate = 60000.0;
          m_hints.fpsscale = 1001.0;
          break;
        case 0x08:
          m_hints.fpsrate = 60000.0;
          m_hints.fpsscale = 1000.0;
          break;
      }
      m_hints.width    = m_mpeg2_sequence->width;
      m_hints.height   = m_mpeg2_sequence->height;
      m_hints.aspect   = m_mpeg2_sequence->ratio;
    }
    return;
  }

  // everything else
  FrameQueuePush(dts, pts);

  // we might have out-of-order pts,
  // so make sure we wait for at least 8 values in sorted queue.
  if (m_queue_depth > 16)
  {
    pthread_mutex_lock(&m_queue_mutex);

    float cur_pts = m_frame_queue->pts;
    if (cur_pts == DVD_NOPTS_VALUE)
      cur_pts = m_frame_queue->dts;

    pthread_mutex_unlock(&m_queue_mutex);	

    float duration = cur_pts - m_last_pts;
    m_last_pts = cur_pts;

    // clamp duration to sensible range,
    // 66 fsp to 20 fsp
    if (duration >= 15000.0 && duration <= 50000.0)
    {
      double framerate;
      switch((int)(0.5 + duration))
      {
        // 59.940 (16683.333333)
        case 16000 ... 17000:
          framerate = 60000.0 / 1001.0;
          break;

        // 50.000 (20000.000000)
        case 20000:
          framerate = 50000.0 / 1000.0;
          break;

        // 49.950 (20020.000000)
        case 20020:
          framerate = 50000.0 / 1001.0;
          break;

        // 29.970 (33366.666656)
        case 32000 ... 35000:
          framerate = 30000.0 / 1001.0;
          break;

        // 25.000 (40000.000000)
        case 40000:
          framerate = 25000.0 / 1000.0;
          break;

        // 24.975 (40040.000000)
        case 40040:
          framerate = 25000.0 / 1001.0;
          break;

        /*
        // 24.000 (41666.666666)
        case 41667:
          framerate = 24000.0 / 1000.0;
          break;
        */

        // 23.976 (41708.33333)
        case 40200 ... 43200:
          // 23.976 seems to have the crappiest encodings :)
          framerate = 24000.0 / 1001.0;
          break;

        default:
          framerate = 0.0;
          //CLog::Log(LOGDEBUG, "%s: unknown duration(%f), cur_pts(%f)",
          //  __MODULE_NAME__, duration, cur_pts);
          break;
      }

      if (framerate > 0.0 && (int)m_framerate != (int)framerate)
      {
        m_framerate = framerate;
        m_video_rate = (int)(0.5 + (96000.0 / framerate));
        CLog::Log(LOGDEBUG, "%s: detected new framerate(%f), video_rate(%d)",
          __MODULE_NAME__, m_framerate, m_video_rate);
      }
    }
Esempio n. 2
0
void CDVDVideoCodecAmlogic::FrameRateTracking(BYTE *pData, int iSize, double dts, double pts)
{
  FrameQueuePush(dts, pts);

  if (m_mpeg2_aspect)
  {
    // if mpeg2, probe demux data for aspect_ratio_information
    // in the sequence_header_code.
    if (CBitstreamConverter::mpeg2_aspect_ratio_information(pData, iSize, m_mpeg2_aspect))
    {
      m_mpeg2_aspect_pts = pts;
      if (m_mpeg2_aspect_pts == DVD_NOPTS_VALUE)
        m_mpeg2_aspect_pts = dts;
      CLog::Log(LOGDEBUG, "%s: detected new aspect ratio(%f)", __MODULE_NAME__, m_mpeg2_aspect->ratio);
    }
  }

  // we might have out-of-order pts,
  // so make sure we wait for at least 8 values in sorted queue.
  if (m_queue_depth > 16)
  {
    pthread_mutex_lock(&m_queue_mutex);

    float cur_pts = m_frame_queue->pts;
    if (cur_pts == DVD_NOPTS_VALUE)
      cur_pts = m_frame_queue->dts;

    pthread_mutex_unlock(&m_queue_mutex);	

    float duration = cur_pts - m_last_pts;
    m_last_pts = cur_pts;

    // clamp duration to sensible range,
    // 66 fsp to 20 fsp
    if (duration >= 15000.0 && duration <= 50000.0)
    {
      double framerate;
      switch((int)(0.5 + duration))
      {
        // 59.940 (16683.333333)
        case 16000 ... 17000:
          framerate = 60000.0 / 1001.0;
          break;

        // 50.000 (20000.000000)
        case 20000:
          framerate = 50000.0 / 1000.0;
          break;

        // 49.950 (20020.000000)
        case 20020:
          framerate = 50000.0 / 1001.0;
          break;

        // 29.970 (33366.666656)
        case 32000 ... 35000:
          framerate = 30000.0 / 1001.0;
          break;

        // 25.000 (40000.000000)
        case 40000:
          framerate = 25000.0 / 1000.0;
          break;

        // 24.975 (40040.000000)
        case 40040:
          framerate = 25000.0 / 1001.0;
          break;

        /*
        // 24.000 (41666.666666)
        case 41667:
          framerate = 24000.0 / 1000.0;
          break;
        */

        // 23.976 (41708.33333)
        case 40200 ... 43200:
          // 23.976 seems to have the crappiest encodings :)
          framerate = 24000.0 / 1001.0;
          break;

        default:
          framerate = 0.0;
          //CLog::Log(LOGDEBUG, "%s: unknown duration(%f), cur_pts(%f)",
          //  __MODULE_NAME__, duration, cur_pts);
          break;
      }

      if (framerate > 0.0 && (int)m_framerate != (int)framerate)
      {
        m_framerate = framerate;
        m_video_rate = (int)(0.5 + (96000.0 / framerate));
        CLog::Log(LOGDEBUG, "%s: detected new framerate(%f), video_rate(%d)",
          __MODULE_NAME__, m_framerate, m_video_rate);
      }
    }