#include "DynamicDll.h"
#include "cores/dvdplayer/DVDClock.h"
+#include "cores/VideoRenderers/RenderFlags.h"
#include "cores/VideoRenderers/RenderManager.h"
#include "guilib/GraphicContext.h"
#include "settings/MediaSettings.h"
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// AppContext - Application state
+#define MODE_3D_DISABLE 0x00000000
+#define MODE_3D_LR 0x00000101
+#define MODE_3D_LR_SWITCH 0x00000501
+#define MODE_3D_BT 0x00000201
+#define MODE_3D_BT_SWITCH 0x00000601
+#define MODE_3D_TO_2D_L 0x00000102
+#define MODE_3D_TO_2D_R 0x00000902
+#define MODE_3D_TO_2D_T 0x00000202
+#define MODE_3D_TO_2D_B 0x00000a02
+
#define PTS_FREQ 90000
#define UNIT_FREQ 96000
#define AV_SYNC_THRESH PTS_FREQ*30
}
}
- if (VFORMAT_H264 == para->video_format /*|| VFORMAT_H264MVC == para->video_format*/) {
+ if (VFORMAT_H264 == para->video_format || VFORMAT_H264_4K2K == para->video_format) {
ret = h264_write_header(para, pkt);
if (ret != PLAYER_SUCCESS) {
return ret;
am_private->video_rotation_degree = 3;
// handle extradata
am_private->video_format = codecid_to_vformat(hints.codec);
+ if (am_private->video_format == VFORMAT_H264) {
+ if (hints.width > 1920 || hints.height > 1088) {
+ am_private->video_format = VFORMAT_H264_4K2K;
+ }
+ }
switch (am_private->video_format)
{
default:
if (m_hints.ptsinvalid)
am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
break;
+ case VFORMAT_H264_4K2K:
+ if (aml_get_cputype() >= AML_DEVICE_TYPE_M8) {
+ am_private->gcodec.format = VIDEO_DEC_FORMAT_H264_4K2K;
+ am_private->gcodec.param = (void*)EXTERNAL_PTS;
+ // h264 in an avi file
+ if (m_hints.ptsinvalid)
+ am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE);
+ } else {
+ CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, 4K supported only on Meson8.");
+ return false;
+ }
+ break;
case VFORMAT_REAL:
am_private->stream_type = AM_STREAM_RM;
am_private->vcodec.noblock = 1;
CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder codec init failed, ret=0x%x", -ret);
return false;
}
+
am_private->dumpdemux = false;
dumpfile_open(am_private);
aml_set_sysfs_int("/sys/class/tsync/enable", 1);
ShowMainVideo(false);
-
}
void CAMLCodec::Reset()
pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
- pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
- // video pts cannot be late or dvdplayer goes nuts,
- // so run it one frame ahead
- pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
+ if (m_speed == DVD_PLAYSPEED_NORMAL)
+ {
+ pDvdVideoPicture->pts = GetPlayerPtsSeconds() * (double)DVD_TIME_BASE;
+ // video pts cannot be late or dvdplayer goes nuts,
+ // so run it one frame ahead
+ pDvdVideoPicture->pts += 1 * pDvdVideoPicture->iDuration;
+ }
+ else
+ {
+ // We are FF/RW; Do not use the Player clock or it just doesn't work
+ 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;
+ }
return true;
}
break;
default:
m_dll->codec_resume(&am_private->vcodec);
- if (am_private->video_format == VFORMAT_H264)
+ if ((am_private->video_format == VFORMAT_H264) || (am_private->video_format == VFORMAT_H264_4K2K))
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
else
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_I);
return;
}
+void CAMLCodec::SetVideo3dMode(const int mode3d)
+{
+ CLog::Log(LOGDEBUG, "CAMLCodec::SetVideo3dMode:mode3d(0x%x)", mode3d);
+ aml_set_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode", mode3d);
+}
+
+std::string CAMLCodec::GetStereoMode()
+{
+ std::string stereo_mode;
+
+ switch(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoMode)
+ {
+ case RENDER_STEREO_MODE_SPLIT_VERTICAL: stereo_mode = "left_right"; break;
+ case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: stereo_mode = "top_bottom"; break;
+ default: stereo_mode = m_hints.stereo_mode; break;
+ }
+
+ if(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoInvert)
+ stereo_mode = RenderManager::GetStereoModeInvert(stereo_mode);
+ return stereo_mode;
+}
+
void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
{
CAMLCodec *codec = (CAMLCodec*)ctx;
// this routine gets called every video frame
// and is in the context of the renderer thread so
// do not do anything stupid here.
+ bool update = false;
// video zoom adjustment.
float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
m_brightness = brightness;
}
- // check if destination rect or video view mode has changed
- if ((m_dst_rect != DestRect) || (m_view_mode != CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode))
+ // video view mode
+ int view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
+ if (m_view_mode != view_mode)
+ {
+ m_view_mode = view_mode;
+ update = true;
+ }
+
+ // video stereo mode/view.
+ RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode();
+ if (m_stereo_mode != stereo_mode)
+ {
+ m_stereo_mode = stereo_mode;
+ update = true;
+ }
+ RENDER_STEREO_VIEW stereo_view = g_graphicsContext.GetStereoView();
+ if (m_stereo_view != stereo_view)
+ {
+ // left/right/top/bottom eye,
+ // this might change every other frame.
+ // we do not care but just track it.
+ m_stereo_view = stereo_view;
+ }
+
+ // dest_rect
+ if (m_dst_rect != DestRect)
{
m_dst_rect = DestRect;
- m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
+ update = true;
}
- else
+
+ if (!update)
{
// mainvideo 'should' be showing already if we get here, make sure.
ShowMainVideo(true);
dst_rect.y2 *= yscale;
}
- ShowMainVideo(false);
+#if 0
+ std::string rectangle = StringUtils::Format("%i,%i,%i,%i",
+ (int)dst_rect.x1, (int)dst_rect.y1,
+ (int)dst_rect.Width(), (int)dst_rect.Height());
+ CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
+ CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_mode(%d)", m_stereo_mode);
+ CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_view(%d)", m_stereo_view);
+#endif
+
+ if (m_stereo_mode == RENDER_STEREO_MODE_MONO)
+ {
+ std::string mode = GetStereoMode();
+ if (mode == "left_right")
+ SetVideo3dMode(MODE_3D_TO_2D_L);
+ else if (mode == "right_left")
+ SetVideo3dMode(MODE_3D_TO_2D_R);
+ else if (mode == "top_bottom")
+ SetVideo3dMode(MODE_3D_TO_2D_T);
+ else if (mode == "bottom_top")
+ SetVideo3dMode(MODE_3D_TO_2D_B);
+ else
+ SetVideo3dMode(MODE_3D_DISABLE);
+ }
+ else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
+ {
+ dst_rect.x2 *= 2.0;
+ SetVideo3dMode(MODE_3D_DISABLE);
+ }
+ else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
+ {
+ dst_rect.y2 *= 2.0;
+ SetVideo3dMode(MODE_3D_DISABLE);
+ }
+ else if (m_stereo_mode == RENDER_STEREO_MODE_INTERLACED)
+ {
+ std::string mode = GetStereoMode();
+ if (mode == "left_right")
+ SetVideo3dMode(MODE_3D_LR);
+ else if (mode == "right_left")
+ SetVideo3dMode(MODE_3D_LR_SWITCH);
+ else if (mode == "row_interleaved_lr")
+ SetVideo3dMode(MODE_3D_LR);
+ else if (mode == "row_interleaved_rl")
+ SetVideo3dMode(MODE_3D_LR_SWITCH);
+ else
+ SetVideo3dMode(MODE_3D_DISABLE);
+ }
+ else
+ {
+ SetVideo3dMode(MODE_3D_DISABLE);
+ }
// goofy 0/1 based difference in aml axis coordinates.
// fix them.
dst_rect.x2--;
dst_rect.y2--;
- char video_axis[256] = {0};
+ char video_axis[256] = {};
sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
+
aml_set_sysfs_str("/sys/class/video/axis", video_axis);
// make sure we are in 'full stretch' so we can stretch
aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
-/*
- CStdString rectangle;
- rectangle.Format("%i,%i,%i,%i",
- (int)dst_rect.x1, (int)dst_rect.y1,
- (int)dst_rect.Width(), (int)dst_rect.Height());
- CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
-*/
-
// we only get called once gui has changed to something
// that would show video playback, so show it.
ShowMainVideo(true);