Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
- index c38c223..b91ed02 100644
- --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
- +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
- @@ -26,6 +26,7 @@
- #include "cores/VideoPlayer/DVDClock.h"
- #include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
- #include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
- +#include "settings/AdvancedSettings.h"
- #include "guilib/GraphicContext.h"
- #include "settings/DisplaySettings.h"
- #include "settings/MediaSettings.h"
- @@ -41,19 +42,15 @@
- #include "utils/BitstreamConverter.h"
- #endif
- -extern "C" {
- -#include "libavutil/avutil.h"
- -} // extern "C"
- -
- #include <unistd.h>
- #include <queue>
- #include <vector>
- #include <signal.h>
- -#include <semaphore.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
- +#include <sys/utsname.h>
- #include <linux/videodev2.h>
- // amcodec include
- @@ -133,6 +130,11 @@ public:
- virtual int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode)=0;
- virtual int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh)=0;
- virtual int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh)=0;
- +
- + virtual int codec_set_av_threshold(codec_para_t *pcodec, int threshold)=0;
- + virtual int codec_set_video_delay_limited_ms(codec_para_t *pcodec,int delay_ms)=0;
- + virtual int codec_get_video_delay_limited_ms(codec_para_t *pcodec,int *delay_ms)=0;
- + virtual int codec_get_video_cur_delay_ms(codec_para_t *pcodec,int *delay_ms)=0;
- };
- class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
- @@ -156,6 +158,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
- DEFINE_METHOD2(int, codec_set_cntl_avthresh, (codec_para_t *p1, unsigned int p2))
- DEFINE_METHOD2(int, codec_set_cntl_syncthresh,(codec_para_t *p1, unsigned int p2))
- + DEFINE_METHOD2(int, codec_set_av_threshold, (codec_para_t *p1, int p2))
- + DEFINE_METHOD2(int, codec_set_video_delay_limited_ms, (codec_para_t *p1, int p2))
- + DEFINE_METHOD2(int, codec_get_video_delay_limited_ms, (codec_para_t *p1, int *p2))
- + DEFINE_METHOD2(int, codec_get_video_cur_delay_ms, (codec_para_t *p1, int *p2))
- +
- BEGIN_METHOD_RESOLVE()
- RESOLVE_METHOD(codec_init)
- RESOLVE_METHOD(codec_close)
- @@ -172,6 +179,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
- RESOLVE_METHOD(codec_set_cntl_mode)
- RESOLVE_METHOD(codec_set_cntl_avthresh)
- RESOLVE_METHOD(codec_set_cntl_syncthresh)
- +
- + RESOLVE_METHOD(codec_set_av_threshold)
- + RESOLVE_METHOD(codec_set_video_delay_limited_ms)
- + RESOLVE_METHOD(codec_get_video_delay_limited_ms)
- + RESOLVE_METHOD(codec_get_video_cur_delay_ms)
- END_METHOD_RESOLVE()
- public:
- @@ -279,8 +291,7 @@ public:
- #define TRICKMODE_I 0x01
- #define TRICKMODE_FFFB 0x02
- -// same as AV_NOPTS_VALUE
- -#define INT64_0 INT64_C(0x8000000000000000)
- +static const int64_t INT64_0 = 0x8000000000000000ULL;
- #define EXTERNAL_PTS (1)
- #define SYNC_OUTSIDE (2)
- @@ -371,6 +382,18 @@ typedef struct am_private_t
- bool dumpdemux;
- } am_private_t;
- +typedef struct vframe_states
- +{
- + int vf_pool_size;
- + int buf_free_num;
- + int buf_recycle_num;
- + int buf_avail_num;
- +} vframe_states_t;
- +
- +#define AMSTREAM_IOC_MAGIC 'S'
- +#define AMSTREAM_IOC_VF_STATUS _IOR(AMSTREAM_IOC_MAGIC, 0x60, unsigned long)
- +
- +
- /*************************************************************************/
- /*************************************************************************/
- void dumpfile_open(am_private_t *para)
- @@ -579,7 +602,7 @@ static void am_packet_init(am_packet_t *pkt)
- pkt->avduration = 0;
- pkt->isvalid = 0;
- pkt->newflag = 0;
- - pkt->lastpts = 0;
- + pkt->lastpts = INT64_0;
- pkt->data = NULL;
- pkt->buf = NULL;
- pkt->data_size = 0;
- @@ -604,46 +627,14 @@ void am_packet_release(am_packet_t *pkt)
- int check_in_pts(am_private_t *para, am_packet_t *pkt)
- {
- - int last_duration = 0;
- - static int last_v_duration = 0;
- - int64_t pts = 0;
- -
- - last_duration = last_v_duration;
- -
- - if (para->stream_type == AM_STREAM_ES) {
- - if ((int64_t)INT64_0 != pkt->avpts) {
- - pts = pkt->avpts;
- -
- - if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
- - CLog::Log(LOGDEBUG, "ERROR check in pts error!");
- - return PLAYER_PTS_ERROR;
- - }
- -
- - } else if ((int64_t)INT64_0 != pkt->avdts) {
- - pts = pkt->avdts * last_duration;
- -
- - if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
- - CLog::Log(LOGDEBUG, "ERROR check in dts error!");
- - return PLAYER_PTS_ERROR;
- - }
- -
- - last_v_duration = pkt->avduration ? pkt->avduration : 1;
- - } else {
- - if (!para->check_first_pts) {
- - if (para->m_dll->codec_checkin_pts(pkt->codec, 0) != 0) {
- - CLog::Log(LOGDEBUG, "ERROR check in 0 to video pts error!");
- - return PLAYER_PTS_ERROR;
- - }
- - }
- - }
- - if (!para->check_first_pts) {
- - para->check_first_pts = 1;
- - }
- - }
- - if (pts > 0)
- - pkt->lastpts = pts;
- -
- - return PLAYER_SUCCESS;
- + if (para->stream_type == AM_STREAM_ES
- + && INT64_0 != pkt->avpts
- + && para->m_dll->codec_checkin_pts(pkt->codec, pkt->avpts) != 0)
- + {
- + CLog::Log(LOGDEBUG, "ERROR check in pts error!");
- + return PLAYER_PTS_ERROR;
- + }
- + return PLAYER_SUCCESS;
- }
- static int write_header(am_private_t *para, am_packet_t *pkt)
- @@ -713,7 +704,7 @@ int write_av_packet(am_private_t *para, am_packet_t *pkt)
- }
- pkt->newflag = 0;
- }
- -
- +
- buf = pkt->data;
- size = pkt->data_size ;
- if (size == 0 && pkt->isvalid) {
- @@ -1380,9 +1371,12 @@ int set_header_info(am_private_t *para)
- /*************************************************************************/
- CAMLCodec::CAMLCodec()
- - : CThread("CAMLCodec")
- + : m_opened(false)
- + , m_ptsIs64us(false)
- + , m_cur_pts(INT64_0)
- + , m_last_pts(0)
- + , m_state(0)
- {
- - m_opened = false;
- am_private = new am_private_t;
- memset(am_private, 0, sizeof(am_private_t));
- m_dll = new DllLibAmCodec;
- @@ -1402,12 +1396,26 @@ CAMLCodec::CAMLCodec()
- CAMLCodec::~CAMLCodec()
- {
- - StopThread();
- delete am_private;
- am_private = NULL;
- delete m_dll, m_dll = NULL;
- }
- +float CAMLCodec::OMXPtsToSeconds(int omxpts)
- +{
- + return static_cast<float>(omxpts) / PTS_FREQ;
- +}
- +
- +int CAMLCodec::OMXDurationToNs(int duration)
- +{
- + return static_cast<int>(static_cast<float>(duration) / PTS_FREQ * 1000000 );
- +}
- +
- +int CAMLCodec::GetAmlDuration() const
- +{
- + return am_private ? (am_private->video_rate * PTS_FREQ) / UNIT_FREQ : 0;
- +};
- +
- bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
- {
- #ifdef TARGET_ANDROID
- @@ -1415,16 +1423,15 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
- #endif
- m_speed = DVD_PLAYSPEED_NORMAL;
- - m_1st_pts = 0;
- - m_cur_pts = 0;
- + m_cur_pts = INT64_0;
- m_dst_rect.SetRect(0, 0, 0, 0);
- m_zoom = -1;
- m_contrast = -1;
- m_brightness = -1;
- m_vbufsize = 500000 * 2;
- - m_start_dts = 0;
- - m_start_pts = 0;
- + m_start_adj = 0;
- m_hints = hints;
- + m_state = 0;
- if (!OpenAmlVideo(hints))
- {
- @@ -1615,9 +1622,10 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
- am_private->dumpdemux = false;
- dumpfile_open(am_private);
- - //! @bug make sure we are not stuck in pause (amcodec bug)
- - m_dll->codec_resume(&am_private->vcodec);
- + m_dll->codec_pause(&am_private->vcodec);
- +
- m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
- + m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000);
- m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
- m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
- @@ -1627,8 +1635,6 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
- am_private->am_pkt.codec = &am_private->vcodec;
- pre_header_feeding(am_private, &am_private->am_pkt);
- - Create();
- -
- m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iHeight);
- std::string strScaler;
- @@ -1636,16 +1642,19 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
- if (strScaler.find("enabled") == std::string::npos) // Scaler not enabled, use screen size
- m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenHeight);
- -/*
- - // if display is set to 1080xxx, then disable deinterlacer for HD content
- - // else bandwidth usage is too heavy and it will slow down video decoder.
- - char display_mode[256] = {0};
- - SysfsUtils::GetString("/sys/class/display/mode", display_mode, 255);
- - if (strstr(display_mode,"1080"))
- - SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 1);
- - else
- - SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 0);
- -*/
- + SysfsUtils::SetInt("/sys/class/video/freerun_mode", 0);
- +
- +
- + struct utsname un;
- + if (uname(&un) == 0)
- + {
- + int linuxversion[2];
- + sscanf(un.release,"%d.%d", &linuxversion[0], &linuxversion[1]);
- + if (linuxversion[0] > 3 || (linuxversion[0] == 3 && linuxversion[1] >= 14))
- + m_ptsIs64us = true;
- + }
- +
- + CLog::Log(LOGNOTICE, "CAMLCodec::OpenDecoder - using V4L2 pts format: %s", m_ptsIs64us ? "64Bit":"32Bit");
- m_opened = true;
- // vcodec is open, update speed if it was
- @@ -1705,7 +1714,6 @@ void CAMLCodec::SetVfmMap(const std::string &name, const std::string &map)
- void CAMLCodec::CloseDecoder()
- {
- CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
- - StopThread();
- // never leave vcodec ff/rw or paused.
- if (m_speed != DVD_PLAYSPEED_NORMAL)
- @@ -1749,11 +1757,14 @@ void CAMLCodec::Reset()
- // restore the speed (some amcodec versions require this)
- if (m_speed != DVD_PLAYSPEED_NORMAL)
- {
- - m_dll->codec_resume(&am_private->vcodec);
- m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
- }
- + m_dll->codec_pause(&am_private->vcodec);
- +
- // reset the decoder
- m_dll->codec_reset(&am_private->vcodec);
- + m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000);
- +
- dumpfile_close(am_private);
- dumpfile_open(am_private);
- @@ -1767,9 +1778,9 @@ void CAMLCodec::Reset()
- SysfsUtils::SetInt("/sys/class/video/blackout_policy", blackout_policy);
- // reset some interal vars
- - m_1st_pts = 0;
- - m_cur_pts = 0;
- - m_ptsQueue.clear();
- + m_cur_pts = INT64_0;
- + m_state = 0;
- + m_start_adj = 0;
- SetSpeed(m_speed);
- }
- @@ -1778,6 +1789,7 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
- if (!m_opened)
- return VC_BUFFER;
- + float timesize(static_cast<float>(GetTimeSize()));
- if (pData)
- {
- am_private->am_pkt.data = pData;
- @@ -1790,31 +1802,35 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
- // handle pts, including 31bit wrap, aml can only handle 31
- // bit pts as it uses an int in kernel.
- if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
- - am_private->am_pkt.avpts = AV_NOPTS_VALUE;
- + am_private->am_pkt.avpts = INT64_0;
- else
- {
- am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
- - if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
- - m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
- + if (!m_start_adj && am_private->am_pkt.avpts >= 0x7fffffff)
- + m_start_adj = am_private->am_pkt.avpts & ~0x0000ffff;
- + am_private->am_pkt.avpts -= m_start_adj;
- + m_state |= STATE_HASPTS;
- }
- - if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
- - am_private->am_pkt.avpts -= m_start_pts;
- // handle dts, including 31bit wrap, aml can only handle 31
- // bit dts as it uses an int in kernel.
- if (dts == DVD_NOPTS_VALUE)
- - am_private->am_pkt.avdts = AV_NOPTS_VALUE;
- + am_private->am_pkt.avdts = am_private->am_pkt.avpts;
- else
- {
- am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
- - if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
- - m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
- + if (!m_start_adj && am_private->am_pkt.avdts >= 0x7fffffff)
- + m_start_adj = am_private->am_pkt.avdts & ~0x0000ffff;
- + am_private->am_pkt.avdts -= m_start_adj;
- + }
- + // We use this to determine the fill state if no PTS is given
- + if (m_cur_pts == INT64_0)
- + {
- + m_cur_pts = am_private->am_pkt.avdts;
- + // No PTS given -> use first DTS for AML ptsserver initialization
- + if ((m_state & STATE_HASPTS) == 0)
- + am_private->am_pkt.avpts = am_private->am_pkt.avdts;
- }
- - if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
- - am_private->am_pkt.avdts -= m_start_dts;
- -
- - //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
- - // iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
- // some formats need header/data tweaks.
- // the actual write occurs once in write_av_packet
- @@ -1840,47 +1856,61 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
- // Decoder got stuck; Reset
- Reset();
- }
- -
- - // if we seek, then GetTimeSize is wrong as
- - // reports lastpts - cur_pts and hw decoder has
- - // not started outputing new pts values yet.
- - // so we grab the 1st pts sent into driver and
- - // use that to calc GetTimeSize.
- - if (m_1st_pts == 0)
- - m_1st_pts = am_private->am_pkt.lastpts;
- + if ((m_state & STATE_PREFILLED) == 0 && timesize >= 1.0)
- + {
- + m_dll->codec_resume(&am_private->vcodec);
- + m_state |= STATE_PREFILLED;
- + }
- }
- - // if we have still frames, demux size will be small
- - // and we need to pre-buffer more.
- - double target_timesize = 1.0;
- - if (iSize < 20)
- - target_timesize = 2.0;
- -
- - int rtn = 0;
- -
- - // keep hw buffered demux above 1 second
- - if (GetTimeSize() < target_timesize)
- - rtn |= VC_BUFFER;
- + int rtn(0);
- + int64_t decode_pts = 0;
- + if ((m_state & STATE_PREFILLED) != 0 && timesize > 0.5 && DequeueBuffer(decode_pts) == 0)
- + {
- + rtn |= VC_PICTURE;
- + m_last_pts = m_cur_pts;
- + m_cur_pts = decode_pts;
- + }
- + else //Timesize actualizes each 10ms, throttle decode calls to avoid reading too much
- + usleep(2500);
- - // wait until we get a new frame or 25ms,
- - if (m_ptsQueue.size() == 0)
- - m_ready_event.WaitMSec(25);
- + if (((rtn & VC_PICTURE) == 0 && timesize < 2.0) || timesize < 1.0)
- + rtn |= VC_BUFFER;
- - if (m_ptsQueue.size() > 0)
- + if (g_advancedSettings.CanLogComponent(LOGVIDEO))
- {
- - CSingleLock lock(m_ptsQueueMutex);
- - m_cur_pts = m_ptsQueue.front();
- - m_ptsQueue.pop_front();
- - rtn |= VC_PICTURE;
- + vframe_states_t vfs;
- + int fd(open("/dev/amvideo", O_RDONLY));
- + if(fd)
- + {
- + if (ioctl(fd, AMSTREAM_IOC_VF_STATUS, &vfs) != 0)
- + memset(&vfs, 0, sizeof(vfs));
- + close(fd);
- + }
- + else
- + memset(&vfs, 0, sizeof(vfs));
- +
- + CLog::Log(LOGDEBUG, "CAMLCodec::Decode: ret: %d, sz: %llu, dts_in: %0.6f[%llX], pts_in: %0.6f[%llX], adj:%llu, ptsOut:%0.6f, amlpts:%d vfs:[%d-%d-%d-%d] timesize:%0.2f",
- + rtn,
- + iSize,
- + static_cast<float>(dts)/DVD_TIME_BASE, am_private->am_pkt.avdts,
- + static_cast<float>(pts)/DVD_TIME_BASE, am_private->am_pkt.avpts,
- + m_start_adj,
- + static_cast<float>(m_cur_pts)/PTS_FREQ,
- + static_cast<int>(m_cur_pts),
- + vfs.vf_pool_size, vfs.buf_free_num,vfs.buf_recycle_num,vfs.buf_avail_num,
- + timesize
- + );
- }
- -/*
- - CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
- - "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
- - rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
- -*/
- +
- return rtn;
- }
- +int CAMLCodec::PollFrame()
- +{
- + return m_dll->codec_poll_cntl(&am_private->vcodec);
- +}
- +
- int CAMLCodec::DequeueBuffer(int64_t &pts)
- {
- v4l2_buffer vbuf = { 0 };
- @@ -1896,7 +1926,7 @@ int CAMLCodec::DequeueBuffer(int64_t &pts)
- // Since kernel 3.14 Amlogic changed length and units of PTS values reported here.
- // To differentiate such PTS values we check for existence of omx_pts_interval_lower
- // parameter, because it was introduced since kernel 3.14.
- - if (access("/sys/module/amvideo/parameters/omx_pts_interval_lower", F_OK) != -1)
- + if (m_ptsIs64us)
- {
- pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF;
- pts <<= 32;
- @@ -1917,24 +1947,26 @@ bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
- pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
- pDvdVideoPicture->format = RENDER_FMT_AML;
- - pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
- - pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
- - if (m_speed == DVD_PLAYSPEED_NORMAL)
- - pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
- + if (m_last_pts <= 0)
- + pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
- else
- - {
- - if (m_cur_pts == 0)
- - pDvdVideoPicture->pts = (double)m_1st_pts / PTS_FREQ * DVD_TIME_BASE;
- - else
- - pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
- - }
- + pDvdVideoPicture->iDuration = (double)((m_cur_pts - m_last_pts) * DVD_TIME_BASE) / PTS_FREQ;
- +
- + pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
- + pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
- +
- + //AML video is ~ 2 frames to fast - sync audio
- + pDvdVideoPicture->pts += 2*pDvdVideoPicture->iDuration;
- return true;
- }
- void CAMLCodec::SetSpeed(int speed)
- {
- + if (m_speed == speed)
- + return;
- +
- CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
- // update internal vars regardless
- @@ -1981,17 +2013,16 @@ double CAMLCodec::GetTimeSize()
- if (!m_opened)
- return 0;
- - // if m_cur_pts is zero, hw decoder was not started yet
- - // so we use the pts of the 1st demux packet that was send
- - // to hw decoder to calc timesize.
- - if (m_cur_pts == 0)
- - m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
- - else
- - m_timesize = (double)(am_private->am_pkt.lastpts - GetOMXPts()) / PTS_FREQ;
- + double timesize(0);
- + if (m_cur_pts != INT64_0)
- + {
- + timesize = static_cast<double>(am_private->am_pkt.avdts - m_cur_pts) / PTS_FREQ;
- + if (timesize < 0 || timesize > 5.0)
- + CLog::Log(LOGWARNING, "CAMLCodec::GetTimeSize limits exceed: avdts: %lld cur_pts: %lld",am_private->am_pkt.avdts, m_cur_pts);
- + }
- // lie to VideoPlayer, it is hardcoded to a max of 8 seconds,
- // if you buffer more than 8 seconds, it goes nuts.
- - double timesize = m_timesize;
- if (timesize < 0.0)
- timesize = 0.0;
- else if (timesize > 7.0)
- @@ -2000,32 +2031,6 @@ double CAMLCodec::GetTimeSize()
- return timesize;
- }
- -void CAMLCodec::Process()
- -{
- - CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
- -
- - while (!m_bStop)
- - {
- - if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
- - {
- - CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
- - Sleep(10);
- - }
- -
- - {
- - CSingleLock lock(m_ptsQueueMutex);
- - int64_t pts = 0;
- - if (DequeueBuffer(pts) == 0)
- - {
- - m_ptsQueue.push_back(pts + m_start_pts);
- - m_ready_event.Set();
- - }
- - }
- - }
- -
- - CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
- -}
- -
- void CAMLCodec::ShowMainVideo(const bool show)
- {
- static int saved_disable_video = -1;
- @@ -2273,3 +2278,9 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
- // that would show video playback, so show it.
- ShowMainVideo(true);
- }
- +
- +void CAMLCodec::SetVideoRate(int videoRate)
- +{
- + if (am_private)
- + am_private->video_rate = videoRate;
- +}
- diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
- index 0eb5c3e..b18e6e2 100644
- --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
- +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
- @@ -24,8 +24,6 @@
- #include "cores/IPlayer.h"
- #include "guilib/Geometry.h"
- #include "rendering/RenderSystem.h"
- -#include "threads/Thread.h"
- -#include <deque>
- typedef struct am_private_t am_private_t;
- @@ -34,7 +32,7 @@ class DllLibAmCodec;
- class PosixFile;
- typedef std::shared_ptr<PosixFile> PosixFilePtr;
- -class CAMLCodec : public CThread
- +class CAMLCodec
- {
- public:
- CAMLCodec();
- @@ -51,11 +49,13 @@ public:
- int GetDataSize();
- double GetTimeSize();
- void SetVideoRect(const CRect &SrcRect, const CRect &DestRect);
- - int64_t GetCurPts() const { return m_cur_pts; }
- - int GetOMXPts() const { return static_cast<int>(m_cur_pts - m_start_pts); }
- -
- -protected:
- - virtual void Process();
- + void SetVideoRate(int videoRate);
- + int64_t GetCurPts() const { return m_cur_pts + m_start_adj; }
- + int GetOMXPts() const { return static_cast<int>(m_cur_pts); }
- + static float OMXPtsToSeconds(int omxpts);
- + static int OMXDurationToNs(int duration);
- + int GetAmlDuration() const;
- + int PollFrame();
- private:
- void ShowMainVideo(const bool show);
- @@ -73,16 +73,14 @@ private:
- DllLibAmCodec *m_dll;
- bool m_opened;
- + bool m_ptsIs64us;
- am_private_t *am_private;
- CDVDStreamInfo m_hints;
- - volatile int m_speed;
- - volatile int64_t m_1st_pts;
- - volatile int64_t m_cur_pts;
- - volatile double m_timesize;
- + int m_speed;
- + int64_t m_cur_pts;
- volatile int64_t m_vbufsize;
- - int64_t m_start_dts;
- - int64_t m_start_pts;
- - CEvent m_ready_event;
- + int64_t m_start_adj;
- + int64_t m_last_pts;
- CRect m_dst_rect;
- CRect m_display_rect;
- @@ -94,8 +92,12 @@ private:
- int m_contrast;
- int m_brightness;
- + static const unsigned int STATE_PREFILLED = 1;
- + static const unsigned int STATE_HASPTS = 2;
- +
- + unsigned int m_state;
- +
- PosixFilePtr m_amlVideoFile;
- std::string m_defaultVfmMap;
- - std::deque<int64_t> m_ptsQueue;
- CCriticalSection m_ptsQueueMutex;
- };
- diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
- index a27d3e3..a6803e4 100644
- --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
- +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
- @@ -30,6 +30,7 @@
- #include "utils/SysfsUtils.h"
- #include "threads/Atomics.h"
- #include "settings/Settings.h"
- +#include "threads/Thread.h"
- #define __MODULE_NAME__ "DVDVideoCodecAmlogic"
- @@ -52,7 +53,8 @@ CDVDVideoCodecAmlogic::CDVDVideoCodecAmlogic(CProcessInfo &processInfo) : CDVDVi
- m_bitparser(NULL),
- m_bitstream(NULL),
- m_opened(false),
- - m_drop(false)
- + m_drop(false),
- + m_has_keyframe(false)
- {
- pthread_mutex_init(&m_queue_mutex, NULL);
- }
- @@ -125,14 +127,18 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option
- {
- m_bitstream = new CBitstreamConverter;
- m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true);
- + m_bitstream->ResetKeyframe();
- // make sure we do not leak the existing m_hints.extradata
- free(m_hints.extradata);
- m_hints.extrasize = m_bitstream->GetExtraSize();
- m_hints.extradata = malloc(m_hints.extrasize);
- memcpy(m_hints.extradata, m_bitstream->GetExtraData(), m_hints.extrasize);
- }
- - //m_bitparser = new CBitstreamParser();
- - //m_bitparser->Open();
- + else
- + {
- + m_bitparser = new CBitstreamParser();
- + m_bitparser->Open();
- + }
- break;
- case AV_CODEC_ID_MPEG4:
- case AV_CODEC_ID_MSMPEG4V2:
- @@ -236,6 +242,9 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option
- m_processInfo.SetVideoDecoderName(m_pFormatName, true);
- m_processInfo.SetVideoDimensions(m_hints.width, m_hints.height);
- m_processInfo.SetVideoDeintMethod("hardware");
- + m_processInfo.SetVideoDAR(m_hints.aspect);
- +
- + m_has_keyframe = false;
- CLog::Log(LOGINFO, "%s: Opened Amlogic Codec", __MODULE_NAME__);
- return true;
- @@ -277,13 +286,24 @@ int CDVDVideoCodecAmlogic::Decode(uint8_t *pData, int iSize, double dts, double
- if (!m_bitstream->Convert(pData, iSize))
- return VC_ERROR;
- + if (!m_bitstream->HasKeyframe())
- + {
- + CLog::Log(LOGDEBUG, "CDVDVideoCodecAmlogic::Decode waiting for keyframe (bitstream)", __MODULE_NAME__);
- + return VC_BUFFER;
- + }
- pData = m_bitstream->GetConvertBuffer();
- iSize = m_bitstream->GetConvertSize();
- }
- -
- - if (m_bitparser)
- - m_bitparser->FindIdrSlice(pData, iSize);
- -
- + else if (!m_has_keyframe && m_bitparser)
- + {
- + if (!m_bitparser->HasKeyframe(pData, iSize))
- + {
- + CLog::Log(LOGDEBUG, "CDVDVideoCodecAmlogic::Decode waiting for keyframe (bitparser)", __MODULE_NAME__);
- + return VC_BUFFER;
- + }
- + else
- + m_has_keyframe = true;
- + }
- FrameRateTracking( pData, iSize, dts, pts);
- }
- @@ -307,6 +327,9 @@ void CDVDVideoCodecAmlogic::Reset(void)
- m_Codec->Reset();
- m_mpeg2_sequence_pts = 0;
- + m_has_keyframe = false;
- + if (m_bitstream && m_hints.codec == AV_CODEC_ID_H264)
- + m_bitstream->ResetKeyframe();
- }
- bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture)
- @@ -315,7 +338,7 @@ bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture)
- m_Codec->GetPicture(&m_videobuffer);
- *pDvdVideoPicture = m_videobuffer;
- - CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec, m_Codec->GetOMXPts());
- + CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec, m_Codec->GetOMXPts(), m_Codec->GetAmlDuration());
- {
- CSingleLock lock(m_secure);
- @@ -363,7 +386,7 @@ void CDVDVideoCodecAmlogic::SetDropState(bool bDrop)
- // Freerun mode causes amvideo driver to ignore timing and process frames
- // as quickly as they are coming from decoder. By enabling freerun mode we can
- // skip rendering of the frames that are requested to be dropped by VideoPlayer.
- - SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0);
- + //SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0);
- }
- void CDVDVideoCodecAmlogic::SetSpeed(int iSpeed)
- @@ -466,8 +489,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
- 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);
- + m_processInfo.SetVideoFps(m_framerate);
- // update m_hints for 1st frame fixup.
- switch(m_mpeg2_sequence->rate_info)
- @@ -526,7 +548,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
- if (cur_pts == DVD_NOPTS_VALUE)
- cur_pts = m_frame_queue->dts;
- - pthread_mutex_unlock(&m_queue_mutex);
- + pthread_mutex_unlock(&m_queue_mutex);
- float duration = cur_pts - m_last_pts;
- m_last_pts = cur_pts;
- @@ -559,22 +581,10 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
- break;
- // 25.000 (40000.000000)
- - case 40000:
- + case 39900 ... 40100:
- 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 :)
- @@ -592,6 +602,12 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
- {
- m_framerate = framerate;
- m_video_rate = (int)(0.5 + (96000.0 / framerate));
- +
- + if (m_Codec)
- + m_Codec->SetVideoRate(m_video_rate);
- +
- + m_processInfo.SetVideoFps(m_framerate);
- +
- CLog::Log(LOGDEBUG, "%s: detected new framerate(%f), video_rate(%d)",
- __MODULE_NAME__, m_framerate, m_video_rate);
- }
- @@ -607,11 +623,12 @@ void CDVDVideoCodecAmlogic::RemoveInfo(CDVDAmlogicInfo *info)
- m_inflight.erase(m_inflight.find(info));
- }
- -CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts)
- +CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration)
- : m_refs(0)
- , m_codec(codec)
- , m_amlCodec(amlcodec)
- , m_omxPts(omxPts)
- + , m_amlDuration(amlDuration)
- {
- }
- diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
- index 2c44241..a494ace 100644
- --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
- +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
- @@ -36,7 +36,7 @@ class CDVDVideoCodecAmlogic;
- class CDVDAmlogicInfo
- {
- public:
- - CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts);
- + CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration);
- // reference counting
- CDVDAmlogicInfo* Retain();
- @@ -44,6 +44,7 @@ public:
- CAMLCodec *getAmlCodec() const;
- int GetOmxPts() const { return m_omxPts; }
- + int GetAmlDuration() const { return m_amlDuration; }
- void invalidate();
- protected:
- @@ -52,7 +53,7 @@ protected:
- CDVDVideoCodecAmlogic* m_codec;
- CAMLCodec* m_amlCodec;
- - int m_omxPts;
- + int m_omxPts, m_amlDuration;
- };
- class CDVDVideoCodecAmlogic : public CDVDVideoCodec
- @@ -98,6 +99,7 @@ protected:
- mpeg2_sequence *m_mpeg2_sequence;
- double m_mpeg2_sequence_pts;
- bool m_drop;
- + bool m_has_keyframe;
- CBitstreamParser *m_bitparser;
- CBitstreamConverter *m_bitstream;
- diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
- index d8674c8..e6b39f3 100644
- --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
- +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
- @@ -21,26 +21,84 @@
- #include "RendererAML.h"
- #if defined(HAS_LIBAMCODEC)
- -#include "cores/IPlayer.h"
- -#include "windowing/egl/EGLWrapper.h"
- #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h"
- #include "cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h"
- #include "utils/log.h"
- -#include "utils/GLUtils.h"
- #include "utils/SysfsUtils.h"
- #include "settings/MediaSettings.h"
- #include "windowing/WindowingFactory.h"
- #include "cores/VideoPlayer/VideoRenderers/RenderCapture.h"
- +#include "settings/AdvancedSettings.h"
- +
- +static int get_pts(const char *strPath)
- +{
- + int fd = open(strPath, O_RDONLY);
- + if (fd >= 0)
- + {
- + char pts_str[64];
- + int size = read(fd, pts_str, sizeof(pts_str));
- + close(fd);
- + return strtol(pts_str, NULL, 16);
- + }
- + return 0;
- +}
- +
- +static void set_pts(const char *strPath, int pts)
- +{
- + int fd = open(strPath, O_WRONLY);
- + if (fd >= 0)
- + {
- + char pts_str[64];
- + sprintf(pts_str, "0x%x", pts);
- + write(fd, pts_str, strlen(pts_str));
- + close(fd);
- + }
- +}
- CRendererAML::CRendererAML()
- + : m_prevVPts(-1)
- + , m_bConfigured(false)
- + , m_iRenderBuffer(0)
- + , m_diff_counter(0)
- {
- - m_prevPts = -1;
- }
- CRendererAML::~CRendererAML()
- {
- }
- +bool CRendererAML::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation)
- +{
- + m_sourceWidth = width;
- + m_sourceHeight = height;
- + m_renderOrientation = orientation;
- +
- + // Save the flags.
- + m_iFlags = flags;
- + m_format = format;
- +
- + // Calculate the input frame aspect ratio.
- + CalculateFrameAspectRatio(d_width, d_height);
- + SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode);
- + ManageRenderArea();
- +
- + m_bConfigured = true;
- +
- + for (int i = 0 ; i < m_numRenderBuffers ; ++i)
- + m_buffers[i].hwDec = 0;
- +
- + return true;
- +}
- +
- +CRenderInfo CRendererAML::GetRenderInfo()
- +{
- + CRenderInfo info;
- + info.formats.push_back(RENDER_FMT_BYPASS);
- + info.max_buffer_size = m_numRenderBuffers;
- + info.optimal_buffer_size = m_numRenderBuffers;
- + return info;
- +}
- +
- bool CRendererAML::RenderCapture(CRenderCapture* capture)
- {
- capture->BeginRender();
- @@ -48,16 +106,28 @@ bool CRendererAML::RenderCapture(CRenderCapture* capture)
- return true;
- }
- +int CRendererAML::GetImage(YV12Image *image, int source, bool readonly)
- +{
- + if (image == nullptr)
- + return -1;
- +
- + /* take next available buffer */
- + if (source == -1)
- + source = (m_iRenderBuffer + 1) % m_numRenderBuffers;
- +
- + return source;
- +}
- +
- void CRendererAML::AddVideoPictureHW(DVDVideoPicture &picture, int index)
- {
- - YUVBUFFER &buf = m_buffers[index];
- + BUFFER &buf = m_buffers[index];
- if (picture.amlcodec)
- buf.hwDec = picture.amlcodec->Retain();
- }
- void CRendererAML::ReleaseBuffer(int idx)
- {
- - YUVBUFFER &buf = m_buffers[idx];
- + BUFFER &buf = m_buffers[idx];
- if (buf.hwDec)
- {
- CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(buf.hwDec);
- @@ -66,9 +136,14 @@ void CRendererAML::ReleaseBuffer(int idx)
- }
- }
- -int CRendererAML::GetImageHook(YV12Image *image, int source, bool readonly)
- +void CRendererAML::FlipPage(int source)
- {
- - return source;
- + if( source >= 0 && source < m_numRenderBuffers )
- + m_iRenderBuffer = source;
- + else
- + m_iRenderBuffer = (m_iRenderBuffer + 1) % m_numRenderBuffers;
- +
- + return;
- }
- bool CRendererAML::IsGuiLayer()
- @@ -104,37 +179,63 @@ EINTERLACEMETHOD CRendererAML::AutoInterlaceMethod()
- return VS_INTERLACEMETHOD_NONE;
- }
- -bool CRendererAML::LoadShadersHook()
- +void CRendererAML::Reset()
- {
- - CLog::Log(LOGNOTICE, "GL: Using AML render method");
- - m_textureTarget = GL_TEXTURE_2D;
- - m_renderMethod = RENDER_BYPASS;
- - return false;
- + m_prevVPts = -1;
- + m_diff_counter = 0;
- }
- -bool CRendererAML::RenderHook(int index)
- -{
- - return true;// nothing to be done for aml
- -}
- -
- -bool CRendererAML::RenderUpdateVideoHook(bool clear, DWORD flags, DWORD alpha)
- +void CRendererAML::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
- {
- ManageRenderArea();
- - CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iYV12RenderBuffer].hwDec);
- - if (amli && amli->GetOmxPts() != m_prevPts)
- + CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iRenderBuffer].hwDec);
- + CAMLCodec *amlcodec = amli ? amli->getAmlCodec() : 0;
- +
- + int videopts(0);
- + if(amlcodec)
- {
- - m_prevPts = amli->GetOmxPts();
- - SysfsUtils::SetInt("/sys/module/amvideo/parameters/omx_pts", amli->GetOmxPts());
- + unsigned int i(0);
- + do {
- + amlcodec->PollFrame();
- + videopts = get_pts("/sys/class/tsync/pts_video");
- + } while (i++ < 5 && videopts == m_prevVPts);
- + }
- + m_prevVPts = videopts;
- - CAMLCodec *amlcodec = amli->getAmlCodec();
- - if (amlcodec)
- + if (amli)
- + {
- + int pts = amli->GetOmxPts();
- +
- + int pcrscr(get_pts("/sys/class/tsync/pts_pcrscr"));
- + int diff(static_cast<int>((pcrscr - pts)*1.1 / amli->GetAmlDuration()));
- + m_diff_counter += diff;
- +
- + if(!diff)
- + {
- + if (m_diff_counter > 0)
- + --m_diff_counter;
- + else if (m_diff_counter < 0)
- + ++m_diff_counter;
- + }
- +
- + if (abs(m_diff_counter) > 5)
- + {
- + set_pts("/sys/class/tsync/pts_pcrscr", pts);
- + CLog::Log(LOGDEBUG, "RenderUpdate: Adjusting: ptsclock:%d ptsscr:%d vpts:%d dur:%d diff:%d diffsum:%d", pts, pcrscr, videopts,amli->GetAmlDuration(), diff, m_diff_counter);
- + pcrscr = pts;
- + m_diff_counter = 0;
- + }
- + else if (g_advancedSettings.CanLogComponent(LOGVIDEO))
- + {
- + CLog::Log(LOGDEBUG, "RenderUpdate: ptsclock:%d ptsscr:%d vpts:%d diff:%d", pts, pcrscr, videopts, m_diff_counter);
- + }
- +
- + SysfsUtils::SetInt("/sys/module/amvideo/parameters/omx_pts", pcrscr);
- +
- + if(amlcodec)
- amlcodec->SetVideoRect(m_sourceRect, m_destRect);
- }
- -
- - usleep(10000);
- -
- - return true;
- }
- #endif
- diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
- index 828f584..7b4203b 100644
- --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
- +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
- @@ -24,17 +24,29 @@
- #if defined(HAS_LIBAMCODEC)
- -#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
- +#include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
- -class CRendererAML : public CLinuxRendererGLES
- +class CRendererAML : public CBaseRenderer
- {
- public:
- CRendererAML();
- virtual ~CRendererAML();
- -
- +
- virtual bool RenderCapture(CRenderCapture* capture);
- virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
- virtual void ReleaseBuffer(int idx);
- + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation);
- + virtual bool IsConfigured(){ return m_bConfigured; };
- + virtual CRenderInfo GetRenderInfo();
- + virtual int GetImage(YV12Image *image, int source = -1, bool readonly = false);
- + virtual void ReleaseImage(int source, bool preserve = false){};
- + virtual void FlipPage(int source);
- + virtual void PreInit(){};
- + virtual void UnInit(){};
- + virtual void Reset();
- + virtual void Update(){};
- + virtual void RenderUpdate(bool clear, unsigned int flags = 0, unsigned int alpha = 255);
- + virtual bool SupportsMultiPassRendering(){ return false; };
- // Player functions
- virtual bool IsGuiLayer();
- @@ -47,16 +59,20 @@ public:
- virtual EINTERLACEMETHOD AutoInterlaceMethod();
- -protected:
- +private:
- +
- + int m_iRenderBuffer;
- + static const int m_numRenderBuffers = 4;
- - // hooks for hw dec renderer
- - virtual bool LoadShadersHook();
- - virtual bool RenderHook(int index);
- - virtual int GetImageHook(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
- - virtual bool RenderUpdateVideoHook(bool clear, DWORD flags = 0, DWORD alpha = 255);
- + struct BUFFER
- + {
- + void *hwDec;
- + int duration;
- + } m_buffers[m_numRenderBuffers];
- -private:
- - int m_prevPts;
- + int m_prevVPts;
- + bool m_bConfigured;
- + int m_diff_counter;
- };
- #endif
- diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp
- index d0a4c20..be942a1 100644
- --- a/xbmc/utils/BitstreamConverter.cpp
- +++ b/xbmc/utils/BitstreamConverter.cpp
- @@ -72,6 +72,34 @@ enum {
- HEVC_NAL_SEI_SUFFIX = 40
- };
- +enum {
- + SEI_BUFFERING_PERIOD = 0,
- + SEI_PIC_TIMING,
- + SEI_PAN_SCAN_RECT,
- + SEI_FILLER_PAYLOAD,
- + SEI_USER_DATA_REGISTERED_ITU_T_T35,
- + SEI_USER_DATA_UNREGISTERED,
- + SEI_RECOVERY_POINT,
- + SEI_DEC_REF_PIC_MARKING_REPETITION,
- + SEI_SPARE_PIC,
- + SEI_SCENE_INFO,
- + SEI_SUB_SEQ_INFO,
- + SEI_SUB_SEQ_LAYER_CHARACTERISTICS,
- + SEI_SUB_SEQ_CHARACTERISTICS,
- + SEI_FULL_FRAME_FREEZE,
- + SEI_FULL_FRAME_FREEZE_RELEASE,
- + SEI_FULL_FRAME_SNAPSHOT,
- + SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START,
- + SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END,
- + SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET,
- + SEI_FILM_GRAIN_CHARACTERISTICS,
- + SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE,
- + SEI_STEREO_VIDEO_INFO,
- + SEI_POST_FILTER_HINTS,
- + SEI_TONE_MAPPING
- +};
- +
- +
- ////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- // GStreamer h264 parser
- @@ -205,6 +233,34 @@ static const uint8_t* avc_find_startcode(const uint8_t *p, const uint8_t *end)
- return out;
- }
- +static bool has_sei_recovery_point(const uint8_t *p, const uint8_t *end)
- +{
- + int pt(0), ps(0), offset(1);
- +
- + do
- + {
- + pt = 0;
- + do {
- + pt += p[offset];
- + } while (p[offset++] == 0xFF);
- +
- + ps = 0;
- + do {
- + ps += p[offset];
- + } while (p[offset++] == 0xFF);
- +
- + if (pt == SEI_RECOVERY_POINT)
- + {
- + nal_bitstream bs;
- + nal_bs_init(&bs, p + offset, ps);
- + return nal_bs_read_ue(&bs) >= 0;
- + }
- + offset += ps;
- + } while(p + offset < end && p[offset] != 0x80);
- +
- + return false;
- +}
- +
- ////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- CBitstreamParser::CBitstreamParser()
- @@ -255,49 +311,43 @@ const uint8_t* CBitstreamParser::find_start_code(const uint8_t *p,
- return p + 4;
- }
- -bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size)
- +bool CBitstreamParser::HasKeyframe(const uint8_t *buf, int buf_size)
- {
- if (!buf)
- return false;
- bool rtn = false;
- uint32_t state = -1;
- - const uint8_t *buf_end = buf + buf_size;
- + const uint8_t *buf_begin, *buf_end = buf + buf_size;
- - for(;;)
- + for(;rtn == false;)
- {
- buf = find_start_code(buf, buf_end, &state);
- if (buf >= buf_end)
- {
- - //CLog::Log(LOGDEBUG, "FindIdrSlice: buf(%p), buf_end(%p)", buf, buf_end);
- break;
- }
- - --buf;
- - int src_length = buf_end - buf;
- switch (state & 0x1f)
- {
- - default:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found nal_type(%d)", state & 0x1f);
- - break;
- case AVC_NAL_SLICE:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SLICE");
- break;
- case AVC_NAL_IDR_SLICE:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_IDR_SLICE");
- rtn = true;
- break;
- case AVC_NAL_SEI:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SEI");
- + buf_begin = buf - 1;
- + buf = find_start_code(buf, buf_end, &state) - 4;
- + if (has_sei_recovery_point(buf_begin, buf))
- + rtn = true;
- break;
- case AVC_NAL_SPS:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SPS");
- break;
- case AVC_NAL_PPS:
- - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_PPS");
- + break;
- + default:
- break;
- }
- - buf += src_length;
- }
- return rtn;
- @@ -318,6 +368,7 @@ CBitstreamConverter::CBitstreamConverter()
- m_convert_3byteTo4byteNALSize = false;
- m_convert_bytestream = false;
- m_sps_pps_context.sps_pps_data = NULL;
- + m_has_keyframe = true;
- }
- CBitstreamConverter::~CBitstreamConverter()
- @@ -397,7 +448,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
- // are valid, setup to convert 3 byte NAL sizes to 4 byte.
- in_extradata[4] = 0xFF;
- m_convert_3byteTo4byteNALSize = true;
- -
- +
- m_extradata = (uint8_t *)av_malloc(in_extrasize);
- memcpy(m_extradata, in_extradata, in_extrasize);
- m_extrasize = in_extrasize;
- @@ -508,7 +559,7 @@ void CBitstreamConverter::Close(void)
- bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
- {
- if (m_convertBuffer)
- - {
- + {
- av_free(m_convertBuffer);
- m_convertBuffer = NULL;
- }
- @@ -558,7 +609,7 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
- {
- m_inputSize = iSize;
- m_inputBuffer = pData;
- -
- +
- if (m_convert_bytestream)
- {
- if(m_convertBuffer)
- @@ -646,6 +697,16 @@ int CBitstreamConverter::GetExtraSize() const
- return m_extrasize;
- }
- +void CBitstreamConverter::ResetKeyframe(void)
- +{
- + m_has_keyframe = false;
- +}
- +
- +bool CBitstreamConverter::HasKeyframe() const
- +{
- + return m_has_keyframe;
- +}
- +
- bool CBitstreamConverter::BitstreamConvertInitAVC(void *in_extradata, int in_extrasize)
- {
- // based on h264_mp4toannexb_bsf.c (ffmpeg)
- @@ -860,7 +921,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
- int i;
- uint8_t *buf = pData;
- uint32_t buf_size = iSize;
- - uint8_t unit_type, nal_sps, nal_pps;
- + uint8_t unit_type, nal_sps, nal_pps, nal_sei;
- int32_t nal_size;
- uint32_t cumul_size = 0;
- const uint8_t *buf_end = buf + buf_size;
- @@ -870,10 +931,12 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
- case AV_CODEC_ID_H264:
- nal_sps = AVC_NAL_SPS;
- nal_pps = AVC_NAL_PPS;
- + nal_sei = AVC_NAL_SEI;
- break;
- case AV_CODEC_ID_HEVC:
- nal_sps = HEVC_NAL_SPS;
- nal_pps = HEVC_NAL_PPS;
- + nal_sei = HEVC_NAL_SEI_PREFIX;
- break;
- default:
- return false;
- @@ -904,7 +967,10 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
- if (m_sps_pps_context.first_idr && (unit_type == nal_sps || unit_type == nal_pps))
- m_sps_pps_context.idr_sps_pps_seen = 1;
- - // prepend only to the first access unit of an IDR picture, if no sps/pps already present
- + if (!m_has_keyframe && (IsIDR(unit_type) || (unit_type == nal_sei && has_sei_recovery_point(buf, buf + nal_size))))
- + m_has_keyframe = true;
- +
- + // prepend only to the first access unit of an IDR picture, if no sps/pps already present
- if (m_sps_pps_context.first_idr && IsIDR(unit_type) && !m_sps_pps_context.idr_sps_pps_seen)
- {
- BitstreamAllocAndCopy(poutbuf, poutbuf_size,
- diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h
- index 9045ef9..d953907 100644
- --- a/xbmc/utils/BitstreamConverter.h
- +++ b/xbmc/utils/BitstreamConverter.h
- @@ -137,7 +137,7 @@ public:
- static bool Open();
- static void Close();
- - static bool FindIdrSlice(const uint8_t *buf, int buf_size);
- + static bool HasKeyframe(const uint8_t *buf, int buf_size);
- protected:
- static const uint8_t* find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
- @@ -157,6 +157,8 @@ public:
- int GetConvertSize() const;
- uint8_t* GetExtraData(void) const;
- int GetExtraSize() const;
- + void ResetKeyframe(void);
- + bool HasKeyframe() const;
- static void bits_reader_set( bits_reader_t *br, uint8_t *buf, int len );
- static uint32_t read_bits( bits_reader_t *br, int nbits );
- @@ -207,5 +209,6 @@ protected:
- bool m_convert_3byteTo4byteNALSize;
- bool m_convert_bytestream;
- AVCodecID m_codec;
- + bool m_has_keyframe;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement