bool aml_probe_resolutions(std::vector<RESOLUTION_INFO> &resolutions) { std::string valstr, dcapfile; dcapfile = CSpecialProtocol::TranslatePath("special://home/userdata/disp_cap"); if (SysfsUtils::GetString(dcapfile, valstr) < 0) { if (SysfsUtils::GetString("/sys/class/amhdmitx/amhdmitx0/disp_cap", valstr) < 0) return false; } std::vector<std::string> probe_str = StringUtils::Split(valstr, "\n"); resolutions.clear(); RESOLUTION_INFO res; for (std::vector<std::string>::const_iterator i = probe_str.begin(); i != probe_str.end(); ++i) { if (((StringUtils::StartsWith(i->c_str(), "4k2k")) && (aml_support_h264_4k2k() > AML_NO_H264_4K2K)) || !(StringUtils::StartsWith(i->c_str(), "4k2k"))) { if (aml_mode_to_resolution(i->c_str(), &res)) resolutions.push_back(res); } } return resolutions.size() > 0; }
bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) { if (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEAMCODEC)) return false; if (hints.stills) return false; if (!aml_permissions()) { CLog::Log(LOGERROR, "AML: no proper permission, please contact the device vendor. Skipping codec..."); return false; } m_hints = hints; switch(m_hints.codec) { case AV_CODEC_ID_MJPEG: m_pFormatName = "am-mjpeg"; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: case AV_CODEC_ID_MPEG2VIDEO_XVMC: if (m_hints.width <= CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_USEAMCODECMPEG2)) return false; m_mpeg2_sequence_pts = 0; m_mpeg2_sequence = new mpeg2_sequence; m_mpeg2_sequence->width = m_hints.width; m_mpeg2_sequence->height = m_hints.height; m_mpeg2_sequence->ratio = m_hints.aspect; if (m_hints.fpsrate > 0 && m_hints.fpsscale != 0) m_mpeg2_sequence->rate = (float)m_hints.fpsrate / m_hints.fpsscale; else m_mpeg2_sequence->rate = 1.0; m_pFormatName = "am-mpeg2"; break; case AV_CODEC_ID_H264: if (m_hints.width <= CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_USEAMCODECH264)) return false; if ((!aml_support_h264_4k2k()) && ((m_hints.width > 1920) || (m_hints.height > 1088))) { // 4K is supported only on Amlogic S802/S812 chip return false; } m_pFormatName = "am-h264"; // convert h264-avcC to h264-annex-b as h264-avcC // under streamers can have issues when seeking. if (m_hints.extradata && *(uint8_t*)m_hints.extradata == 1) { m_bitstream = new CBitstreamConverter; m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true); // 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(); break; case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_MSMPEG4V2: case AV_CODEC_ID_MSMPEG4V3: if (m_hints.width <= CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_USEAMCODECMPEG4)) return false; m_pFormatName = "am-mpeg4"; break; case AV_CODEC_ID_H263: case AV_CODEC_ID_H263P: case AV_CODEC_ID_H263I: // amcodec can't handle h263 return false; break; case AV_CODEC_ID_FLV1: m_pFormatName = "am-flv1"; break; case AV_CODEC_ID_RV10: case AV_CODEC_ID_RV20: case AV_CODEC_ID_RV30: case AV_CODEC_ID_RV40: // m_pFormatName = "am-rv"; // rmvb is not handled well by amcodec return false; break; case AV_CODEC_ID_VC1: m_pFormatName = "am-vc1"; break; case AV_CODEC_ID_WMV3: m_pFormatName = "am-wmv3"; break; case AV_CODEC_ID_AVS: case AV_CODEC_ID_CAVS: m_pFormatName = "am-avs"; break; case AV_CODEC_ID_HEVC: if (aml_support_hevc()) { if (!aml_support_hevc_4k2k() && ((m_hints.width > 1920) || (m_hints.height > 1088))) { // 4K HEVC is supported only on Amlogic S812 chip return false; } } else { // HEVC supported only on S805 and S812. return false; } m_pFormatName = "am-h265"; m_bitstream = new CBitstreamConverter(); m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true); // 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); break; default: CLog::Log(LOGDEBUG, "%s: Unknown hints.codec(%d", __MODULE_NAME__, m_hints.codec); return false; break; } m_aspect_ratio = m_hints.aspect; m_Codec = new CAMLCodec(); if (!m_Codec) { CLog::Log(LOGERROR, "%s: Failed to create Amlogic Codec", __MODULE_NAME__); return false; } m_opened = false; // allocate a dummy DVDVideoPicture buffer. // first make sure all properties are reset. memset(&m_videobuffer, 0, sizeof(DVDVideoPicture)); m_videobuffer.dts = DVD_NOPTS_VALUE; m_videobuffer.pts = DVD_NOPTS_VALUE; m_videobuffer.format = RENDER_FMT_AML; m_videobuffer.color_range = 0; m_videobuffer.color_matrix = 4; m_videobuffer.iFlags = DVP_FLAG_ALLOCATED; m_videobuffer.iWidth = m_hints.width; m_videobuffer.iHeight = m_hints.height; m_videobuffer.amlcodec = NULL; m_videobuffer.iDisplayWidth = m_videobuffer.iWidth; m_videobuffer.iDisplayHeight = m_videobuffer.iHeight; if (m_hints.aspect > 0.0 && !m_hints.forced_aspect) { m_videobuffer.iDisplayWidth = ((int)lrint(m_videobuffer.iHeight * m_hints.aspect)) & ~3; if (m_videobuffer.iDisplayWidth > m_videobuffer.iWidth) { m_videobuffer.iDisplayWidth = m_videobuffer.iWidth; m_videobuffer.iDisplayHeight = ((int)lrint(m_videobuffer.iWidth / m_hints.aspect)) & ~3; } } CLog::Log(LOGINFO, "%s: Opened Amlogic Codec", __MODULE_NAME__); return true; }