From bf0e76b64a1d786b6d08cca4be6f275410d3737f Mon Sep 17 00:00:00 2001 From: carlonluca Date: Sun, 13 Dec 2015 14:39:49 +0100 Subject: [PATCH] Several fixes and improvements. --- .gitignore | 2 +- piomxtextures_lib/piomxtextures_lib.pro | 2 +- .../qml/POC_ControlBarVideo.qml | 5 +- .../mediaplayer/openmaxilmetadataprovider.cpp | 4 +- .../mediaplayer/openmaxilplayercontrol.cpp | 6 +- .../mediaplayer/openmaxilplayercontrol.h | 19 +-- .../openmaxilplayerserviceplugin.cpp | 2 +- .../openmaxilvideorenderercontrol.cpp | 6 + .../piomxtextures_samples.pro | 3 +- .../video_audio_concurrent.qml | 108 +++++++++++++++ ...ml => video_audio_concurrent_position.qml} | 61 ++++++--- .../video_audio_concurrent_seek.qml | 125 ++++++++++++++++++ piomxtextures_samples/video_loop.qml | 2 +- piomxtextures_samples/video_loop_position.qml | 66 +++++++++ piomxtextures_samples/video_seek.qml | 89 +++++++++++++ piomxtextures_src/omx_logging.h | 1 + piomxtextures_src/omx_mediaprocessor.cpp | 105 ++++++++++----- piomxtextures_src/omx_mediaprocessor.h | 8 +- piomxtextures_src/omx_omxplayer_logging.cpp | 2 +- piomxtextures_src/omx_playeraudio.cpp | 63 +-------- piomxtextures_src/omx_staticconf.cpp | 121 +++++++++++++++++ piomxtextures_src/omx_staticconf.h | 39 ++++++ piomxtextures_src/omx_texture.h | 2 +- piomxtextures_src/omx_textureprovider.h | 64 ++++++--- piomxtextures_src/omx_watchdog.cpp | 103 +++++++++++++++ piomxtextures_src/omx_watchdog.h | 54 ++++++++ .../omx_wrapper/OMXComponent.cpp | 2 +- piomxtextures_src/omx_wrapper/OMX_Core.cpp | 2 +- piomxtextures_src/omx_wrapper/omxtunnel.cpp | 2 +- piomxtextures_src/omxplayer_lib/OMXCore.cpp | 102 +++++++++++++- piomxtextures_src/omxplayer_lib/OMXCore.h | 21 ++- .../omxplayer_lib/OMXPlayerVideo.cpp | 2 +- piomxtextures_src/omxplayer_lib/OMXVideo.cpp | 25 ++-- piomxtextures_src/omxplayer_lib/OMXVideo.h | 13 +- piomxtextures_src/openmaxiltextureloader.cpp | 3 +- piomxtextures_src/piomxtextures_src.pri | 11 +- piomxtextures_tools/compile_ffmpeg.sh | 6 +- piomxtextures_tools/notes_icu.txt | 25 ++++ piomxtextures_tools/prepare_3rdparty.sh | 2 +- 39 files changed, 1083 insertions(+), 195 deletions(-) create mode 100644 piomxtextures_samples/video_audio_concurrent.qml rename piomxtextures_samples/{video_audio_multi.qml => video_audio_concurrent_position.qml} (60%) create mode 100644 piomxtextures_samples/video_audio_concurrent_seek.qml create mode 100644 piomxtextures_samples/video_loop_position.qml create mode 100644 piomxtextures_samples/video_seek.qml create mode 100644 piomxtextures_src/omx_staticconf.cpp create mode 100644 piomxtextures_src/omx_staticconf.h create mode 100644 piomxtextures_src/omx_watchdog.cpp create mode 100644 piomxtextures_src/omx_watchdog.h create mode 100644 piomxtextures_tools/notes_icu.txt diff --git a/.gitignore b/.gitignore index b4b2a22..3bf9465 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ tools/build* *.pro.user* -3rdparty +3rdparty* 3rdparty/* openmaxil_backend/3rdparty/* piomxtextures_qt_driver/mediaplayer/.qmake.conf diff --git a/piomxtextures_lib/piomxtextures_lib.pro b/piomxtextures_lib/piomxtextures_lib.pro index 3aa3413..4b0a7c1 100644 --- a/piomxtextures_lib/piomxtextures_lib.pro +++ b/piomxtextures_lib/piomxtextures_lib.pro @@ -23,7 +23,7 @@ TEMPLATE = lib -VERSION = 5.0.0 +VERSION = 5.1.0 QT += core core-private gui gui-private opengl quick quick-private CONFIG += no_private_qt_headers_warning diff --git a/piomxtextures_pocplayer/qml/POC_ControlBarVideo.qml b/piomxtextures_pocplayer/qml/POC_ControlBarVideo.qml index e2dc71f..301cf70 100644 --- a/piomxtextures_pocplayer/qml/POC_ControlBarVideo.qml +++ b/piomxtextures_pocplayer/qml/POC_ControlBarVideo.qml @@ -40,8 +40,9 @@ POC_ControlBar { Layout.fillWidth: true maximumValue: 1.0 minimumValue: 0.0 - stepSize: 0.01 - value: videoOutputSurface.position/videoOutputSurface.duration; + stepSize: 0.0001 + value: + mediaPlayer.position/mediaPlayer.duration; updateValueWhileDragging: false // NOTE: Remember to avoid seeking on value changed. That will result in diff --git a/piomxtextures_qt_driver/mediaplayer/openmaxilmetadataprovider.cpp b/piomxtextures_qt_driver/mediaplayer/openmaxilmetadataprovider.cpp index c8f65ae..bbce8f1 100644 --- a/piomxtextures_qt_driver/mediaplayer/openmaxilmetadataprovider.cpp +++ b/piomxtextures_qt_driver/mediaplayer/openmaxilmetadataprovider.cpp @@ -24,9 +24,9 @@ /*------------------------------------------------------------------------------ | includes +-----------------------------------------------------------------------------*/ -#include +#include -#include "QtCore/QDate" +#include "omx_logging.h" #include "qmediametadata.h" #include "openmaxilmetadataprovider.h" diff --git a/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.cpp b/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.cpp index 2a44ebb..e6da574 100644 --- a/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.cpp +++ b/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.cpp @@ -55,15 +55,15 @@ | definitions +-----------------------------------------------------------------------------*/ //#define DEBUG_PLAYBIN -#define DEBUG_PLAYER_CONTROL +//#define DEBUG_PLAYER_CONTROL #ifndef DEBUG_PLAYER_CONTROL #ifdef LOG_DEBUG #undef LOG_DEBUG -#define LOG_DEBUG(...) {(void)0} +#define LOG_DEBUG(...) {(void)0;} #endif // LOG_DEBUG #else -#include +#include #endif // DEBUG_PLAYER_CONTROL diff --git a/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.h b/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.h index f1f5cc6..4384790 100644 --- a/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.h +++ b/piomxtextures_qt_driver/mediaplayer/openmaxilplayercontrol.h @@ -27,15 +27,15 @@ /*------------------------------------------------------------------------------ | includes +-----------------------------------------------------------------------------*/ -#include -#include -#include -#include +#include +#include +#include +#include #include - -#include -#include -#include +#include +#include +#include +#include #include @@ -125,9 +125,10 @@ private slots: const OMX_MediaProcessor::OMX_MediaStatus& status) const; bool m_ownStream; - bool m_seekToStartPending; + qint64 m_pendingSeekPosition; + QMediaContent m_currentResource; OMX_EGLBufferProviderSh m_texProvider; diff --git a/piomxtextures_qt_driver/mediaplayer/openmaxilplayerserviceplugin.cpp b/piomxtextures_qt_driver/mediaplayer/openmaxilplayerserviceplugin.cpp index 47b2e03..2403561 100644 --- a/piomxtextures_qt_driver/mediaplayer/openmaxilplayerserviceplugin.cpp +++ b/piomxtextures_qt_driver/mediaplayer/openmaxilplayerserviceplugin.cpp @@ -32,7 +32,7 @@ #include "openmaxilplayerserviceplugin.h" #include "openmaxilplayerservice.h" -#include "lc_logging.h" +#include "omx_logging.h" /*------------------------------------------------------------------------------ | OMX_PlayerServicePlugin::create diff --git a/piomxtextures_qt_driver/mediaplayer/openmaxilvideorenderercontrol.cpp b/piomxtextures_qt_driver/mediaplayer/openmaxilvideorenderercontrol.cpp index aa4324a..d643b07 100644 --- a/piomxtextures_qt_driver/mediaplayer/openmaxilvideorenderercontrol.cpp +++ b/piomxtextures_qt_driver/mediaplayer/openmaxilvideorenderercontrol.cpp @@ -205,6 +205,12 @@ void OpenMAXILVideoRendererControl::onTexturesReady() QVideoFrame::Format_RGB565, QAbstractVideoBuffer::GLTextureHandle ); + + // This is needed to force an update of the surface format int the + // following refresh. + if (m_surface) + if (m_surface->isActive()) + m_surface->stop(); } /*------------------------------------------------------------------------------ diff --git a/piomxtextures_samples/piomxtextures_samples.pro b/piomxtextures_samples/piomxtextures_samples.pro index 44e6f57..4f1303d 100644 --- a/piomxtextures_samples/piomxtextures_samples.pro +++ b/piomxtextures_samples/piomxtextures_samples.pro @@ -30,4 +30,5 @@ OTHER_FILES += video_* DISTFILES += \ audio_simple.qml \ video_concurrent.qml \ - video_loop.qml + video_loop.qml \ + video_loop_position.qml diff --git a/piomxtextures_samples/video_audio_concurrent.qml b/piomxtextures_samples/video_audio_concurrent.qml new file mode 100644 index 0000000..e68b960 --- /dev/null +++ b/piomxtextures_samples/video_audio_concurrent.qml @@ -0,0 +1,108 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 08.08.2015 + * + * Copyright (c) 2012-2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +import QtQuick 2.0 +import QtQml 2.2 +import QtMultimedia 5.0 + +Rectangle { + property var videoUris: [] + property var audioUris: [] + property int videoIndex: 0 + property int audioIndex: 0 + + color: "red" + + Component.onCompleted: { + var arguments = Qt.application.arguments; + if (arguments.length < 6) { + console.log("Too few arguments."); + Qt.quit(); + } + + videoUris.push(arguments[2]); + videoUris.push(arguments[3]); + audioUris.push(arguments[4]); + audioUris.push(arguments[5]); + + nextVideo(video1); + nextVideo(video2); + nextAudio(audio); + } + + Video { + id: video1 + width: 500 + height: 450 + x: parent.width/3 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video1) + } + + Video { + id: video2 + width: 500 + height: 450 + x: parent.width/3*2 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video2) + } + + Audio { + id: audio + source: uri3 + autoPlay: false + onStopped: nextAudio(audio) + } + + //Timer { + // interval: 500 + // running: true; repeat: true + // onTriggered: { + // console.log("Position video1: " + video1.position + "."); + // console.log("Position video2: " + video2.position + "."); + // console.log("Position audio: " + audio.position + "."); + // } + //} + + Timer { + interval: 5000 + running: true; repeat: true + onTriggered: { + console.log("Switching audio..."); + audio.stop(); + } + } + + function nextVideo(element) { + element.source = videoUris[videoIndex++%2]; + element.play(); + } + + function nextAudio(element) { + element.source = audioUris[audioIndex++%2]; + element.play(); + } +} diff --git a/piomxtextures_samples/video_audio_multi.qml b/piomxtextures_samples/video_audio_concurrent_position.qml similarity index 60% rename from piomxtextures_samples/video_audio_multi.qml rename to piomxtextures_samples/video_audio_concurrent_position.qml index 2be679c..947efc4 100644 --- a/piomxtextures_samples/video_audio_multi.qml +++ b/piomxtextures_samples/video_audio_concurrent_position.qml @@ -26,51 +26,55 @@ import QtQml 2.2 import QtMultimedia 5.0 Rectangle { - property string uri1 - property string uri2 - property string uri3 + property var videoUris: [] + property var audioUris: [] + property int videoIndex: 0 + property int audioIndex: 0 color: "red" Component.onCompleted: { var arguments = Qt.application.arguments; - if (arguments.length < 5) { + if (arguments.length < 6) { console.log("Too few arguments."); Qt.quit(); } - uri1 = arguments[2]; - uri2 = arguments[3]; - uri3 = arguments[4]; + videoUris.push(arguments[2]); + videoUris.push(arguments[3]); + audioUris.push(arguments[4]); + audioUris.push(arguments[5]); + + nextVideo(video1); + nextVideo(video2); + nextAudio(audio); } Video { id: video1 width: 500 height: 450 - x: 100 - y: 400 - source: uri1 - autoPlay: true - onStopped: {video1.seek(0); video1.play();} + x: parent.width/3 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video1) } Video { id: video2 - x: 900 - y: 400 width: 500 height: 450 - source: uri2 - autoPlay: true - onStopped: {video2.seek(0); video2.play();} + x: parent.width/3*2 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video2) } Audio { id: audio source: uri3 - autoPlay: true - onStopped: {audio.seek(0); audio.play();} + autoPlay: false + onStopped: nextAudio(audio) } Timer { @@ -82,4 +86,23 @@ Rectangle { console.log("Position audio: " + audio.position + "."); } } + + Timer { + interval: 5000 + running: true; repeat: true + onTriggered: { + console.log("Switching audio..."); + audio.stop(); + } + } + + function nextVideo(element) { + element.source = videoUris[videoIndex++%2]; + element.play(); + } + + function nextAudio(element) { + element.source = audioUris[audioIndex++%2]; + element.play(); + } } diff --git a/piomxtextures_samples/video_audio_concurrent_seek.qml b/piomxtextures_samples/video_audio_concurrent_seek.qml new file mode 100644 index 0000000..04155a3 --- /dev/null +++ b/piomxtextures_samples/video_audio_concurrent_seek.qml @@ -0,0 +1,125 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 08.08.2015 + * + * Copyright (c) 2012-2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +import QtQuick 2.0 +import QtQml 2.2 +import QtMultimedia 5.0 + +Rectangle { + property var videoUris: [] + property var audioUris: [] + property int videoIndex: 0 + property int audioIndex: 0 + + color: "red" + + Component.onCompleted: { + var arguments = Qt.application.arguments; + if (arguments.length < 6) { + console.log("Too few arguments."); + Qt.quit(); + } + + videoUris.push(arguments[2]); + videoUris.push(arguments[3]); + audioUris.push(arguments[4]); + audioUris.push(arguments[5]); + + nextVideo(video1); + nextVideo(video2); + nextAudio(audio); + } + + Video { + id: video1 + width: 500 + height: 450 + x: parent.width/3 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video1) + } + + Video { + id: video2 + width: 500 + height: 450 + x: parent.width/3*2 - width/2 + y: parent.height/2 - height/2 + autoPlay: false + onStopped: nextVideo(video2) + } + + Audio { + id: audio + source: uri3 + autoPlay: false + onStopped: nextAudio(audio) + } + + Timer { + property int playerIdx: 0; + + interval: 1000 + running: true; repeat: true + onTriggered: { + //console.log("Position video1: " + video1.position + "."); + //console.log("Position video2: " + video2.position + "."); + //console.log("Position audio: " + audio.position + "."); + console.log("Seeking..."); + if (playerIdx === 0) + randomSeek(video1); + else if (playerIdx === 1) + randomSeek(video2); + //else if (playerIdx === 2) + // randomSeek(audio); + + playerIdx = (++playerIdx)%2; + } + } + + //Timer { + // interval: 5000 + // running: true; repeat: true + // onTriggered: { + // console.log("Switching audio..."); + // audio.stop(); + // } + //} + + function nextVideo(element) { + element.source = videoUris[videoIndex++%2]; + element.play(); + } + + function nextAudio(element) { + element.source = audioUris[audioIndex++%2]; + element.play(); + } + + function randomSeek(element) { + var length = element.duration - 1000; + var randomPosition = Math.random()*length; + element.seek(randomPosition); + } +} diff --git a/piomxtextures_samples/video_loop.qml b/piomxtextures_samples/video_loop.qml index 7abc00d..8913ae8 100644 --- a/piomxtextures_samples/video_loop.qml +++ b/piomxtextures_samples/video_loop.qml @@ -3,7 +3,7 @@ * Author: Luca Carlon * Date: 08.24.2015 * -* Copyright (c) 2012, 2013, 2014 Luca Carlon. All rights reserved. +* Copyright (c) 2012-2015 Luca Carlon. All rights reserved. * * This file is part of PiOmxTextures. * diff --git a/piomxtextures_samples/video_loop_position.qml b/piomxtextures_samples/video_loop_position.qml new file mode 100644 index 0000000..e6b2ec5 --- /dev/null +++ b/piomxtextures_samples/video_loop_position.qml @@ -0,0 +1,66 @@ +import QtQuick 2.0 +import QtMultimedia 5.0 + +Rectangle { + property int index: 0 + property int count: 0 + property var playlist + + anchors.fill: parent + + Component.onCompleted: { + var arguments = Qt.application.arguments; + if (arguments.length < 3) { + console.log("Too few arguments."); + Qt.quit(); + } + + var mediaList = []; + for (var i = 2; i < arguments.length; i++) + mediaList.push(arguments[i]); + + showMedia(mediaList); + } + + MediaPlayer { + id: mediaPlayer + + onStopped: + goToNextMedia(); + } + + VideoOutput { + anchors.fill: parent + source: mediaPlayer + fillMode: VideoOutput.Stretch + } + + Timer { + running: true; + interval: 10; + repeat: true; + onTriggered: { + console.log("Position: " + mediaPlayer.position + "."); + } + } + + function showMedia(mediaList) { + for (var i = 0; i < mediaList.length; i++) + console.log("" + mediaList[i] + " added to the playlist."); + playlist = mediaList; + goToNextMedia(); + } + + function goToNextMedia() { + console.log("Play count: " + count + "."); + console.log("Opening video file: " + playlist[index] + "."); + //console.log("Uptime: " + uptime.uptimeString() + "."); + + mediaPlayer.source = playlist[index]; + mediaPlayer.play(); + + count++; + index++; + index = index >= playlist.length ? 0 : index; + } +} diff --git a/piomxtextures_samples/video_seek.qml b/piomxtextures_samples/video_seek.qml new file mode 100644 index 0000000..db32bda --- /dev/null +++ b/piomxtextures_samples/video_seek.qml @@ -0,0 +1,89 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 08.08.2015 + * + * Copyright (c) 2012-2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +import QtQuick 2.2 +import QtQml 2.2 +import QtQuick.Window 2.0 +import QtMultimedia 5.0 + +/** + * This sample creates a Video surface including a MediaPlayer, plays continuously + * and asks for the current position every 10ms. + */ +Rectangle { + property string uri + + id: root + objectName: "root" + visible: true + color: "black" + + Component.onCompleted: { + var arguments = Qt.application.arguments; + if (arguments.length < 3) { + console.log("Too few arguments."); + Qt.quit(); + } + + uri = arguments[2]; + } + + Video { + id: myVideo + anchors.fill: parent + visible: true + + source: uri + autoPlay: true + + //onStopped: { + // console.log("Stopped."); + // myVideo.seek(0); + // myVideo.play(); + //} + + onStatusChanged: { + console.log("Status changed to: " + status + "."); + } + } + + Timer { + property int seekCount: 0 + + id: videoInterval + interval: 500 + repeat: true + running: true + + onTriggered: { + console.log("Seek n. " + seekCount++ + "..."); + randomSeek(myVideo); + } + } + + function randomSeek(element) { + var length = element.duration - 1000; + var randomPosition = Math.random()*length; + element.seek(randomPosition); + } +} diff --git a/piomxtextures_src/omx_logging.h b/piomxtextures_src/omx_logging.h index 4d544da..06def73 100644 --- a/piomxtextures_src/omx_logging.h +++ b/piomxtextures_src/omx_logging.h @@ -29,6 +29,7 @@ +-----------------------------------------------------------------------------*/ #include +#define BUILD_LOG_LEVEL_INFORMATION #include using namespace std; diff --git a/piomxtextures_src/omx_mediaprocessor.cpp b/piomxtextures_src/omx_mediaprocessor.cpp index 20ff9c3..567fb3e 100644 --- a/piomxtextures_src/omx_mediaprocessor.cpp +++ b/piomxtextures_src/omx_mediaprocessor.cpp @@ -33,13 +33,14 @@ #include #include -#include "lc_logging.h" - #include "omx_mediaprocessor.h" #include "omx_textureprovider.h" #include "omx_playeraudio.h" #include "omx_reader.h" #include "omx_globals.h" +#ifdef OMX_LOCK_WATCHDOG +#include "omx_watchdog.h" +#endif // OMX_LOCK_WATCHDOG // omxplayer lib. #include "omxplayer_lib/linux/RBP.h" @@ -109,7 +110,7 @@ static int get_mem_gpu(void) return gpu_mem; } -std::once_flag flag1; +static std::once_flag flag1; /*------------------------------------------------------------------------------ | print_build_once @@ -121,6 +122,20 @@ static void print_build_once() }); } +#ifdef OMX_LOCK_WATCHDOG +/*------------------------------------------------------------------------------ +| start_watchdog_once ++-----------------------------------------------------------------------------*/ +static void start_watchdog_once() +{ + std::call_once(flag2, []() { + log_info("Starting watchdog..."); + static OMX_Watchdog watchDog; + watchDog.startWatchdog(); + }); +} +#endif // OMX_LOCK_WATCHDOG + /*------------------------------------------------------------------------------ | OMX_MediaProcessor::OMX_MediaProcessor +-----------------------------------------------------------------------------*/ @@ -131,9 +146,9 @@ OMX_MediaProcessor::OMX_MediaProcessor(OMX_EGLBufferProviderSh provider) : m_state(STATE_INACTIVE), m_mediaStatus(MEDIA_STATUS_NO_MEDIA), m_sendCmd(QMutex::Recursive), - #ifdef ENABLE_SUBTITLES +#ifdef ENABLE_SUBTITLES m_has_subtitle(false), - #endif +#endif m_av_clock(new OMXClock), m_player_video(new OMXPlayerVideo(provider)), m_player_audio(new OMX_PlayerAudio), @@ -148,20 +163,23 @@ OMX_MediaProcessor::OMX_MediaProcessor(OMX_EGLBufferProviderSh provider) : m_pendingPause(false), m_subtitle_index(0), m_audio_index(0), - m_incr(0), + m_incrMs(0), m_audioConfig(new OMXAudioConfig()), m_videoConfig(new OMXVideoConfig()), m_playspeedCurrent(playspeed_normal), m_seekFlush(false), m_packetAfterSeek(false), startpts(0), - m_loop(false), m_muted(false), - m_loop_from(0.0f), + m_volume(1.0), m_fps(0.0f) { print_build_once(); +#ifdef OMX_LOCK_WATCHDOG + start_watchdog_once(); +#endif // OMX_LOCK_WATCHDOG + qRegisterMetaType( "OMX_MediaProcessor::OMX_MediaProcessorError"); qRegisterMetaType( @@ -247,6 +265,7 @@ bool OMX_MediaProcessor::setFilename(const QString& filename) +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::setFilenameWrapper(const QString& filename) { + stopInt(); setMediaStatus(MEDIA_STATUS_LOADING); if (!setFilenameInt(filename)) { @@ -313,8 +332,9 @@ bool OMX_MediaProcessor::setFilenameInt(const QString& filename) #ifdef ENABLE_SUBTITLES m_has_subtitle = m_omx_reader->SubtitleStreamCount(); #endif - m_loop = m_loop && m_omx_reader->CanSeek(); - m_incr = 0; + m_incrMs = 0; + m_packetAfterSeek = false; + m_seekFlush = false; LOG_VERBOSE(LOG_TAG, "Initializing OMX clock..."); if (!m_av_clock->OMXInitialize()) @@ -404,7 +424,7 @@ bool OMX_MediaProcessor::setFilenameInt(const QString& filename) if (!m_player_audio->Open(m_av_clock, *m_audioConfig, m_omx_reader)) return false; if (m_has_audio) - m_player_audio->SetVolume(pow(10, 0 / 2000.0)); + m_player_audio->SetCurrentVolume(m_volume, true); } setState(STATE_STOPPED); @@ -574,21 +594,21 @@ bool OMX_MediaProcessor::pauseInt() +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::seek(qint64 position) { + QMutexLocker locker(&m_sendCmd); + LOG_VERBOSE(LOG_TAG, "Seek %lldms.", position); if (!m_av_clock) return false; // Get current position in ms. - qint64 current = m_av_clock->OMXMediaTime(false)*1E-3; - qint64 currentS = qRound64(current/1000.0d); + qint64 currentMs = m_av_clock->OMXMediaTime(false)*1E-3; // position is in ms. Translate to seconds. - int seconds = qRound64(position/1000.0d); - int increment = seconds - currentS; - if (!increment) + int incrementMs = position - currentMs; + if (!incrementMs) return true; - m_incr = increment; + m_incrMs = incrementMs; return true; } @@ -598,8 +618,11 @@ bool OMX_MediaProcessor::seek(qint64 position) +-----------------------------------------------------------------------------*/ qint64 OMX_MediaProcessor::streamPosition() { + QMutexLocker locker(&m_sendCmd); if (!m_av_clock) return -1; + if (m_state == OMX_MediaProcessor::STATE_STOPPED) + return 0; return m_av_clock->OMXMediaTime(false)*1E-3; } @@ -608,7 +631,15 @@ qint64 OMX_MediaProcessor::streamPosition() +-----------------------------------------------------------------------------*/ void OMX_MediaProcessor::setVolume(long volume, bool linear) { - m_player_audio->SetCurrentVolume(volume, linear); + QMutexLocker locker(&m_sendCmd); + +#define VOL_MAX 2 +#define VOL_MIN 0 + + m_volume = volume/100.0*(VOL_MAX - VOL_MIN); + + log_debug("setVolume %f", m_volume); + m_player_audio->SetCurrentVolume(m_volume, linear); } /*------------------------------------------------------------------------------ @@ -616,7 +647,10 @@ void OMX_MediaProcessor::setVolume(long volume, bool linear) +-----------------------------------------------------------------------------*/ long OMX_MediaProcessor::volume(bool linear) { - return m_player_audio->GetCurrentVolume(linear); + QMutexLocker locker(&m_sendCmd); + //return m_player_audio->GetCurrentVolume(linear)/(VOL_MAX - VOL_MIN)*100; + + return m_volume; } /*------------------------------------------------------------------------------ @@ -624,6 +658,7 @@ long OMX_MediaProcessor::volume(bool linear) +-----------------------------------------------------------------------------*/ void OMX_MediaProcessor::setMute(bool muted) { + QMutexLocker locker(&m_sendCmd); m_muted = muted; if (LIKELY(m_player_audio != NULL)) @@ -635,6 +670,7 @@ void OMX_MediaProcessor::setMute(bool muted) +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::muted() { + QMutexLocker locker(&m_sendCmd); return m_muted; } @@ -712,17 +748,18 @@ void OMX_MediaProcessor::mediaDecoding() continue; } - if (UNLIKELY(m_seekFlush || m_incr != 0)) { + if (UNLIKELY(m_seekFlush || m_incrMs != 0)) { double seek_pos = 0; double pts = m_av_clock->OMXMediaTime(); + double ptsMs = DVD_TIME_TO_MSEC(pts); //seek_pos = (pts / DVD_TIME_BASE) + m_incr; - seek_pos = (pts ? pts / DVD_TIME_BASE : last_seek_pos) + m_incr; + seek_pos = (ptsMs ? ptsMs : last_seek_pos) + m_incrMs; last_seek_pos = seek_pos; - seek_pos *= 1000.0; + //seek_pos *= 1000.0; - if(m_omx_reader->SeekTime((int)seek_pos, m_incr < 0.0f, &startpts)) + if(m_omx_reader->SeekTime((int)seek_pos, m_incrMs < 0.0f, &startpts)) { unsigned t = (unsigned)(startpts*1e-6); //auto dur = m_omx_reader->GetStreamLength() / 1000; @@ -737,11 +774,11 @@ void OMX_MediaProcessor::mediaDecoding() break; if (m_has_video && !m_player_video->Reset()) { - m_incr = 0; + m_incrMs = 0; break; } - m_incr = 0; + m_incrMs = 0; #ifdef ENABLE_PAUSE_FOR_BUFFERING m_av_clock->OMXPause(); @@ -764,9 +801,10 @@ void OMX_MediaProcessor::mediaDecoding() double pts = 0; pts = m_av_clock->OMXMediaTime(); - seek_pos = (pts/DVD_TIME_BASE); + //seek_pos = (pts/DVD_TIME_BASE); + seek_pos = DVD_TIME_TO_MSEC(pts); - seek_pos *= 1000.0; + //seek_pos *= 1000.0; #if 1 if (m_omx_reader->SeekTime((int)seek_pos, m_av_clock->OMXPlaySpeed() < 0, &startpts)) @@ -912,12 +950,6 @@ void OMX_MediaProcessor::mediaDecoding() continue; } - if (m_loop) - { - m_incr = m_loop_from - (m_av_clock->OMXMediaTime() ? m_av_clock->OMXMediaTime() / DVD_TIME_BASE : last_seek_pos); - continue; - } - setMediaStatus(MEDIA_STATUS_END_OF_MEDIA); break; } @@ -968,7 +1000,8 @@ void OMX_MediaProcessor::mediaDecoding() m_av_clock->OMXStop(); m_av_clock->OMXStateIdle(); - m_incr = m_loop_from - (m_av_clock->OMXMediaTime() ? m_av_clock->OMXMediaTime() / DVD_TIME_BASE : last_seek_pos); + const double mediaTime = m_av_clock->OMXMediaTime(); + m_incrMs = -(mediaTime ? DVD_TIME_TO_MSEC(mediaTime) : last_seek_pos); m_seekFlush = true; flushStreams(DVD_NOPTS_VALUE); @@ -1013,8 +1046,10 @@ void OMX_MediaProcessor::flushStreams(double pts) m_av_clock->OMXStop(); m_av_clock->OMXPause(); - if (m_has_video) + if (m_has_video) { m_player_video->Flush(); + m_provider->flush(); + } if (m_has_audio) m_player_audio->Flush(); diff --git a/piomxtextures_src/omx_mediaprocessor.h b/piomxtextures_src/omx_mediaprocessor.h index 8ab3e62..d14e721 100644 --- a/piomxtextures_src/omx_mediaprocessor.h +++ b/piomxtextures_src/omx_mediaprocessor.h @@ -38,8 +38,7 @@ #include #include -#include - +#include "omx_logging.h" #include "omx_qthread.h" #include "omx_textureprovider.h" @@ -211,7 +210,7 @@ private slots: QMutex m_mutexPending; QWaitCondition m_waitPendingCommand; - volatile long m_incr; + volatile long m_incrMs; OMXAudioConfig* m_audioConfig; OMXVideoConfig* m_videoConfig; @@ -223,9 +222,8 @@ private slots: QVariantMap m_metadata; - bool m_loop; bool m_muted; - double m_loop_from; + double m_volume; float m_fps; // QtConcurrent uses a thread pool which on Pi1 counts only diff --git a/piomxtextures_src/omx_omxplayer_logging.cpp b/piomxtextures_src/omx_omxplayer_logging.cpp index 9162e43..85b38fc 100644 --- a/piomxtextures_src/omx_omxplayer_logging.cpp +++ b/piomxtextures_src/omx_omxplayer_logging.cpp @@ -51,7 +51,7 @@ #include "stat_utf8.h" #include "utils/StdString.h" -#include "lc_logging.h" +#include "omx_logging.h" /*------------------------------------------------------------------------------ | definitions diff --git a/piomxtextures_src/omx_playeraudio.cpp b/piomxtextures_src/omx_playeraudio.cpp index fa482a7..2872011 100644 --- a/piomxtextures_src/omx_playeraudio.cpp +++ b/piomxtextures_src/omx_playeraudio.cpp @@ -73,47 +73,12 @@ bool OMX_PlayerAudio::GetMuted() +-----------------------------------------------------------------------------*/ /** * @brief OMX_PlayerAudio::SetCurrentVolume - * @param volume Volume in mB or percentage [0, 100]. + * @param volume * @param linear */ void OMX_PlayerAudio::SetCurrentVolume(double volume, bool linear) { - if (!linear) { - OMXPlayerAudio::SetVolume(volume); - return; - } - - // I supposed it was possible to get the available range from OpenMAX - // but it seems to always return 0. -#ifdef ENABLE_RANGE_FROM_OMX - // Get current configuration to determine max and min mB. - OMX_AUDIO_CONFIG_VOLUMETYPE omxVolume; - OMX_INIT_STRUCTURE(omxVolume); - omxVolume.nPortIndex = m_decoder->m_omx_render.GetInputPort(); - omxVolume.bLinear = OMX_FALSE; - OMX_ERRORTYPE omx_err = m_decoder->m_omx_render.GetConfig(OMX_IndexConfigAudioVolume, &omxVolume); - if (omx_err != OMX_ErrorNone) { - LOG_WARNING(LOG_TAG, "%s - error getting OMX_IndexConfigAudioVolume, error 0x%08x\n", - Q_FUNC_INFO, omx_err); - return; - } - - // Determine the mB value to be used. - OMX_S32 mbMax = omxVolume.sVolume.nMax; - OMX_S32 mbMin = omxVolume.sVolume.nMin; -#else -#define MAX 600 -#define MIN -3000 -#endif - - //double expMin = exp(mbMin); - //double expMax = exp(mbMax); - //double mbVolume = log((double)volume/100*(expMax - expMin) + expMin); - double mbVolume = volume/100.0f*(MAX - MIN) + MIN; - LOG_VERBOSE(LOG_TAG, "Setting volume to %fmB.", mbVolume); - - // omxplayer expects millibels here. - OMXPlayerAudio::SetVolume(pow(10, mbVolume/2000.0f)); + OMXPlayerAudio::SetVolume((float)volume); } /*------------------------------------------------------------------------------ @@ -121,27 +86,5 @@ void OMX_PlayerAudio::SetCurrentVolume(double volume, bool linear) +-----------------------------------------------------------------------------*/ double OMX_PlayerAudio::GetCurrentVolume(bool linear) { - if (!linear) - return OMXPlayerAudio::GetVolume(); - - const float mbVol = OMXPlayerAudio::GetVolume(); - const double vol = (log10(mbVol)*2000.0f - MIN)*100.0f/(MAX - MIN); - - return (long)vol; - -#if 0 - long mbVol = OMXPlayerAudio::GetCurrentVolume(); - if (!linear) - return mbVol; - - OMX_S32 mbMax = 2; - OMX_S32 mbMin = -6; - double expMin = exp(mbMin); - double expMax = exp(mbMax); - double num = 100*exp(mbVol/1000) - expMin; - double den = expMax - expMin; - - LOG_VERBOSE(LOG_TAG, "Volume: %ld.", (long)(num/den)); - return (long)(num/den); -#endif + return OMXPlayerAudio::GetVolume(); } diff --git a/piomxtextures_src/omx_staticconf.cpp b/piomxtextures_src/omx_staticconf.cpp new file mode 100644 index 0000000..6703e2f --- /dev/null +++ b/piomxtextures_src/omx_staticconf.cpp @@ -0,0 +1,121 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 09.09.2015 + * + * Copyright (c) 2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +/*------------------------------------------------------------------------------ +| includes ++-----------------------------------------------------------------------------*/ +#include + +#include + +#include "omx_logging.h" +#include "omx_staticconf.h" + +static std::once_flag flag1; +static std::once_flag flag2; +static std::once_flag flag3; +static std::once_flag flag4; + +/*------------------------------------------------------------------------------ +| OMX_StaticConf::getHalfFramerate ++-----------------------------------------------------------------------------*/ +bool OMX_StaticConf::getHalfFramerate() +{ + static bool halfFramerate = false; + std::call_once(flag1, []() { + QByteArray ba = qgetenv("POT_HALF_FRAMERATE_MODE"); + if (ba.isEmpty() || ba.isNull()) + return; + bool convOk; + int hf = ba.toInt(&convOk); + if (convOk && (hf == 0 || hf == 1)) + halfFramerate = hf; + + log_verbose("Setting half framerate to %d.", halfFramerate); + }); + + return halfFramerate; +} + +/*------------------------------------------------------------------------------ +| OMX_StaticConf::getTextureCount ++-----------------------------------------------------------------------------*/ +int OMX_StaticConf::getTextureCount() +{ + static int textureCount = 4; + std::call_once(flag3, []() { + QByteArray ba = qgetenv("POT_TEXTURE_COUNT"); + if (ba.isEmpty() || ba.isNull()) + return; + bool convOk; + int tc = ba.toInt(&convOk); + if (convOk && tc > 1) + textureCount = tc; + + log_verbose("Setting texture count to %d.", textureCount); + }); + + return textureCount; +} + +/*------------------------------------------------------------------------------ +| OMX_StaticConf::getInterlaceMode ++-----------------------------------------------------------------------------*/ +int OMX_StaticConf::getInterlaceMode() +{ + static int interlaceMode = 0; // Off. + std::call_once(flag2, []() { + QByteArray ba = qgetenv("POT_DEINTERLACE_MODE"); + if (ba.isEmpty() || ba.isNull()) + return; + bool convOk; + int im = ba.toInt(&convOk); + if (convOk && (im >= 0 && im < 3)) + interlaceMode = im; + + log_verbose("Setting interlace mode to %d.", interlaceMode); + }); + + return interlaceMode; +} + +/*------------------------------------------------------------------------------ +| OMX_StaticConf::getInterlaceQpu ++-----------------------------------------------------------------------------*/ +int OMX_StaticConf::getInterlaceQpu() +{ + static int interlaceQpu = 1; + std::call_once(flag4, [] { + QByteArray ba = qgetenv("POT_DEINTERLACE_QPU"); + if (ba.isEmpty() || ba.isNull()) + return; + bool convOk; + int qpu = ba.toInt(&convOk); + if (convOk && (qpu != 0 && qpu != 1)) + interlaceQpu = qpu; + + log_verbose("Setting qpu interlace to %d.", qpu); + }); + + return interlaceQpu; +} diff --git a/piomxtextures_src/omx_staticconf.h b/piomxtextures_src/omx_staticconf.h new file mode 100644 index 0000000..012e199 --- /dev/null +++ b/piomxtextures_src/omx_staticconf.h @@ -0,0 +1,39 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 09.09.2015 + * + * Copyright (c) 2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +#ifndef OMX_STATICCONF_H +#define OMX_STATICCONF_H + +/*------------------------------------------------------------------------------ +| OMX_StaticConf class ++-----------------------------------------------------------------------------*/ +class OMX_StaticConf +{ +public: + static int getInterlaceMode(); + static int getInterlaceQpu(); + static int getTextureCount(); + static bool getHalfFramerate(); +}; + +#endif // OMX_STATICCONF_H diff --git a/piomxtextures_src/omx_texture.h b/piomxtextures_src/omx_texture.h index 6102bc9..c020be1 100644 --- a/piomxtextures_src/omx_texture.h +++ b/piomxtextures_src/omx_texture.h @@ -37,7 +37,7 @@ #include #include -#include "lc_logging.h" +#include "omx_logging.h" /*------------------------------------------------------------------------------ diff --git a/piomxtextures_src/omx_textureprovider.h b/piomxtextures_src/omx_textureprovider.h index 61f944f..af72d29 100644 --- a/piomxtextures_src/omx_textureprovider.h +++ b/piomxtextures_src/omx_textureprovider.h @@ -46,12 +46,16 @@ #include "omx_globals.h" #include "omx_logging.h" +#include "omx_staticconf.h" /*------------------------------------------------------------------------------ | definitions +-----------------------------------------------------------------------------*/ class QQuickItem; +#define TEXTURE_COUNT (OMX_StaticConf::getTextureCount()) +//#define DEBUG_TEXTURE_PROVIDER + /*------------------------------------------------------------------------------ | OMX_TextureData class +-----------------------------------------------------------------------------*/ @@ -81,10 +85,10 @@ class OMX_EGLBufferProvider : public QObject public: OMX_EGLBufferProvider() : QObject() + , m_semEmpty(TEXTURE_COUNT) , m_currentDecoder(NULL) , m_currentRenderer(NULL) - , m_mutex(QMutex::Recursive) - , m_texCount(0) + , m_mutex(QMutex::Recursive) , m_initialized(false) , m_oglContext(NULL) , m_eglContext(NULL) @@ -95,7 +99,7 @@ class OMX_EGLBufferProvider : public QObject ~OMX_EGLBufferProvider(); bool init(); - bool instantiateTextures(const QSize& s, int count); + bool instantiateTextures(const QSize& s); OMX_TextureData* instantiateTexture(const QSize& size); bool textureInstantiated(); @@ -137,6 +141,7 @@ class OMX_EGLBufferProvider : public QObject m_currentRenderer = NULL; m_emptyQueue.append(m_available); + m_semEmpty.release(TEXTURE_COUNT - m_semEmpty.available()); } public slots: @@ -146,16 +151,16 @@ public slots: signals: void texturesReady(); void texturesFreed(); - void frameReady(); + void frameReady(); private: QQueue m_filledQueue; QQueue m_emptyQueue; + QSemaphore m_semEmpty; QList m_available; OMX_TextureData* m_currentDecoder; OMX_TextureData* m_currentRenderer; - QMutex m_mutex; - int m_texCount; + QMutex m_mutex; bool m_initialized; // The context to be used to create buffers and textures. @@ -190,7 +195,7 @@ inline OMX_EGLBufferProvider::~OMX_EGLBufferProvider() inline bool OMX_EGLBufferProvider::textureInstantiated() { - return m_texCount != 0; + return m_available.size() != 0; } /*------------------------------------------------------------------------------ @@ -270,16 +275,20 @@ bool OMX_EGLBufferProvider::init() | OMX_EGLBufferProvider::instantiateBuffers +-----------------------------------------------------------------------------*/ inline -bool OMX_EGLBufferProvider::instantiateTextures(const QSize& s, int count) +bool OMX_EGLBufferProvider::instantiateTextures(const QSize& s) { - QMutexLocker locker(&m_mutex); - if (!m_available.isEmpty()) - if (m_available.at(0)->m_textureSize == s) - return log_verbose("Reusing allocated textures."); + QMutexLocker locker(&m_mutex); + if (!m_available.isEmpty()) { + if (m_available.at(0)->m_textureSize == s) { + flush(); + return log_verbose("Reusing allocated textures."); + } + } // Free all textures. free(); +#if 0 if (UNLIKELY(m_texCount != 0)) { log_warn("There are currently %d textures available already.", m_texCount); return false; @@ -289,16 +298,16 @@ bool OMX_EGLBufferProvider::instantiateTextures(const QSize& s, int count) log_warn("It makes no sense to instantiate <= 0 textures."); return false; } +#endif - for (int i = 0; i < count; i++) { + m_semEmpty.release(TEXTURE_COUNT - m_semEmpty.available()); + for (int i = 0; i < TEXTURE_COUNT; i++) { log_info("Instantiating texture data..."); OMX_TextureData* tex = instantiateTexture(s); m_emptyQueue.append(tex); m_available.append(tex); } - m_texCount = count; - emit texturesReady(); return true; @@ -369,12 +378,19 @@ GLuint OMX_EGLBufferProvider::getNextTexture() return m_currentRenderer->m_textureId; } - log_warn("No decoded frame to show at all. Let' render black."); + log_warn("No decoded frame to show at all. Let's render black."); return 0; } - if (LIKELY(m_currentRenderer != NULL)) + if (LIKELY(m_currentRenderer != NULL)) { m_emptyQueue.enqueue(m_currentRenderer); + + m_semEmpty.release(); +#ifdef DEBUG_TEXTURE_PROVIDER + log_debug("sem released: %d.", m_semEmpty.available()); +#endif + } + m_currentRenderer = data; return data->m_textureId; @@ -387,7 +403,6 @@ inline bool OMX_EGLBufferProvider::registerFilledBuffer(OMX_BUFFERHEADERTYPE* buffer) { QMutexLocker locker(&m_mutex); - if (UNLIKELY(m_currentDecoder == NULL)) return true; @@ -405,9 +420,17 @@ bool OMX_EGLBufferProvider::registerFilledBuffer(OMX_BUFFERHEADERTYPE* buffer) inline OMX_TextureData* OMX_EGLBufferProvider::getNextEmptyBuffer() { +#ifdef DEBUG_TEXTURE_PROVIDER + log_debug("Waiting for the sem: %d.", m_semEmpty.available()); +#endif + const bool found = m_semEmpty.tryAcquire(1, 40); +#ifdef DEBUG_TEXTURE_PROVIDER + log_debug("Acquired sem: %d.", m_semEmpty.available()); +#endif + QMutexLocker locker(&m_mutex); - if (LIKELY(!m_emptyQueue.empty())) + if (LIKELY(found)) return (m_currentDecoder = m_emptyQueue.dequeue()); if (LIKELY(!m_filledQueue.empty())) { log_warn("One frame couldn't be shown."); @@ -425,7 +448,6 @@ OMX_TextureData* OMX_EGLBufferProvider::getNextEmptyBuffer() inline void OMX_EGLBufferProvider::free() { QMutexLocker locker(&m_mutex); - foreach (OMX_TextureData* data, m_available) data->freeData(); @@ -436,7 +458,7 @@ inline void OMX_EGLBufferProvider::free() m_emptyQueue.clear(); m_available.clear(); - m_texCount = 0; + m_semEmpty.release(TEXTURE_COUNT - m_semEmpty.available()); emit texturesFreed(); } diff --git a/piomxtextures_src/omx_watchdog.cpp b/piomxtextures_src/omx_watchdog.cpp new file mode 100644 index 0000000..df14e4a --- /dev/null +++ b/piomxtextures_src/omx_watchdog.cpp @@ -0,0 +1,103 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 10.22.2015 + * + * Copyright (c) 2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + + +/*------------------------------------------------------------------------------ +| includes ++-----------------------------------------------------------------------------*/ +#include + +#include "OMXCore.h" + +#include "omx_watchdog.h" +#include "omx_logging.h" + +/*------------------------------------------------------------------------------ +| definitions ++-----------------------------------------------------------------------------*/ +#define IPC_FILE_ABS_PATH "/tmp/omx_lock" + +#ifdef OMX_LOCK_WATCHDOG +/*------------------------------------------------------------------------------ +| OMX_WatchDog::OMX_WatchDog ++-----------------------------------------------------------------------------*/ +OMX_Watchdog::OMX_Watchdog(QObject* parent) : QObject(parent) +{ + moveToThread(&m_thread); + + // Note that the even timer must be in a separate thread as we MUST ensure + // its own thread does not lock. + m_timer.moveToThread(&m_thread); + m_timer.setSingleShot(false); + m_timer.setInterval(1000); + + m_thread.start(); + + connect(&m_timer, SIGNAL(timeout()), + this, SLOT(testOmx())); + +#if 0 + QFile f(IPC_FILE_ABS_PATH); + f.remove(); +#endif +} + +/*------------------------------------------------------------------------------ +| OMX_WatchDog::startWatchDog ++-----------------------------------------------------------------------------*/ +void OMX_Watchdog::startWatchdog() +{ + QMetaObject::invokeMethod(&m_timer, "start"); +} + +/*------------------------------------------------------------------------------ +| OMX_WatchDog::stopWatchDog ++-----------------------------------------------------------------------------*/ +void OMX_Watchdog::stopWatchdog() +{ + QMetaObject::invokeMethod(&m_timer, "stop"); +} + +/*------------------------------------------------------------------------------ +| OMX_WatchDog::testOmx ++-----------------------------------------------------------------------------*/ +void OMX_Watchdog::testOmx() +{ + if (!COMXCoreComponent::testOmx()) + return; + + log_verbose("Touching IPC file..."); + QFile f(IPC_FILE_ABS_PATH); + if (!f.open(QIODevice::WriteOnly)) { + log_warn("Cannot touch file %s.", IPC_FILE_ABS_PATH); + return; + } + + if (!f.exists()) { + log_warn("Could not create file %s.", IPC_FILE_ABS_PATH); + return; + } + + f.flush(); +} +#endif // OMX_LOCK_WATCHDOG diff --git a/piomxtextures_src/omx_watchdog.h b/piomxtextures_src/omx_watchdog.h new file mode 100644 index 0000000..8c12c91 --- /dev/null +++ b/piomxtextures_src/omx_watchdog.h @@ -0,0 +1,54 @@ +/* + * Project: PiOmxTextures + * Author: Luca Carlon + * Date: 10.22.2015 + * + * Copyright (c) 2015 Luca Carlon. All rights reserved. + * + * This file is part of PiOmxTextures. + * + * PiOmxTextures 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 3 of the License, or + * (at your option) any later version. + * + * PiOmxTextures 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 PiOmxTextures. If not, see . + */ + +#ifndef OMX_WATCHDOG_H +#define OMX_WATCHDOG_H + +/*------------------------------------------------------------------------------ +| includes ++-----------------------------------------------------------------------------*/ +#include +#include + +/*------------------------------------------------------------------------------ +| OMX_WatchDog class ++-----------------------------------------------------------------------------*/ +#ifdef OMX_LOCK_WATCHDOG +class OMX_Watchdog : public QObject +{ + Q_OBJECT +public: + OMX_Watchdog(QObject* parent = 0); + virtual ~OMX_Watchdog() {} + +public slots: + void startWatchdog(); + void stopWatchdog(); + void testOmx(); + +private: + QTimer m_timer; + QThread m_thread; +}; +#endif // OMX_LOCK_WATCHDOG +#endif // OMX_WATCHDOG_H diff --git a/piomxtextures_src/omx_wrapper/OMXComponent.cpp b/piomxtextures_src/omx_wrapper/OMXComponent.cpp index f6e278e..b07b04d 100644 --- a/piomxtextures_src/omx_wrapper/OMXComponent.cpp +++ b/piomxtextures_src/omx_wrapper/OMXComponent.cpp @@ -14,7 +14,7 @@ #include "interface/vcos/vcos.h" -#include "lc_logging.h" +#include "omx_logging.h" #define TIMEOUT_MS 10000 diff --git a/piomxtextures_src/omx_wrapper/OMX_Core.cpp b/piomxtextures_src/omx_wrapper/OMX_Core.cpp index fbcb00d..76c075c 100644 --- a/piomxtextures_src/omx_wrapper/OMX_Core.cpp +++ b/piomxtextures_src/omx_wrapper/OMX_Core.cpp @@ -6,7 +6,7 @@ #include #include -#include "lc_logging.h" +#include "omx_logging.h" using namespace std; diff --git a/piomxtextures_src/omx_wrapper/omxtunnel.cpp b/piomxtextures_src/omx_wrapper/omxtunnel.cpp index b7b8c01..d91276c 100644 --- a/piomxtextures_src/omx_wrapper/omxtunnel.cpp +++ b/piomxtextures_src/omx_wrapper/omxtunnel.cpp @@ -4,7 +4,7 @@ #include #include "omxtunnel.h" -#include "lc_logging.h" +#include "omx_logging.h" using namespace std; diff --git a/piomxtextures_src/omxplayer_lib/OMXCore.cpp b/piomxtextures_src/omxplayer_lib/OMXCore.cpp index 11fd042..05cf56f 100644 --- a/piomxtextures_src/omxplayer_lib/OMXCore.cpp +++ b/piomxtextures_src/omxplayer_lib/OMXCore.cpp @@ -37,9 +37,53 @@ #include "XMemUtils.h" #endif +#include + //#define OMX_DEBUG_EVENTS //#define OMX_DEBUG_EVENTHANDLER +#ifdef OMX_THREAD_UNSAFE +#define log_lock log_disabled + +// lcarlon: temporary implementation. +QMutex COMXCoreComponent::m_mxOmx(QMutex::Recursive); + +/*------------------------------------------------------------------------------ +| COMXCoreComponent::testOmx ++-----------------------------------------------------------------------------*/ +bool COMXCoreComponent::testOmx() +{ + // Try to lock and timeout in 1s. + log_debug("Testing OpenMAX health..."); + const bool alive = m_mxOmx.tryLock(1000); + if (alive) + m_mxOmx.unlock(); + + if (alive) + return log_debug("OpenMAX seems healthy :-)"); + return log_warn("OpenMAX seems dead ;-("); +} + +/*------------------------------------------------------------------------------ +| lock_mutex ++-----------------------------------------------------------------------------*/ +inline void lock_mutex(QMutex* m) +{ + log_lock("Waiting for lock %p...", m); + m->lock(); + log_lock("Got lock %p...", m); +} + +/*------------------------------------------------------------------------------ +| unlock_mutex ++-----------------------------------------------------------------------------*/ +inline void unlock_mutex(QMutex* m) +{ + log_lock("Releasing lock %p...", m); + m->unlock(); +} +#endif // OMX_THREAD_UNSAFE + //////////////////////////////////////////////////////////////////////////////////////////// #define CLASSNAME "COMXCoreComponent" //////////////////////////////////////////////////////////////////////////////////////////// @@ -366,6 +410,21 @@ OMX_ERRORTYPE COMXCoreComponent::EmptyThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffe if(!m_handle || !omx_buffer) return OMX_ErrorUndefined; +#ifdef OMX_THREAD_UNSAFE + // lcarlon + lock_mutex(&m_mxOmx); + +//#define SIMULATE_OMX_LOCK +#ifdef SIMULATE_OMX_LOCK + static int count = 0; + count++; + if (count >= 500) { + while (true) + OMXClock::OMXSleep(10000); + } +#endif // SIMULATE_OMX_LOCK +#endif // OMX_THREAD_UNSAFE + omx_err = OMX_EmptyThisBuffer(m_handle, omx_buffer); if (omx_err != OMX_ErrorNone) { @@ -373,6 +432,11 @@ OMX_ERRORTYPE COMXCoreComponent::EmptyThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffe m_componentName.c_str(), omx_err); } +#ifdef OMX_THREAD_UNSAFE + // lcarlon + unlock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + return omx_err; } @@ -386,6 +450,11 @@ OMX_ERRORTYPE COMXCoreComponent::FillThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer if(!m_handle || !omx_buffer) return OMX_ErrorUndefined; +#ifdef OMX_THREAD_UNSAFE + // lcarlon + lock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + omx_err = OMX_FillThisBuffer(m_handle, omx_buffer); if (omx_err != OMX_ErrorNone) { @@ -393,6 +462,11 @@ OMX_ERRORTYPE COMXCoreComponent::FillThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer m_componentName.c_str(), omx_err); } +#ifdef OMX_THREAD_UNSAFE + // lcarlon + unlock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + return omx_err; } @@ -426,6 +500,10 @@ void COMXCoreComponent::FlushInput() OMX_ERRORTYPE omx_err = OMX_ErrorNone; +#ifdef OMX_THREAD_UNSAFE + lock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_input_port, NULL); if(omx_err != OMX_ErrorNone) @@ -439,6 +517,10 @@ void COMXCoreComponent::FlushInput() CLog::Log(LOGERROR, "COMXCoreComponent::FlushInput - %s WaitForCommand omx_err(0x%08x)", m_componentName.c_str(), (int)omx_err); } + +#ifdef OMX_THREAD_UNSAFE + unlock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE } void COMXCoreComponent::FlushOutput() @@ -448,6 +530,10 @@ void COMXCoreComponent::FlushOutput() OMX_ERRORTYPE omx_err = OMX_ErrorNone; +#ifdef OMX_THREAD_UNSAFE + lock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_output_port, NULL); if(omx_err != OMX_ErrorNone) @@ -461,6 +547,10 @@ void COMXCoreComponent::FlushOutput() CLog::Log(LOGERROR, "COMXCoreComponent::FlushOutput - %s WaitForCommand omx_err(0x%08x)", m_componentName.c_str(), (int)omx_err); } + +#ifdef OMX_THREAD_UNSAFE + unlock_mutex(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE } // timeout in milliseconds @@ -1189,10 +1279,18 @@ OMX_ERRORTYPE COMXCoreComponent::SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR co return omx_err; } -OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) const +OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) +#ifndef OMX_THREAD_UNSAFE + const +#endif // OMX_THREAD_UNSAFE { +#ifdef OMX_THREAD_UNSAFE + // lcarlon + QMutexLocker locker(&m_mxOmx); +#endif // OMX_THREAD_UNSAFE + if(!m_handle) - return OMX_ErrorUndefined; + return OMX_ErrorUndefined; OMX_ERRORTYPE omx_err; diff --git a/piomxtextures_src/omxplayer_lib/OMXCore.h b/piomxtextures_src/omxplayer_lib/OMXCore.h index d7761c0..85db721 100644 --- a/piomxtextures_src/omxplayer_lib/OMXCore.h +++ b/piomxtextures_src/omxplayer_lib/OMXCore.h @@ -33,6 +33,12 @@ #include +//#define OMX_THREAD_UNSAFE + +#ifdef OMX_THREAD_UNSAFE +#include +#endif // OMX_THREAD_UNSAFE + //////////////////////////////////////////////////////////////////////////////////////////// // debug spew defines #if 0 @@ -101,7 +107,12 @@ class COMXCoreComponent OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct); OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) const; OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct); - OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) const; + OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) +#ifdef OMX_THREAD_UNSAFE + ; +#else + const; +#endif // OMX_THREAD_UNSAFE OMX_ERRORTYPE SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdParam, OMX_PTR cmdParamData); OMX_ERRORTYPE EnablePort(unsigned int port, bool wait = true); OMX_ERRORTYPE DisablePort(unsigned int port, bool wait = true); @@ -163,6 +174,10 @@ class COMXCoreComponent void SetCustomDecoderFillBufferDoneHandler(OMX_ERRORTYPE (*p)(OMX_HANDLETYPE, OMX_PTR, OMX_BUFFERHEADERTYPE*)){ CustomDecoderFillBufferDoneHandler = p;}; void SetCustomDecoderEmptyBufferDoneHandler(OMX_ERRORTYPE (*p)(OMX_HANDLETYPE, OMX_PTR, OMX_BUFFERHEADERTYPE*)){ CustomDecoderEmptyBufferDoneHandler = p;}; +#ifdef OMX_THREAD_UNSAFE + static bool testOmx(); +#endif // OMX_THREAD_UNSAFE + private: OMX_HANDLETYPE m_handle; unsigned int m_input_port; @@ -208,6 +223,10 @@ class COMXCoreComponent bool m_flush_output; bool m_resource_error; +#ifdef OMX_THREAD_UNSAFE + static QMutex m_mxOmx; +#endif // OMX_THREAD_UNSAFE + // lcarlon: keep during merges. // lcarlon: this is needed as an hack. friend class COMXVideo; diff --git a/piomxtextures_src/omxplayer_lib/OMXPlayerVideo.cpp b/piomxtextures_src/omxplayer_lib/OMXPlayerVideo.cpp index cff39bd..ba6eb3c 100644 --- a/piomxtextures_src/omxplayer_lib/OMXPlayerVideo.cpp +++ b/piomxtextures_src/omxplayer_lib/OMXPlayerVideo.cpp @@ -34,7 +34,7 @@ #include "linux/XMemUtils.h" // lcarlon: keep during merges. -#include "lc_logging.h" +#include "omx_logging.h" #include "omx_textureprovider.h" #include "omx_videosurfaceelement.h" diff --git a/piomxtextures_src/omxplayer_lib/OMXVideo.cpp b/piomxtextures_src/omxplayer_lib/OMXVideo.cpp index bd2d983..d1dc0d2 100644 --- a/piomxtextures_src/omxplayer_lib/OMXVideo.cpp +++ b/piomxtextures_src/omxplayer_lib/OMXVideo.cpp @@ -41,7 +41,7 @@ #include #include -#include "lc_logging.h" +#include "omx_logging.h" #include "omx_videosurfaceelement.h" #include "omx_textureprovider.h" // === @@ -80,8 +80,14 @@ OMX_ERRORTYPE fill_buffer_done_callback(OMX_HANDLETYPE handle, OMX_PTR pAppData, OMX_EGLBufferProvider* provider = videoDecoder->m_provider.get(); assert(provider->registerFilledBuffer(pBuffer)); - // Get next empty buffer. - OMX_TextureData* empty = provider->getNextEmptyBuffer(); + // Get next empty buffer. It is possible none is returned when the provider + // was cleaned up. + OMX_TextureData* empty = provider->getNextEmptyBuffer(); + if (!empty) { + log_warn("Couldn't get an empty buffer."); + return OMX_ErrorNone; + } + return OMX_FillThisBuffer(handle, empty->m_omxBuffer); } @@ -314,9 +320,12 @@ bool COMXVideo::PortSettingsChanged() } else { - image_filter.nNumParams = 1; + image_filter.nNumParams = 4; image_filter.nParams[0] = 3; - if (!advanced_deinterlace) + image_filter.nParams[1] = 0; // Default frame interval. + image_filter.nParams[2] = OMX_StaticConf::getHalfFramerate(); // Half frame rate. + image_filter.nParams[3] = OMX_StaticConf::getInterlaceQpu(); // Use QPUs. + if (!advanced_deinterlace) image_filter.eImageFilter = OMX_ImageFilterDeInterlaceFast; else image_filter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; @@ -441,7 +450,7 @@ bool COMXVideo::Open(OMXClock *clock, const OMXVideoConfig &config) // re-use an existing one. For instance seek and restart may want to simply close and reopen // the video player without generating a new texture. QSize videoSize(m_config.hints.width, m_config.hints.height); - m_provider->instantiateTextures(videoSize, 4); + m_provider->instantiateTextures(videoSize); if(!m_config.hints.width || !m_config.hints.height) return false; @@ -943,7 +952,7 @@ bool COMXVideo::SetVideoEGL() { // Query output buffer requirements for renderer and provide the native display // the renderer will use. - LOG_DEBUG(LOG_TAG, "%s", Q_FUNC_INFO); + log_verbose_func; OMX_PARAM_PORTDEFINITIONTYPE portdef; portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); @@ -953,7 +962,7 @@ bool COMXVideo::SetVideoEGL() if (omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "Failed to get port definition for renderer output port."); - portdef.nBufferCountActual = 4; + portdef.nBufferCountActual = TEXTURE_COUNT; portdef.format.video.pNativeWindow = get_egl_display(); omx_err = m_omx_render.SetParameter(OMX_IndexParamPortDefinition, &portdef); if (omx_err != OMX_ErrorNone) diff --git a/piomxtextures_src/omxplayer_lib/OMXVideo.h b/piomxtextures_src/omxplayer_lib/OMXVideo.h index a0408bf..436ae54 100644 --- a/piomxtextures_src/omxplayer_lib/OMXVideo.h +++ b/piomxtextures_src/omxplayer_lib/OMXVideo.h @@ -38,6 +38,7 @@ #include "utils/SingleLock.h" #include "omx_textureprovider.h" +#include "omx_staticconf.h" using namespace std; @@ -76,20 +77,10 @@ class OMXVideoConfig OMXVideoConfig() { - EDEINTERLACEMODE mode = VS_DEINTERLACEMODE_OFF; - QByteArray ba = qgetenv("INTERLACE_MODE"); - - bool convOk; - int im = ba.toInt(&convOk); - if (convOk && im < 3 && im >= 0) - mode = (EDEINTERLACEMODE)im; - - log_verbose("Using deinterlace mode: %d.", mode); - use_thread = true; dst_rect.SetRect(0, 0, 0, 0); display_aspect = 0.0f; - deinterlace = mode; // lcarlon: keep this off + deinterlace = (EDEINTERLACEMODE)OMX_StaticConf::getInterlaceMode(); anaglyph = OMX_ImageFilterAnaglyphNone; hdmi_clock_sync = false; allow_mvc = false; diff --git a/piomxtextures_src/openmaxiltextureloader.cpp b/piomxtextures_src/openmaxiltextureloader.cpp index b111d13..49d2630 100644 --- a/piomxtextures_src/openmaxiltextureloader.cpp +++ b/piomxtextures_src/openmaxiltextureloader.cpp @@ -49,9 +49,10 @@ extern "C" { } #include -#include #include "omxtunnel.h" +#include "omx_logging.h" + /*---------------------------------------------------------------------- | definitions +---------------------------------------------------------------------*/ diff --git a/piomxtextures_src/piomxtextures_src.pri b/piomxtextures_src/piomxtextures_src.pri index a3a8d91..516219e 100644 --- a/piomxtextures_src/piomxtextures_src.pri +++ b/piomxtextures_src/piomxtextures_src.pri @@ -117,6 +117,9 @@ DEFINES += ENABLE_IMPROVED_BUFFERING # This enables logs coming from omxplayer core. #DEFINES += ENABLE_OMXPLAYER_LOGS +# Define this to enable watchdog. +#DEFINES += OMX_LOCK_WATCHDOG + # For omxplayer. QMAKE_CXXFLAGS += -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS \ -DTARGET_POSIX -D_LINUX -fPIC -DPIC -D_REENTRANT -D_LARGEFILE64_SOURCE \ @@ -173,7 +176,9 @@ SOURCES += \ $$SRC/omx_textureprovider.cpp \ $$SRC/omx_playeraudio.cpp \ $$SRC/omx_reader.cpp \ - $$SRC/ilclient/* + $$SRC/ilclient/* \ + $$SRC/omx_staticconf.cpp \ + $$SRC/omx_watchdog.cpp # This is the PiOmxTextures implementation of the logging class # in omxplayer. @@ -245,7 +250,9 @@ HEADERS += \ $$SRC/omx_playeraudio.h \ $$SRC/omx_reader.h \ $$SRC/ilclient/* \ - $$PWD/omx_logging.h + $$SRC/omx_logging.h \ + $$SRC/omx_staticconf.h \ + $$SRC/omx_watchdog.h HEADERS += \ $$SRC/omxplayer_lib/Unicode.h \ diff --git a/piomxtextures_tools/compile_ffmpeg.sh b/piomxtextures_tools/compile_ffmpeg.sh index 0b7da08..7a59ad3 100755 --- a/piomxtextures_tools/compile_ffmpeg.sh +++ b/piomxtextures_tools/compile_ffmpeg.sh @@ -297,7 +297,8 @@ if [ "$1" == "pi1" ]; then --enable-decoder=opus \ --cross-prefix=arm-linux-gnueabihf- \ --prefix=$PWD/ffmpeg_compiled \ ---disable-symver +--disable-symver \ +--pkg-config=pkg-config else ./configure \ --sysroot=$RPI_SYSROOT \ @@ -525,7 +526,8 @@ else --enable-decoder=opus \ --cross-prefix=arm-linux-gnueabihf- \ --prefix=$PWD/ffmpeg_compiled \ ---disable-symver +--disable-symver \ +--pkg-config=pkg-config fi echo "Building..." diff --git a/piomxtextures_tools/notes_icu.txt b/piomxtextures_tools/notes_icu.txt new file mode 100644 index 0000000..cb5e6b5 --- /dev/null +++ b/piomxtextures_tools/notes_icu.txt @@ -0,0 +1,25 @@ + 7661 svn export http://source.icu-project.org/repos/icu/icu/tags/release-55-1 + 7662 mkdir build_icu_linux + 7663 cd build_icu_linux/ + 7664 sh $ICU_SOURCES/source/runConfigureICU Linux --prefix=$PWD/icu_build + 7665 make -j10 + 7666 make install + 7667 cd .. + 7668 mkdir build_icu_rpi + 7669 cd build_icu_rpi/ + 7670 ls -lh + 7671 export CPPFLAGS="-O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=1 -fno-short-enums -pipe -march=armv6j -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard" + 7672 export CFLAGS=CPPFLAGS + 7673 export PATH=/opt/rpi/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH + 7674 $ICU_SOURCES/source/configure --with-cross-build=~/project/pi/icu/build_icu_rpi/build_icu_linux --enable-shared --host=arm-linux-gnueabihf --prefix=$PWD/icu_build + 7675 cat config.log + 7676 export CFLAGS=$CPPFLAGS + 7677 $ICU_SOURCES/source/configure --with-cross-build=~/project/pi/icu/build_icu_rpi/build_icu_linux --enable-shared --host=arm-linux-gnueabihf --prefix=$PWD/icu_build + 7678 $ICU_SOURCES/source/configure --with-cross-build=/home/luca/project/pi/icu/build_icu_rpi/build_icu_linux --enable-shared --host=arm-linux-gnueabihf --prefix=$PWD/icu_build + 7679 $ICU_SOURCES/source/configure --with-cross-build=/home/luca/project/pi/icu/build_icu_linux --enable-shared --host=arm-linux-gnueabihf --prefix=$PWD/icu_build + 7680 make -j8 + 7681 make install + 7682 cd icu_build/ + 7683 grep -R ucol_open_55 * + 7684 ls -lh + 7685 rsync -chavzP --stats * pi@192.168.1.243:/home/pi/qtdeps diff --git a/piomxtextures_tools/prepare_3rdparty.sh b/piomxtextures_tools/prepare_3rdparty.sh index 5bb7753..fb4dbf2 100755 --- a/piomxtextures_tools/prepare_3rdparty.sh +++ b/piomxtextures_tools/prepare_3rdparty.sh @@ -1,7 +1,7 @@ #!/bin/bash function show_help { - echo "Usage: prepare_3rdparty.sh " + echo "Usage: prepare_3rdparty.sh pi1|pi2" exit 0 }