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); } }
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); } }