diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 0bd766ee4..7165c886a 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -180,6 +180,7 @@ install_DATA += \ numericpad.png \ ok.png \ personalize.png \ + pip.png \ power.png \ powervu_green.png \ powervu_white.png \ diff --git a/data/icons/pip.png b/data/icons/pip.png new file mode 100644 index 000000000..101a2b254 Binary files /dev/null and b/data/icons/pip.png differ diff --git a/data/locale/english.locale b/data/locale/english.locale index ecc235b4e..6718517bd 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -360,6 +360,7 @@ extra.fec_s2_qpsk_9_10 9/10 s2 qpsk extra.key_current_transponder Current Transponder Key extra.key_list_end end extra.key_list_start home +extra.key_pip PiP extra.key_plugin One touch plugin extra.key_screenshot Screenshot key extra.key_timeshift Timeshift @@ -843,6 +844,7 @@ menu.hint_key_mptime Assign button to show play time\nleft time menu.hint_key_mptimeshift Assign button to start timeshift menu.hint_key_pagedown Assign button to show next items page menu.hint_key_pageup Assign button to show previous items page +menu.hint_key_pip Assign button to top PiP menu.hint_key_poweroff Assign button to switch power state\n (standby/deepstandby <-> running) menu.hint_key_quickzap Configure keybingdings for quick\nchannel switch menu.hint_key_repeatblock Delay after button press and before\nfirst key repeat @@ -1078,11 +1080,15 @@ menu.hint_vfd_statusline Choose what to display in short\nVFD status line menu.hint_video Video output, resolution, format\nAspect ratio, fast mode switch options menu.hint_video_43mode Display mode for 4:3 content\non 16:9 TV menu.hint_video_analog_mode Select analog output mode\nfor SCART and CINCH connectors +menu.hint_video_brightness Change picture brightness menu.hint_video_cinch_mode Select analog output mode for\ncomposite video out +menu.hint_video_contrast Change picture contrast menu.hint_video_dbdr MPEG2 enhancement filters menu.hint_video_format TV aspect ratio menu.hint_video_mode HDMI output video mode menu.hint_video_modes VF key will cycle between enabled modes +menu.hint_video_pip Picture in picture size and position +menu.hint_video_saturation Change picture saturation menu.hint_video_scart_mode Select analog output mode for SCART connectors menu.hint_volume_digits Numeric display of the volumebar on/off menu.hint_volume_pos Select volume indicator position @@ -1837,6 +1843,8 @@ videomenu.hue Hue videomenu.letterbox Letterbox videomenu.panscan Pan&Scan videomenu.panscan2 14:9 Pan&Scan +videomenu.pip PiP setup +videomenu.pip_error PiP start failed videomenu.saturation Saturation videomenu.scart Scart videomenu.screensetup Screen Setup diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 46a87863f..e4e3b9cb9 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -1613,13 +1613,21 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend * } if (unlock) CFEManager::getInstance()->unlockFrontend(live_fe); - } else { + } +#ifdef DYNAMIC_DEMUX + else { frontend = CFEManager::getInstance()->allocateFE(channel, true); } printf("%s: record demux: %d\n", __FUNCTION__, channel->getRecordDemux()); if (channel->getRecordDemux() == 0) ret = false; +#endif if(ret) { +#ifdef BOXMODEL_APOLLO + if (CZapit::getInstance()->GetPipChannelID() == channel_id) + CZapit::getInstance()->StopPip(); +#endif + if(StopSectionsd) { printf("%s: g_Sectionsd->setPauseScanning(true)\n", __FUNCTION__); g_Sectionsd->setPauseScanning(true); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 91c7ca707..9db1b6516 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -108,6 +108,7 @@ libneutrino_gui_a_SOURCES = \ user_menue_setup.cpp \ vfd_setup.cpp \ videosettings.cpp \ + pipsetup.cpp \ zapit_setup.cpp libneutrino_gui2_a_SOURCES = \ diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index f8437f611..97a6d8253 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -778,6 +778,21 @@ int CChannelList::show() loop=false; } } +#ifdef BOXMODEL_APOLLO + else if ( msg == CRCInput::RC_play) { + if(SameTP() && CRecordManager::getInstance()->GetRecordMode(chanlist[selected]->channel_id) == CRecordManager::RECMODE_OFF) { + if (CZapit::getInstance()->GetPipChannelID() == chanlist[selected]->getChannelID()) { + CZapit::getInstance()->StopPip(); + paint(); + } else { + if (CZapit::getInstance()->StartPip(chanlist[selected]->getChannelID())) + paint(); + else + DisplayErrorMessage(g_Locale->getText(LOCALE_VIDEOMENU_PIP_ERROR)); + } + } + } +#endif else if (( msg == CRCInput::RC_spkr ) && new_zap_mode ) { if(CNeutrinoApp::getInstance()->getMode() != NeutrinoMessages::mode_ts) { switch (new_zap_mode) { @@ -1856,11 +1871,19 @@ void CChannelList::paintItem(int pos) rec_mode = CRecordManager::getInstance()->GetRecordMode(chanlist[curr]->channel_id); //set recording icon - const char * rec_icon = ""; + std::string rec_icon; if (rec_mode & CRecordManager::RECMODE_REC) rec_icon = NEUTRINO_ICON_REC; else if (rec_mode & CRecordManager::RECMODE_TSHIFT) rec_icon = NEUTRINO_ICON_AUTO_SHIFT; +#ifdef BOXMODEL_APOLLO + else if (chanlist[curr]->channel_id == CZapit::getInstance()->GetPipChannelID()) { + int h; + frameBuffer->getIconSize(NEUTRINO_ICON_PIP, &ChannelList_Rec, &h); + rec_icon = NEUTRINO_ICON_PIP; + ChannelList_Rec += 8; + } +#endif //calculating icons int icon_x = (x+width-15-2) - RADIUS_LARGE/2; @@ -1875,7 +1898,8 @@ void CChannelList::paintItem(int pos) r_icon_x = r_icon_x - s_icon_w; //paint recording icon - if (rec_mode != CRecordManager::RECMODE_OFF) + //if (rec_mode != CRecordManager::RECMODE_OFF) + if (!rec_icon.empty()) frameBuffer->paintIcon(rec_icon, r_icon_x - r_icon_w, ypos, fheight);//ypos + (fheight - 16)/2); //paint buttons diff --git a/src/gui/keybind_setup.cpp b/src/gui/keybind_setup.cpp index 376452cb2..1b014f6b3 100644 --- a/src/gui/keybind_setup.cpp +++ b/src/gui/keybind_setup.cpp @@ -184,7 +184,8 @@ const key_settings_struct_t key_settings[CKeybindSetup::KEYBINDS_COUNT] = {LOCALE_MPKEY_PLUGIN, &g_settings.mpkey_plugin, LOCALE_MENU_HINT_KEY_MPPLUGIN }, /*{LOCALE_EXTRA_KEY_PLUGIN, &g_settings.key_plugin, },*/ {LOCALE_EXTRA_KEY_UNLOCK, &g_settings.key_unlock, LOCALE_MENU_HINT_KEY_UNLOCK}, - {LOCALE_EXTRA_KEY_SCREENSHOT, &g_settings.key_screenshot, LOCALE_MENU_HINT_KEY_SCREENSHOT } + {LOCALE_EXTRA_KEY_SCREENSHOT, &g_settings.key_screenshot, LOCALE_MENU_HINT_KEY_SCREENSHOT }, + {LOCALE_EXTRA_KEY_PIP, &g_settings.key_pip, LOCALE_MENU_HINT_KEY_PIP } }; @@ -311,6 +312,12 @@ void CKeybindSetup::showKeyBindSetup(CMenuWidget *bindSettings) mf = new CMenuDForwarder(key_settings[KEY_SCREENSHOT].keydescription, true, keychooser[KEY_SCREENSHOT]->getKeyName(), keychooser[KEY_SCREENSHOT]); mf->setHint("", key_settings[KEY_SCREENSHOT].hint); bindSettings->addItem(mf); +#ifdef BOXMODEL_APOLLO + // pip + mf = new CMenuDForwarder(key_settings[KEY_PIP].keydescription, true, keychooser[KEY_PIP]->getKeyName(), keychooser[KEY_PIP]); + mf->setHint("", key_settings[KEY_PIP].hint); + bindSettings->addItem(mf); +#endif //bindSettings->addItem(new CMenuOptionChooser(LOCALE_EXTRA_ZAP_CYCLE, &g_settings.zap_cycle, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true)); // left-exit, FIXME is this option really change anything ?? diff --git a/src/gui/keybind_setup.h b/src/gui/keybind_setup.h index e936219cf..cdb49b041 100644 --- a/src/gui/keybind_setup.h +++ b/src/gui/keybind_setup.h @@ -76,6 +76,7 @@ class CKeybindSetup : public CMenuTarget, public CChangeObserver /*KEY_PLUGIN,*/ KEY_UNLOCK, KEY_SCREENSHOT, + KEY_PIP, KEYBINDS_COUNT }; diff --git a/src/gui/pipsetup.cpp b/src/gui/pipsetup.cpp new file mode 100644 index 000000000..a3679c762 --- /dev/null +++ b/src/gui/pipsetup.cpp @@ -0,0 +1,219 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define PERCENT 5 +#define XMOVE 10 +#define YMOVE 10 + +#ifdef BOXMODEL_APOLLO + +extern cVideo *pipDecoder; + +CPipSetup::CPipSetup() +{ + frameBuffer = CFrameBuffer::getInstance(); + x_coord = g_settings.pip_x; + y_coord = g_settings.pip_y; + width = g_settings.pip_width; + height = g_settings.pip_height; + + maxw = frameBuffer->getScreenWidth(true); + maxh = frameBuffer->getScreenHeight(true); + minw = maxw/8; + minh = minw*1000/1825; +} + +void CPipSetup::move(int x, int y, bool abs) +{ + int newx, newy; + + if(abs) { + newx = x; + newy = y; + } else { + newx = x_coord + x; + newy = y_coord + y; + if(newx < 0) newx = 0; + else if((newx + width) >= maxw) newx = maxw - width; + if(newy < 0) newy = 0; + else if((newy + height) >= maxh) newy = maxh - height; + } + x_coord = newx; + y_coord = newy; + g_settings.pip_x = x_coord; + g_settings.pip_y = y_coord; + + printf("CPipSetup::move: x %d y %d\n", x_coord, y_coord); + pipDecoder->Pig(x_coord, y_coord, width, height, maxw, maxh); +} + +// w and h is percent, if not absolute +void CPipSetup::resize(int w, int h, bool abs) +{ + int neww, newh; + + if(abs) { + width = w; + height = h; + } else { + neww = width + (maxw*w/100); + //newh = neww * 100 / 125; + newh = height + (maxh*h/100); + + if(neww > maxw) neww = maxw; + else if(neww < minw) neww = minw; + + if(newh > maxh) newh = maxh; + else if(newh < minh) newh = minh; + if( (x_coord + neww) > maxw) + return; + if( (y_coord + newh) > maxh) + return; + width = neww; + height = newh; + } + g_settings.pip_width = width; + g_settings.pip_height = height; + + printf("CPipSetup::resize: w %d h %d \n", width, height); + pipDecoder->Pig(x_coord, y_coord, width, height, maxw, maxh); +} + +int CPipSetup::exec(CMenuTarget* parent, const std::string &) +{ + neutrino_msg_t msg; + neutrino_msg_data_t data; + int oldx = x_coord; + int oldy = y_coord; + int oldw = width; + int oldh = height; + + printf("CPipSetup::exec\n"); + int res = menu_return::RETURN_REPAINT; + + if (parent) + parent->hide(); + + paint(); + + uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + + bool loop=true; + while (loop) { + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd, true); + + if ( msg <= CRCInput::RC_MaxRC ) + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + + switch (msg) { + case CRCInput::RC_timeout: + case CRCInput::RC_ok: + loop = false; + break; + case CRCInput::RC_setup: + res = menu_return::RETURN_EXIT_ALL; + loop = false; + break; + case CRCInput::RC_home: + loop = false; + case CRCInput::RC_spkr: + clear(); + move(oldx, oldy, true); + resize(oldw, oldh, true); + paint(); + break; + case CRCInput::RC_up: + clear(); + move(0, -YMOVE); + paint(); + break; + case CRCInput::RC_down: + clear(); + move(0, YMOVE); + paint(); + break; + case CRCInput::RC_left: + clear(); + move(-XMOVE, 0); + paint(); + break; + case CRCInput::RC_right: + clear(); + move(XMOVE, 0); + paint(); + break; + case CRCInput::RC_plus: + clear(); + resize(PERCENT, PERCENT); + paint(); + break; + case CRCInput::RC_minus: + clear(); + resize(-PERCENT, -PERCENT); + paint(); + break; + default: + if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) { + loop = false; + res = menu_return::RETURN_EXIT_ALL; + } + } + } + hide(); + return res; +} + +void CPipSetup::hide() +{ + frameBuffer->Clear(); +} + +void CPipSetup::clear() +{ + frameBuffer->paintBackgroundBoxRel(x_coord, y_coord, width, height); +} + +void CPipSetup::paint() +{ + if (!frameBuffer->getActive()) + return; + + char xpos[30]; + char ypos[30]; + char wpos[30]; + char hpos[30]; + + sprintf(xpos, "X: %d", x_coord ); + sprintf(ypos, "Y: %d", y_coord ); + sprintf(wpos, "W: %d", width ); + sprintf(hpos, "H: %d", height ); + + int mheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); + int mwidth = 10 + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth("W: 9999"); + int x = (frameBuffer->getScreenWidth() - mwidth)/2; + int y = (frameBuffer->getScreenHeight() - mheight*4)/2; + + if (pipDecoder->getBlank()) + frameBuffer->paintBoxRel(x_coord, y_coord, width, height, COL_MENUCONTENT_PLUS_0); + + frameBuffer->paintBoxRel(x, y, mwidth, mheight*4, COL_MENUCONTENT_PLUS_0); + + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+5, y+mheight, mwidth, xpos, COL_MENUCONTENT); + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+5, y+mheight*2, mwidth, ypos, COL_MENUCONTENT); + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+5, y+mheight*3, mwidth, wpos, COL_MENUCONTENT); + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+5, y+mheight*4, mwidth, hpos, COL_MENUCONTENT); +} + +#endif //BOXMODEL_APOLLO diff --git a/src/gui/pipsetup.h b/src/gui/pipsetup.h new file mode 100644 index 000000000..373f3096b --- /dev/null +++ b/src/gui/pipsetup.h @@ -0,0 +1,29 @@ +#ifndef __PIP_SETUP_H_ +#define __PIP_SETUP_H_ + +#include +#include +#include + +class CPipSetup : public CMenuTarget +{ + private: + CFrameBuffer * frameBuffer; + int x_coord; + int y_coord; + int width; + int height; + int maxw; + int maxh; + int minw; + int minh; + void paint(); + void hide(); + void clear(); + public: + CPipSetup(); + void move(int x, int y, bool abs = false); + void resize(int w, int h, bool abs = false); + int exec(CMenuTarget* parent, const std::string & actionKey); +}; +#endif diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index 58a80590c..f2fbbca19 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -200,6 +200,9 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) CRecordManager::getInstance()->StopAutoRecord(); g_Zapit->stopPlayBack(); +#ifdef BOXMODEL_APOLLO + CZapit::getInstance()->StopPip(); +#endif frameBuffer->paintBackground(); videoDecoder->ShowPicture(DATADIR "/neutrino/icons/scan.jpg"); @@ -342,6 +345,8 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) videoDecoder->StopPicture(); frameBuffer->Clear(); g_Sectionsd->setPauseScanning(false); + CNeutrinoApp::getInstance()->channelList->setSelected(0xfffffff); + CNeutrinoApp::getInstance()->channelList->zapTo_ChannelID(CZapit::getInstance()->GetCurrentChannelID()); CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); return menu_return::RETURN_REPAINT; diff --git a/src/gui/videosettings.cpp b/src/gui/videosettings.cpp index da5860f90..8af4e7f8b 100644 --- a/src/gui/videosettings.cpp +++ b/src/gui/videosettings.cpp @@ -54,6 +54,10 @@ #include extern cVideo *videoDecoder; +#ifdef BOXMODEL_APOLLO +extern cVideo *pipDecoder; +#include +#endif extern int prev_video_mode; extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */ @@ -297,11 +301,19 @@ int CVideoSettings::showVideoSetup() #ifdef BOXMODEL_APOLLO /* values are from -128 to 127, but brightness really no sense after +/- 40. changeNotify multiply contrast and saturation to 3 */ CMenuOptionNumberChooser * bcont = new CMenuOptionNumberChooser(LOCALE_VIDEOMENU_BRIGHTNESS, &g_settings.brightness, true, -42, 42, this); + bcont->setHint("", LOCALE_MENU_HINT_VIDEO_BRIGHTNESS); CMenuOptionNumberChooser * ccont = new CMenuOptionNumberChooser(LOCALE_VIDEOMENU_CONTRAST, &g_settings.contrast, true, -42, 42, this); + ccont->setHint("", LOCALE_MENU_HINT_VIDEO_CONTRAST); CMenuOptionNumberChooser * scont = new CMenuOptionNumberChooser(LOCALE_VIDEOMENU_SATURATION, &g_settings.saturation, true, -42, 42, this); + scont->setHint("", LOCALE_MENU_HINT_VIDEO_SATURATION); videosetup->addItem(bcont); videosetup->addItem(ccont); videosetup->addItem(scont); + + CPipSetup pip; + CMenuForwarder * pipsetup = new CMenuForwarder(LOCALE_VIDEOMENU_PIP, true, NULL, &pip); + pipsetup->setHint("", LOCALE_MENU_HINT_VIDEO_PIP); + videosetup->addItem(pipsetup); #endif int res = videosetup->exec(NULL, ""); selected = videosetup->getSelected(); @@ -332,6 +344,9 @@ void CVideoSettings::setVideoSettings() videoDecoder->setAspectRatio(g_settings.video_Format, -1); #endif videoDecoder->setAspectRatio(g_settings.video_Format, g_settings.video_43mode); +#ifdef BOXMODEL_APOLLO + pipDecoder->setAspectRatio(g_settings.video_Format, g_settings.video_43mode); +#endif videoDecoder->SetDBDR(g_settings.video_dbdr); CAutoModeNotifier anotify; @@ -340,6 +355,7 @@ void CVideoSettings::setVideoSettings() changeNotify(LOCALE_VIDEOMENU_BRIGHTNESS, NULL); changeNotify(LOCALE_VIDEOMENU_CONTRAST, NULL); changeNotify(LOCALE_VIDEOMENU_SATURATION, NULL); + pipDecoder->Pig(g_settings.pip_x, g_settings.pip_y, g_settings.pip_width, g_settings.pip_height, frameBuffer->getScreenWidth(true), frameBuffer->getScreenHeight(true)); #endif } @@ -397,6 +413,9 @@ bool CVideoSettings::changeNotify(const neutrino_locale_t OptionName, void * /* if (g_settings.video_Format != 1 && g_settings.video_Format != 3 && g_settings.video_Format != 2) g_settings.video_Format = 3; videoDecoder->setAspectRatio(g_settings.video_Format, g_settings.video_43mode); +#ifdef BOXMODEL_APOLLO + pipDecoder->setAspectRatio(g_settings.video_Format, g_settings.video_43mode); +#endif } else if (ARE_LOCALES_EQUAL(OptionName, LOCALE_VIDEOMENU_VIDEOMODE)) { @@ -449,6 +468,9 @@ void CVideoSettings::next43Mode(void) text = VIDEOMENU_43MODE_OPTIONS[curmode].value; g_settings.video_43mode = VIDEOMENU_43MODE_OPTIONS[curmode].key; videoDecoder->setAspectRatio(-1, g_settings.video_43mode); +#ifdef BOXMODEL_APOLLO + pipDecoder->setAspectRatio(-1, g_settings.video_43mode); +#endif ShowHintUTF(LOCALE_VIDEOMENU_43MODE, g_Locale->getText(text), 450, 2); } @@ -472,6 +494,9 @@ void CVideoSettings::SwitchFormat() g_settings.video_Format = VIDEOMENU_VIDEOFORMAT_OPTIONS[curmode].key; videoDecoder->setAspectRatio(g_settings.video_Format, -1); +#ifdef BOXMODEL_APOLLO + pipDecoder->setAspectRatio(g_settings.video_Format, -1); +#endif ShowHintUTF(LOCALE_VIDEOMENU_VIDEOFORMAT, g_Locale->getText(text), 450, 2); } diff --git a/src/gui/widget/icons.h b/src/gui/widget/icons.h index 8a3685cc2..c028bbb06 100644 --- a/src/gui/widget/icons.h +++ b/src/gui/widget/icons.h @@ -163,6 +163,7 @@ #define NEUTRINO_ICON_PERSONALIZE "personalize" #define NEUTRINO_ICON_RECORDING_EVENT_MARKER "rec_event_marker" #define NEUTRINO_ICON_ZAP "zap" +#define NEUTRINO_ICON_PIP "pip" #define DUMMY_ICON "dummy" diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 4f94b8250..eaff487e5 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -317,11 +317,6 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.video_Format = configfile.getInt32("video_Format", DISPLAY_AR_16_9); g_settings.video_43mode = configfile.getInt32("video_43mode", DISPLAY_AR_MODE_LETTERBOX); -#ifdef BOXMODEL_APOLLO - g_settings.brightness = configfile.getInt32("brightness", 0); - g_settings.contrast = configfile.getInt32("contrast", 0); - g_settings.saturation = configfile.getInt32("saturation", 0); -#endif g_settings.current_volume = configfile.getInt32("current_volume", 50); g_settings.current_volume_step = configfile.getInt32("current_volume_step", 2); g_settings.channel_mode = configfile.getInt32("channel_mode", LIST_MODE_PROV); @@ -770,6 +765,15 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.screen_width = frameBuffer->getScreenWidth(true); g_settings.screen_height = frameBuffer->getScreenHeight(true); } +#ifdef BOXMODEL_APOLLO + g_settings.brightness = configfile.getInt32("brightness", 0); + g_settings.contrast = configfile.getInt32("contrast", 0); + g_settings.saturation = configfile.getInt32("saturation", 0); + g_settings.pip_x = configfile.getInt32("pip_x", 50); + g_settings.pip_y = configfile.getInt32("pip_y", 50); + g_settings.pip_width = configfile.getInt32("pip_width", 365); + g_settings.pip_height = configfile.getInt32("pip_height", 200); +#endif if(erg) configfile.setModifiedFlag(true); return erg; @@ -792,11 +796,6 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32( "analog_mode2", g_settings.analog_mode2 ); configfile.setInt32( "video_Format", g_settings.video_Format ); configfile.setInt32( "video_43mode", g_settings.video_43mode ); -#ifdef BOXMODEL_APOLLO - configfile.setInt32( "brightness", g_settings.brightness ); - configfile.setInt32( "contrast", g_settings.contrast ); - configfile.setInt32( "saturation", g_settings.saturation ); -#endif configfile.setInt32( "hdmi_cec_mode", g_settings.hdmi_cec_mode ); configfile.setInt32( "hdmi_cec_view_on", g_settings.hdmi_cec_view_on ); configfile.setInt32( "hdmi_cec_standby", g_settings.hdmi_cec_standby ); @@ -1147,7 +1146,10 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("bigFonts", g_settings.bigFonts); configfile.setInt32("big_windows", g_settings.big_windows); -#if 0 +#ifdef BOXMODEL_APOLLO + configfile.setInt32("brightness", g_settings.brightness ); + configfile.setInt32("contrast", g_settings.contrast ); + configfile.setInt32("saturation", g_settings.saturation ); configfile.setInt32("pip_x", g_settings.pip_x); configfile.setInt32("pip_y", g_settings.pip_y); configfile.setInt32("pip_width", g_settings.pip_width); @@ -2109,6 +2111,11 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) else if (msg == (neutrino_msg_t) g_settings.key_current_transponder){ numericZap( msg ); } +#ifdef BOXMODEL_APOLLO + else if (msg == (neutrino_msg_t) g_settings.key_pip) { + CZapit::getInstance()->StopPip(); + } +#endif else if (CRCInput::isNumeric(msg)) { numericZap( msg ); } @@ -2686,7 +2693,7 @@ _repeat: printf("NeutrinoMessages::INACTIVITY SLEEPTIMER: skiping\n"); skipShutdownTimer = false; return messages_return::handled; - } + } }else{ //MAIN-MENU SLEEPTIMER if(skipSleepTimer) { printf("NeutrinoMessages::SLEEPTIMER: skiping\n"); @@ -3593,6 +3600,7 @@ void CNeutrinoApp::loadKeys(const char * fname) g_settings.key_plugin = tconfig.getInt32( "key_plugin", CRCInput::RC_nokey ); g_settings.key_unlock = tconfig.getInt32( "key_unlock", CRCInput::RC_setup ); g_settings.key_screenshot = tconfig.getInt32( "key_screenshot", CRCInput::RC_nokey ); + g_settings.key_pip = tconfig.getInt32( "key_pip", CRCInput::RC_help ); g_settings.key_current_transponder = tconfig.getInt32( "key_current_transponder", CRCInput::RC_games ); g_settings.key_quickzap_up = tconfig.getInt32( "key_quickzap_up", CRCInput::RC_up ); @@ -3651,6 +3659,7 @@ void CNeutrinoApp::saveKeys(const char * fname) tconfig.setInt32( "key_plugin", g_settings.key_plugin ); tconfig.setInt32( "key_unlock", g_settings.key_unlock ); tconfig.setInt32( "key_screenshot", g_settings.key_screenshot ); + tconfig.setInt32( "key_pip", g_settings.key_pip ); tconfig.setInt32( "key_current_transponder", g_settings.key_current_transponder ); tconfig.setInt32( "key_quickzap_up", g_settings.key_quickzap_up ); diff --git a/src/system/locals.h b/src/system/locals.h index 238c0629a..355f80321 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -387,6 +387,7 @@ typedef enum LOCALE_EXTRA_KEY_CURRENT_TRANSPONDER, LOCALE_EXTRA_KEY_LIST_END, LOCALE_EXTRA_KEY_LIST_START, + LOCALE_EXTRA_KEY_PIP, LOCALE_EXTRA_KEY_PLUGIN, LOCALE_EXTRA_KEY_SCREENSHOT, LOCALE_EXTRA_KEY_TIMESHIFT, @@ -870,6 +871,7 @@ typedef enum LOCALE_MENU_HINT_KEY_MPTIMESHIFT, LOCALE_MENU_HINT_KEY_PAGEDOWN, LOCALE_MENU_HINT_KEY_PAGEUP, + LOCALE_MENU_HINT_KEY_PIP, LOCALE_MENU_HINT_KEY_POWEROFF, LOCALE_MENU_HINT_KEY_QUICKZAP, LOCALE_MENU_HINT_KEY_REPEATBLOCK, @@ -1105,11 +1107,15 @@ typedef enum LOCALE_MENU_HINT_VIDEO, LOCALE_MENU_HINT_VIDEO_43MODE, LOCALE_MENU_HINT_VIDEO_ANALOG_MODE, + LOCALE_MENU_HINT_VIDEO_BRIGHTNESS, LOCALE_MENU_HINT_VIDEO_CINCH_MODE, + LOCALE_MENU_HINT_VIDEO_CONTRAST, LOCALE_MENU_HINT_VIDEO_DBDR, LOCALE_MENU_HINT_VIDEO_FORMAT, LOCALE_MENU_HINT_VIDEO_MODE, LOCALE_MENU_HINT_VIDEO_MODES, + LOCALE_MENU_HINT_VIDEO_PIP, + LOCALE_MENU_HINT_VIDEO_SATURATION, LOCALE_MENU_HINT_VIDEO_SCART_MODE, LOCALE_MENU_HINT_VOLUME_DIGITS, LOCALE_MENU_HINT_VOLUME_POS, @@ -1864,6 +1870,8 @@ typedef enum LOCALE_VIDEOMENU_LETTERBOX, LOCALE_VIDEOMENU_PANSCAN, LOCALE_VIDEOMENU_PANSCAN2, + LOCALE_VIDEOMENU_PIP, + LOCALE_VIDEOMENU_PIP_ERROR, LOCALE_VIDEOMENU_SATURATION, LOCALE_VIDEOMENU_SCART, LOCALE_VIDEOMENU_SCREENSETUP, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 775a5f391..84365e5be 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -387,6 +387,7 @@ const char * locale_real_names[] = "extra.key_current_transponder", "extra.key_list_end", "extra.key_list_start", + "extra.key_pip", "extra.key_plugin", "extra.key_screenshot", "extra.key_timeshift", @@ -870,6 +871,7 @@ const char * locale_real_names[] = "menu.hint_key_mptimeshift", "menu.hint_key_pagedown", "menu.hint_key_pageup", + "menu.hint_key_pip", "menu.hint_key_poweroff", "menu.hint_key_quickzap", "menu.hint_key_repeatblock", @@ -1105,11 +1107,15 @@ const char * locale_real_names[] = "menu.hint_video", "menu.hint_video_43mode", "menu.hint_video_analog_mode", + "menu.hint_video_brightness", "menu.hint_video_cinch_mode", + "menu.hint_video_contrast", "menu.hint_video_dbdr", "menu.hint_video_format", "menu.hint_video_mode", "menu.hint_video_modes", + "menu.hint_video_pip", + "menu.hint_video_saturation", "menu.hint_video_scart_mode", "menu.hint_volume_digits", "menu.hint_volume_pos", @@ -1864,6 +1870,8 @@ const char * locale_real_names[] = "videomenu.letterbox", "videomenu.panscan", "videomenu.panscan2", + "videomenu.pip", + "videomenu.pip_error", "videomenu.saturation", "videomenu.scart", "videomenu.screensetup", diff --git a/src/system/settings.h b/src/system/settings.h index 984604388..c8ceefbcc 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -401,6 +401,7 @@ struct SNeutrinoSettings std::string screenshot_dir; int key_current_transponder; + int key_pip; int cacheTXT; int minimode; diff --git a/src/zapit/include/zapit/femanager.h b/src/zapit/include/zapit/femanager.h index 5b794c530..67a347536 100644 --- a/src/zapit/include/zapit/femanager.h +++ b/src/zapit/include/zapit/femanager.h @@ -33,6 +33,7 @@ #define MAX_FE 4 #define MAX_ADAPTERS 1 +//#define DYNAMIC_DEMUX //#define MAKE_FE_KEY(adapter, number) ((adapter << 8) | (number & 0xFF)) #define FECONFIGFILE CONFIGDIR "/zapit/frontend.conf" diff --git a/src/zapit/include/zapit/zapit.h b/src/zapit/include/zapit/zapit.h index 7325d8c53..f054614f7 100644 --- a/src/zapit/include/zapit/zapit.h +++ b/src/zapit/include/zapit/zapit.h @@ -132,11 +132,13 @@ class CZapit : public OpenThreads::Thread CZapitChannel * current_channel; t_channel_id live_channel_id; + t_channel_id pip_channel_id; /* scan params */ TP_params TP; fast_scan_type_t scant; CFrontend * live_fe; + CFrontend * pip_fe; audio_map_t audio_map; volume_map_t vol_map; @@ -240,6 +242,7 @@ class CZapit : public OpenThreads::Thread CZapitChannel * GetCurrentChannel() { return current_channel; }; t_channel_id GetCurrentChannelID() { return live_channel_id; }; + t_channel_id GetPipChannelID() { return pip_channel_id; }; t_channel_id GetLastTVChannel() { return lastChannelTV; } t_channel_id GetLastRADIOChannel() { return lastChannelRadio; } void SetCurrentChannelID(const t_channel_id channel_id) { live_channel_id = channel_id; }; @@ -251,5 +254,7 @@ class CZapit : public OpenThreads::Thread void SetVolume(int vol); int GetVolume() { return current_volume; }; int SetVolumePercent(int percent); + bool StartPip(const t_channel_id channel_id); + bool StopPip(); }; #endif /* __zapit_h__ */ diff --git a/src/zapit/src/femanager.cpp b/src/zapit/src/femanager.cpp index 30438e881..3aa4a4f71 100644 --- a/src/zapit/src/femanager.cpp +++ b/src/zapit/src/femanager.cpp @@ -570,6 +570,7 @@ CFrontend * CFEManager::getFrontend(CZapitChannel * channel) return free_frontend; } +#ifdef DYNAMIC_DEMUX int CFEManager::getDemux(transponder_id_t id) { for (unsigned int i = 1; i < dmap.size(); i++) { @@ -608,14 +609,18 @@ bool CFEManager::haveFreeDemux() } return false; } +#endif // DYNAMIC_DEMUX CFrontend * CFEManager::allocateFE(CZapitChannel * channel, bool forrecord) { OpenThreads::ScopedLock m_lock(mutex); fedebug = 1; + if (forrecord) + fedebug = 1; CFrontend * frontend = getFrontend(channel); if (frontend) { +#ifdef DYNAMIC_DEMUX int dnum = getDemux(channel->getTransponderId()); INFO("record demux: %d", dnum); channel->setRecordDemux(dnum); @@ -624,6 +629,11 @@ CFrontend * CFEManager::allocateFE(CZapitChannel * channel, bool forrecord) } else { cDemux::SetSource(dnum, frontend->fenumber); } +#else + channel->setRecordDemux(frontend->fenumber+1); + cDemux::SetSource(frontend->fenumber+1, frontend->fenumber); +#endif + } return frontend; } @@ -675,9 +685,11 @@ bool CFEManager::lockFrontend(CFrontend * frontend, CZapitChannel * channel) have_locked = true; if (channel) { +#ifdef DYNAMIC_DEMUX int di = channel->getRecordDemux(); if ((unsigned int) di < dmap.size()) dmap[di].Lock(channel->getTransponderId()); +#endif } return true; } @@ -688,12 +700,14 @@ bool CFEManager::unlockFrontend(CFrontend * frontend, bool unlock_demux) have_locked = false; frontend->Unlock(); if (unlock_demux) { +#ifdef DYNAMIC_DEMUX for (unsigned int i = 1; i < dmap.size(); i++) { if(dmap[i].tpid == frontend->getTsidOnid()) { dmap[i].Unlock(); break; } } +#endif } for(fe_map_iterator_t it = femap.begin(); it != femap.end(); it++) { CFrontend * fe = it->second; diff --git a/src/zapit/src/scan.cpp b/src/zapit/src/scan.cpp index ba0137b44..17ac9596b 100644 --- a/src/zapit/src/scan.cpp +++ b/src/zapit/src/scan.cpp @@ -559,8 +559,10 @@ bool CServiceScan::ScanProviders() } else { Cleanup(false); frontend->setTsidOnid(0); +#if 0 t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); CZapit::getInstance()->ZapIt(live_channel_id, false); +#endif } return (found_channels != 0); @@ -621,8 +623,10 @@ bool CServiceScan::ScanTransponder() } else { Cleanup(false); frontend->setTsidOnid(0); +#if 0 t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); CZapit::getInstance()->ZapIt(live_channel_id, false); +#endif } return (found_channels != 0); diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 40a4bd1bd..bdf3e74db 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -86,6 +86,11 @@ extern cAudio *audioDecoder; extern cDemux *audioDemux; extern cDemux *videoDemux; +#ifdef BOXMODEL_APOLLO +cVideo *pipDecoder; +cDemux *pipDemux; +#endif + cDemux *pcrDemux = NULL; /* the map which stores the wanted cable/satellites */ @@ -123,6 +128,8 @@ CZapit::CZapit() currentMode = 0; current_volume = 100; volume_percent = 0; + pip_channel_id = 0; + pip_fe = NULL; } CZapit::~CZapit() @@ -510,6 +517,11 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay } SendEvent(CZapitClient::EVT_TUNE_COMPLETE, &live_channel_id, sizeof(t_channel_id)); +#ifdef BOXMODEL_APOLLO + if (transponder_change && (live_fe == pip_fe)) + StopPip(); +#endif + if (current_channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) { current_is_nvod = true; return true; @@ -550,6 +562,75 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay return true; } +#ifdef BOXMODEL_APOLLO +bool CZapit::StopPip() +{ + if (pip_channel_id) { + INFO("[pip] stop %llx", pip_channel_id); + CCamManager::getInstance()->Stop(pip_channel_id, CCamManager::RECORD); + pipDemux->Stop(); + pipDecoder->Stop(); + pip_fe = NULL; + pip_channel_id = 0; + return true; + } + return false; +} + +bool CZapit::StartPip(const t_channel_id channel_id) +{ + CZapitChannel* newchannel; + bool transponder_change; + + StopPip(); + + if((newchannel = CServiceManager::getInstance()->FindChannel(channel_id)) == NULL) { + printf("zapit_to_record: channel_id " PRINTF_CHANNEL_ID_TYPE " not found", channel_id); + return false; + } + INFO("[pip] zap to %s (%llx tp %llx)", newchannel->getName().c_str(), newchannel->getChannelID(), newchannel->getTransponderId()); + + CFEManager::getInstance()->lockFrontend(live_fe); + CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel); + CFEManager::getInstance()->unlockFrontend(live_fe); + if(frontend == NULL) { + ERROR("Cannot get frontend\n"); + return false; + } + if(!TuneChannel(frontend, newchannel, transponder_change)) + return false; + + if(!ParsePatPmt(newchannel)) + return false; + + pip_fe = frontend; + + INFO("[pip] vpid %X apid %X pcr %X", newchannel->getVideoPid(), newchannel->getAudioPid(), newchannel->getPcrPid()); + if (pipDemux && (pipDemux->getUnit() != newchannel->getRecordDemux())) { + pipDecoder->SetDemux(NULL); + delete pipDemux; + pipDemux = new cDemux(newchannel->getRecordDemux()); + pipDemux->Open(DMX_PIP_CHANNEL); + pipDecoder->SetDemux(pipDemux); + } +#if 0 + pipDecoder->SetSyncMode(AVSYNC_DISABLED); + pipDemux->SetSyncMode(AVSYNC_DISABLED); +#endif + + pipDecoder->SetStreamType((VIDEO_FORMAT)newchannel->type); + pipDemux->pesFilter(newchannel->getVideoPid()); + pipDecoder->Start(0, newchannel->getPcrPid(), newchannel->getVideoPid()); + pipDemux->Start(); + pip_channel_id = channel_id; + + //pipDecoder->setBlank(false); + + CCamManager::getInstance()->Start(newchannel->getChannelID(), CCamManager::RECORD); + return true; +} +#endif + bool CZapit::ZapForRecord(const t_channel_id channel_id) { CZapitChannel* newchannel; @@ -569,6 +650,10 @@ bool CZapit::ZapForRecord(const t_channel_id channel_id) if(!TuneChannel(frontend, newchannel, transponder_change)) return false; +#ifdef BOXMODEL_APOLLO + if (transponder_change && (frontend == pip_fe)) + StopPip(); +#endif if(!ParsePatPmt(newchannel)) return false; @@ -1072,7 +1157,7 @@ bool CZapit::ParseCommand(CBasicMessage::Header &rmsg, int connfd) DBG("[zapit] sending EVT_SERVICES_CHANGED\n"); SendEvent(CZapitClient::EVT_SERVICES_CHANGED); live_fe->setTsidOnid(0); - ZapIt(live_channel_id, current_is_nvod); + //ZapIt(live_channel_id, current_is_nvod); //SendEvent(CZapitClient::EVT_BOUQUETS_CHANGED); break; } @@ -1938,6 +2023,9 @@ void CZapit::enterStandby(void) SaveAudioMap(); SaveVolumeMap(); StopPlayBack(true); +#ifdef BOXMODEL_APOLLO + StopPip(); +#endif if(!(currentMode & RECORD_MODE)) { pmt_stop_update_filter(&pmt_update_fd); @@ -2053,6 +2141,11 @@ bool CZapit::Start(Z_start_arg *ZapStart_arg) audioDecoder->SetDemux(audioDemux); audioDecoder->SetVideo(videoDecoder); + + pipDemux = new cDemux(); + pipDemux->Open(DMX_PIP_CHANNEL); + pipDecoder = cVideo::GetDecoder(1); + pipDecoder->SetDemux(pipDemux); #else videoDecoder = new cVideo(video_mode, videoDemux->getChannel(), videoDemux->getBuffer()); videoDecoder->Standby(false); @@ -2237,6 +2330,11 @@ void CZapit::run() delete pmtDemux; delete audioDecoder; delete audioDemux; +#ifdef BOXMODEL_APOLLO + StopPip(); + delete pipDecoder; + delete pipDemux; +#endif INFO("demuxes/decoders deleted");