Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote-tracking branch 'origin/adddroidlibstagefright' into Got…

…ham_alpha2_stagefright
  • Loading branch information...
commit 6200f76b32ce1b13055d751272f2d4326d23a784 2 parents 194c408 + b5bc8f1
@koying authored
Showing with 3,110 additions and 14 deletions.
  1. +22 −0 configure.in
  2. +5 −1 language/English/strings.po
  3. +4 −0 tools/depends/target/Makefile
  4. +62 −0 tools/depends/target/android-sources-ics/Makefile
  5. +43 −0 tools/depends/target/android-sources-ics/libbinder.cpp
  6. +25 −0 tools/depends/target/android-sources-ics/libcutils.c
  7. +32 −0 tools/depends/target/android-sources-ics/libgui.cpp
  8. +381 −0 tools/depends/target/android-sources-ics/libstagefright.cpp
  9. +37 −0 tools/depends/target/android-sources-ics/libui.cpp
  10. +333 −0 tools/depends/target/android-sources-ics/libutils.cpp
  11. +108 −3 xbmc/android/activity/XBMCApp.cpp
  12. +36 −1 xbmc/android/activity/XBMCApp.h
  13. +3 −3 xbmc/android/activity/android_main.cpp
  14. +234 −1 xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
  15. +16 −3 xbmc/cores/VideoRenderers/LinuxRendererGLES.h
  16. +1 −0  xbmc/cores/VideoRenderers/RenderFormats.h
  17. +5 −0 xbmc/cores/VideoRenderers/RenderManager.cpp
  18. +36 −2 xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
  19. +7 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
  20. +201 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecStageFright.cpp
  21. +55 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecStageFright.h
  22. +14 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
  23. +1,337 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/StageFrightVideo.cpp
  24. +54 −0 xbmc/cores/dvdplayer/DVDCodecs/Video/StageFrightVideo.h
  25. +3 −0  xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
  26. +20 −0 xbmc/settings/AdvancedSettings.cpp
  27. +12 −0 xbmc/settings/AdvancedSettings.h
  28. +3 −0  xbmc/settings/GUISettings.cpp
  29. +12 −0 xbmc/windowing/egl/EGLWrapper.cpp
  30. +2 −0  xbmc/windowing/egl/EGLWrapper.h
  31. +5 −0 xbmc/windowing/egl/WinSystemEGL.cpp
  32. +2 −0  xbmc/windowing/egl/WinSystemEGL.h
View
22 configure.in
@@ -392,6 +392,12 @@ AC_ARG_ENABLE([ffmpeg_libvorbis],
[use_ffmpeg_libvorbis=$enableval],
[use_ffmpeg_libvorbis=no])
+AC_ARG_ENABLE([libstagefright],
+ [AS_HELP_STRING([--enable-libstagefright],
+ [enable libstagefright-based HW accelerated decoding 'Android only' (default is no)])],
+ [use_libstagefright=$enableval],
+ [use_libstagefright=no])
+
AC_ARG_ENABLE([dvdcss],
[AS_HELP_STRING([--enable-dvdcss],
[enable DVDCSS support (default is yes)])],
@@ -651,6 +657,7 @@ case $host in
use_optical_drive=no
use_sdl=no
use_x11=no
+ use_libstagefright=yes
build_shared_lib=yes
;;
*)
@@ -1841,6 +1848,14 @@ else
fi
fi
+# libStageFright
+if test "$target_platform" = "target_android" ; then
+ if test "$use_libstagefright" = "yes"; then
+ USE_LIBSTAGEFRIGHT=1; AC_DEFINE([HAVE_LIBSTAGEFRIGHT],[1],["Define to 1 if libstagefright is enabled"])
+ LIBS+="-L${prefix}/opt/android-libs -lstdc++ -lutils -lcutils -lstagefright -lbinder -lui -lgui"
+ fi
+fi
+
# yajl version check (yajl_version.h was added in yajl 2.0)
AC_CHECK_HEADERS([yajl/yajl_version.h], [], [
AC_DEFINE(YAJL_MAJOR, 1, [yajl version 1])
@@ -2005,6 +2020,12 @@ else
final_message="$final_message\n OpenMax:\tNo"
fi
+if test "$use_libstagefright" != "no"; then
+ final_message="$final_message\n libstagefright:\tYes"
+else
+ final_message="$final_message\n libstagefright:\tNo"
+fi
+
if test "$use_joystick" = "yes"; then
final_message="$final_message\n Joystick:\tYes"
SDL_DEFINES="$SDL_DEFINES -DHAS_SDL_JOYSTICK"
@@ -2456,6 +2477,7 @@ AC_SUBST(USE_LIBAFPCLIENT)
AC_SUBST(USE_AIRPLAY)
AC_SUBST(USE_VDA)
AC_SUBST(USE_OPENMAX)
+AC_SUBST(USE_LIBSTAGEFRIGHT)
AC_SUBST(USE_PULSE)
AC_SUBST(USE_XRANDR)
AC_SUBST(USE_ALSA)
View
6 language/English/strings.po
@@ -5348,7 +5348,11 @@ msgctxt "#13434"
msgid "Play only this"
msgstr ""
-#empty strings from id 13435 to 13499
+msgctxt "#13435"
+msgid "Allow hardware acceleration (libstagefright)"
+msgstr ""
+
+#empty strings from id 13436 to 13499
#: xbmc/settings/GUISettings.cpp
msgctxt "#13500"
View
4 tools/depends/target/Makefile
@@ -33,6 +33,10 @@ ifeq ($(OS),osx)
EXCLUDED_DEPENDS = libusb
endif
+ifeq ($(OS),android)
+ DEPENDS += android-sources-ics
+endif
+
DEPENDS := $(filter-out $(EXCLUDED_DEPENDS),$(DEPENDS))
ZLIB=
View
62 tools/depends/target/android-sources-ics/Makefile
@@ -0,0 +1,62 @@
+include ../../Makefile.include
+DEPS= ../../Makefile.include Makefile
+INCLUDES += -I$(PREFIX)/opt/android-source/frameworks/base/include
+INCLUDES += -I$(PREFIX)/opt/android-source/frameworks/base/native/include
+INCLUDES += -I$(PREFIX)/opt/android-source/frameworks/base/include/media/stagefright
+INCLUDES += -I$(PREFIX)/opt/android-source/frameworks/base/include/media/stagefright/openmax
+INCLUDES += -I$(PREFIX)/opt/android-source/system/core/include
+INCLUDES += -I$(PREFIX)/opt/android-source/libhardware/include
+
+ANDROID_VERSION=ics-mr0
+ANDROID_SOURCE=android-source
+ANDROID_LIBS=android-libs
+
+all: .installed-$(PLATFORM)
+
+.installed-$(PLATFORM): install-sources $(ANDROID_LIBS)
+ rm -rf $(PREFIX)/opt/$(ANDROID_LIBS)
+ mkdir -p $(PREFIX)/opt/$(ANDROID_LIBS)
+ cp $(PLATFORM)/libstagefright.so $(PLATFORM)/libutils.so $(PLATFORM)/libbinder.so $(PLATFORM)/libcutils.so $(PLATFORM)/libui.so $(PLATFORM)/libgui.so $(PREFIX)/opt/$(ANDROID_LIBS)
+ touch $@
+
+$(ANDROID_SOURCE):
+ echo "Fetching Android system headers"
+ git clone --depth=1 --branch $(ANDROID_VERSION) https://android.googlesource.com/platform/frameworks/base $(ANDROID_SOURCE)/frameworks/base
+ git clone --depth=1 --branch $(ANDROID_VERSION) https://android.googlesource.com/platform/system/core $(ANDROID_SOURCE)/system/core
+ git clone --depth=1 --branch $(ANDROID_VERSION) https://android.googlesource.com/platform/hardware/libhardware $(ANDROID_SOURCE)/libhardware
+
+install-sources: $(ANDROID_SOURCE)
+ mkdir -p $(PREFIX)/opt
+ rm -f $(PREFIX)/opt/$(ANDROID_SOURCE)
+ ln -s $(CURDIR)/$(ANDROID_SOURCE) $(PREFIX)/opt/$(ANDROID_SOURCE)
+
+$(ANDROID_LIBS): $(PLATFORM)/libstagefright.so $(PLATFORM)/libutils.so $(PLATFORM)/libbinder.so $(PLATFORM)/libcutils.so $(PLATFORM)/libui.so $(PLATFORM)/libgui.so
+ mkdir -p $(PREFIX)/opt/$(ANDROID_LIBS)
+ cp $(PLATFORM)/libstagefright.so $(PLATFORM)/libutils.so $(PLATFORM)/libbinder.so $(PLATFORM)/libcutils.so $(PLATFORM)/libui.so $(PLATFORM)/libgui.so $(PREFIX)/opt/$(ANDROID_LIBS)
+
+$(PLATFORM): install-sources
+ mkdir -p $(PLATFORM)
+
+$(PLATFORM)/libstagefright.so: $(PLATFORM) $(DEPS) libstagefright.cpp
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -DHAVE_PTHREADS -shared -o $(PLATFORM)/libstagefright.so libstagefright.cpp
+
+$(PLATFORM)/libutils.so: $(PLATFORM) $(DEPS) libutils.cpp
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -shared -o $(PLATFORM)/libutils.so libutils.cpp
+
+$(PLATFORM)/libbinder.so: $(PLATFORM) $(DEPS) libbinder.cpp
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -shared -o $(PLATFORM)/libbinder.so libbinder.cpp
+
+$(PLATFORM)/libcutils.so: $(PLATFORM) $(DEPS) libcutils.c
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -shared -o $(PLATFORM)/libcutils.so libcutils.c
+
+$(PLATFORM)/libui.so: $(PLATFORM) $(DEPS) libui.cpp
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -shared -o $(PLATFORM)/libui.so libui.cpp
+
+$(PLATFORM)/libgui.so: $(PLATFORM) $(DEPS) libgui.cpp
+ $(CXX) -Wno-multichar -fno-exceptions -fno-rtti $(INCLUDES) -shared -o $(PLATFORM)/libgui.so libgui.cpp
+
+clean:
+ rm -f $(PREFIX)/opt/$(ANDROID_SOURCE)
+ rm -rf .installed-$(PLATFORM) $(ANDROID_SOURCE) $(PLATFORM) $(ANDROID_LIBS_ARCHIVE) $(ANDROID_LIBS)
+
+distclean: clean
View
43 tools/depends/target/android-sources-ics/libbinder.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// ---------------------------------------------------------------------------
+
+#include <binder/ProcessState.h>
+
+namespace android {
+
+sp<ProcessState> ProcessState::self()
+{
+}
+
+void ProcessState::startThreadPool()
+{
+}
+
+ProcessState::ProcessState()
+{
+}
+
+ProcessState::~ProcessState()
+{
+}
+
+}; // namespace android
View
25 tools/depends/target/android-sources-ics/libcutils.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cutils/atomic.h>
+
+int32_t android_atomic_dec(volatile int32_t* addr) {
+ return 0;
+}
View
32 tools/depends/target/android-sources-ics/libgui.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <gui/SurfaceTexture.h>
+
+namespace android {
+
+status_t SurfaceTexture::updateTexImage()
+{
+ return 0;
+}
+
+void SurfaceTexture::getTransformMatrix(float mtx[16]) {}
+
+}
+
View
381 tools/depends/target/android-sources-ics/libstagefright.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define STAGEFRIGHT_EXPORT __attribute__ ((visibility ("default")))
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+
+#include <media/stagefright/MediaDefs.h>
+
+namespace android {
+
+const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg";
+
+const char *MEDIA_MIMETYPE_VIDEO_VPX = "video/x-vnd.on2.vp8";
+const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
+const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
+const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp";
+const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
+const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
+
+const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
+const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I = "audio/mpeg-L1";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II = "audio/mpeg-L2";
+const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp";
+const char *MEDIA_MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
+const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
+const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
+const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
+const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";
+const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
+
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
+const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
+const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
+const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
+const char *MEDIA_MIMETYPE_CONTAINER_AVI = "video/avi";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS = "video/mp2p";
+
+const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm";
+#ifdef QCOM_HARDWARE
+const char *MEDIA_MIMETYPE_AUDIO_EVRC = "audio/evrc";
+
+const char *MEDIA_MIMETYPE_VIDEO_WMV = "video/x-ms-wmv";
+const char *MEDIA_MIMETYPE_AUDIO_WMA = "audio/x-ms-wma";
+const char *MEDIA_MIMETYPE_CONTAINER_ASF = "video/x-ms-asf";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX = "video/divx";
+const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
+const char *MEDIA_MIMETYPE_CONTAINER_AAC = "audio/aac";
+const char *MEDIA_MIMETYPE_CONTAINER_QCP = "audio/vnd.qcelp";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX311 = "video/divx311";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX4 = "video/divx4";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG2 = "video/mp2";
+const char *MEDIA_MIMETYPE_CONTAINER_3G2 = "video/3g2";
+#endif
+const char *MEDIA_MIMETYPE_TEXT_3GPP = "text/3gpp-tt";
+
+MetaData::MetaData() {
+}
+
+MetaData::MetaData(const MetaData &from) {
+}
+
+MetaData::~MetaData() {
+}
+
+void MetaData::clear() {
+}
+
+bool MetaData::remove(uint32_t key) {
+ return false;
+}
+
+bool MetaData::setCString(uint32_t key, const char *value) {
+ return false;
+}
+
+bool MetaData::setInt32(uint32_t key, int32_t value) {
+ return false;
+}
+
+bool MetaData::setInt64(uint32_t key, int64_t value) {
+ return false;
+}
+
+bool MetaData::setFloat(uint32_t key, float value) {
+ return false;
+}
+
+bool MetaData::setPointer(uint32_t key, void *value) {
+ return false;
+}
+
+bool MetaData::setRect(
+ uint32_t key,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom) {
+ return false;
+}
+
+bool MetaData::findCString(uint32_t key, const char **value) {
+ return false;
+}
+
+bool MetaData::findInt32(uint32_t key, int32_t *value) {
+ return false;
+}
+
+bool MetaData::findInt64(uint32_t key, int64_t *value) {
+ return false;
+}
+
+bool MetaData::findFloat(uint32_t key, float *value) {
+ return false;
+}
+
+bool MetaData::findPointer(uint32_t key, void **value) {
+ return false;
+}
+
+bool MetaData::findRect(
+ uint32_t key,
+ int32_t *left, int32_t *top,
+ int32_t *right, int32_t *bottom) {
+ return false;
+}
+
+bool MetaData::setData(
+ uint32_t key, uint32_t type, const void *data, size_t size) {
+ return false;
+}
+
+bool MetaData::findData(uint32_t key, uint32_t *type,
+ const void **data, size_t *size) const {
+ return false;
+}
+
+MetaData::typed_data::typed_data()
+ : mType(0),
+ mSize(0) {
+}
+
+MetaData::typed_data::~typed_data() {
+}
+
+MetaData::typed_data::typed_data(const typed_data &from)
+ : mType(from.mType),
+ mSize(0) {
+}
+
+MetaData::typed_data &MetaData::typed_data::operator=(
+ const MetaData::typed_data &from) {
+ return *this;
+}
+
+void MetaData::typed_data::clear() {
+}
+
+void MetaData::typed_data::setData(
+ uint32_t type, const void *data, size_t size) {
+}
+
+void MetaData::typed_data::getData(
+ uint32_t *type, const void **data, size_t *size) const {
+}
+
+void MetaData::typed_data::allocateStorage(size_t size) {
+}
+
+void MetaData::typed_data::freeStorage() {
+}
+
+MediaBuffer::MediaBuffer(void *data, size_t size)
+{}
+
+MediaBuffer::MediaBuffer(size_t size)
+{}
+
+MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
+{}
+
+MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
+{}
+
+void MediaBuffer::release() {
+}
+
+void MediaBuffer::claim() {
+}
+
+void MediaBuffer::add_ref() {
+}
+
+void *MediaBuffer::data() const {
+ return 0;
+}
+
+size_t MediaBuffer::size() const {
+ return 0;
+}
+
+size_t MediaBuffer::range_offset() const {
+ return 0;
+}
+
+size_t MediaBuffer::range_length() const {
+ return 0;
+}
+
+void MediaBuffer::set_range(size_t offset, size_t length) {
+}
+
+sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
+}
+
+sp<MetaData> MediaBuffer::meta_data() {
+}
+
+void MediaBuffer::reset() {
+}
+
+MediaBuffer::~MediaBuffer() {
+}
+
+void MediaBuffer::setObserver(MediaBufferObserver *observer) {
+}
+
+void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
+}
+
+MediaBuffer *MediaBuffer::nextBuffer() {
+ return 0;
+}
+
+int MediaBuffer::refcount() const {
+ return 0;
+}
+
+MediaBuffer *MediaBuffer::clone() {
+ return 0;
+}
+
+MediaBufferGroup::MediaBufferGroup() {}
+
+MediaBufferGroup::~MediaBufferGroup() {}
+
+void MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
+}
+
+status_t MediaBufferGroup::acquire_buffer(MediaBuffer **out) {
+ return OK;
+}
+
+void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
+}
+
+MediaSource::MediaSource() {}
+
+MediaSource::~MediaSource() {}
+
+MediaSource::MediaSource(const MediaSource &) {}
+
+MediaSource& MediaSource::operator=(const MediaSource &) {}
+
+MediaSource::ReadOptions::ReadOptions() {
+}
+
+void MediaSource::ReadOptions::reset() {
+}
+
+void MediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
+}
+
+void MediaSource::ReadOptions::clearSeekTo() {
+}
+
+bool MediaSource::ReadOptions::getSeekTo(
+ int64_t *time_us, SeekMode *mode) const {
+ return false;
+}
+
+void MediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
+}
+
+int64_t MediaSource::ReadOptions::getLateBy() const {
+ return 0;
+}
+
+status_t
+DataSource::getSize(off64_t *size)
+{
+ return 0;
+}
+
+String8
+DataSource::getMIMEType() const
+{
+ return String8();
+}
+
+void
+DataSource::RegisterDefaultSniffers()
+{
+}
+
+sp<MediaExtractor>
+MediaExtractor::Create(const sp<DataSource> &source, const char *mime)
+{
+ return 0;
+}
+
+sp<MediaSource>
+OMXCodec::Create(
+ const sp<IOMX> &omx,
+ const sp<MetaData> &meta, bool createEncoder,
+ const sp<MediaSource> &source,
+ const char *matchComponentName,
+ uint32_t flags,
+ const sp<ANativeWindow> &nativeWindow)
+{
+ return 0;
+}
+
+OMXClient::OMXClient()
+{
+}
+
+status_t OMXClient::connect()
+{
+ return OK;
+}
+
+void OMXClient::disconnect()
+{
+}
+
+class __attribute__ ((visibility ("default"))) UnknownDataSource : public DataSource {
+public:
+UnknownDataSource();
+
+virtual status_t initCheck() const { return 0; }
+virtual ssize_t readAt(off64_t offset, void *data, size_t size) { return 0; }
+virtual status_t getSize(off64_t *size) { return 0; }
+
+virtual ~UnknownDataSource() { }
+};
+
+UnknownDataSource foo;
+
+UnknownDataSource::UnknownDataSource() { }
+}
View
37 tools/depends/target/android-sources-ics/libui.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <EGL/egl.h>
+
+using namespace android;
+
+ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
+{
+ return NULL;
+}
+
+namespace android {
+ssize_t bytesPerPixel(PixelFormat format)
+{
+ return 0;
+}
+}
View
333 tools/depends/target/android-sources-ics/libutils.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "utils/RefBase.h"
+#include "utils/String16.h"
+#include "utils/String8.h"
+#include "utils/VectorImpl.h"
+#include "utils/Unicode.h"
+
+extern "C" {
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+ return 0;
+}
+
+}
+
+namespace android {
+RefBase::RefBase() : mRefs(0)
+{
+}
+
+RefBase::~RefBase()
+{
+}
+
+void RefBase::incStrong(const void *id) const
+{
+}
+
+void RefBase::decStrong(const void *id) const
+{
+}
+
+void RefBase::onFirstRef()
+{
+}
+
+void RefBase::onLastStrongRef(const void* id)
+{
+}
+
+bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+ return false;
+}
+
+void RefBase::onLastWeakRef(void const* id)
+{
+}
+
+String16::String16()
+{
+}
+
+String16::String16(String16 const&)
+{
+}
+
+String16::String16(char const*)
+{
+}
+
+String16::~String16()
+{
+}
+
+String8::String8()
+{
+}
+
+String8::~String8()
+{
+}
+
+VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
+ : mFlags(flags), mItemSize(itemSize)
+{
+}
+
+VectorImpl::VectorImpl(const VectorImpl& rhs)
+ : mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
+{
+}
+
+VectorImpl::~VectorImpl()
+{
+}
+
+VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
+{
+}
+
+void* VectorImpl::editArrayImpl()
+{
+}
+
+size_t VectorImpl::capacity() const
+{
+ return 0;
+}
+
+ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::appendVector(const VectorImpl& vector)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::appendArray(const void* array, size_t length)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
+{
+ return 0;
+}
+
+static int sortProxy(const void* lhs, const void* rhs, void* func)
+{
+ return 0;
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_t cmp)
+{
+ return 0;
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
+{
+ return 0;
+}
+
+void VectorImpl::pop()
+{
+}
+
+void VectorImpl::push()
+{
+}
+
+void VectorImpl::push(const void* item)
+{
+}
+
+ssize_t VectorImpl::add()
+{
+ return 0;
+}
+
+ssize_t VectorImpl::add(const void* item)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::replaceAt(size_t index)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
+{
+ return 0;
+}
+
+ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
+{
+ return 0;
+}
+
+void VectorImpl::finish_vector()
+{
+}
+
+void VectorImpl::clear()
+{
+}
+
+void* VectorImpl::editItemLocation(size_t index)
+{
+ return 0;
+}
+
+const void* VectorImpl::itemLocation(size_t index) const
+{
+ return 0;
+}
+
+ssize_t VectorImpl::setCapacity(size_t new_capacity)
+{
+ return 0;
+}
+
+void VectorImpl::release_storage()
+{
+}
+
+void* VectorImpl::_grow(size_t where, size_t amount)
+{
+ return 0;
+}
+
+void VectorImpl::_shrink(size_t where, size_t amount)
+{
+}
+
+size_t VectorImpl::itemSize() const {
+ return 0;
+}
+
+void VectorImpl::_do_construct(void* storage, size_t num) const
+{
+}
+
+void VectorImpl::_do_destroy(void* storage, size_t num) const
+{
+}
+
+void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
+{
+}
+
+void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
+}
+
+void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
+}
+
+void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
+}
+
+void VectorImpl::reservedVectorImpl1() { }
+void VectorImpl::reservedVectorImpl2() { }
+void VectorImpl::reservedVectorImpl3() { }
+void VectorImpl::reservedVectorImpl4() { }
+void VectorImpl::reservedVectorImpl5() { }
+void VectorImpl::reservedVectorImpl6() { }
+void VectorImpl::reservedVectorImpl7() { }
+void VectorImpl::reservedVectorImpl8() { }
+
+/*****************************************************************************/
+
+SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
+ : VectorImpl(itemSize, flags)
+{
+}
+
+SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
+: VectorImpl(rhs)
+{
+}
+
+SortedVectorImpl::~SortedVectorImpl()
+{
+}
+
+ssize_t SortedVectorImpl::indexOf(const void* item) const
+{
+ return 0;
+}
+
+size_t SortedVectorImpl::orderOf(const void* item) const
+{
+ return 0;
+}
+
+ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
+{
+ return 0;
+}
+
+ssize_t SortedVectorImpl::add(const void* item)
+{
+ return 0;
+}
+
+ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
+{
+ return 0;
+}
+
+ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
+{
+ return 0;
+}
+
+ssize_t SortedVectorImpl::remove(const void* item)
+{
+ return 0;
+}
+
+void SortedVectorImpl::reservedSortedVectorImpl1() { };
+void SortedVectorImpl::reservedSortedVectorImpl2() { };
+void SortedVectorImpl::reservedSortedVectorImpl3() { };
+void SortedVectorImpl::reservedSortedVectorImpl4() { };
+void SortedVectorImpl::reservedSortedVectorImpl5() { };
+void SortedVectorImpl::reservedSortedVectorImpl6() { };
+void SortedVectorImpl::reservedSortedVectorImpl7() { };
+void SortedVectorImpl::reservedSortedVectorImpl8() { };
+
+}
View
111 xbmc/android/activity/XBMCApp.cpp
@@ -18,6 +18,8 @@
*
*/
+#include "system.h"
+
#include <sstream>
#include <unistd.h>
@@ -26,6 +28,7 @@
#include <string.h>
#include <android/native_window.h>
+#include <android/native_window_jni.h>
#include <android/configuration.h>
#include <jni.h>
@@ -46,6 +49,15 @@
#include "ApplicationMessenger.h"
#include "JNIThreading.h"
+#ifdef HAVE_LIBSTAGEFRIGHT
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+#endif
+
#define GIGABYTES 1073741824
using namespace std;
@@ -60,12 +72,17 @@ void* thread_run(void* obj)
ANativeActivity *CXBMCApp::m_activity = NULL;
ANativeWindow* CXBMCApp::m_window = NULL;
-CXBMCApp::CXBMCApp(ANativeActivity *nativeActivity)
- : m_wakeLock(NULL)
+CXBMCApp::CXBMCApp()
+ : m_wakeLock(NULL), m_VideoNativeWindow(NULL)
{
- m_activity = nativeActivity;
m_firstrun = true;
m_exiting=false;
+}
+
+void CXBMCApp::SetActivity(ANativeActivity *nativeActivity)
+{
+ m_activity = nativeActivity;
+
if (m_activity == NULL)
{
android_printf("CXBMCApp: invalid ANativeActivity instance");
@@ -975,3 +992,91 @@ void CXBMCApp::SetSystemVolume(JNIEnv *env, float percent)
env->DeleteLocalRef(cAudioManager);
}
+#ifdef HAVE_LIBSTAGEFRIGHT
+bool CXBMCApp::InitStagefrightSurface()
+{
+ if (m_VideoNativeWindow != NULL)
+ return true;
+
+ JNIEnv* env = xbmc_jnienv();
+
+ m_VideoTextureId = -1;
+
+ glGenTextures(1, &m_VideoTextureId);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_VideoTextureId);
+ glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+
+ jclass cSurfaceTexture = env->FindClass("android/graphics/SurfaceTexture");
+ jmethodID midSurfaceTextureCtor = env->GetMethodID(cSurfaceTexture, "<init>", "(I)V");
+ midSurfaceTextureRelease = env->GetMethodID(cSurfaceTexture, "release", "()V");
+ m_midUpdateTexImage = env->GetMethodID(cSurfaceTexture, "updateTexImage", "()V");
+ m_midGetTransformMatrix = env->GetMethodID(cSurfaceTexture, "getTransformMatrix", "([F)V");
+ jobject oSurfTexture = env->NewObject(cSurfaceTexture, midSurfaceTextureCtor, m_VideoTextureId);
+
+ //jfieldID fidSurfaceTexture = env->GetFieldID(cSurfaceTexture, ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
+ //m_SurfaceTexture = (android::SurfaceTexture*)env->GetIntField(oSurfTexture, fidSurfaceTexture);
+
+ env->DeleteLocalRef(cSurfaceTexture);
+ m_SurfTexture = env->NewGlobalRef(oSurfTexture);
+ env->DeleteLocalRef(oSurfTexture);
+
+ jclass cSurface = env->FindClass("android/view/Surface");
+ jmethodID midSurfaceCtor = env->GetMethodID(cSurface, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
+ midSurfaceRelease = env->GetMethodID(cSurface, "release", "()V");
+ jobject oSurface = env->NewObject(cSurface, midSurfaceCtor, m_SurfTexture);
+ env->DeleteLocalRef(cSurface);
+ m_Surface = env->NewGlobalRef(oSurface);
+ env->DeleteLocalRef(oSurface);
+
+ m_VideoNativeWindow = ANativeWindow_fromSurface(env, m_Surface);
+
+ return true;
+}
+
+void CXBMCApp::UninitStagefrightSurface()
+{
+ if (m_VideoNativeWindow == NULL)
+ return;
+
+ JNIEnv* env = xbmc_jnienv();
+
+ ANativeWindow_release(m_VideoNativeWindow);
+ m_VideoNativeWindow = NULL;
+
+ env->CallVoidMethod(m_Surface, midSurfaceRelease);
+ env->DeleteGlobalRef(m_Surface);
+
+ env->CallVoidMethod(m_SurfTexture, midSurfaceTextureRelease);
+ env->DeleteGlobalRef(m_SurfTexture);
+
+ glDeleteTextures(1, &m_VideoTextureId);
+}
+
+void CXBMCApp::UpdateStagefrightTexture()
+{
+// m_SurfaceTexture->updateTexImage();
+
+ JNIEnv* env = xbmc_jnienv();
+
+ env->CallVoidMethod(m_SurfTexture, m_midUpdateTexImage);
+}
+
+void CXBMCApp::GetStagefrightTransformMatrix(float* transformMatrix)
+{
+// m_SurfaceTexture->getTransformMatrix(transformMatrix);
+
+ JNIEnv* env = xbmc_jnienv();
+
+ jfloatArray arr = (jfloatArray)env->NewFloatArray(16);
+ env->SetFloatArrayRegion(arr, 0, 16, transformMatrix);
+
+ env->CallVoidMethod(m_SurfTexture, m_midGetTransformMatrix, arr);
+ env->GetFloatArrayRegion(arr, 0, 16, transformMatrix);
+ env->DeleteLocalRef(arr);
+}
+
+#endif
View
37 xbmc/android/activity/XBMCApp.h
@@ -30,7 +30,15 @@
#include "IInputHandler.h"
#include "xbmc.h"
+#include "utils/GlobalsHandling.h"
+/*
+#ifdef HAVE_LIBSTAGEFRIGHT
+namespace android {
+ class SurfaceTexture;
+}
+#endif
+*/
// forward delares
class CAESinkAUDIOTRACK;
@@ -53,7 +61,8 @@ struct androidPackage
class CXBMCApp : public IActivityHandler
{
public:
- CXBMCApp(ANativeActivity *nativeActivity);
+ CXBMCApp();
+ void SetActivity(ANativeActivity *nativeActivity);
virtual ~CXBMCApp();
bool isValid() { return m_activity != NULL; }
@@ -96,6 +105,18 @@ class CXBMCApp : public IActivityHandler
static int GetMaxSystemVolume();
static int GetDPI();
+
+#ifdef HAVE_LIBSTAGEFRIGHT
+ bool InitStagefrightSurface();
+ void UninitStagefrightSurface();
+ void UpdateStagefrightTexture();
+ void GetStagefrightTransformMatrix(float* transformMatrix);
+
+ ANativeWindow* GetAndroidVideoWindow() const { return m_VideoNativeWindow;}
+ const unsigned int GetAndroidTexture() const { return m_VideoTextureId; }
+ //android::SurfaceTexture* GetSurfaceTexture() const { return m_SurfaceTexture; }
+#endif
+
protected:
// limit who can access Volume
friend class CAESinkAUDIOTRACK;
@@ -119,9 +140,23 @@ class CXBMCApp : public IActivityHandler
pthread_t m_thread;
static ANativeWindow* m_window;
+#ifdef HAVE_LIBSTAGEFRIGHT
+ unsigned int m_VideoTextureId;
+ jobject m_SurfTexture;
+ jobject m_Surface;
+ jmethodID m_midUpdateTexImage;
+ jmethodID m_midGetTransformMatrix;
+ jmethodID midSurfaceTextureRelease;
+ jmethodID midSurfaceRelease;
+ ANativeWindow* m_VideoNativeWindow;
+ //android::SurfaceTexture* m_SurfaceTexture;
+#endif
void XBMC_Pause(bool pause);
void XBMC_Stop();
bool XBMC_DestroyDisplay();
bool XBMC_SetupDisplay();
};
+
+XBMC_GLOBAL_REF(CXBMCApp,g_xbmcapp);
+#define g_xbmcapp XBMC_GLOBAL_USE(CXBMCApp)
View
6 xbmc/android/activity/android_main.cpp
@@ -165,11 +165,11 @@ extern void android_main(struct android_app* state)
CAndroidJNIManager::GetInstance().SetActivityInstance(state->activity->clazz);
setup_env(state);
CEventLoop eventLoop(state);
- CXBMCApp xbmcApp(state->activity);
- if (xbmcApp.isValid())
+ g_xbmcapp.SetActivity(state->activity);
+ if (g_xbmcapp.isValid())
{
IInputHandler inputHandler;
- eventLoop.run(xbmcApp, inputHandler);
+ eventLoop.run(g_xbmcapp, inputHandler);
}
else
CXBMCApp::android_printf("android_main: setup failed");
View
235 xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
@@ -17,6 +17,7 @@
* <http://www.gnu.org/licenses/>.
*
*/
+//#define DEBUG_VERBOSE 1
#include "system.h"
#if (defined HAVE_CONFIG_H) && (!defined WIN32)
@@ -60,6 +61,18 @@
#ifdef TARGET_DARWIN_IOS
#include "osx/DarwinUtils.h"
#endif
+#if defined(HAVE_LIBSTAGEFRIGHT)
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "windowing/egl/EGLWrapper.h"
+#include "android/activity/XBMCApp.h"
+#include "DVDCodecs/Video/StageFrightVideo.h"
+
+// EGL extension functions
+static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
+static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
+static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
+#endif
using namespace Shaders;
@@ -86,6 +99,10 @@ CLinuxRendererGLES::CLinuxRendererGLES()
#ifdef HAVE_VIDEOTOOLBOXDECODER
m_buffers[i].cvBufferRef = NULL;
#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+ m_buffers[i].stf = NULL;
+ m_buffers[i].eglimg = EGL_NO_IMAGE_KHR;
+#endif
}
m_renderMethod = RENDER_GLSL;
@@ -113,6 +130,15 @@ CLinuxRendererGLES::CLinuxRendererGLES()
m_dllSwScale = new DllSwScale;
m_sw_context = NULL;
+
+#ifdef HAVE_LIBSTAGEFRIGHT
+ if (!eglCreateImageKHR)
+ eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) CEGLWrapper::GetProcAddress("eglCreateImageKHR");
+ if (!eglDestroyImageKHR)
+ eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) CEGLWrapper::GetProcAddress("eglDestroyImageKHR");
+ if (!glEGLImageTargetTexture2DOES)
+ glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) CEGLWrapper::GetProcAddress("glEGLImageTargetTexture2DOES");
+#endif
}
CLinuxRendererGLES::~CLinuxRendererGLES()
@@ -148,6 +174,7 @@ bool CLinuxRendererGLES::ValidateRenderTarget()
if (!m_bValidated)
{
CLog::Log(LOGNOTICE,"Using GL_TEXTURE_2D");
+ m_textureTarget = GL_TEXTURE_2D;
// create the yuv textures
LoadShaders();
@@ -221,6 +248,12 @@ int CLinuxRendererGLES::GetImage(YV12Image *image, int source, bool readonly)
{
return source;
}
+#ifdef HAVE_LIBSTAGEFRIGHT
+ if ( m_renderMethod & RENDER_EGLIMG )
+ {
+ return source;
+ }
+#endif
#ifdef HAVE_VIDEOTOOLBOXDECODER
if (m_renderMethod & RENDER_CVREF )
{
@@ -442,7 +475,7 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
int index = m_iYV12RenderBuffer;
YUVBUFFER& buf = m_buffers[index];
- if (m_format != RENDER_FMT_OMXEGL)
+ if (m_format != RENDER_FMT_OMXEGL && m_format != RENDER_FMT_EGLIMG)
{
if (!buf.fields[FIELD_FULL][0].id) return;
}
@@ -533,6 +566,9 @@ unsigned int CLinuxRendererGLES::PreInit()
#ifdef HAVE_VIDEOTOOLBOXDECODER
m_formats.push_back(RENDER_FMT_CVBREF);
#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+ m_formats.push_back(RENDER_FMT_EGLIMG);
+#endif
// setup the background colour
m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff;
@@ -632,6 +668,12 @@ void CLinuxRendererGLES::LoadShaders(int field)
m_renderMethod = RENDER_OMXEGL;
break;
}
+ else if (m_format == RENDER_FMT_EGLIMG)
+ {
+ CLog::Log(LOGNOTICE, "GL: Using EGL Image render method");
+ m_renderMethod = RENDER_EGLIMG;
+ break;
+ }
else if (m_format == RENDER_FMT_BYPASS)
{
CLog::Log(LOGNOTICE, "GL: Using BYPASS render method");
@@ -706,6 +748,12 @@ void CLinuxRendererGLES::LoadShaders(int field)
m_textureCreate = &CLinuxRendererGLES::CreateBYPASSTexture;
m_textureDelete = &CLinuxRendererGLES::DeleteBYPASSTexture;
}
+ else if (m_format == RENDER_FMT_EGLIMG)
+ {
+ m_textureUpload = &CLinuxRendererGLES::UploadEGLIMGTexture;
+ m_textureCreate = &CLinuxRendererGLES::CreateEGLIMGTexture;
+ m_textureDelete = &CLinuxRendererGLES::DeleteEGLIMGTexture;
+ }
else
{
// default to YV12 texture handlers
@@ -743,6 +791,7 @@ void CLinuxRendererGLES::UnInit()
m_dllSwScale->sws_freeContext(m_sw_context);
m_sw_context = NULL;
}
+
// cleanup framebuffer object if it was in use
m_fbo.Cleanup();
m_bValidated = false;
@@ -815,6 +864,11 @@ void CLinuxRendererGLES::Render(DWORD flags, int index)
RenderOpenMax(index, m_currentField);
VerifyGLState();
}
+ else if (m_renderMethod & RENDER_EGLIMG)
+ {
+ RenderEglImage(index, m_currentField);
+ VerifyGLState();
+ }
else if (m_renderMethod & RENDER_CVREF)
{
RenderCoreVideoRef(index, m_currentField);
@@ -1251,6 +1305,77 @@ void CLinuxRendererGLES::RenderOpenMax(int index, int field)
#endif
}
+void CLinuxRendererGLES::RenderEglImage(int index, int field)
+{
+#if defined(HAVE_LIBSTAGEFRIGHT)
+#ifdef DEBUG_VERBOSE
+ unsigned int time = XbmcThreads::SystemClockMillis();
+#endif
+
+ YUVPLANE &plane = m_buffers[index].fields[field][0];
+
+ glDisable(GL_DEPTH_TEST);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(m_textureTarget, plane.id);
+
+ g_Windowing.EnableGUIShader(SM_TEXTURE_RGBA);
+
+ GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
+ GLfloat ver[4][4];
+ GLfloat tex[4][2];
+ float col[4][3];
+
+ for (int i = 0;i < 4;++i)
+ {
+ col[i][0] = col[i][1] = col[i][2] = 1.0;
+ }
+
+ GLint posLoc = g_Windowing.GUIShaderGetPos();
+ GLint texLoc = g_Windowing.GUIShaderGetCoord0();
+ GLint colLoc = g_Windowing.GUIShaderGetCol();
+
+ glVertexAttribPointer(posLoc, 4, GL_FLOAT, 0, 0, ver);
+ glVertexAttribPointer(texLoc, 2, GL_FLOAT, 0, 0, tex);
+ glVertexAttribPointer(colLoc, 3, GL_FLOAT, 0, 0, col);
+
+ glEnableVertexAttribArray(posLoc);
+ glEnableVertexAttribArray(texLoc);
+ glEnableVertexAttribArray(colLoc);
+
+ // Set vertex coordinates
+ for(int i = 0; i < 4; i++)
+ {
+ ver[i][0] = m_rotatedDestCoords[i].x;
+ ver[i][1] = m_rotatedDestCoords[i].y;
+ ver[i][2] = 0.0f;// set z to 0
+ ver[i][3] = 1.0f;
+ }
+
+ // Set texture coordinates (corevideo is flipped in y)
+ tex[0][0] = tex[3][0] = 0;
+ tex[0][1] = tex[1][1] = 1;
+ tex[1][0] = tex[2][0] = 1;
+ tex[2][1] = tex[3][1] = 0;
+
+ glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
+
+ glDisableVertexAttribArray(posLoc);
+ glDisableVertexAttribArray(texLoc);
+ glDisableVertexAttribArray(colLoc);
+
+ g_Windowing.DisableGUIShader();
+ VerifyGLState();
+
+ glBindTexture(m_textureTarget, 0);
+ VerifyGLState();
+
+#ifdef DEBUG_VERBOSE
+ CLog::Log(LOGDEBUG, "RenderEglImage %d: tm:%d\n", index, XbmcThreads::SystemClockMillis() - time);
+#endif
+#endif
+}
+
void CLinuxRendererGLES::RenderCoreVideoRef(int index, int field)
{
#ifdef HAVE_VIDEOTOOLBOXDECODER
@@ -1813,6 +1938,88 @@ bool CLinuxRendererGLES::CreateBYPASSTexture(int index)
return true;
}
+//********************************************************************************************************
+// EGLIMG creation, deletion, copying + clearing
+//********************************************************************************************************
+void CLinuxRendererGLES::UploadEGLIMGTexture(int index)
+{
+#ifdef HAVE_LIBSTAGEFRIGHT
+#ifdef DEBUG_VERBOSE
+ unsigned int time = XbmcThreads::SystemClockMillis();
+#endif
+
+ if(m_buffers[index].eglimg != EGL_NO_IMAGE_KHR)
+ {
+ YUVPLANE &plane = m_buffers[index].fields[0][0];
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(m_textureTarget, plane.id);
+ glEGLImageTargetTexture2DOES(m_textureTarget, (EGLImageKHR)m_buffers[index].eglimg);
+ glBindTexture(m_textureTarget, 0);
+
+ plane.flipindex = m_buffers[index].flipindex;
+ }
+ m_eventTexturesDone[index]->Set();
+
+#ifdef DEBUG_VERBOSE
+ CLog::Log(LOGDEBUG, "UploadEGLIMGTexture %d: img:%p, tm:%d\n", index, m_buffers[index].eglimg, XbmcThreads::SystemClockMillis() - time);
+#endif
+#endif
+}
+void CLinuxRendererGLES::DeleteEGLIMGTexture(int index)
+{
+#ifdef HAVE_LIBSTAGEFRIGHT
+ YUVPLANE &plane = m_buffers[index].fields[0][0];
+
+ if(plane.id && glIsTexture(plane.id))
+ glDeleteTextures(1, &plane.id);
+ plane.id = 0;
+#endif
+}
+bool CLinuxRendererGLES::CreateEGLIMGTexture(int index)
+{
+#ifdef HAVE_LIBSTAGEFRIGHT
+ YV12Image &im = m_buffers[index].image;
+ YUVFIELDS &fields = m_buffers[index].fields;
+ YUVPLANE &plane = fields[0][0];
+
+ DeleteEGLIMGTexture(index);
+
+ memset(&im , 0, sizeof(im));
+ memset(&fields, 0, sizeof(fields));
+
+ im.height = m_sourceHeight;
+ im.width = m_sourceWidth;
+
+ plane.texwidth = im.width;
+ plane.texheight = im.height;
+
+ if(m_renderMethod & RENDER_POT)
+ {
+ plane.texwidth = NP2(plane.texwidth);
+ plane.texheight = NP2(plane.texheight);
+ }
+ glEnable(m_textureTarget);
+ glGenTextures(1, &plane.id);
+ VerifyGLState();
+
+ glBindTexture(m_textureTarget, plane.id);
+
+ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ // This is necessary for non-power-of-two textures
+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(m_textureTarget, 0, GL_RGBA, plane.texwidth, plane.texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glDisable(m_textureTarget);
+
+ m_eventTexturesDone[index]->Set();
+#endif
+ return true;
+}
+
void CLinuxRendererGLES::SetTextureFilter(GLenum method)
{
for (int i = 0 ; i<m_NumYV12Buffers ; i++)
@@ -1924,6 +2131,9 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method)
if(m_renderMethod & RENDER_OMXEGL)
return false;
+ if(m_renderMethod & RENDER_EGLIMG)
+ return false;
+
if(m_renderMethod & RENDER_CVREF)
return false;
@@ -1972,6 +2182,9 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod()
if(m_renderMethod & RENDER_OMXEGL)
return VS_INTERLACEMETHOD_NONE;
+ if(m_renderMethod & RENDER_EGLIMG)
+ return VS_INTERLACEMETHOD_NONE;
+
if(m_renderMethod & RENDER_CVREF)
return VS_INTERLACEMETHOD_NONE;
@@ -2000,6 +2213,26 @@ void CLinuxRendererGLES::AddProcessor(struct __CVBuffer *cvBufferRef)
CVBufferRetain(buf.cvBufferRef);
}
#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+void CLinuxRendererGLES::AddProcessor(CStageFrightVideo* stf, EGLImageKHR eglimg)
+{
+#ifdef DEBUG_VERBOSE
+ unsigned int time = XbmcThreads::SystemClockMillis();
+#endif
+
+ YUVBUFFER &buf = m_buffers[NextYV12Texture()];
+ if (buf.eglimg != EGL_NO_IMAGE_KHR)
+ stf->ReleaseBuffer(buf.eglimg);
+ stf->LockBuffer(eglimg);
+
+ buf.stf = stf;
+ buf.eglimg = eglimg;
+
+#ifdef DEBUG_VERBOSE
+ CLog::Log(LOGDEBUG, "AddProcessor %d: img:%p: tm:%d\n", NextYV12Texture(), eglimg, XbmcThreads::SystemClockMillis() - time);
+#endif
+}
+#endif
#endif
View
19 xbmc/cores/VideoRenderers/LinuxRendererGLES.h
@@ -39,6 +39,7 @@ class CBaseTexture;
namespace Shaders { class BaseYUV2RGBShader; }
namespace Shaders { class BaseVideoFilterShader; }
class COpenMaxVideo;
+class CStageFrightVideo;
typedef std::vector<int> Features;
#define NUM_BUFFERS 3
@@ -86,7 +87,8 @@ enum RenderMethod
RENDER_POT = 0x010,
RENDER_OMXEGL = 0x040,
RENDER_CVREF = 0x080,
- RENDER_BYPASS = 0x100
+ RENDER_BYPASS = 0x100,
+ RENDER_EGLIMG = 0x200
};
enum RenderQuality
@@ -158,6 +160,9 @@ class CLinuxRendererGLES : public CBaseRenderer
#ifdef HAVE_VIDEOTOOLBOXDECODER
virtual void AddProcessor(struct __CVBuffer *cvBufferRef);
#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+ virtual void AddProcessor(CStageFrightVideo* stf, EGLImageKHR eglimg);
+#endif
protected:
virtual void Render(DWORD flags, int index);
@@ -186,6 +191,10 @@ class CLinuxRendererGLES : public CBaseRenderer
void DeleteBYPASSTexture(int index);
bool CreateBYPASSTexture(int index);
+ void UploadEGLIMGTexture(int index);
+ void DeleteEGLIMGTexture(int index);
+ bool CreateEGLIMGTexture(int index);
+
void CalculateTextureSourceRects(int source, int num_planes);
// renderers
@@ -193,6 +202,7 @@ class CLinuxRendererGLES : public CBaseRenderer
void RenderSinglePass(int index, int field); // single pass glsl renderer
void RenderSoftware(int index, int field); // single pass s/w yuv2rgb renderer
void RenderOpenMax(int index, int field); // OpenMAX rgb texture
+ void RenderEglImage(int index, int field); // Android OES texture
void RenderCoreVideoRef(int index, int field); // CoreVideo reference
CFrameBufferObject m_fbo;
@@ -247,9 +257,12 @@ class CLinuxRendererGLES : public CBaseRenderer
OpenMaxVideoBuffer *openMaxBuffer;
#endif
#ifdef HAVE_VIDEOTOOLBOXDECODER
- struct __CVBuffer *cvBufferRef;
+ struct __CVBuffer *cvBufferRef;
+#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+ CStageFrightVideo* stf;
+ EGLImageKHR eglimg;
#endif
-
};
typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS];
View
1  xbmc/cores/VideoRenderers/RenderFormats.h
@@ -34,6 +34,7 @@ enum ERenderFormat {
RENDER_FMT_OMXEGL,
RENDER_FMT_CVBREF,
RENDER_FMT_BYPASS,
+ RENDER_FMT_EGLIMG,
};
#endif
View
5 xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -844,6 +844,11 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
else if(pic.format == RENDER_FMT_VAAPI)
m_pRenderer->AddProcessor(*pic.vaapi);
#endif
+#ifdef HAVE_LIBSTAGEFRIGHT
+ else if(pic.format == RENDER_FMT_EGLIMG)
+ m_pRenderer->AddProcessor(pic.stf, pic.eglimg);
+#endif
+
m_pRenderer->ReleaseImage(index, false);
return index;
View
38 xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
@@ -35,6 +35,7 @@
#include "Video/DVDVideoCodecFFmpeg.h"
#include "Video/DVDVideoCodecOpenMax.h"
#include "Video/DVDVideoCodecLibMpeg2.h"
+#include "Video/DVDVideoCodecStageFright.h"
#if defined(HAVE_LIBCRYSTALHD)
#include "Video/DVDVideoCodecCrystalHD.h"
#endif
@@ -156,6 +157,11 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne
#elif defined(_LINUX)
hwSupport += "OpenMax:no ";
#endif
+#if defined(HAVE_LIBSTAGEFRIGHT)
+ hwSupport += "libstagefright:yes ";
+#elif defined(_LINUX)
+ hwSupport += "libstagefright:no ";
+#endif
#if defined(HAVE_LIBVDPAU) && defined(_LINUX)
hwSupport += "VDPAU:yes ";
#elif defined(_LINUX) && !defined(TARGET_DARWIN)
@@ -238,9 +244,37 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne
#if defined(HAVE_LIBOPENMAX)
if (g_guiSettings.GetBool("videoplayer.useomx") && !hint.software )
{
- if (hint.codec == CODEC_ID_H264 || hint.codec == CODEC_ID_MPEG2VIDEO || hint.codec == CODEC_ID_VC1)
+ switch(hint.codec)
+ {
+ case CODEC_ID_H264:
+ case CODEC_ID_MPEG2VIDEO:
+ case CODEC_ID_VC1:
+ if ( (pCodec = OpenCodec(new CDVDVideoCodecOpenMax(), hint, options)) ) return pCodec;
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+#if defined(HAVE_LIBSTAGEFRIGHT)
+ if (g_guiSettings.GetBool("videoplayer.usestagefright") && !hint.software )
+ {
+ switch(hint.codec)
{
- if ( (pCodec = OpenCodec(new CDVDVideoCodecOpenMax(), hint, options)) ) return pCodec;
+ case CODEC_ID_H264:
+ case CODEC_ID_MPEG4:
+ case CODEC_ID_MPEG2VIDEO:
+ case CODEC_ID_VC1:
+ case CODEC_ID_WMV3:
+ case CODEC_ID_VP3:
+ case CODEC_ID_VP6:
+ case CODEC_ID_VP6F:
+ case CODEC_ID_VP8:
+ if ( (pCodec = OpenCodec(new CDVDVideoCodecStageFright(), hint, options)) ) return pCodec;
+ break;
+ default:
+ break;
}
}
#endif
View
7 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
@@ -38,6 +38,8 @@ class CVDPAU;
class COpenMax;
class COpenMaxVideo;
struct OpenMaxVideoBuffer;
+class CStageFrightVideo;
+typedef void* EGLImageKHR;
// should be entirely filled by all codecs
struct DVDVideoPicture
@@ -69,6 +71,11 @@ struct DVDVideoPicture
struct {
struct __CVBuffer *cvBufferRef;
};
+
+ struct {
+ CStageFrightVideo* stf;
+ EGLImageKHR eglimg;
+ };
};
unsigned int iFlags;
View
201 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecStageFright.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+//#define DEBUG_VERBOSE 1
+
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+#include "config.h"
+#elif defined(_WIN32)
+#include "system.h"
+#endif
+
+#if defined(HAVE_LIBSTAGEFRIGHT)
+#include "DVDClock.h"
+#include "settings/GUISettings.h"
+#include "DVDStreamInfo.h"
+#include "DVDVideoCodecStageFright.h"
+#include "StageFrightVideo.h"
+#include "utils/log.h"
+
+#define CLASSNAME "CDVDVideoCodecStageFright"
+////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////
+CDVDVideoCodecStageFright::CDVDVideoCodecStageFright()
+ : CDVDVideoCodec()
+ , m_stf_decoder(NULL), m_converter(NULL), m_convert_bitstream(false)
+{
+ m_pFormatName = "stf-xxxx";
+}
+
+CDVDVideoCodecStageFright::~CDVDVideoCodecStageFright()
+{
+ Dispose();
+}
+
+bool CDVDVideoCodecStageFright::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
+{
+ // we always qualify even if DVDFactoryCodec does this too.
+ if (g_guiSettings.GetBool("videoplayer.usestagefright") && !hints.software)
+ {
+ m_convert_bitstream = false;
+ CLog::Log(LOGDEBUG,
+ "%s::%s - trying to open, codec(%d), profile(%d), level(%d)",
+ CLASSNAME, __func__, hints.codec, hints.profile, hints.level);
+
+ switch (hints.codec)
+ {
+ case CODEC_ID_H264:
+ m_pFormatName = "stf-h264";
+ if (hints.extrasize < 7 || hints.extradata == NULL)
+ {
+ CLog::Log(LOGNOTICE,
+ "%s::%s - avcC data too small or missing", CLASSNAME, __func__);
+ return false;
+ }
+ m_converter = new CBitstreamConverter();
+ m_convert_bitstream = m_converter->Open(hints.codec, (uint8_t *)hints.extradata, hints.extrasize, true);
+
+ break;
+ case CODEC_ID_MPEG2VIDEO:
+ m_pFormatName = "stf-mpeg2";
+ break;
+ case CODEC_ID_MPEG4:
+ m_pFormatName = "stf-mpeg4";
+ break;
+ case CODEC_ID_VP3:
+ case CODEC_ID_VP6:
+ case CODEC_ID_VP6F:
+ case CODEC_ID_VP8:
+ m_pFormatName = "stf-vpx";
+ break;
+ case CODEC_ID_WMV3:
+ case CODEC_ID_VC1:
+ m_pFormatName = "stf-wmv";
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ m_stf_decoder = new CStageFrightVideo;
+ if (!m_stf_decoder->Open(hints))
+ {
+ CLog::Log(LOGERROR,
+ "%s::%s - failed to open, codec(%d), profile(%d), level(%d)",
+ CLASSNAME, __func__, hints.codec, hints.profile, hints.level);
+ delete m_stf_decoder;
+ m_stf_decoder = NULL;
+
+ if (m_converter)
+ {
+ m_converter->Close();
+ delete m_converter;
+ m_converter = NULL;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void CDVDVideoCodecStageFright::Dispose()
+{
+ if (m_converter)
+ {
+ m_converter->Close();
+ delete m_converter;
+ m_converter = NULL;
+ }
+ if (m_stf_decoder)
+ {
+ m_stf_decoder->Close();
+ delete m_stf_decoder;
+ m_stf_decoder = NULL;
+ }
+}
+
+void CDVDVideoCodecStageFright::SetDropState(bool bDrop)
+{
+ m_stf_decoder->SetDropState(bDrop);
+}
+
+int CDVDVideoCodecStageFright::Decode(BYTE* pData, int iSize, double dts, double pts)
+{
+#if defined(DEBUG_VERBOSE)
+ unsigned int time = XbmcThreads::SystemClockMillis();
+#endif
+ int rtn;
+ int demuxer_bytes = iSize;
+ uint8_t *demuxer_content = pData;
+
+ if (m_convert_bitstream && demuxer_content)
+ {
+ // convert demuxer packet from bitstream to bytestream (AnnexB)
+ if (m_converter->Convert(demuxer_content, demuxer_bytes))
+ {
+ demuxer_content = m_converter->GetConvertBuffer();
+ demuxer_bytes = m_converter->GetConvertSize();
+ }
+ else
+ CLog::Log(LOGERROR,"%s::%s - bitstream_convert error", CLASSNAME, __func__);
+ }
+#if defined(DEBUG_VERBOSE)
+ CLog::Log(LOGDEBUG, ">>> decode conversion - tm:%d\n", XbmcThreads::SystemClockMillis() - time);
+#endif
+
+ rtn = m_stf_decoder->Decode(demuxer_content, demuxer_bytes, dts, pts);
+
+ return rtn;
+}
+
+void CDVDVideoCodecStageFright::Reset(void)
+{
+ m_stf_decoder->Reset();
+}
+
+bool CDVDVideoCodecStageFright::GetPicture(DVDVideoPicture* pDvdVideoPicture)
+{
+ return m_stf_decoder->GetPicture(pDvdVideoPicture);
+}
+
+bool CDVDVideoCodecStageFright::ClearPicture(DVDVideoPicture* pDvdVideoPicture)
+{
+ return m_stf_decoder->ClearPicture(pDvdVideoPicture);
+}
+
+void CDVDVideoCodecStageFright::SetSpeed(int iSpeed)
+{
+ m_stf_decoder->SetSpeed(iSpeed);
+}
+
+int CDVDVideoCodecStageFright::GetDataSize(void)
+{
+ return 0;
+}
+
+double CDVDVideoCodecStageFright::GetTimeSize(void)
+{
+ return 0;
+}
+
+#endif
View
55 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecStageFright.h
@@ -0,0 +1,55 @@
+#pragma once
+/*
+ * Copyright (C) 2010-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if defined(HAVE_LIBSTAGEFRIGHT)
+
+#include "DVDVideoCodec.h"
+#include "utils/BitstreamConverter.h"
+
+class CStageFrightVideo;
+class CDVDVideoCodecStageFright : public CDVDVideoCodec
+{
+public:
+ CDVDVideoCodecStageFright();
+ virtual ~CDVDVideoCodecStageFright();
+
+ // Required overrides
+ virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
+ virtual void Dispose(void);
+ virtual int Decode(BYTE *pData, int iSize, double dts, double pts);
+ virtual void Reset(void);
+ virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture);
+ virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture);
+ virtual void SetDropState(bool bDrop);
+ virtual const char* GetName(void) { return (const char*)m_pFormatName; }
+ virtual void SetSpeed(int iSpeed);
+ virtual int GetDataSize(void);
+ virtual double GetTimeSize(void);
+
+protected:
+ const char *m_pFormatName;
+ CStageFrightVideo *m_stf_decoder;
+
+ bool m_convert_bitstream;
+ CBitstreamConverter *m_converter;
+};
+
+#endif
View
14 xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
@@ -22,9 +22,23 @@ SRCS += OpenMax.cpp
SRCS += OpenMaxVideo.cpp
SRCS += DVDVideoCodecOpenMax.cpp
endif
+ifeq (@USE_LIBSTAGEFRIGHT@,1)
+SRCS += StageFrightVideo.cpp
+SRCS += DVDVideoCodecStageFright.cpp
+INCLUDES += -I${prefix}/opt/android-source/frameworks/base/include
+INCLUDES += -I${prefix}/opt/android-source/frameworks/base/native/include
+INCLUDES += -I${prefix}/opt/android-source/frameworks/base/include/media/stagefright
+INCLUDES += -I${prefix}/opt/android-source/frameworks/base/include/media/stagefright/openmax
+INCLUDES += -I${prefix}/opt/android-source/system/core/include
+INCLUDES += -I${prefix}/opt/android-source/libhardware/include
+endif
LIB=Video.a
include @abs_top_srcdir@/Makefile.include
-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
+ifeq (@USE_LIBSTAGEFRIGHT@,1)
+CXXFLAGS += -Wno-multichar -fno-rtti
+endif
+
View
1,337 xbmc/cores/dvdplayer/DVDCodecs/Video/StageFrightVideo.cpp
@@ -0,0 +1,1337 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+/***************************************************************************/
+
+//#define DEBUG_VERBOSE 1
+
+#include "system.h"
+#include "system_gl.h"
+
+#include "StageFrightVideo.h"
+
+#include "android/activity/XBMCApp.h"
+#include "guilib/GraphicContext.h"
+#include "DVDClock.h"
+#include "utils/log.h"
+#include "utils/fastmemcpy.h"
+#include "threads/Thread.h"
+#include "threads/Event.h"
+#include "settings/AdvancedSettings.h"
+
+#include "xbmc/guilib/FrameBufferObject.h"
+#include "windowing/WindowingFactory.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "windowing/egl/EGLWrapper.h"
+
+#include <binder/ProcessState.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <gui/SurfaceTexture.h>
+
+#include <new>
+#include <map>
+#include <queue>
+#include <list>
+
+#define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
+#define CLASSNAME "CStageFrightVideo"
+#define INBUFCOUNT 16
+#define NUMFBOTEX 4
+
+// EGL extension functions
+static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
+static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
+static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
+
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+
+GLint glerror;
+#define CheckEglError(x) while((glerror = eglGetError()) != EGL_SUCCESS) CLog::Log(LOGERROR, "EGL error in %s: %x",x, glerror);
+#define CheckGlError(x) while((glerror = glGetError()) != GL_NO_ERROR) CLog::Log(LOGERROR, "GL error in %s: %x",x, glerror);
+
+const char *MEDIA_MIMETYPE_VIDEO_WMV = "video/x-ms-wmv";
+
+using namespace android;
+
+static int64_t pts_dtoi(double pts)
+{
+ return (int64_t)(pts);
+}
+
+static double pts_itod(int64_t pts)
+{
+ return (double)pts;
+}
+
+struct Frame
+{
+ status_t status;
+ int32_t width, height;
+ int64_t pts;
+ ERenderFormat format;
+ EGLImageKHR eglimg;
+ MediaBuffer* medbuf;
+};
+
+enum StageFrightQuirks
+{
+ QuirkNone = 0,
+ QuirkSWRender = 0x01,
+};
+
+class CStageFrightDecodeThread;
+
+class CStageFrightVideoPrivate : public MediaBufferObserver
+{
+public:
+ CStageFrightVideoPrivate()
+ : decode_thread(NULL), source(NULL), natwin(NULL)
+ , eglDisplay(EGL_NO_DISPLAY), eglSurface(EGL_NO_SURFACE), eglContext(EGL_NO_CONTEXT)
+ , eglInitialized(false)
+ , framecount(0)
+ , quirks(QuirkNone), cur_frame(NULL), prev_frame(NULL)
+ , width(-1), height(-1)
+ , texwidth(-1), texheight(-1)
+ , client(NULL), decoder(NULL), decoder_component(NULL)
+ , drop_state(false), resetting(false)
+ {}
+
+ virtual void signalBufferReturned(MediaBuffer *buffer)
+ {
+ }
+
+ MediaBuffer* getBuffer(size_t size)
+ {
+ int i=0;
+ for (; i<INBUFCOUNT; ++i)
+ if (inbuf[i]->refcount() == 0 && inbuf[i]->size() >= size)
+ break;
+ if (i == INBUFCOUNT)
+ {
+ i = 0;
+ for (; i<INBUFCOUNT; ++i)
+ if (inbuf[i]->refcount() == 0)
+ break;
+ if (i == INBUFCOUNT)
+ return NULL;
+ inbuf[i]->setObserver(NULL);
+ inbuf[i]->release();
+ inbuf[i] = new MediaBuffer(size);
+ inbuf[i]->setObserver(this);
+ }
+
+ inbuf[i]->add_ref();
+ inbuf[i]->set_range(0, size);
+ return inbuf[i];
+ }
+
+ bool inputBufferAvailable()
+ {
+ for (int i=0; i<INBUFCOUNT; ++i)
+ if (inbuf[i]->refcount() == 0)
+ return true;
+
+ return false;
+ }
+
+ void loadOESShader(GLenum shaderType, const char* pSource, GLuint* outShader)
+ {
+ #if defined(DEBUG_VERBOSE)
+ CLog::Log(LOGDEBUG, ">>loadOESShader\n");
+ #endif
+
+ GLuint shader = glCreateShader(shaderType);
+ CheckGlError("loadOESShader");
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ printf("Shader compile log:\n%s\n", buf);
+ free(buf);
+ }
+ } else {
+ char* buf = (char*) malloc(0x1000);
+ if (buf) {
+ glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+ printf("Shader compile log:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ *outShader = shader;
+ }
+
+ void createOESProgram(const char* pVertexSource, const char* pFragmentSource, GLuint* outPgm)
+ {
+ #if defined(DEBUG_VERBOSE)
+ CLog::Log(LOGDEBUG, ">>createOESProgram\n");
+ #endif
+ GLuint vertexShader, fragmentShader;
+ {
+ loadOESShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
+ }
+ {
+ loadOESShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ printf("Program link log:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ *outPgm = program;
+ }
+
+ void OES_shader_setUp()
+ {
+
+ const char vsrc[] =
+ "attribute vec4 vPosition;\n"
+ "varying vec2 texCoords;\n"
+ "uniform mat4 texMatrix;\n"
+ "void main() {\n"
+ " vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
+ " texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+ const char fsrc[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES texSampler;\n"
+ "varying vec2 texCoords;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texSampler, texCoords);\n"
+ "}\n";
+
+ {
+ #if defined(DEBUG_VERBOSE)
+ CLog::Log(LOGDEBUG, ">>OES_shader_setUp\n");
+ #endif
+ CheckGlError("OES_shader_setUp");
+ createOESProgram(vsrc, fsrc, &mPgm);
+ }
+
+ mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
+ mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
+ mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
+ }
+
+ int NP2( unsigned x ) {
+ --x;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return ++x;
+ }
+
+ void InitializeEGL(int w, int h)
+ {
+ texwidth = w;
+ texheight = h;
+ if (!g_Windowing.IsExtSupported("GL_TEXTURE_NPOT"))
+ {
+ texwidth = NP2(texwidth);
+ texheight = NP2(texheight);
+ }
+
+ eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ eglBindAPI(EGL_OPENGL_ES_API);
+ EGLint contextAttributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ eglContext = eglCreateContext(e