Files
recycled-ni-neutrino/src/gui/movieplayer.cpp
Stefan Seyfried ef71d00d7f remove "using namespace std" from header files
"using namespace std" in headers is considered bad practice, so move it
either into the respective cpp files or (for files which have lots of
other std::xxx usage anyway) just write it out explicitly.
Looking at the headers and the affected cpp files, one can actually see
why it is bad practice, as it's spreading very far ;-)


Origin commit data
------------------
Branch: ni/coolstream
Commit: 0d9139054a
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2017-10-01 (Sun, 01 Oct 2017)



------------------
This commit was generated by Migit
2017-10-02 13:43:57 +02:00

2845 lines
87 KiB
C++

/*
Neutrino-GUI - DBoxII-Project
Movieplayer (c) 2003, 2004 by gagga
Based on code by Dirch, obi and the Metzler Bros. Thanks.
Copyright (C) 2011 CoolStream International Ltd
License: GPL
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 of the License, 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include <global.h>
#include <neutrino.h>
#include <gui/audiomute.h>
#include <gui/audio_select.h>
#include <gui/epgview.h>
#include <gui/eventlist.h>
#include <gui/movieplayer.h>
#include <gui/osd_helpers.h>
#include <gui/infoviewer.h>
#include <gui/timeosd.h>
#include <gui/widget/helpbox.h>
#include <gui/infoclock.h>
#include <gui/plugins.h>
#include <gui/videosettings.h>
#include <gui/streaminfo2.h>
#include <gui/lua/luainstance.h>
#include <gui/lua/lua_video.h>
#include <gui/screensaver.h>
#include <driver/screenshot.h>
#include <driver/volume.h>
#include <driver/display.h>
#include <driver/abstime.h>
#include <driver/record.h>
#include <driver/fontrenderer.h>
#include <eitd/edvbstring.h>
#include <system/helpers.h>
#include <system/helpers-json.h>
#include <src/mymenu.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <sys/mount.h>
#include <json/json.h>
#include <video.h>
#include <libtuxtxt/teletext.h>
#include <zapit/zapit.h>
#include <system/set_threadname.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <iconv.h>
#include <system/stacktrace.h>
extern cVideo * videoDecoder;
extern CRemoteControl *g_RemoteControl; /* neutrino.cpp */
extern CVolume* g_volume;
extern CTimeOSD *FileTimeOSD;
#define TIMESHIFT_SECONDS 3
#define ISO_MOUNT_POINT "/media/iso"
#define MUTE true
#define NO_MUTE false
CMoviePlayerGui* CMoviePlayerGui::instance_mp = NULL;
CMoviePlayerGui* CMoviePlayerGui::instance_bg = NULL;
OpenThreads::Mutex CMoviePlayerGui::mutex;
OpenThreads::Mutex CMoviePlayerGui::bgmutex;
OpenThreads::Condition CMoviePlayerGui::cond;
pthread_t CMoviePlayerGui::bgThread;
cPlayback *CMoviePlayerGui::playback;
bool CMoviePlayerGui::webtv_started;
CMovieBrowser* CMoviePlayerGui::moviebrowser;
CBookmarkManager * CMoviePlayerGui::bookmarkmanager;
CMoviePlayerGui& CMoviePlayerGui::getInstance(bool background)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
if (!instance_mp )
{
instance_mp = new CMoviePlayerGui();
instance_bg = new CMoviePlayerGui();
printf("[neutrino CMoviePlayerGui] Instance created...\n");
}
return background ? *instance_bg : *instance_mp;
}
CMoviePlayerGui::CMoviePlayerGui()
{
Init();
}
CMoviePlayerGui::~CMoviePlayerGui()
{
if (this == instance_mp)
stopPlayBack();
if(moviebrowser){
delete moviebrowser;
moviebrowser = NULL;
}
if(filebrowser){
delete filebrowser;
filebrowser = NULL;
}
if(bookmarkmanager){
delete bookmarkmanager;
bookmarkmanager = NULL;
}
if(playback){
delete playback;
playback = NULL;
}
if (this == instance_mp) {
delete instance_bg;
instance_bg = NULL;
}
instance_mp = NULL;
}
void CMoviePlayerGui::Init(void)
{
playing = false;
stopped = true;
currentVideoSystem = -1;
currentOsdResolution = 0;
frameBuffer = CFrameBuffer::getInstance();
if (playback == NULL)
playback = new cPlayback(0);
if (moviebrowser == NULL)
moviebrowser = new CMovieBrowser();
if (bookmarkmanager == NULL)
bookmarkmanager = new CBookmarkManager();
tsfilefilter.addFilter("ts");
tsfilefilter.addFilter("avi");
tsfilefilter.addFilter("mkv");
tsfilefilter.addFilter("wav");
tsfilefilter.addFilter("asf");
tsfilefilter.addFilter("aiff");
tsfilefilter.addFilter("mpg");
tsfilefilter.addFilter("mpeg");
tsfilefilter.addFilter("m2p");
tsfilefilter.addFilter("mpv");
tsfilefilter.addFilter("vob");
tsfilefilter.addFilter("m2ts");
tsfilefilter.addFilter("mp4");
tsfilefilter.addFilter("mov");
tsfilefilter.addFilter("m3u");
tsfilefilter.addFilter("m3u8");
tsfilefilter.addFilter("pls");
tsfilefilter.addFilter("iso");
if (g_settings.network_nfs_moviedir.empty())
Path_local = "/";
else
Path_local = g_settings.network_nfs_moviedir;
if (g_settings.filebrowser_denydirectoryleave)
filebrowser = new CFileBrowser(Path_local.c_str());
else
filebrowser = new CFileBrowser();
filebrowser->Filter = &tsfilefilter;
filebrowser->Hide_records = true;
filebrowser->Multi_Select = true;
filebrowser->Dirs_Selectable = true;
speed = 1;
timeshift = TSHIFT_MODE_OFF;
numpida = 0;
showStartingHint = false;
min_x = 0;
max_x = 0;
min_y = 0;
max_y = 0;
ext_subs = false;
iso_file = false;
lock_subs = false;
bgThread = 0;
info_1 = "";
info_2 = "";
filelist_it = filelist.end();
vzap_it = filelist_it;
fromInfoviewer = false;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_NORMAL;
isLuaPlay = false;
haveLuaInfoFunc = false;
blockedFromPlugin = false;
m_screensaver = false;
m_idletime = time(NULL);
}
void CMoviePlayerGui::cutNeutrino()
{
printf("%s: playing %d isUPNP %d\n", __func__, playing, isUPNP);
if (playing)
return;
#ifdef ENABLE_CHANGE_OSD_RESOLUTION
COsdHelpers *coh = COsdHelpers::getInstance();
currentVideoSystem = coh->getVideoSystem();
currentOsdResolution = coh->getOsdResolution();
#endif
playing = true;
/* set g_InfoViewer update timer to 1 sec, should be reset to default from restoreNeutrino->set neutrino mode */
if (!isWebTV)
g_InfoViewer->setUpdateTimer(1000 * 1000);
if (isUPNP)
return;
g_Zapit->lockPlayBack();
m_LastMode = (CNeutrinoApp::getInstance()->getMode() /*| NeutrinoMessages::norezap*/);
if (isWebTV)
m_LastMode |= NeutrinoMessages::norezap;
printf("%s: save mode %x\n", __func__, m_LastMode);fflush(stdout);
int new_mode = NeutrinoMessages::norezap | (isWebTV ? NeutrinoMessages::mode_webtv : NeutrinoMessages::mode_ts);
CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, new_mode);
}
void CMoviePlayerGui::restoreNeutrino()
{
printf("%s: playing %d isUPNP %d\n", __func__, playing, isUPNP);
if (!playing)
return;
#ifdef ENABLE_CHANGE_OSD_RESOLUTION
if ((currentVideoSystem > -1) &&
(g_settings.video_Mode == VIDEO_STD_AUTO) &&
(g_settings.enabled_auto_modes[currentVideoSystem] == 1)) {
COsdHelpers *coh = COsdHelpers::getInstance();
if (currentVideoSystem != coh->getVideoSystem()) {
coh->setVideoSystem(currentVideoSystem, false);
coh->changeOsdResolution(currentOsdResolution, false, true);
}
currentVideoSystem = -1;
}
#endif
playing = false;
if (isUPNP)
return;
//g_Zapit->unlockPlayBack();
CZapit::getInstance()->EnablePlayback(true);
printf("%s: restore mode %x\n", __func__, m_LastMode);fflush(stdout);
#if 0
if (m_LastMode == NeutrinoMessages::mode_tv)
g_RCInput->postMsg(NeutrinoMessages::EVT_PROGRAMLOCKSTATUS, 0x200, false);
#endif
if (m_LastMode != NeutrinoMessages::mode_unknown)
CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE, m_LastMode);
#if 0
if (m_LastMode == NeutrinoMessages::mode_tv) {
CZapitChannel *channel = CZapit::getInstance()->GetCurrentChannel();
if (channel && channel->scrambled)
CZapit::getInstance()->Rezap();
}
#endif
printf("%s: restoring done.\n", __func__);fflush(stdout);
}
int CMoviePlayerGui::exec(CMenuTarget * parent, const std::string & actionKey)
{
printf("[movieplayer] actionKey=%s\n", actionKey.c_str());
if (parent)
parent->hide();
puts("[movieplayer.cpp] executing " MOVIEPLAYER_START_SCRIPT ".");
if (my_system(MOVIEPLAYER_START_SCRIPT) != 0)
perror(MOVIEPLAYER_START_SCRIPT " failed");
Cleanup();
ClearFlags();
ClearQueue();
FileTimeOSD->kill();
FileTimeOSD->setMode(CTimeOSD::MODE_HIDE);
FileTimeOSD->setMpTimeForced(false);
time_forced = false;
if (actionKey == "tsmoviebrowser") {
isMovieBrowser = true;
moviebrowser->setMode(MB_SHOW_RECORDS);
}
else if (actionKey == "ytplayback") {
isMovieBrowser = true;
moviebrowser->setMode(MB_SHOW_YT);
isYT = true;
}
else if (actionKey == "fileplayback") {
}
else if (actionKey == "timeshift") {
timeshift = TSHIFT_MODE_ON;
}
else if (actionKey == "ptimeshift") {
timeshift = TSHIFT_MODE_PAUSE;
}
else if (actionKey == "rtimeshift") {
timeshift = TSHIFT_MODE_REWIND;
}
#if 0 // TODO ?
else if (actionKey == "bookmarkplayback") {
isBookmark = true;
}
#endif
else if (actionKey == "upnp") {
isUPNP = true;
is_file_player = true;
PlayFile();
}
else if (actionKey == "http") {
isHTTP = true;
is_file_player = true;
PlayFile();
}
else if (actionKey == "http_lua") {
isHTTP = true;
isLuaPlay = true;
is_file_player = true;
PlayFile();
haveLuaInfoFunc = false;
}
else {
return menu_return::RETURN_REPAINT;
}
while(!isHTTP && !isUPNP && SelectFile()) {
if (timeshift != TSHIFT_MODE_OFF) {
PlayFile();
break;
}
do {
PlayFile();
}
while (repeat_mode || filelist_it != filelist.end());
}
bookmarkmanager->flush();
puts("[movieplayer.cpp] executing " MOVIEPLAYER_END_SCRIPT ".");
if (my_system(MOVIEPLAYER_END_SCRIPT) != 0)
perror(MOVIEPLAYER_END_SCRIPT " failed");
CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO);
if (timeshift != TSHIFT_MODE_OFF){
timeshift = TSHIFT_MODE_OFF;
return menu_return::RETURN_EXIT_ALL;
}
return menu_ret;
}
void CMoviePlayerGui::updateLcd()
{
char tmp[20];
std::string lcd;
std::string name;
if (isMovieBrowser && p_movie_info && !p_movie_info->epgTitle.empty() && p_movie_info->epgTitle.size() && strncmp(p_movie_info->epgTitle.c_str(), "not", 3))
name = p_movie_info->epgTitle;
else
name = pretty_name;
switch (playstate) {
case CMoviePlayerGui::PAUSE:
if (speed < 0) {
sprintf(tmp, "%dx<| ", abs(speed));
lcd = tmp;
} else if (speed > 0) {
sprintf(tmp, "%dx|> ", abs(speed));
lcd = tmp;
} else
lcd = "|| ";
break;
case CMoviePlayerGui::REW:
sprintf(tmp, "%dx<< ", abs(speed));
lcd = tmp;
break;
case CMoviePlayerGui::FF:
sprintf(tmp, "%dx>> ", abs(speed));
lcd = tmp;
break;
case CMoviePlayerGui::PLAY:
lcd = "> ";
break;
default:
break;
}
lcd += name;
CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8);
CVFD::getInstance()->showMenuText(0, lcd.c_str(), -1, true);
}
void CMoviePlayerGui::fillPids()
{
if (p_movie_info == NULL)
return;
vpid = p_movie_info->VideoPid;
vtype = p_movie_info->VideoType;
numpida = 0; currentapid = 0;
/* FIXME: better way to detect TS recording */
if (!p_movie_info->audioPids.empty()) {
currentapid = p_movie_info->audioPids[0].AudioPid;
currentac3 = p_movie_info->audioPids[0].atype;
} else if (!vpid) {
is_file_player = true;
return;
}
for (int i = 0; i < (int)p_movie_info->audioPids.size(); i++) {
apids[i] = p_movie_info->audioPids[i].AudioPid;
ac3flags[i] = p_movie_info->audioPids[i].atype;
numpida++;
if (p_movie_info->audioPids[i].selected) {
currentapid = p_movie_info->audioPids[i].AudioPid;
currentac3 = p_movie_info->audioPids[i].atype;
}
}
}
void CMoviePlayerGui::Cleanup()
{
for (int i = 0; i < numpida; i++) {
apids[i] = 0;
ac3flags[i] = 0;
language[i].clear();
}
numpida = 0; currentapid = 0;
currentspid = -1;
numsubs = 0;
vpid = 0;
vtype = 0;
startposition = -1;
is_file_player = false;
p_movie_info = NULL;
autoshot_done = false;
currentaudioname = "Unk";
}
void CMoviePlayerGui::ClearFlags()
{
isMovieBrowser = false;
isBookmark = false;
isHTTP = false;
isLuaPlay = false;
isUPNP = false;
isWebTV = false;
isYT = false;
is_file_player = false;
timeshift = TSHIFT_MODE_OFF;
}
void CMoviePlayerGui::ClearQueue()
{
repeat_mode = REPEAT_OFF;
filelist.clear();
filelist_it = filelist.end();
milist.clear();
}
void CMoviePlayerGui::enableOsdElements(bool mute)
{
if (mute)
CAudioMute::getInstance()->enableMuteIcon(true);
CInfoClock::getInstance()->enableInfoClock(true);
}
void CMoviePlayerGui::disableOsdElements(bool mute)
{
if (mute)
CAudioMute::getInstance()->enableMuteIcon(false);
CInfoClock::getInstance()->enableInfoClock(false);
}
void CMoviePlayerGui::makeFilename()
{
if (pretty_name.empty()) {
std::string::size_type pos = file_name.find_last_of('/');
if (pos != std::string::npos) {
pretty_name = file_name.substr(pos+1);
std::replace(pretty_name.begin(), pretty_name.end(), '_', ' ');
} else
pretty_name = file_name;
if (pretty_name.substr(0,14)=="videoplayback?") {//youtube name
if (!p_movie_info->epgTitle.empty())
pretty_name = p_movie_info->epgTitle;
else
pretty_name = "";
}
printf("CMoviePlayerGui::makeFilename: file_name [%s] pretty_name [%s]\n", file_name.c_str(), pretty_name.c_str());
}
}
bool CMoviePlayerGui::prepareFile(CFile *file)
{
bool ret = true;
numpida = 0; currentapid = 0;
currentspid = -1;
numsubs = 0;
autoshot_done = 0;
if (file->Url.empty())
file_name = file->Name;
else {
file_name = file->Url;
pretty_name = file->Name;
}
if (isMovieBrowser) {
if (filelist_it != filelist.end()) {
unsigned idx = filelist_it - filelist.begin();
if(milist.size() > idx){
p_movie_info = milist[idx];
startposition = p_movie_info->bookmarks.start > 0 ? p_movie_info->bookmarks.start*1000 : -1;
printf("CMoviePlayerGui::prepareFile: file %s start %d\n", file_name.c_str(), startposition);
}
}
if (isYT) {
file_name = file->Url;
is_file_player = true;
}
fillPids();
}
if (file->getType() == CFile::FILE_ISO)
ret = mountIso(file);
//else if (file->getType() == CFile::FILE_PLAYLIST)
//parsePlaylist(file);
if (ret)
makeFilename();
return ret;
}
bool CMoviePlayerGui::SelectFile()
{
bool ret = false;
menu_ret = menu_return::RETURN_REPAINT;
Cleanup();
info_1 = "";
info_2 = "";
pretty_name.clear();
file_name.clear();
cookie_header.clear();
//reinit Path_local for webif reloadsetup
if (g_settings.network_nfs_moviedir.empty())
Path_local = "/";
else
Path_local = g_settings.network_nfs_moviedir;
printf("CMoviePlayerGui::SelectFile: isBookmark %d timeshift %d isMovieBrowser %d\n", isBookmark, timeshift, isMovieBrowser);
wakeup_hdd(g_settings.network_nfs_recordingdir.c_str());
if (timeshift != TSHIFT_MODE_OFF) {
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
p_movie_info = CRecordManager::getInstance()->GetMovieInfo(live_channel_id);
file_name = CRecordManager::getInstance()->GetFileName(live_channel_id) + ".ts";
fillPids();
makeFilename();
ret = true;
}
#if 0 // TODO
else if (isBookmark) {
const CBookmark * theBookmark = bookmarkmanager->getBookmark(NULL);
if (theBookmark == NULL) {
bookmarkmanager->flush();
return false;
}
file_name = theBookmark->getUrl();
sscanf(theBookmark->getTime(), "%lld", &startposition);
startposition *= 1000;
ret = true;
}
#endif
else if (isMovieBrowser) {
disableOsdElements(MUTE);
if (moviebrowser->exec(Path_local.c_str())) {
Path_local = moviebrowser->getCurrentDir();
CFile *file = NULL;
filelist_it = filelist.end();
if (moviebrowser->getSelectedFiles(filelist, milist)) {
filelist_it = filelist.begin();
p_movie_info = *(milist.begin());
// file = &(*filelist_it);
}
else if ((file = moviebrowser->getSelectedFile()) != NULL) {
p_movie_info = moviebrowser->getCurrentMovieInfo();
startposition = 1000 * moviebrowser->getCurrentStartPos();
printf("CMoviePlayerGui::SelectFile: file %s start %d apid %X atype %d vpid %x vtype %d\n", file_name.c_str(), startposition, currentapid, currentac3, vpid, vtype);
}
if (p_movie_info)
ret = prepareFile(&p_movie_info->file);
} else
menu_ret = moviebrowser->getMenuRet();
enableOsdElements(MUTE);
} else { // filebrowser
disableOsdElements(MUTE);
while (ret == false && filebrowser->exec(Path_local.c_str()) == true) {
Path_local = filebrowser->getCurrentDir();
CFile *file = NULL;
filelist = filebrowser->getSelectedFiles();
filelist_it = filelist.end();
if (!filelist.empty()) {
filelist_it = filelist.begin();
file = &(*filelist_it);
}
if (file) {
is_file_player = true;
if (file->getType() == CFile::FILE_PLAYLIST)
parsePlaylist(file);
if (!filelist.empty()) {
filelist_it = filelist.begin();
file = &(*filelist_it);
}
ret = prepareFile(file);
}
}
menu_ret = filebrowser->getMenuRet();
enableOsdElements(MUTE);
}
g_settings.network_nfs_moviedir = Path_local;
return ret;
}
void *CMoviePlayerGui::ShowStartHint(void *arg)
{
set_threadname(__func__);
CMoviePlayerGui *caller = (CMoviePlayerGui *)arg;
CHintBox *hintbox = NULL;
if (!caller->pretty_name.empty()) {
hintbox = new CHintBox(LOCALE_MOVIEPLAYER_STARTING, caller->pretty_name.c_str(), 450, NEUTRINO_ICON_MOVIEPLAYER);
hintbox->paint();
}
while (caller->showStartingHint) {
neutrino_msg_t msg;
neutrino_msg_data_t data;
g_RCInput->getMsg(&msg, &data, 1);
if (msg == CRCInput::RC_home || msg == CRCInput::RC_stop) {
caller->playback->RequestAbort();
}
#if 0
else if (caller->isWebTV) {
CNeutrinoApp::getInstance()->handleMsg(msg, data);
}
#endif
else if (caller->isWebTV && ((msg == (neutrino_msg_t) g_settings.key_quickzap_up ) || (msg == (neutrino_msg_t) g_settings.key_quickzap_down))) {
caller->playback->RequestAbort();
g_RCInput->postMsg(msg, data);
}
else if (msg != NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE && msg != CRCInput::RC_timeout && msg > CRCInput::RC_MaxRC) {
CNeutrinoApp::getInstance()->handleMsg(msg, data);
}
else if ((msg>= CRCInput::RC_WithData) && (msg< CRCInput::RC_WithData+ 0x10000000))
delete[] (unsigned char*) data;
}
if (hintbox != NULL) {
hintbox->hide();
delete hintbox;
}
return NULL;
}
bool CMoviePlayerGui::StartWebtv(void)
{
printf("%s: starting...\n", __func__);fflush(stdout);
last_read = position = duration = 0;
cutNeutrino();
clearSubtitle();
playback->Open(is_file_player ? PLAYMODE_FILE : PLAYMODE_TS);
bool res = playback->Start((char *) file_name.c_str(), cookie_header);//url with cookies
playback->SetSpeed(1);
if (!res) {
playback->Close();
} else {
getCurrentAudioName(is_file_player, currentaudioname);
if (is_file_player)
selectAutoLang();
}
return res;
}
void* CMoviePlayerGui::bgPlayThread(void *arg)
{
set_threadname(__func__);
CMoviePlayerGui *mp = (CMoviePlayerGui *) arg;
printf("%s: starting... instance %p\n", __func__, mp);fflush(stdout);
int eof = 0, pos = 0;
unsigned char *chid = new unsigned char[sizeof(t_channel_id)];
*(t_channel_id*)chid = mp->movie_info.channelId;
bool started = mp->StartWebtv();
printf("%s: started: %d\n", __func__, started);fflush(stdout);
bool chidused = false;
mutex.lock();
if (!webtv_started)
started = false;
else if (!started){
g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_FAILED, (neutrino_msg_data_t) chid);
chidused = true;
}
webtv_started = started;
mutex.unlock();
while(webtv_started) {
if (mp->playback->GetPosition(mp->position, mp->duration)) {
#if 0
printf("CMoviePlayerGui::bgPlayThread: position %d duration %d (%d)\n", mp->position, mp->duration, mp->duration-mp->position);
#endif
if (pos == mp->position)
eof++;
else
eof = 0;
if (eof > 5) {
printf("CMoviePlayerGui::bgPlayThread: playback stopped, try to rezap...\n");
g_RCInput->postMsg(NeutrinoMessages::EVT_WEBTV_ZAP_COMPLETE, (neutrino_msg_data_t) chid);
chidused = true;
break;
}
pos = mp->position;
}
bgmutex.lock();
int res = cond.wait(&bgmutex, 1000);
bgmutex.unlock();
if (res == 0)
break;
mp->showSubtitle(0);
}
printf("%s: play end...\n", __func__);fflush(stdout);
mp->PlayFileEnd();
if(!chidused)
delete [] chid;
pthread_exit(NULL);
}
bool CMoviePlayerGui::sortStreamList(livestream_info_t info1, livestream_info_t info2)
{
return (info1.res1 < info2.res1);
}
bool CMoviePlayerGui::luaGetUrl(const std::string &script, const std::string &file, std::vector<livestream_info_t> &streamList)
{
CHintBox* box = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_LIVESTREAM_READ_DATA));
box->paint();
std::string result_code = "";
std::string result_string = "";
std::vector<std::string> args;
args.push_back(file);
#ifdef ENABLE_LUA
CLuaInstance *lua = new CLuaInstance();
lua->runScript(script.c_str(), &args, &result_code, &result_string);
delete lua;
#endif
if ((result_code != "0") || result_string.empty()) {
if (box != NULL) {
box->hide();
delete box;
}
return false;
}
std::string errMsg = "";
Json::Value root;
bool ok = parseJsonFromString(result_string, &root, &errMsg);
if (!ok) {
printf("Failed to parse JSON\n");
printf("%s\n", errMsg.c_str());
if (box != NULL) {
box->hide();
delete box;
}
return false;
}
livestream_info_t info;
std::string tmp;
bool haveurl = false;
if ( !root.isObject() ) {
for (Json::Value::iterator it = root.begin(); it != root.end(); ++it) {
info.url=""; info.name=""; info.header=""; info.bandwidth = 1; info.resolution=""; info.res1 = 1;
tmp = "0";
Json::Value object_it = *it;
for (Json::Value::iterator iti = object_it.begin(); iti != object_it.end(); iti++) {
std::string name = iti.name();
if (name=="url") {
info.url = (*iti).asString();
haveurl = true;
} else if (name=="name") {
info.name = (*iti).asString();
}
else if (name=="header") {
info.header = (*iti).asString();
}
else if (name=="band") {
info.bandwidth = atoi((*iti).asString().c_str());
} else if (name=="res1") {
tmp = (*iti).asString();
info.res1 = atoi(tmp.c_str());
} else if (name=="res2") {
info.resolution = tmp + "x" + (*iti).asString();
}
}
if (haveurl) {
streamList.push_back(info);
}
haveurl = false;
}
}
if (root.isObject()) {
for (Json::Value::iterator it = root.begin(); it != root.end(); ++it) {
info.url=""; info.name=""; info.header=""; info.bandwidth = 1; info.resolution=""; info.res1 = 1;
tmp = "0";
std::string name = it.name();
if (name=="url") {
info.url = (*it).asString();
haveurl = true;
} else if (name=="name") {
info.name = (*it).asString();
} else if (name=="header") {
info.header = (*it).asString();
} else if (name=="band") {
info.bandwidth = atoi((*it).asString().c_str());
} else if (name=="res1") {
tmp = (*it).asString();
info.res1 = atoi(tmp.c_str());
} else if (name=="res2") {
info.resolution = tmp + "x" + (*it).asString();
}
}
if (haveurl) {
streamList.push_back(info);
}
}
/* sort streamlist */
std::sort(streamList.begin(), streamList.end(), sortStreamList);
/* remove duplicate resolutions */
livestream_info_t *_info;
int res_old = 0;
for (size_t i = 0; i < streamList.size(); ++i) {
_info = &(streamList[i]);
if (res_old == _info->res1)
streamList.erase(streamList.begin()+i);
res_old = _info->res1;
}
if (box != NULL) {
box->hide();
delete box;
}
return true;
}
bool CMoviePlayerGui::selectLivestream(std::vector<livestream_info_t> &streamList, int res, livestream_info_t* info)
{
livestream_info_t* _info;
int _res = res;
#if 0
printf("\n");
for (size_t i = 0; i < streamList.size(); ++i) {
_info = &(streamList[i]);
printf("%d - _info->res1: %4d, _info->res: %9s, _info->bandwidth: %d\n", i, _info->res1, (_info->resolution).c_str(), _info->bandwidth);
}
printf("\n");
#endif
bool resIO = false;
while (!streamList.empty()) {
size_t i;
for (i = 0; i < streamList.size(); ++i) {
_info = &(streamList[i]);
if (_info->res1 == _res) {
info->url = _info->url;
info->name = _info->name;
info->header = _info->header;
info->resolution = _info->resolution;
info->res1 = _info->res1;
info->bandwidth = _info->bandwidth;
return true;
}
}
/* Required resolution not found, decreasing resolution */
for (i = streamList.size(); i > 0; --i) {
_info = &(streamList[i-1]);
if (_info->res1 < _res) {
_res = _info->res1;
resIO = true;
break;
}
}
/* Required resolution not found, increasing resolution */
if (resIO == false) {
for (i = 0; i < streamList.size(); ++i) {
_info = &(streamList[i]);
if (_info->res1 > _res) {
_res = _info->res1;
break;
}
}
}
}
return false;
}
bool CMoviePlayerGui::getLiveUrl(const std::string &url, const std::string &script, std::string &realUrl, std::string &_pretty_name, std::string &info1, std::string &info2, std::string &header)
{
std::vector<livestream_info_t> liveStreamList;
livestream_info_t info;
if (script.empty()) {
realUrl = url;
return true;
}
std::string _script = script;
if (_script.find("/") == std::string::npos)
_script = g_settings.livestreamScriptPath + "/" + _script;
size_t pos = _script.find(".lua");
if (!file_exists(_script.c_str()) || (pos == std::string::npos) || (_script.length()-pos != 4)) {
printf(">>>>> [%s:%s:%d] script error\n", __file__, __func__, __LINE__);
return false;
}
if (!luaGetUrl(_script, url, liveStreamList)) {
printf(">>>>> [%s:%s:%d] lua script error\n", __file__, __func__, __LINE__);
return false;
}
if (!selectLivestream(liveStreamList, g_settings.livestreamResolution, &info)) {
printf(">>>>> [%s:%s:%d] error selectLivestream\n", __file__, __func__, __LINE__);
return false;
}
realUrl = info.url;
if (!info.name.empty()) {
info1 = info.name;
_pretty_name = info.name;
}
if (!info.header.empty()) {
header = info.header;
}
#if 0
if (!info.resolution.empty())
info2 = info.resolution;
if (info.bandwidth > 0) {
char buf[32];
memset(buf, '\0', sizeof(buf));
snprintf(buf, sizeof(buf), "%.02f kbps", (float)((float)info.bandwidth/(float)1000));
info2 += (std::string)", " + (std::string)buf;
}
#else
if (info.bandwidth > 0) {
char buf[32];
memset(buf, '\0', sizeof(buf));
snprintf(buf, sizeof(buf), "%.02f kbps", (float)((float)info.bandwidth/(float)1000));
info2 = (std::string)buf;
}
#endif
return true;
}
bool CMoviePlayerGui::PlayBackgroundStart(const std::string &file, const std::string &name, t_channel_id chan, const std::string &script)
{
printf("%s: starting...\n", __func__);fflush(stdout);
static CZapProtection *zp = NULL;
if (zp)
return true;
if (g_settings.parentallock_prompt != PARENTALLOCK_PROMPT_NEVER) {
int age = -1;
const char *ages[] = { "18+", "16+", "12+", "6+", "0+", NULL };
int agen[] = { 18, 16, 12, 6, 0 };
for (int i = 0; ages[i] && age < 0; i++) {
const char *n = name.c_str();
const char *h = n;
while ((age < 0) && (h = strstr(h, ages[i])))
if ((h == n) || !isdigit(*(h - 1)))
age = agen[i];
}
if (age > -1 && age >= g_settings.parentallock_lockage && g_settings.parentallock_prompt != PARENTALLOCK_PROMPT_NEVER) {
zp = new CZapProtection(g_settings.parentallock_pincode, age);
bool unlocked = zp->check();
delete zp;
zp = NULL;
if (!unlocked)
return false;
} else {
CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(chan);
if (channel && channel->Locked() != g_settings.parentallock_defaultlocked && !CNeutrinoApp::getInstance()->channelList->checkLockStatus(0x100))
return false;
}
}
std::string realUrl;
std::string _pretty_name = name;
cookie_header.clear();
if (!getLiveUrl(file, script, realUrl, _pretty_name, livestreamInfo1, livestreamInfo2, cookie_header)) {
return false;
}
instance_bg->Cleanup();
instance_bg->ClearFlags();
instance_bg->ClearQueue();
instance_bg->isWebTV = true;
instance_bg->is_file_player = true;
instance_bg->isHTTP = true;
instance_bg->file_name = realUrl;
instance_bg->pretty_name = _pretty_name;
instance_bg->cookie_header = cookie_header;
instance_bg->movie_info.epgTitle = name;
instance_bg->movie_info.channelName = realUrl;
instance_bg->movie_info.channelId = chan;
instance_bg->p_movie_info = &movie_info;
stopPlayBack();
webtv_started = true;
if (pthread_create (&bgThread, 0, CMoviePlayerGui::bgPlayThread, instance_bg)) {
printf("ERROR: pthread_create(%s)\n", __func__);
webtv_started = false;
return false;
}
printf("%s: this %p started, thread %lx\n", __func__, this, bgThread);fflush(stdout);
return true;
}
void CMoviePlayerGui::stopPlayBack(void)
{
printf("%s: stopping...\n", __func__);
//playback->RequestAbort();
repeat_mode = REPEAT_OFF;
if (bgThread) {
printf("%s: this %p join background thread %lx\n", __func__, this, bgThread);fflush(stdout);
mutex.lock();
webtv_started = false;
if(playback)
playback->RequestAbort();
mutex.unlock();
cond.broadcast();
pthread_join(bgThread, NULL);
bgThread = 0;
livestreamInfo1.clear();
livestreamInfo2.clear();
}
printf("%s: stopped\n", __func__);
}
void CMoviePlayerGui::Pause(bool b)
{
if (b && (playstate == CMoviePlayerGui::PAUSE))
b = !b;
if (b) {
playback->SetSpeed(0);
playstate = CMoviePlayerGui::PAUSE;
} else {
playback->SetSpeed(1);
playstate = CMoviePlayerGui::PLAY;
}
}
void CMoviePlayerGui::PlayFile(void)
{
PlayFileStart();
PlayFileLoop();
bool repeat = (repeat_mode == REPEAT_OFF);
if (isLuaPlay)
repeat = (!blockedFromPlugin);
PlayFileEnd(repeat);
}
bool CMoviePlayerGui::PlayFileStart(void)
{
menu_ret = menu_return::RETURN_REPAINT;
FileTimeOSD->setMpTimeForced(false);
time_forced = false;
position = 0, duration = 0;
speed = 1;
last_read = 0;
printf("%s: starting...\n", __func__);
stopPlayBack();
playstate = CMoviePlayerGui::STOPPED;
printf("Startplay at %d seconds\n", startposition/1000);
handleMovieBrowser(CRCInput::RC_nokey, position);
cutNeutrino();
if (isWebTV)
videoDecoder->setBlank(true);
clearSubtitle();
printf("IS FILE PLAYER: %s\n", is_file_player ? "true": "false" );
playback->Open(is_file_player ? PLAYMODE_FILE : PLAYMODE_TS);
if (p_movie_info) {
if (timeshift != TSHIFT_MODE_OFF) {
// p_movie_info may be invalidated by CRecordManager while we're still using it. Create and use a copy.
movie_info = *p_movie_info;
p_movie_info = &movie_info;
}
duration = p_movie_info->length * 60 * 1000;
int percent = CZapit::getInstance()->GetPidVolume(p_movie_info->channelId, currentapid, currentac3 == 1);
CZapit::getInstance()->SetVolumePercent(percent);
}
file_prozent = 0;
pthread_t thrStartHint = 0;
if (is_file_player) {
showStartingHint = true;
pthread_create(&thrStartHint, NULL, CMoviePlayerGui::ShowStartHint, this);
}
bool res = playback->Start((char *) file_name.c_str(), vpid, vtype, currentapid, currentac3, duration);
if (thrStartHint) {
showStartingHint = false;
pthread_join(thrStartHint, NULL);
}
if (!res) {
playback->Close();
repeat_mode = REPEAT_OFF;
return false;
} else {
repeat_mode = (repeat_mode_enum) g_settings.movieplayer_repeat_on;
playstate = CMoviePlayerGui::PLAY;
CVFD::getInstance()->ShowIcon(FP_ICON_PLAY, true);
if(timeshift != TSHIFT_MODE_OFF) {
startposition = -1;
int i;
int towait = (timeshift == TSHIFT_MODE_ON) ? TIMESHIFT_SECONDS+1 : TIMESHIFT_SECONDS;
int cnt = 500;
if (IS_WEBTV(movie_info.channelId)) {
videoDecoder->setBlank(false);
cnt = 200;
towait = 20;
}
for(i = 0; i < cnt; i++) {
playback->GetPosition(position, duration);
startposition = (duration - position);
//printf("CMoviePlayerGui::PlayFile: waiting for data, position %d duration %d (%d), start %d\n", position, duration, towait, startposition);
if (startposition > towait*1000)
break;
usleep(20000);
}
printf("CMoviePlayerGui::PlayFile: waiting for data: i=%d position %d duration %d (%d), start %d\n", i, position, duration, towait, startposition);
if (timeshift == TSHIFT_MODE_REWIND) {
startposition = duration;
} else {
if (g_settings.timeshift_pause)
playstate = CMoviePlayerGui::PAUSE;
if (timeshift == TSHIFT_MODE_ON)
startposition = 0;
else
startposition = std::max(0, duration - towait*1000);
}
printf("******************* Timeshift %d, position %d, seek to %d seconds\n", timeshift, position, startposition/1000);
}
if (/* !is_file_player && */ startposition >= 0)
playback->SetPosition(startposition, true);
/* playback->Start() starts paused */
if (timeshift == TSHIFT_MODE_REWIND) {
speed = -1;
playback->SetSpeed(-1);
playstate = CMoviePlayerGui::REW;
if (!FileTimeOSD->IsVisible() && !time_forced) {
FileTimeOSD->switchMode(position, duration);
time_forced = true;
}
FileTimeOSD->setMpTimeForced(true);
} else if (timeshift == TSHIFT_MODE_OFF || !g_settings.timeshift_pause) {
playback->SetSpeed(1);
}
}
getCurrentAudioName(is_file_player, currentaudioname);
if (is_file_player)
selectAutoLang();
enableOsdElements(MUTE);
return res;
}
bool CMoviePlayerGui::SetPosition(int pos, bool absolute)
{
clearSubtitle();
bool res = playback->SetPosition(pos, absolute);
if(is_file_player && res && speed == 0 && playstate == CMoviePlayerGui::PAUSE){
playstate = CMoviePlayerGui::PLAY;
speed = 1;
playback->SetSpeed(speed);
}
return res;
}
void CMoviePlayerGui::quickZap(neutrino_msg_t msg)
{
if ((msg == CRCInput::RC_right) || msg == (neutrino_msg_t) g_settings.key_quickzap_up)
{
//printf("CMoviePlayerGui::%s: CRCInput::RC_right or g_settings.key_quickzap_up\n", __func__);
if (isLuaPlay)
{
playstate = CMoviePlayerGui::STOPPED;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_NEXT;
ClearQueue();
}
else if (!filelist.empty())
{
if (filelist_it < (filelist.end() - 1))
{
playstate = CMoviePlayerGui::STOPPED;
++filelist_it;
}
else if (repeat_mode == REPEAT_ALL)
{
playstate = CMoviePlayerGui::STOPPED;
++filelist_it;
if (filelist_it == filelist.end())
{
filelist_it = filelist.begin();
}
}
}
}
else if ((msg == CRCInput::RC_left) || msg == (neutrino_msg_t) g_settings.key_quickzap_down)
{
//printf("CMoviePlayerGui::%s: CRCInput::RC_left or g_settings.key_quickzap_down\n", __func__);
if (isLuaPlay)
{
playstate = CMoviePlayerGui::STOPPED;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_PREV;
ClearQueue();
}
else if (filelist.size() > 1)
{
if (filelist_it != filelist.begin())
{
playstate = CMoviePlayerGui::STOPPED;
--filelist_it;
}
}
}
}
void CMoviePlayerGui::PlayFileLoop(void)
{
bool first_start = true;
bool update_lcd = true;
int eof = 0;
int eof2 = 0;
int position_tmp = 0;
bool at_eof = !(playstate >= CMoviePlayerGui::PLAY);;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_NORMAL;
while (playstate >= CMoviePlayerGui::PLAY)
{
if (update_lcd) {
update_lcd = false;
updateLcd();
}
if (first_start) {
callInfoViewer();
first_start = false;
}
neutrino_msg_t msg;
neutrino_msg_data_t data;
g_RCInput->getMsg(&msg, &data, 10); // 1 secs..
if ((playstate >= CMoviePlayerGui::PLAY) && (timeshift != TSHIFT_MODE_OFF || (playstate != CMoviePlayerGui::PAUSE))) {
if (playback->GetPosition(position, duration)) {
FileTimeOSD->update(position, duration);
if (duration > 100)
file_prozent = (unsigned char) (position / (duration / 100));
CVFD::getInstance()->showPercentOver(file_prozent);
playback->GetSpeed(speed);
/* at BOF lib set speed 1, check it */
if ((playstate != CMoviePlayerGui::PLAY) && (speed == 1)) {
playstate = CMoviePlayerGui::PLAY;
update_lcd = true;
}
#ifdef DEBUG
printf("CMoviePlayerGui::%s: spd %d pos %d/%d (%d, %d%%)\n", __func__, speed, position, duration, duration-position, file_prozent);
#endif
/* in case ffmpeg report incorrect values */
if(file_prozent > 89 && (playstate == CMoviePlayerGui::PLAY) && (speed == 1)){
if(position_tmp != position){
position_tmp = position ;
eof2 = 0;
}else{
if (++eof2 > 12) {
at_eof = true;
break;
}
}
}
else{
eof2 = 0;
}
int posdiff = duration - position;
if ((posdiff >= 0) && (posdiff < 2000) && timeshift == TSHIFT_MODE_OFF)
{
int delay = (filelist_it != filelist.end() || repeat_mode != REPEAT_OFF) ? 5 : 10;
if (++eof > delay) {
at_eof = true;
break;
}
}
else
eof = 0;
}
handleMovieBrowser(0, position);
if (playstate == CMoviePlayerGui::STOPPED)
at_eof = true;
FileTimeOSD->update(position, duration);
}
showSubtitle(0);
if (playstate == CMoviePlayerGui::PAUSE && (msg == CRCInput::RC_timeout || msg == NeutrinoMessages::EVT_TIMER))
{
int delay = time(NULL) - m_idletime;
int screensaver_delay = g_settings.screensaver_delay;
if (screensaver_delay != 0 && delay > screensaver_delay*60 && !m_screensaver) {
videoDecoder->setBlank(true);
screensaver(true);
}
}
else
{
m_idletime = time(NULL);
if (m_screensaver)
{
videoDecoder->setBlank(false);
screensaver(false);
//ignore first keypress stop - just quit the screensaver and call infoviewer
if (msg == CRCInput::RC_stop) {
g_RCInput->clearRCMsg();
callInfoViewer();
continue;
}
}
}
if (msg == (neutrino_msg_t) g_settings.mpkey_plugin) {
g_Plugins->startPlugin_by_name(g_settings.movieplayer_plugin.c_str ());
} else if (msg == (neutrino_msg_t) g_settings.mpkey_stop) {
playstate = CMoviePlayerGui::STOPPED;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_STOP;
ClearQueue();
} else if (msg == CRCInput::RC_left || msg == CRCInput::RC_right) {
bool reset_vzap_it = true;
switch (g_settings.mode_left_right_key_tv)
{
case SNeutrinoSettings::INFOBAR:
callInfoViewer();
break;
case SNeutrinoSettings::VZAP:
if (fromInfoviewer)
{
set_vzap_it(msg == CRCInput::RC_right);
reset_vzap_it = false;
fromInfoviewer = false;
}
callInfoViewer(reset_vzap_it);
break;
case SNeutrinoSettings::VOLUME:
g_volume->setVolume(msg);
break;
default: /* SNeutrinoSettings::ZAP */
quickZap(msg);
break;
}
} else if (msg == (neutrino_msg_t) g_settings.key_quickzap_up || msg == (neutrino_msg_t) g_settings.key_quickzap_down) {
quickZap(msg);
} else if (fromInfoviewer && msg == CRCInput::RC_ok && !filelist.empty()) {
printf("CMoviePlayerGui::%s: start playlist movie #%d\n", __func__, (int)(vzap_it - filelist.begin()));
fromInfoviewer = false;
playstate = CMoviePlayerGui::STOPPED;
filelist_it = vzap_it;
} else if (timeshift == TSHIFT_MODE_OFF && !isWebTV /* && !isYT */ && (msg == (neutrino_msg_t) g_settings.mpkey_next_repeat_mode)) {
repeat_mode = (repeat_mode_enum)((int)repeat_mode + 1);
if (repeat_mode > (int) REPEAT_ALL)
repeat_mode = REPEAT_OFF;
g_settings.movieplayer_repeat_on = repeat_mode;
callInfoViewer();
} else if (msg == (neutrino_msg_t) g_settings.mpkey_play) {
if (time_forced) {
time_forced = false;
FileTimeOSD->kill();
}
FileTimeOSD->setMpTimeForced(false);
if (playstate > CMoviePlayerGui::PLAY) {
playstate = CMoviePlayerGui::PLAY;
speed = 1;
playback->SetSpeed(speed);
updateLcd();
if (timeshift == TSHIFT_MODE_OFF)
callInfoViewer();
} else if (!filelist.empty()) {
disableOsdElements(MUTE);
CFileBrowser *playlist = new CFileBrowser();
CFile *pfile = NULL;
int selected = std::distance( filelist.begin(), filelist_it );
filelist_it = filelist.end();
if (playlist->playlist_manager(filelist, selected))
{
playstate = CMoviePlayerGui::STOPPED;
CFile *sfile = NULL;
for (filelist_it = filelist.begin(); filelist_it != filelist.end(); ++filelist_it)
{
pfile = &(*filelist_it);
sfile = playlist->getSelectedFile();
if ( (sfile->getFileName() == pfile->getFileName()) && (sfile->getPath() == pfile->getPath()))
break;
}
}
else {
if (!filelist.empty())
filelist_it = filelist.begin() + selected;
}
delete playlist;
enableOsdElements(MUTE);
}
} else if (msg == (neutrino_msg_t) g_settings.mpkey_pause) {
if (time_forced) {
time_forced = false;
FileTimeOSD->kill();
}
FileTimeOSD->setMpTimeForced(false);
if (playstate == CMoviePlayerGui::PAUSE) {
playstate = CMoviePlayerGui::PLAY;
//CVFD::getInstance()->ShowIcon(VFD_ICON_PAUSE, false);
speed = 1;
playback->SetSpeed(speed);
} else {
playstate = CMoviePlayerGui::PAUSE;
//CVFD::getInstance()->ShowIcon(VFD_ICON_PAUSE, true);
speed = 0;
playback->SetSpeed(speed);
}
updateLcd();
if (timeshift == TSHIFT_MODE_OFF)
callInfoViewer();
} else if (msg == (neutrino_msg_t) g_settings.mpkey_bookmark) {
if (is_file_player)
selectChapter();
else
handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_bookmark, position);
update_lcd = true;
clearSubtitle();
} else if (msg == (neutrino_msg_t) g_settings.mpkey_audio) {
selectAudioPid();
update_lcd = true;
clearSubtitle();
} else if (msg == (neutrino_msg_t) g_settings.mpkey_subtitle) {
selectSubtitle();
clearSubtitle();
update_lcd = true;
} else if (msg == (neutrino_msg_t) g_settings.mpkey_time) {
FileTimeOSD->switchMode(position, duration);
time_forced = false;
FileTimeOSD->setMpTimeForced(false);
} else if (msg == (neutrino_msg_t) g_settings.mbkey_cover) {
makeScreenShot(false, true);
} else if (msg == (neutrino_msg_t) g_settings.key_screenshot) {
makeScreenShot();
} else if ((msg == (neutrino_msg_t) g_settings.mpkey_rewind) ||
(msg == (neutrino_msg_t) g_settings.mpkey_forward)) {
int newspeed = 0;
bool setSpeed = false;
if (msg == (neutrino_msg_t) g_settings.mpkey_rewind) {
newspeed = (speed >= 0) ? -1 : speed - 1;
} else {
newspeed = (speed <= 0) ? 2 : speed + 1;
}
/* if paused, playback->SetSpeed() start slow motion */
if (playback->SetSpeed(newspeed)) {
printf("SetSpeed: update speed\n");
speed = newspeed;
if (playstate != CMoviePlayerGui::PAUSE)
playstate = msg == (neutrino_msg_t) g_settings.mpkey_rewind ? CMoviePlayerGui::REW : CMoviePlayerGui::FF;
updateLcd();
setSpeed = true;
}
if (!FileTimeOSD->IsVisible() && !time_forced && setSpeed) {
FileTimeOSD->switchMode(position, duration);
time_forced = true;
}
FileTimeOSD->setMpTimeForced(true);
if (timeshift == TSHIFT_MODE_OFF)
callInfoViewer();
} else if (msg == CRCInput::RC_1) { // Jump Backwards 1 minute
SetPosition(-60 * 1000);
} else if (msg == CRCInput::RC_3) { // Jump Forward 1 minute
SetPosition(60 * 1000);
} else if (msg == CRCInput::RC_4) { // Jump Backwards 5 minutes
SetPosition(-5 * 60 * 1000);
} else if (msg == CRCInput::RC_6) { // Jump Forward 5 minutes
SetPosition(5 * 60 * 1000);
} else if (msg == CRCInput::RC_7) { // Jump Backwards 10 minutes
SetPosition(-10 * 60 * 1000);
} else if (msg == CRCInput::RC_9) { // Jump Forward 10 minutes
SetPosition(10 * 60 * 1000);
} else if (msg == CRCInput::RC_2) { // goto start
SetPosition(0, true);
} else if (msg == CRCInput::RC_5) { // goto middle
SetPosition(duration/2, true);
} else if (msg == CRCInput::RC_8) { // goto end
SetPosition(duration - 60 * 1000, true);
} else if (msg == CRCInput::RC_page_up) {
SetPosition(10 * 1000);
} else if (msg == CRCInput::RC_page_down) {
SetPosition(-10 * 1000);
} else if (msg == CRCInput::RC_0) { // cancel bookmark jump
handleMovieBrowser(CRCInput::RC_0, position);
} else if (msg == (neutrino_msg_t) g_settings.mpkey_goto) {
bool cancel = true;
playback->GetPosition(position, duration);
int ss = position/1000;
int hh = ss/3600;
ss -= hh * 3600;
int mm = ss/60;
ss -= mm * 60;
std::string Value = to_string(hh/10) + to_string(hh%10) + ":" + to_string(mm/10) + to_string(mm%10) + ":" + to_string(ss/10) + to_string(ss%10);
CTimeInput jumpTime (LOCALE_MPKEY_GOTO, &Value, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, NULL, &cancel);
jumpTime.exec(NULL, "");
jumpTime.hide();
if (!cancel && (3 == sscanf(Value.c_str(), "%d:%d:%d", &hh, &mm, &ss)))
SetPosition(1000 * (hh * 3600 + mm * 60 + ss), true);
} else if (msg == CRCInput::RC_help) {
disableOsdElements(NO_MUTE);
showHelp();
enableOsdElements(NO_MUTE);
} else if (msg == CRCInput::RC_info) {
if (fromInfoviewer) {
disableOsdElements(NO_MUTE);
#ifdef ENABLE_LUA
if (isLuaPlay && haveLuaInfoFunc) {
int xres = 0, yres = 0, aspectRatio = 0, framerate = -1;
if (!videoDecoder->getBlank()) {
videoDecoder->getPictureInfo(xres, yres, framerate);
if (yres == 1088)
yres = 1080;
aspectRatio = videoDecoder->getAspectRatio();
}
CLuaInstVideo::getInstance()->execLuaInfoFunc(luaState, xres, yres, aspectRatio, framerate);
}
else {
#endif
g_EpgData->show_mp(p_movie_info,GetPosition(),GetDuration());
#ifdef ENABLE_LUA
}
#endif
fromInfoviewer = false;
enableOsdElements(NO_MUTE);
}
else
callInfoViewer();
update_lcd = true;
clearSubtitle();
} else if (timeshift != TSHIFT_MODE_OFF && (msg == CRCInput::RC_text || msg == CRCInput::RC_epg || msg == NeutrinoMessages::SHOW_EPG)) {
bool restore = FileTimeOSD->IsVisible();
FileTimeOSD->kill();
if (msg == CRCInput::RC_epg )
g_EventList->exec(CNeutrinoApp::getInstance()->channelList->getActiveChannel_ChannelID(), CNeutrinoApp::getInstance()->channelList->getActiveChannelName());
else if (msg == NeutrinoMessages::SHOW_EPG)
g_EpgData->show(CNeutrinoApp::getInstance()->channelList->getActiveChannel_ChannelID());
else {
if (g_settings.cacheTXT)
tuxtxt_stop();
tuxtx_main(g_RemoteControl->current_PIDs.PIDs.vtxtpid, 0, 2);
frameBuffer->paintBackground();
}
if (restore)
FileTimeOSD->show(position);
#if 0
} else if (msg == CRCInput::RC_red) {
bool restore = FileTimeOSD->IsVisible();
FileTimeOSD->kill();
CStreamInfo2 streaminfo;
streaminfo.exec(NULL, "");
if (restore)
FileTimeOSD->show(position);
update_lcd = true;
#endif
} else if (msg == NeutrinoMessages::SHOW_EPG) {
handleMovieBrowser(NeutrinoMessages::SHOW_EPG, position);
} else if (msg == NeutrinoMessages::EVT_SUBT_MESSAGE) {
showSubtitle(data);
} else if (msg == NeutrinoMessages::ANNOUNCE_RECORD ||
msg == NeutrinoMessages::RECORD_START) {
CNeutrinoApp::getInstance()->handleMsg(msg, data);
} else if (msg == NeutrinoMessages::ZAPTO ||
msg == NeutrinoMessages::STANDBY_ON ||
msg == NeutrinoMessages::LEAVE_ALL ||
msg == NeutrinoMessages::SHUTDOWN ||
((msg == NeutrinoMessages::SLEEPTIMER) && !data) ) { // Exit for Record/Zapto Timers
printf("CMoviePlayerGui::PlayFile: ZAPTO etc..\n");
if (msg != NeutrinoMessages::ZAPTO)
menu_ret = menu_return::RETURN_EXIT_ALL;
playstate = CMoviePlayerGui::STOPPED;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_LEAVE_ALL;
ClearQueue();
g_RCInput->postMsg(msg, data);
} else if (msg == CRCInput::RC_timeout || msg == NeutrinoMessages::EVT_TIMER) {
if (playstate == CMoviePlayerGui::PLAY && (position >= 300000 || (duration < 300000 && (position > (duration /2)))))
makeScreenShot(true);
} else if (CNeutrinoApp::getInstance()->listModeKey(msg)) {
// do nothing
} else if (msg == (neutrino_msg_t) CRCInput::RC_setup) {
CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::SHOW_MAINMENU, 0);
} else if (msg == CRCInput::RC_red || msg == CRCInput::RC_green || msg == CRCInput::RC_yellow || msg == CRCInput::RC_blue ) {
//maybe move FileTimeOSD->kill to Usermenu to simplify this call
bool restore = FileTimeOSD->IsVisible();
FileTimeOSD->kill();
CNeutrinoApp::getInstance()->usermenu.showUserMenu(msg);
if (restore)
FileTimeOSD->show(position);
update_lcd = true;
} else {
if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::cancel_all) {
printf("CMoviePlayerGui::PlayFile: neutrino handleMsg messages_return::cancel_all\n");
menu_ret = menu_return::RETURN_EXIT_ALL;
playstate = CMoviePlayerGui::STOPPED;
keyPressed = CMoviePlayerGui::PLUGIN_PLAYSTATE_LEAVE_ALL;
ClearQueue();
}
else if (msg <= CRCInput::RC_MaxRC ) {
update_lcd = true;
clearSubtitle();
}
}
}
printf("CMoviePlayerGui::PlayFile: exit, isMovieBrowser %d p_movie_info %p\n", isMovieBrowser, p_movie_info);
playstate = CMoviePlayerGui::STOPPED;
handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_stop, position);
if (position >= 300000 || (duration < 300000 && (position > (duration /2))))
makeScreenShot(true);
if (at_eof && !filelist.empty()) {
if (filelist_it != filelist.end() && repeat_mode != REPEAT_TRACK)
++filelist_it;
if (filelist_it == filelist.end() && repeat_mode == REPEAT_ALL)
filelist_it = filelist.begin();
}
}
void CMoviePlayerGui::PlayFileEnd(bool restore)
{
printf("%s: stopping, this %p thread %p\n", __func__, this, CMoviePlayerGui::bgPlayThread);fflush(stdout);
if (filelist_it == filelist.end())
FileTimeOSD->kill();
clearSubtitle();
playback->SetSpeed(1);
playback->Close();
if (iso_file) {
iso_file = false;
if (umount2(ISO_MOUNT_POINT ,MNT_FORCE))
perror(ISO_MOUNT_POINT);
}
CVFD::getInstance()->ShowIcon(FP_ICON_PLAY, false);
CVFD::getInstance()->ShowIcon(FP_ICON_PAUSE, false);
if (restore)
restoreNeutrino();
stopped = true;
printf("%s: stopped\n", __func__);
if (!filelist.empty() && filelist_it != filelist.end()) {
pretty_name.clear();
prepareFile(&(*filelist_it));
}
}
void CMoviePlayerGui::set_vzap_it(bool up)
{
//printf("CMoviePlayerGui::%s: vzap_it: %d count %s\n", __func__, (int)(vzap_it - filelist.begin()), up ? "up" : "down");
if (up)
{
if (vzap_it < (filelist.end() - 1))
++vzap_it;
}
else
{
if (vzap_it > filelist.begin())
--vzap_it;
}
//printf("CMoviePlayerGui::%s: vzap_it: %d\n", __func__, (int)(vzap_it - filelist.begin()));
}
void CMoviePlayerGui::callInfoViewer(bool init_vzap_it)
{
if (init_vzap_it)
{
//printf("CMoviePlayerGui::%s: init_vzap_it\n", __func__);
vzap_it = filelist_it;
}
if (timeshift != TSHIFT_MODE_OFF) {
g_InfoViewer->showTitle(CNeutrinoApp::getInstance()->channelList->getActiveChannel());
return;
}
if(duration == 0)
UpdatePosition();
if (isMovieBrowser && p_movie_info)
{
MI_MOVIE_INFO *mi;
mi = p_movie_info;
if (!filelist.empty() && g_settings.mode_left_right_key_tv == SNeutrinoSettings::VZAP)
{
if (vzap_it <= filelist.end()) {
unsigned idx = vzap_it - filelist.begin();
//printf("CMoviePlayerGui::%s: idx: %d\n", __func__, idx);
if(milist.size() > idx)
mi = milist[idx];
}
}
g_InfoViewer->showMovieTitle(playstate, mi->epgId >>16, mi->channelName, mi->epgTitle, mi->epgInfo1,
duration, position, repeat_mode, init_vzap_it ? 0 /*IV_MODE_DEFAULT*/ : 1 /*IV_MODE_VIRTUAL_ZAP*/);
return;
}
/* not moviebrowser => use the filename as title */
g_InfoViewer->showMovieTitle(playstate, 0, pretty_name, info_1, info_2, duration, position, repeat_mode);
}
bool CMoviePlayerGui::getAudioName(int apid, std::string &apidtitle)
{
if (p_movie_info == NULL)
return false;
for (int i = 0; i < (int)p_movie_info->audioPids.size(); i++) {
if (p_movie_info->audioPids[i].AudioPid == apid && !p_movie_info->audioPids[i].AudioPidName.empty()) {
apidtitle = p_movie_info->audioPids[i].AudioPidName;
return true;
}
}
return false;
}
void CMoviePlayerGui::addAudioFormat(int count, std::string &apidtitle, bool& enabled)
{
enabled = true;
switch(ac3flags[count])
{
case 1: /*AC3,EAC3*/
if (apidtitle.find("AC3") == std::string::npos)
apidtitle.append(" (AC3)");
break;
case 2: /*teletext*/
apidtitle.append(" (Teletext)");
enabled = false;
break;
case 3: /*MP2*/
apidtitle.append("( MP2)");
break;
case 4: /*MP3*/
apidtitle.append(" (MP3)");
break;
case 5: /*AAC*/
apidtitle.append(" (AAC)");
break;
case 6: /*DTS*/
if (apidtitle.find("DTS") == std::string::npos)
apidtitle.append(" (DTS)");
#ifndef BOXMODEL_CS_HD2
enabled = false;
#endif
break;
case 7: /*MLP*/
apidtitle.append(" (MLP)");
break;
default:
break;
}
}
void CMoviePlayerGui::getCurrentAudioName(bool file_player, std::string &audioname)
{
if (file_player && !numpida) {
playback->FindAllPids(apids, ac3flags, &numpida, language);
if (numpida)
currentapid = apids[0];
}
bool dumm = true;
for (unsigned int count = 0; count < numpida; count++) {
if (currentapid == apids[count]) {
if (!file_player) {
getAudioName(apids[count], audioname);
return ;
} else if (!language[count].empty()) {
audioname = language[count];
addAudioFormat(count, audioname, dumm);
if (!dumm && (count < numpida)) {
currentapid = apids[count+1];
continue;
}
return ;
}
char apidnumber[20];
sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]);
audioname = apidnumber;
addAudioFormat(count, audioname, dumm);
if (!dumm && (count < numpida)) {
currentapid = apids[count+1];
continue;
}
return ;
}
}
}
void CMoviePlayerGui::selectAudioPid()
{
CMenuWidget APIDSelector(LOCALE_APIDSELECTOR_HEAD, NEUTRINO_ICON_AUDIO);
APIDSelector.addIntroItems();
int select = -1;
CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select);
if (is_file_player && !numpida) {
playback->FindAllPids(apids, ac3flags, &numpida, language);
if (numpida)
currentapid = apids[0];
}
for (unsigned int count = 0; count < numpida; count++) {
bool name_ok = false;
bool enabled = true;
bool defpid = currentapid ? (currentapid == apids[count]) : (count == 0);
std::string apidtitle;
if (!is_file_player) {
name_ok = getAudioName(apids[count], apidtitle);
}
else if (!language[count].empty()) {
apidtitle = language[count];
name_ok = true;
}
if (!name_ok) {
char apidnumber[20];
sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]);
apidtitle = apidnumber;
}
addAudioFormat(count, apidtitle, enabled);
if (defpid && !enabled && (count < numpida)) {
currentapid = apids[count+1];
defpid = false;
}
char cnt[5];
sprintf(cnt, "%d", count);
CMenuForwarder * item = new CMenuForwarder(apidtitle.c_str(), enabled, NULL, selector, cnt, CRCInput::convertDigitToKey(count + 1));
APIDSelector.addItem(item, defpid);
}
int percent[numpida+1];
if (p_movie_info && numpida <= p_movie_info->audioPids.size()) {
APIDSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_AUDIOMENU_VOLUME_ADJUST));
CVolume::getInstance()->SetCurrentChannel(p_movie_info->channelId);
CVolume::getInstance()->SetCurrentPid(currentapid);
for (uint i=0; i < numpida; i++) {
percent[i] = CZapit::getInstance()->GetPidVolume(p_movie_info->channelId, apids[i], ac3flags[i]);
APIDSelector.addItem(new CMenuOptionNumberChooser(p_movie_info->audioPids[i].AudioPidName,
&percent[i], currentapid == apids[i],
0, 999, CVolume::getInstance()));
}
}
APIDSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE));
extern CAudioSetupNotifier * audioSetupNotifier;
APIDSelector.addItem( new CMenuOptionChooser(LOCALE_AUDIOMENU_ANALOG_OUT, &g_settings.analog_out,
OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT,
true, audioSetupNotifier, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN) );
APIDSelector.exec(NULL, "");
delete selector;
printf("CMoviePlayerGui::selectAudioPid: selected %d (%x) current %x\n", select, (select >= 0) ? apids[select] : -1, currentapid);
if ((select >= 0) && (currentapid != apids[select])) {
currentapid = apids[select];
currentac3 = ac3flags[select];
playback->SetAPid(currentapid, currentac3);
getCurrentAudioName(is_file_player, currentaudioname);
printf("[movieplayer] apid changed to %d type %d\n", currentapid, currentac3);
}
}
void CMoviePlayerGui::handleMovieBrowser(neutrino_msg_t msg, int /*position*/)
{
CMovieInfo cMovieInfo; // funktions to save and load movie info
static int jump_not_until = 0; // any jump shall be avoided until this time (in seconds from moviestart)
static MI_BOOKMARK new_bookmark; // used for new movie info bookmarks created from the movieplayer
std::string key_bookmark = CRCInput::getKeyName((neutrino_msg_t) g_settings.mpkey_bookmark);
char txt[1024];
//TODO: width and height could be more flexible
static int width = frameBuffer->getScreenWidth() / 2;
static int height = 65;
static int x = frameBuffer->getScreenX() + (frameBuffer->getScreenWidth() - width) / 2;
static int y = frameBuffer->getScreenY() + frameBuffer->getScreenHeight() - height - 20;
static CBox boxposition(x, y, width, height); // window position for the hint boxes
static CTextBox endHintBox(g_Locale->getText(LOCALE_MOVIEBROWSER_HINT_MOVIEEND), NULL, CTextBox::CENTER /*CTextBox::AUTO_WIDTH | CTextBox::AUTO_HIGH */ , &boxposition);
static CTextBox comHintBox(g_Locale->getText(LOCALE_MOVIEBROWSER_HINT_JUMPFORWARD), NULL, CTextBox::CENTER /*CTextBox::AUTO_WIDTH | CTextBox::AUTO_HIGH */ , &boxposition);
static CTextBox loopHintBox(g_Locale->getText(LOCALE_MOVIEBROWSER_HINT_JUMPBACKWARD), NULL, CTextBox::CENTER /*CTextBox::AUTO_WIDTH | CTextBox::AUTO_HIGH */ , &boxposition);
snprintf(txt, sizeof(txt)-1, g_Locale->getText(LOCALE_MOVIEBROWSER_HINT_NEWBOOK_BACKWARD), key_bookmark.c_str());
static CTextBox newLoopHintBox(txt, NULL, CTextBox::CENTER /*CTextBox::AUTO_WIDTH | CTextBox::AUTO_HIGH */ , &boxposition);
snprintf(txt, sizeof(txt)-1, g_Locale->getText(LOCALE_MOVIEBROWSER_HINT_NEWBOOK_FORWARD), key_bookmark.c_str());
static CTextBox newComHintBox(txt, NULL, CTextBox::CENTER /*CTextBox::AUTO_WIDTH | CTextBox::AUTO_HIGH */ , &boxposition);
static bool showEndHintBox = false; // flag to check whether the box shall be painted
static bool showComHintBox = false; // flag to check whether the box shall be painted
static bool showLoopHintBox = false; // flag to check whether the box shall be painted
int play_sec = position / 1000; // get current seconds from moviestart
if (msg == CRCInput::RC_nokey) {
printf("CMoviePlayerGui::handleMovieBrowser: reset vars\n");
// reset statics
jump_not_until = 0;
showEndHintBox = showComHintBox = showLoopHintBox = false;
new_bookmark.pos = 0;
// move in case osd position changed
int newx = frameBuffer->getScreenX() + (frameBuffer->getScreenWidth() - width) / 2;
int newy = frameBuffer->getScreenY() + frameBuffer->getScreenHeight() - height - 20;
endHintBox.movePosition(newx, newy);
comHintBox.movePosition(newx, newy);
loopHintBox.movePosition(newx, newy);
newLoopHintBox.movePosition(newx, newy);
newComHintBox.movePosition(newx, newy);
return;
}
else if (msg == (neutrino_msg_t) g_settings.mpkey_stop) {
// if we have a movie information, try to save the stop position
printf("CMoviePlayerGui::handleMovieBrowser: stop, isMovieBrowser %d p_movie_info %x\n", isMovieBrowser, (int) p_movie_info);
if (isMovieBrowser && p_movie_info) {
timeb current_time;
ftime(&current_time);
p_movie_info->dateOfLastPlay = current_time.time;
current_time.time = time(NULL);
p_movie_info->bookmarks.lastPlayStop = position / 1000;
cMovieInfo.saveMovieInfo(*p_movie_info);
//p_movie_info->fileInfoStale(); //TODO: we might to tell the Moviebrowser that the movie info has changed, but this could cause long reload times when reentering the Moviebrowser
}
}
else if ((msg == 0) && isMovieBrowser && (playstate == CMoviePlayerGui::PLAY) && p_movie_info) {
if (play_sec + 10 < jump_not_until || play_sec > jump_not_until + 10)
jump_not_until = 0; // check if !jump is stale (e.g. if user jumped forward or backward)
// do bookmark activities only, if there is no new bookmark started
if (new_bookmark.pos != 0)
return;
#ifdef DEBUG
//printf("CMoviePlayerGui::handleMovieBrowser: process bookmarks\n");
#endif
if (p_movie_info->bookmarks.end != 0) {
// *********** Check for stop position *******************************
if (play_sec >= p_movie_info->bookmarks.end - MOVIE_HINT_BOX_TIMER && play_sec < p_movie_info->bookmarks.end && play_sec > jump_not_until) {
if (showEndHintBox == false) {
endHintBox.paint(); // we are 5 sec before the end postition, show warning
showEndHintBox = true;
TRACE("[mp] user stop in 5 sec...\r\n");
}
} else {
if (showEndHintBox == true) {
endHintBox.hide(); // if we showed the warning before, hide the box again
showEndHintBox = false;
}
}
if (play_sec >= p_movie_info->bookmarks.end && play_sec <= p_movie_info->bookmarks.end + 2 && play_sec > jump_not_until) // stop playing
{
// *********** we ARE close behind the stop position, stop playing *******************************
TRACE("[mp] user stop: play_sec %d bookmarks.end %d jump_not_until %d\n", play_sec, p_movie_info->bookmarks.end, jump_not_until);
playstate = CMoviePlayerGui::STOPPED;
return;
}
}
// ************* Check for bookmark jumps *******************************
showLoopHintBox = false;
showComHintBox = false;
for (int book_nr = 0; book_nr < MI_MOVIE_BOOK_USER_MAX; book_nr++) {
if (p_movie_info->bookmarks.user[book_nr].pos != 0 && p_movie_info->bookmarks.user[book_nr].length != 0) {
// valid bookmark found, now check if we are close before or after it
if (play_sec >= p_movie_info->bookmarks.user[book_nr].pos - MOVIE_HINT_BOX_TIMER && play_sec < p_movie_info->bookmarks.user[book_nr].pos && play_sec > jump_not_until) {
if (p_movie_info->bookmarks.user[book_nr].length < 0)
showLoopHintBox = true; // we are 5 sec before , show warning
else if (p_movie_info->bookmarks.user[book_nr].length > 0)
showComHintBox = true; // we are 5 sec before, show warning
//else // TODO should we show a plain bookmark infomation as well?
}
if (play_sec >= p_movie_info->bookmarks.user[book_nr].pos && play_sec <= p_movie_info->bookmarks.user[book_nr].pos + 2 && play_sec > jump_not_until) //
{
//for plain bookmark, the following calc shall result in 0 (no jump)
int jumpseconds = p_movie_info->bookmarks.user[book_nr].length;
// we are close behind the bookmark, do bookmark activity (if any)
if (p_movie_info->bookmarks.user[book_nr].length < 0) {
// if the jump back time is to less, it does sometimes cause problems (it does probably jump only 5 sec which will cause the next jump, and so on)
if (jumpseconds > -15)
jumpseconds = -15;
playback->SetPosition(jumpseconds * 1000);
} else if (p_movie_info->bookmarks.user[book_nr].length > 0) {
// jump at least 15 seconds
if (jumpseconds < 15)
jumpseconds = 15;
playback->SetPosition(jumpseconds * 1000);
}
TRACE("[mp] do jump %d sec\r\n", jumpseconds);
break; // do no further bookmark checks
}
}
}
// check if we shall show the commercial warning
if (showComHintBox == true) {
comHintBox.paint();
TRACE("[mp] com jump in 5 sec...\r\n");
} else
comHintBox.hide();
// check if we shall show the loop warning
if (showLoopHintBox == true) {
loopHintBox.paint();
TRACE("[mp] loop jump in 5 sec...\r\n");
} else
loopHintBox.hide();
return;
} else if (msg == CRCInput::RC_0) { // cancel bookmark jump
printf("CMoviePlayerGui::handleMovieBrowser: CRCInput::RC_0\n");
if (isMovieBrowser == true) {
if (new_bookmark.pos != 0) {
new_bookmark.pos = 0; // stop current bookmark activity, TODO: might bemoved to another key
newLoopHintBox.hide(); // hide hint box if any
newComHintBox.hide();
}
comHintBox.hide();
loopHintBox.hide();
jump_not_until = (position / 1000) + 10; // avoid bookmark jumping for the next 10 seconds, , TODO: might be moved to another key
}
return;
}
else if (msg == (neutrino_msg_t) g_settings.mpkey_bookmark) {
if (newComHintBox.isPainted() == true) {
// yes, let's get the end pos of the jump forward
new_bookmark.length = play_sec - new_bookmark.pos;
TRACE("[mp] commercial length: %d\r\n", new_bookmark.length);
if (cMovieInfo.addNewBookmark(p_movie_info, new_bookmark) == true) {
cMovieInfo.saveMovieInfo(*p_movie_info); /* save immediately in xml file */
}
new_bookmark.pos = 0; // clear again, since this is used as flag for bookmark activity
newComHintBox.hide();
} else if (newLoopHintBox.isPainted() == true) {
// yes, let's get the end pos of the jump backward
new_bookmark.length = new_bookmark.pos - play_sec;
new_bookmark.pos = play_sec;
TRACE("[mp] loop length: %d\r\n", new_bookmark.length);
if (cMovieInfo.addNewBookmark(p_movie_info, new_bookmark) == true) {
cMovieInfo.saveMovieInfo(*p_movie_info); /* save immediately in xml file */
jump_not_until = play_sec + 5; // avoid jumping for this time
}
new_bookmark.pos = 0; // clear again, since this is used as flag for bookmark activity
newLoopHintBox.hide();
} else {
// very dirty usage of the menue, but it works and I already spent to much time with it, feel free to make it better ;-)
#define BOOKMARK_START_MENU_MAX_ITEMS 7
CSelectedMenu cSelectedMenuBookStart[BOOKMARK_START_MENU_MAX_ITEMS];
CMenuWidget bookStartMenu(LOCALE_MOVIEBROWSER_MENU_MAIN_BOOKMARKS, NEUTRINO_ICON_STREAMING);
bookStartMenu.addIntroItems();
#if 0 // not supported, TODO
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEPLAYER_HEAD, !isMovieBrowser, NULL, &cSelectedMenuBookStart[0]));
bookStartMenu.addItem(GenericMenuSeparatorLine);
#endif
const char *unit_short_minute = g_Locale->getText(LOCALE_UNIT_SHORT_MINUTE);
char play_pos[32];
int lastplaystop = p_movie_info ? p_movie_info->bookmarks.lastPlayStop/60:0;
snprintf(play_pos, sizeof(play_pos), "%3d %s", lastplaystop, unit_short_minute);
char start_pos[32] = {0};
if (p_movie_info && p_movie_info->bookmarks.start != 0)
snprintf(start_pos, sizeof(start_pos), "%3d %s", p_movie_info->bookmarks.start/60, unit_short_minute);
char end_pos[32] = {0};
if (p_movie_info && p_movie_info->bookmarks.end != 0)
snprintf(end_pos, sizeof(end_pos), "%3d %s", p_movie_info->bookmarks.end/60, unit_short_minute);
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_LASTMOVIESTOP, isMovieBrowser, play_pos, &cSelectedMenuBookStart[1]));
bookStartMenu.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MOVIEBROWSER_BOOK_ADD));
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_NEW, isMovieBrowser, NULL, &cSelectedMenuBookStart[2]));
bookStartMenu.addItem(new CMenuSeparator());
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_TYPE_FORWARD, isMovieBrowser, NULL, &cSelectedMenuBookStart[3], NULL, CRCInput::RC_red));
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_TYPE_BACKWARD, isMovieBrowser, NULL, &cSelectedMenuBookStart[4], NULL, CRCInput::RC_green));
bookStartMenu.addItem(new CMenuSeparator());
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_MOVIESTART, isMovieBrowser, start_pos, &cSelectedMenuBookStart[5], NULL, CRCInput::RC_yellow));
bookStartMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_MOVIEEND, isMovieBrowser, end_pos, &cSelectedMenuBookStart[6], NULL, CRCInput::RC_blue));
// no, nothing else to do, we open a new bookmark menu
new_bookmark.name = ""; // use default name
new_bookmark.pos = 0;
new_bookmark.length = 0;
// next seems return menu_return::RETURN_EXIT, if something selected
bookStartMenu.exec(NULL, "none");
#if 0 // not supported, TODO
if (cSelectedMenuBookStart[0].selected == true) {
/* Movieplayer bookmark */
if (bookmarkmanager->getBookmarkCount() < bookmarkmanager->getMaxBookmarkCount()) {
char timerstring[200];
sprintf(timerstring, "%lld", play_sec);
std::string bookmarktime = timerstring;
fprintf(stderr, "fileposition: %lld timerstring: %s bookmarktime: %s\n", play_sec, timerstring, bookmarktime.c_str());
bookmarkmanager->createBookmark(file_name, bookmarktime);
} else {
fprintf(stderr, "too many bookmarks\n");
DisplayErrorMessage(g_Locale->getText(LOCALE_MOVIEPLAYER_TOOMANYBOOKMARKS)); // UTF-8
}
cSelectedMenuBookStart[0].selected = false; // clear for next bookmark menu
} else
#endif
if (cSelectedMenuBookStart[1].selected == true) {
int pos = p_movie_info->bookmarks.lastPlayStop;
printf("[mb] last play stop: %d\n", pos);
SetPosition(pos*1000, true);
} else if (cSelectedMenuBookStart[2].selected == true) {
/* Moviebrowser plain bookmark */
new_bookmark.pos = play_sec;
new_bookmark.length = 0;
if (cMovieInfo.addNewBookmark(p_movie_info, new_bookmark) == true)
cMovieInfo.saveMovieInfo(*p_movie_info); /* save immediately in xml file */
new_bookmark.pos = 0; // clear again, since this is used as flag for bookmark activity
} else if (cSelectedMenuBookStart[3].selected == true) {
/* Moviebrowser jump forward bookmark */
new_bookmark.pos = play_sec;
TRACE("[mp] new bookmark 1. pos: %d\r\n", new_bookmark.pos);
newComHintBox.paint();
} else if (cSelectedMenuBookStart[4].selected == true) {
/* Moviebrowser jump backward bookmark */
new_bookmark.pos = play_sec;
TRACE("[mp] new bookmark 1. pos: %d\r\n", new_bookmark.pos);
newLoopHintBox.paint();
} else if (cSelectedMenuBookStart[5].selected == true) {
/* Moviebrowser movie start bookmark */
p_movie_info->bookmarks.start = play_sec;
TRACE("[mp] New movie start pos: %d\r\n", p_movie_info->bookmarks.start);
cMovieInfo.saveMovieInfo(*p_movie_info); /* save immediately in xml file */
} else if (cSelectedMenuBookStart[6].selected == true) {
/* Moviebrowser movie end bookmark */
p_movie_info->bookmarks.end = play_sec;
TRACE("[mp] New movie end pos: %d\r\n", p_movie_info->bookmarks.end);
cMovieInfo.saveMovieInfo(*p_movie_info); /* save immediately in xml file */
}
}
} else if (msg == NeutrinoMessages::SHOW_EPG && p_movie_info) {
disableOsdElements(NO_MUTE);
g_EpgData->show_mp(p_movie_info, position, duration);
enableOsdElements(NO_MUTE);
}
return;
}
void CMoviePlayerGui::UpdatePosition()
{
if (playback->GetPosition(position, duration)) {
if (duration > 100)
file_prozent = (unsigned char) (position / (duration / 100));
FileTimeOSD->update(position, duration);
#ifdef DEBUG
printf("CMoviePlayerGui::%s: spd %d pos %d/%d (%d, %d%%)\n", __func__, speed, position, duration, duration-position, file_prozent);
#endif
}
}
void CMoviePlayerGui::showHelp()
{
Helpbox helpbox(g_Locale->getText(LOCALE_MESSAGEBOX_INFO));
helpbox.addSeparator();
helpbox.addLine(NEUTRINO_ICON_BUTTON_PAUSE, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_PAUSE));
helpbox.addLine(NEUTRINO_ICON_BUTTON_FORWARD, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_FORWARD));
helpbox.addLine(NEUTRINO_ICON_BUTTON_BACKWARD, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_BACKWARD));
helpbox.addLine(NEUTRINO_ICON_BUTTON_STOP, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_STOP));
helpbox.addSeparatorLine();
helpbox.addLine(NEUTRINO_ICON_BUTTON_1, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_1));
helpbox.addLine(NEUTRINO_ICON_BUTTON_2, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_2));
helpbox.addLine(NEUTRINO_ICON_BUTTON_3, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_3));
helpbox.addLine(NEUTRINO_ICON_BUTTON_4, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_4));
helpbox.addLine(NEUTRINO_ICON_BUTTON_5, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_5));
helpbox.addLine(NEUTRINO_ICON_BUTTON_6, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_6));
helpbox.addLine(NEUTRINO_ICON_BUTTON_7, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_7));
helpbox.addLine(NEUTRINO_ICON_BUTTON_8, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_8));
helpbox.addLine(NEUTRINO_ICON_BUTTON_9, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_9));
helpbox.addSeparatorLine();
helpbox.addLine(NEUTRINO_ICON_BUTTON_MENU, g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_BUTTON_MENU));
helpbox.addSeparator();
helpbox.addLine(g_Locale->getText(LOCALE_MOVIEPLAYER_HELP_ADDITIONAL));
helpbox.addExitKey(CRCInput::RC_ok);
helpbox.show();
helpbox.exec();
helpbox.hide();
}
void CMoviePlayerGui::selectChapter()
{
if (!is_file_player)
return;
std::vector<int> positions; std::vector<std::string> titles;
playback->GetChapters(positions, titles);
std::vector<int> playlists; std::vector<std::string> ptitles;
int current = 0;
playback->GetTitles(playlists, ptitles, current);
if (positions.empty() && playlists.empty())
return;
CMenuWidget ChSelector(LOCALE_MOVIEBROWSER_MENU_MAIN_BOOKMARKS, NEUTRINO_ICON_AUDIO);
//ChSelector.addIntroItems();
ChSelector.addItem(GenericMenuCancel);
int pselect = -1;
CMenuSelectorTarget * pselector = new CMenuSelectorTarget(&pselect);
int select = -1;
CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select);
char cnt[5];
if (!playlists.empty()) {
ChSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MOVIEPLAYER_TITLES));
for (unsigned i = 0; i < playlists.size(); i++) {
sprintf(cnt, "%d", i);
CMenuForwarder * item = new CMenuForwarder(ptitles[i].c_str(), current != playlists[i], NULL, pselector, cnt);
ChSelector.addItem(item);
}
}
if (!positions.empty()) {
ChSelector.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MOVIEPLAYER_CHAPTERS));
for (unsigned i = 0; i < positions.size(); i++) {
sprintf(cnt, "%d", i);
CMenuForwarder * item = new CMenuForwarder(titles[i].c_str(), true, NULL, selector, cnt, CRCInput::convertDigitToKey(i + 1));
ChSelector.addItem(item, position > positions[i]);
}
}
ChSelector.exec(NULL, "");
delete selector;
delete pselector;
printf("CMoviePlayerGui::selectChapter: selected %d (%d)\n", select, (select >= 0) ? positions[select] : -1);
printf("CMoviePlayerGui::selectChapter: pselected %d (%d)\n", pselect, (pselect >= 0) ? playlists[pselect] : -1);
if (select >= 0) {
playback->SetPosition(positions[select], true);
} else if (pselect >= 0) {
numsubs = numpida = 0;
currentspid = -1;
currentapid = 0;
playback->SetTitle(playlists[pselect]);
}
}
void CMoviePlayerGui::selectSubtitle()
{
if (!is_file_player)
return;
CMenuWidget APIDSelector(LOCALE_SUBTITLES_HEAD, NEUTRINO_ICON_AUDIO);
APIDSelector.addIntroItems();
int select = -1;
CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select);
if (!numsubs)
playback->FindAllSubs(spids, sub_supported, &numsubs, slanguage);
CMenuOptionStringChooser * sc = new CMenuOptionStringChooser(LOCALE_SUBTITLES_CHARSET, &g_settings.subs_charset, currentspid == -1, NULL, CRCInput::RC_red, NULL, true);
sc->addOption("UTF-8");
sc->addOption("UCS-2");
sc->addOption("CP1250");
sc->addOption("CP1251");
sc->addOption("CP1252");
sc->addOption("CP1253");
sc->addOption("KOI8-R");
APIDSelector.addItem(sc);
APIDSelector.addItem(GenericMenuSeparatorLine);
char cnt[5];
unsigned int count;
for (count = 0; count < numsubs; count++) {
bool enabled = sub_supported[count] && (currentspid != spids[count]);
std::string title = slanguage[count];
if (title.empty()) {
char pidnumber[20];
sprintf(pidnumber, "Stream %d %X", count + 1, spids[count]);
title = pidnumber;
}
sprintf(cnt, "%d", count);
CMenuForwarder * item = new CMenuForwarder(title.c_str(), enabled, NULL, selector, cnt, CRCInput::convertDigitToKey(count + 1));
APIDSelector.addItem(item);
}
sprintf(cnt, "%d", count);
APIDSelector.addItem(new CMenuForwarder(LOCALE_SUBTITLES_STOP, currentspid != -1, NULL, selector, cnt, CRCInput::RC_stop), currentspid > 0);
APIDSelector.exec(NULL, "");
delete selector;
printf("CMoviePlayerGui::selectSubtitle: selected %d (%x) current %x\n", select, (select >= 0) ? spids[select] : -1, currentspid);
if ((select >= 0) && (select < numsubs) && (currentspid != spids[select])) {
currentspid = spids[select];
/* external subtitles pid is 0x1FFF */
ext_subs = (currentspid == 0x1FFF);
playback->SelectSubtitles(currentspid, g_settings.subs_charset);
printf("[movieplayer] spid changed to %d\n", currentspid);
} else if (select > 0) {
ext_subs = false;
currentspid = -1;
playback->SelectSubtitles(currentspid, g_settings.subs_charset);
printf("[movieplayer] spid changed to %d\n", currentspid);
}
}
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}
void CMoviePlayerGui::clearSubtitle(bool lock)
{
if ((max_x-min_x > 0) && (max_y-min_y > 0))
frameBuffer->paintBackgroundBoxRel(min_x, min_y, max_x-min_x, max_y-min_y);
min_x = CFrameBuffer::getInstance()->getScreenWidth();
min_y = CFrameBuffer::getInstance()->getScreenHeight();
max_x = CFrameBuffer::getInstance()->getScreenX();
max_y = CFrameBuffer::getInstance()->getScreenY();
end_time = 0;
lock_subs = lock;
}
fb_pixel_t * simple_resize32(uint8_t * orgin, uint32_t * colors, int nb_colors, int ox, int oy, int dx, int dy);
bool CMoviePlayerGui::convertSubtitle(std::string &text)
{
bool ret = false;
iconv_t cd = iconv_open("UTF-8", g_settings.subs_charset.c_str());
if (cd == (iconv_t)-1) {
perror("iconv_open");
return ret;
}
size_t ilen = text.length();
size_t olen = ilen*4;
size_t len = olen;
char * buf = (char *) calloc(olen + 1, 1);
if (buf == NULL) {
iconv_close(cd);
return ret;
}
char * out = buf;
char * in = (char *) text.c_str();
if (iconv(cd, &in, &ilen, &out, &olen) == (size_t)-1) {
printf("CMoviePlayerGui::convertSubtitle: iconv error\n");
}
else {
memset(buf + (len - olen), 0, olen);
text = buf;
}
free(buf);
iconv_close(cd);
return true;
}
void CMoviePlayerGui::showSubtitle(neutrino_msg_data_t data)
{
AVSubtitle * sub = (AVSubtitle *) data;
if (lock_subs) {
if (sub) {
avsubtitle_free(sub);
delete sub;
}
return;
}
if (!data) {
if (end_time && time_monotonic_ms() > end_time) {
printf("************************* hide subs *************************\n");
clearSubtitle();
}
return;
}
printf("************************* EVT_SUBT_MESSAGE: num_rects %d fmt %d *************************\n", sub->num_rects, sub->format);
#if 0
if (!sub->num_rects)
return;
#endif
if (sub->format == 0) {
int xres = 0, yres = 0, framerate;
videoDecoder->getPictureInfo(xres, yres, framerate);
double xc, yc;
if (sub->num_rects && (sub->rects[0]->x + sub->rects[0]->w) <= 720 &&
sub->rects[0]->y + sub->rects[0]->h <= 576) {
xc = (double) CFrameBuffer::getInstance()->getScreenWidth(/*true*/)/(double) 720;
yc = (double) CFrameBuffer::getInstance()->getScreenHeight(/*true*/)/(double) 576;
} else {
xc = (double) CFrameBuffer::getInstance()->getScreenWidth(/*true*/)/(double) xres;
yc = (double) CFrameBuffer::getInstance()->getScreenHeight(/*true*/)/(double) yres;
}
clearSubtitle();
for (unsigned i = 0; i < sub->num_rects; i++) {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 5, 0)
uint32_t * colors = (uint32_t *) sub->rects[i]->pict.data[1];
#else
uint32_t * colors = (uint32_t *) sub->rects[i]->data[1];
#endif
int xoff = (double) sub->rects[i]->x * xc;
int yoff = (double) sub->rects[i]->y * yc;
int nw = frameBuffer->getWidth4FB_HW_ACC(xoff, (double) sub->rects[i]->w * xc);
int nh = (double) sub->rects[i]->h * yc;
printf("Draw: #%d at %d,%d size %dx%d colors %d (x=%d y=%d w=%d h=%d) \n", i+1,
sub->rects[i]->x, sub->rects[i]->y, sub->rects[i]->w, sub->rects[i]->h,
sub->rects[i]->nb_colors, xoff, yoff, nw, nh);
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 5, 0)
fb_pixel_t * newdata = simple_resize32 (sub->rects[i]->pict.data[0], colors,
sub->rects[i]->nb_colors, sub->rects[i]->w, sub->rects[i]->h, nw, nh);
#else
fb_pixel_t * newdata = simple_resize32 (sub->rects[i]->data[0], colors,
sub->rects[i]->nb_colors, sub->rects[i]->w, sub->rects[i]->h, nw, nh);
#endif
frameBuffer->blit2FB(newdata, nw, nh, xoff, yoff);
free(newdata);
min_x = std::min(min_x, xoff);
max_x = std::max(max_x, xoff + nw);
min_y = std::min(min_y, yoff);
max_y = std::max(max_y, yoff + nh);
}
//end_time = sub->end_display_time + time_monotonic_ms();
end_time = 10*1000;
if (sub->end_display_time != UINT32_MAX)
end_time = sub->end_display_time;
end_time += time_monotonic_ms();
avsubtitle_free(sub);
delete sub;
return;
}
std::vector<std::string> subtext;
for (unsigned i = 0; i < sub->num_rects; i++) {
char * txt = NULL;
if (sub->rects[i]->type == SUBTITLE_TEXT)
txt = sub->rects[i]->text;
else if (sub->rects[i]->type == SUBTITLE_ASS)
txt = sub->rects[i]->ass;
printf("subt[%d] type %d [%s]\n", i, sub->rects[i]->type, txt ? txt : "");
if (txt) {
int len = strlen(txt);
if (len > 10 && memcmp(txt, "Dialogue: ", 10) == 0) {
char* p = txt;
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(55, 69, 100)
int skip_commas = 4;
#else
int skip_commas = 9;
#endif
/* skip ass times */
for (int j = 0; j < skip_commas && *p != '\0'; p++)
if (*p == ',')
j++;
/* skip ass tags */
if (*p == '{') {
char * d = strchr(p, '}');
if (d)
p += d - p + 1;
}
char * d = strchr(p, '{');
if (d && strchr(d, '}'))
*d = 0;
len = strlen(p);
/* remove newline */
for (int j = len-1; j > 0; j--) {
if (p[j] == '\n' || p[j] == '\r')
p[j] = 0;
else
break;
}
if (*p == '\0')
continue;
txt = p;
}
//printf("title: [%s]\n", txt);
std::string str(txt);
size_t start = 0, end = 0;
/* split string with \N as newline */
std::string delim("\\N");
while ((end = str.find(delim, start)) != std::string::npos) {
subtext.push_back(str.substr(start, end - start));
start = end + 2;
}
subtext.push_back(str.substr(start));
}
}
for (unsigned i = 0; i < subtext.size(); i++) {
if (!isUTF8(subtext[i])) {
if (g_settings.subs_charset != "UTF-8")
convertSubtitle(subtext[i]);
else
subtext[i] = convertLatin1UTF8(subtext[i]);
}
printf("subtext %d: [%s]\n", i, subtext[i].c_str());
}
printf("********************************************************************\n");
if (!subtext.empty()) {
int sh = frameBuffer->getScreenHeight();
int sw = frameBuffer->getScreenWidth();
int h = g_Font[SNeutrinoSettings::FONT_TYPE_SUBTITLES]->getHeight();
int height = h*subtext.size();
clearSubtitle();
int x[subtext.size()];
int y[subtext.size()];
for (unsigned i = 0; i < subtext.size(); i++) {
int w = g_Font[SNeutrinoSettings::FONT_TYPE_SUBTITLES]->getRenderWidth (subtext[i]);
x[i] = (sw - w) / 2;
y[i] = sh - height + h*(i + 1);
min_x = std::min(min_x, x[i]);
max_x = std::max(max_x, x[i]+w);
min_y = std::min(min_y, y[i]-h);
max_y = std::max(max_y, y[i]);
}
frameBuffer->paintBoxRel(min_x, min_y, max_x - min_x, max_y-min_y, COL_MENUCONTENT_PLUS_0);
for (unsigned i = 0; i < subtext.size(); i++)
g_Font[SNeutrinoSettings::FONT_TYPE_SUBTITLES]->RenderString(x[i], y[i], sw, subtext[i].c_str(), COL_MENUCONTENT_TEXT);
end_time = sub->end_display_time + time_monotonic_ms();
}
avsubtitle_free(sub);
delete sub;
}
void CMoviePlayerGui::selectAutoLang()
{
if (!numsubs)
playback->FindAllSubs(spids, sub_supported, &numsubs, slanguage);
if (ext_subs) {
for (unsigned count = 0; count < numsubs; count++) {
if (spids[count] == 0x1FFF) {
currentspid = spids[count];
playback->SelectSubtitles(currentspid, g_settings.subs_charset);
}
}
}
if (g_settings.auto_lang && (numpida > 1)) {
int pref_idx = -1;
playback->FindAllPids(apids, ac3flags, &numpida, language);
for(int i = 0; i < 3; i++) {
for (unsigned j = 0; j < numpida; j++) {
std::map<std::string, std::string>::const_iterator it;
for(it = iso639.begin(); it != iso639.end(); ++it) {
if (g_settings.pref_lang[i] == it->second && strncasecmp(language[j].c_str(), it->first.c_str(), 3) == 0) {
bool enabled = true;
// TODO: better check of supported
std::string audioname;
addAudioFormat(j, audioname, enabled);
if (enabled)
pref_idx = j;
break;
}
}
if (pref_idx >= 0)
break;
}
if (pref_idx >= 0)
break;
}
if (pref_idx >= 0) {
currentapid = apids[pref_idx];
currentac3 = ac3flags[pref_idx];
playback->SetAPid(currentapid, currentac3);
getCurrentAudioName(is_file_player, currentaudioname);
}
}
if (isWebTV && g_settings.auto_subs && numsubs > 0) {
for(int i = 0; i < 3; i++) {
if(g_settings.pref_subs[i].empty() || g_settings.pref_subs[i] == "none")
continue;
std::string temp(g_settings.pref_subs[i]);
std::string slang;
for (int j = 0 ; j < numsubs; j++) {
if (!sub_supported[j])
continue;
slang = slanguage[j].substr(0, 3);
std::map<std::string, std::string>::const_iterator it;
for(it = iso639.begin(); it != iso639.end(); ++it) {
if(temp == it->second && slang == it->first) {
currentspid = spids[j];
break;
}
}
if (currentspid > 0)
break;
}
if (currentspid > 0) {
playback->SelectSubtitles(currentspid, g_settings.subs_charset);
printf("[movieplayer] spid changed to %d %s (%s)\n", currentspid, temp.c_str(), slang.c_str());
break;
}
}
}
}
void CMoviePlayerGui::parsePlaylist(CFile *file)
{
std::ifstream infile;
char cLine[1024];
char name[1024] = { 0 };
infile.open(file->Name.c_str(), std::ifstream::in);
filelist_it = filelist.erase(filelist_it);
CFile tmp_file;
while (infile.good())
{
infile.getline(cLine, sizeof(cLine));
size_t len = strlen(cLine);
if (len > 0 && cLine[len-1]=='\r')
cLine[len-1]=0;
int dur;
sscanf(cLine, "#EXTINF:%d,%[^\n]\n", &dur, name);
if (len > 0 && cLine[0]!='#')
{
char *url = NULL;
if ((url = strstr(cLine, "http://")) || (url = strstr(cLine, "https://")) || (url = strstr(cLine, "rtmp://")) || (url = strstr(cLine, "rtsp://")) || (url = strstr(cLine, "mmsh://")) ) {
if (url != NULL) {
printf("name %s [%d] url: %s\n", name, dur, url);
tmp_file.Name = name;
tmp_file.Url = url;
filelist.push_back(tmp_file);
}
}
}
}
filelist_it = filelist.begin();
}
bool CMoviePlayerGui::mountIso(CFile *file)
{
printf("ISO file passed: %s\n", file->Name.c_str());
safe_mkdir(ISO_MOUNT_POINT);
if (my_system(5, "mount", "-o", "loop", file->Name.c_str(), ISO_MOUNT_POINT) == 0) {
makeFilename();
file_name = "/media/iso";
iso_file = true;
return true;
}
return false;
}
void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover)
{
if (autoshot && (autoshot_done || !g_settings.auto_cover))
return;
bool cover = autoshot || g_settings.screenshot_cover || forcover;
char ending[(sizeof(int)*2) + 6] = ".jpg";
if (!cover)
snprintf(ending, sizeof(ending) - 1, "_%x.jpg", position);
std::string fname = file_name;
if (p_movie_info)
fname = p_movie_info->file.Name;
/* quick check we have file and not url as file name */
if (fname.c_str()[0] != '/') {
if (autoshot)
autoshot_done = true;
return;
}
std::string::size_type pos = fname.find_last_of('.');
if (pos != std::string::npos) {
fname.replace(pos, fname.length(), ending);
} else
fname += ending;
if (autoshot && !access(fname.c_str(), F_OK)) {
printf("CMoviePlayerGui::makeScreenShot: cover [%s] already exist..\n", fname.c_str());
autoshot_done = true;
return;
}
if (!cover) {
pos = fname.find_last_of('/');
if (pos != std::string::npos)
fname.replace(0, pos, g_settings.screenshot_dir);
}
CScreenShot * sc = new CScreenShot(fname);
if (cover) {
sc->EnableOSD(false);
sc->EnableVideo(true);
}
if (autoshot || forcover) {
int xres = 0, yres = 0, framerate;
videoDecoder->getPictureInfo(xres, yres, framerate);
if (xres && yres) {
int w = std::min(300, xres);
int h = (float) yres / ((float) xres / (float) w);
sc->SetSize(w, h);
}
}
sc->Start();
if (autoshot)
autoshot_done = true;
}
size_t CMoviePlayerGui::GetReadCount()
{
uint64_t this_read = 0;
this_read = playback->GetReadCount();
uint64_t res;
if (this_read < last_read)
res = 0;
else
res = this_read - last_read;
last_read = this_read;
//printf("GetReadCount: %lld\n", res);
return (size_t) res;
}
void CMoviePlayerGui::screensaver(bool on)
{
if (on)
{
m_screensaver = true;
CScreenSaver::getInstance()->Start();
}
else
{
CScreenSaver::getInstance()->Stop();
m_screensaver = false;
m_idletime = time(NULL);
}
}