diff options
-rw-r--r-- | system/settings/win32.xml | 5 | ||||
-rw-r--r-- | tools/depends/target/xbmc/Makefile | 2 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp | 163 | ||||
-rw-r--r-- | xbmc/dialogs/GUIDialogBoxBase.cpp | 2 | ||||
-rw-r--r-- | xbmc/guilib/GUITextLayout.cpp | 1 |
5 files changed, 147 insertions, 26 deletions
diff --git a/system/settings/win32.xml b/system/settings/win32.xml index acf63d1164..fce8da1b84 100644 --- a/system/settings/win32.xml +++ b/system/settings/win32.xml @@ -38,6 +38,11 @@ <requirement negated="true">HAS_GL</requirement> </setting> </group> + <group id="3"> + <setting id="videoscreen.vsync"> + <default>2</default> <!-- VSYNC_ALWAYS --> + </setting> + </group> </category> <category id="audiooutput" label="772" help="36360"> <group id="1"> diff --git a/tools/depends/target/xbmc/Makefile b/tools/depends/target/xbmc/Makefile index d5a2e2532a..bfaa534995 100644 --- a/tools/depends/target/xbmc/Makefile +++ b/tools/depends/target/xbmc/Makefile @@ -10,7 +10,7 @@ CONFIGURE = cp -f $(CONFIG_SUB) $(CONFIG_GUESS) build-aux/ ;\ ./configure --prefix=$(PREFIX) ifeq ($(OS),android) -CONFIGURE += --enable-codec=libstagefright +CONFIGURE += --enable-codec=libstagefright,amcodec endif CONFIGURE += $(CONFIG_EXTRA) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp index b90452288d..4c1e31420d 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp @@ -33,6 +33,11 @@ #include "utils/StringUtils.h" #include "utils/TimeUtils.h" +#if defined(TARGET_ANDROID) +#include "android/activity/AndroidFeatures.h" +#include "utils/BitstreamConverter.h" +#endif + #include <unistd.h> #include <queue> #include <vector> @@ -48,6 +53,22 @@ extern "C" { #include <amcodec/codec.h> } // extern "C" +typedef struct { + bool noblock; + int video_pid; + int video_type; + stream_type_t stream_type; + unsigned int format; + unsigned int width; + unsigned int height; + unsigned int rate; + unsigned int extra; + unsigned int status; + unsigned int ratio; + unsigned long long ratio64; + void *param; +} aml_generic_param; + class DllLibamCodecInterface { public: @@ -125,6 +146,96 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface RESOLVE_METHOD(av_d2q) END_METHOD_RESOLVE() + +public: + void codec_init_para(aml_generic_param *p_in, codec_para_t *p_out) + { + memset(p_out, 0x00, sizeof(codec_para_t)); + +#ifdef TARGET_ANDROID + bits_writer_t bs = {0}; + + // we are always as large as codec_para_t from headers. + CBitstreamConverter::init_bits_writer(&bs, (uint8_t*)p_out, sizeof(codec_para_t), 1); + + // order matters, so pay attention + // to codec_para_t in codec_types.h + CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE handle + CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE cntl_handle + CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE sub_handle + + // added in JellyBean 4.2 + if (CAndroidFeatures::GetVersion() > 16) + CBitstreamConverter::write_bits(&bs, 32, 0); // CODEC_HANDLE audio_utils_handle + + CBitstreamConverter::write_bits(&bs, 32, p_in->stream_type); // stream_type_t stream_type + + // watch these, using bit fields (which is stupid) + CBitstreamConverter::write_bits(&bs, 1, 1); // unsigned int has_video:1 + CBitstreamConverter::write_bits(&bs, 1, 0); // unsigned int has_audio:1 + CBitstreamConverter::write_bits(&bs, 1, 0); // unsigned int has_sub:1 + unsigned int value = p_in->noblock > 0 ? 1:0; + CBitstreamConverter::write_bits(&bs, 1, value); // unsigned int noblock:1 + CBitstreamConverter::write_bits(&bs, 28, 0); // align back to next word boundary + + CBitstreamConverter::write_bits(&bs, 32, p_in->video_type); // int video_type + CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_type + CBitstreamConverter::write_bits(&bs, 32, 0); // int sub_type + + CBitstreamConverter::write_bits(&bs, 32, p_in->video_pid); // int video_pid + CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_pid + CBitstreamConverter::write_bits(&bs, 32, 0); // int sub_pid + + CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_channels + CBitstreamConverter::write_bits(&bs, 32, 0); // int audio_samplerate + CBitstreamConverter::write_bits(&bs, 32, 0); // int vbuf_size + CBitstreamConverter::write_bits(&bs, 32, 0); // int abuf_size + + // ARM requires 8-byte alignment for 64-bit members (ratio64) + // and this will force am_sysinfo to be also have 8-byte alignment. + // Since the inclusion of audio_utils_handle for JellyBean 4.2 + // 'naturally' aligns am_sysinfo to 8-byte, we need to compensate + // when we are NOT JellyBean 4.2. If these member values get changed, + // then make sure you check that am_sysinfo has 8-byte alignment. + if (CAndroidFeatures::GetVersion() < 17) + CBitstreamConverter::write_bits(&bs, 32, 0); + + CBitstreamConverter::write_bits(&bs, 32, p_in->format); // am_sysinfo, unsigned int format + CBitstreamConverter::write_bits(&bs, 32, p_in->width); // am_sysinfo, unsigned int width + CBitstreamConverter::write_bits(&bs, 32, p_in->height); // am_sysinfo, unsigned int height + CBitstreamConverter::write_bits(&bs, 32, p_in->rate); // am_sysinfo, unsigned int rate + CBitstreamConverter::write_bits(&bs, 32, p_in->extra); // am_sysinfo, unsigned int extra + CBitstreamConverter::write_bits(&bs, 32, p_in->status); // am_sysinfo, unsigned int status + CBitstreamConverter::write_bits(&bs, 32, p_in->ratio); // am_sysinfo, unsigned int ratio + CBitstreamConverter::write_bits(&bs, 32, (unsigned int)p_in->param); // am_sysinfo, unsigned int param + unsigned int lo = 0x00000000ffffffff & p_in->ratio64; + unsigned int hi = p_in->ratio64 >> 32; + CBitstreamConverter::write_bits(&bs, 32, lo); // am_sysinfo, unsigned long long ratio64 + CBitstreamConverter::write_bits(&bs, 32, hi); // am_sysinfo, unsigned long long ratio64 + + // we do not care about the rest, flush and go. + // FYI there are 4.0 to 4.1 differences here. + CBitstreamConverter::flush_bits(&bs); + //CLog::MemDump((char*)p_out, 0xFF); +#else + // direct struct usage, we do not know which flavor + // so just use what we get from headers and pray. + p_out->has_video = 1; + p_out->noblock = p_in->noblock; + p_out->video_pid = p_in->video_pid; + p_out->video_type = p_in->video_type; + p_out->stream_type = p_in->stream_type; + p_out->am_sysinfo.format = p_in->format; + p_out->am_sysinfo.width = p_in->width; + p_out->am_sysinfo.height = p_in->height; + p_out->am_sysinfo.rate = p_in->rate; + p_out->am_sysinfo.extra = p_in->extra; + p_out->am_sysinfo.status = p_in->status; + p_out->am_sysinfo.ratio = p_in->ratio; + p_out->am_sysinfo.ratio64 = p_in->ratio64; + p_out->am_sysinfo.param = p_in->param; +#endif + } }; //----------------------------------------------------------------------------------- @@ -205,6 +316,7 @@ typedef enum { typedef struct am_private_t { am_packet_t am_pkt; + aml_generic_param gcodec; codec_para_t vcodec; pstream_type stream_type; @@ -1303,7 +1415,8 @@ CAMLCodec::~CAMLCodec() bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) { - CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder"); + CLog::Log(LOGDEBUG, "CAMLCodec::OpenDecoder, android version %d", CAndroidFeatures::GetVersion()); + m_speed = DVD_PLAYSPEED_NORMAL; m_1st_pts = 0; m_cur_pts = 0; @@ -1421,33 +1534,32 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) hints.orientation, hints.forced_aspect, hints.extrasize); // default video codec params - am_private->vcodec.has_video = 1; - am_private->vcodec.noblock = 0; - am_private->vcodec.video_pid = am_private->video_pid; - am_private->vcodec.video_type = am_private->video_format; - am_private->vcodec.stream_type = STREAM_TYPE_ES_VIDEO; - am_private->vcodec.am_sysinfo.format = am_private->video_codec_type; - am_private->vcodec.am_sysinfo.width = am_private->video_width; - am_private->vcodec.am_sysinfo.height = am_private->video_height; - am_private->vcodec.am_sysinfo.rate = am_private->video_rate; - am_private->vcodec.am_sysinfo.ratio = am_private->video_ratio; - am_private->vcodec.am_sysinfo.ratio64 = am_private->video_ratio64; - am_private->vcodec.am_sysinfo.param = NULL; + am_private->gcodec.noblock = 0; + am_private->gcodec.video_pid = am_private->video_pid; + am_private->gcodec.video_type = am_private->video_format; + am_private->gcodec.stream_type = STREAM_TYPE_ES_VIDEO; + am_private->gcodec.format = am_private->video_codec_type; + am_private->gcodec.width = am_private->video_width; + am_private->gcodec.height = am_private->video_height; + am_private->gcodec.rate = am_private->video_rate; + am_private->gcodec.ratio = am_private->video_ratio; + am_private->gcodec.ratio64 = am_private->video_ratio64; + am_private->gcodec.param = NULL; switch(am_private->video_format) { default: break; case VFORMAT_MPEG4: - am_private->vcodec.am_sysinfo.param = (void*)EXTERNAL_PTS; + am_private->gcodec.param = (void*)EXTERNAL_PTS; break; case VFORMAT_H264: case VFORMAT_H264MVC: - am_private->vcodec.am_sysinfo.format = VIDEO_DEC_FORMAT_H264; - am_private->vcodec.am_sysinfo.param = (void*)EXTERNAL_PTS; + am_private->gcodec.format = VIDEO_DEC_FORMAT_H264; + am_private->gcodec.param = (void*)EXTERNAL_PTS; // h264 in an avi file if (m_hints.ptsinvalid) - am_private->vcodec.am_sysinfo.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE); + am_private->gcodec.param = (void*)(EXTERNAL_PTS | SYNC_OUTSIDE); break; case VFORMAT_REAL: am_private->stream_type = AM_STREAM_RM; @@ -1459,26 +1571,29 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) static unsigned short tbl[9] = {0}; if (VIDEO_DEC_FORMAT_REAL_8 == am_private->video_codec_type) { - am_private->vcodec.am_sysinfo.extra = am_private->extradata[1] & 7; - tbl[0] = (((am_private->vcodec.am_sysinfo.width >> 2) - 1) << 8) - | (((am_private->vcodec.am_sysinfo.height >> 2) - 1) & 0xff); + am_private->gcodec.extra = am_private->extradata[1] & 7; + tbl[0] = (((am_private->gcodec.width >> 2) - 1) << 8) + | (((am_private->gcodec.height >> 2) - 1) & 0xff); unsigned int j; - for (unsigned int i = 1; i <= am_private->vcodec.am_sysinfo.extra; i++) + for (unsigned int i = 1; i <= am_private->gcodec.extra; i++) { j = 2 * (i - 1); tbl[i] = ((am_private->extradata[8 + j] - 1) << 8) | ((am_private->extradata[8 + j + 1] - 1) & 0xff); } } - am_private->vcodec.am_sysinfo.param = &tbl; + am_private->gcodec.param = &tbl; } break; case VFORMAT_VC1: // vc1 in an avi file if (m_hints.ptsinvalid) - am_private->vcodec.am_sysinfo.param = (void*)EXTERNAL_PTS; + am_private->gcodec.param = (void*)EXTERNAL_PTS; break; } - am_private->vcodec.am_sysinfo.param = (void *)((unsigned int)am_private->vcodec.am_sysinfo.param | (am_private->video_rotation_degree << 16)); + am_private->gcodec.param = (void *)((unsigned int)am_private->gcodec.param | (am_private->video_rotation_degree << 16)); + + // translate from generic to firemware version dependent + m_dll->codec_init_para(&am_private->gcodec, &am_private->vcodec); int ret = m_dll->codec_init(&am_private->vcodec); if (ret != CODEC_ERROR_NONE) diff --git a/xbmc/dialogs/GUIDialogBoxBase.cpp b/xbmc/dialogs/GUIDialogBoxBase.cpp index cd9aa487ba..efb5316df5 100644 --- a/xbmc/dialogs/GUIDialogBoxBase.cpp +++ b/xbmc/dialogs/GUIDialogBoxBase.cpp @@ -85,7 +85,7 @@ void CGUIDialogBoxBase::SetLine(unsigned int iLine, const CVariant& line) std::string text = StringUtils::Join(lines, "\n"); if (text != m_text) { - m_text = StringUtils::Join(lines, "\n"); + m_text = text; SetInvalid(); } } diff --git a/xbmc/guilib/GUITextLayout.cpp b/xbmc/guilib/GUITextLayout.cpp index 1c80aadaac..ade799d796 100644 --- a/xbmc/guilib/GUITextLayout.cpp +++ b/xbmc/guilib/GUITextLayout.cpp @@ -675,6 +675,7 @@ void CGUITextLayout::Reset() { m_lines.clear(); m_lastText.clear(); + m_lastUtf8Text.clear(); m_textWidth = m_textHeight = 0; } |