]> git.vomp.tv Git - vompclient.git/commitdiff
For new raspberry version: fixes, move to new version of libav, use avresample, Bugfi...
authorMarten Richter <marten.richter@freenet.de>
Sun, 21 Sep 2014 09:00:08 +0000 (11:00 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 21 Sep 2014 09:00:08 +0000 (11:00 +0200)
24 files changed:
GNUmakefile
audioomx.cc
audioomx.h
debian/control
event.cc
event.h
imageomx.cc
imageomx.h
objects.mk
osdopenvg.cc
osdvector.cc
osdvector.h
surfacevector.cc
tvmedia.cc
tvmedia.h
vdr.cc
vepg.cc
vepg.h
vepglistadvanced.cc [new file with mode: 0644]
vepglistadvanced.h [new file with mode: 0644]
vepgsummary.cc
vvideolivetv.cc
wselectlist.cc
wselectlist.h

index d0c518ef405eb3af37678a76029f4926f683dbc7..b27c5a53a77385fb276ed4fdc400cfa1a2ffee05 100644 (file)
@@ -8,6 +8,7 @@ vomp_options=
 #vomp_options+= -DVOMP_HAS_EXIT
 
 
+
 ifeq ($(vomp_platform),mvp)
 $(info MVP crosscompiler)
 include ../crosstool/cross-var
@@ -61,10 +62,10 @@ endif
 ifeq ($(vomp_platform),raspberry)
 $(info Raspberry pi flags)
 LDFLAGS = -Wall -Wl,--format=binary -Wl,other/vdrhires.jpg -Wl,other/wallpaper720p.jpg -Wl,--format=default 
-LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lOpenVG -lopenmaxil -lbcm_host   -lavformat -lavcodec -lavutil
+LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lOpenVG -lopenmaxil -lbcm_host   -lavformat -lavcodec -lavutil -lavresample
 
 OBJECTS += main.o threadp.o  osdvector.o surfacevector.o osdopenvg.o ledraspberry.o mtdraspberry.o videoomx.o audioomx.o imageomx.o wjpegsimple.o remotelinux.o  
-LIBS+=  -lfreetype -lMagick++ 
+LIBS+= -ldl -lfontconfig -lfreetype -lMagick++ 
 CROSSLIBS = 
 INCLUDES = -DVOMP_PLATTFORM_RASPBERRY   -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads  -I/usr/include/freetype2 -I/usr/include/ImageMagick
 CXXFLAGS_DEV += -D__STDC_CONSTANT_MACROS
@@ -75,10 +76,10 @@ endif
 ifeq ($(vomp_platform),crossraspberry)
 $(info Raspberry pi flags cross compiler)
 LDFLAGS = -Wall -Wl,--format=binary -Wl,other/vdrhires.jpg -Wl,other/wallpaper720p.jpg -Wl,--format=default -Wl,--verbose -Xlinker --rpath-link=rpi-root/usr/lib/arm-linux-gnueabihf -Xlinker --rpath-link=rpi-root/lib/arm-linux-gnueabihf -Xlinker --rpath-link=rpi-root/opt/vc/lib
-LIBS = -Lrpi-root/opt/vc/lib -Lrpi-root/lib -Lrpi-root/usr/lib -Lrpi-root/lib/arm-linux-gnueabihf -Lrpi-root/usr/lib/arm-linux-gnueabihf -Lrpi-root/usr/local/lib -lpthread -lrt -lEGL -lOpenVG -lopenmaxil -lbcm_host -lavformat -lavcodec -lavutil -ldl -lfontconfig
+LIBS = -Lrpi-root/opt/vc/lib -Lrpi-root/lib -Lrpi-root/usr/lib -Lrpi-root/lib/arm-linux-gnueabihf -Lrpi-root/usr/lib/arm-linux-gnueabihf -Lrpi-root/usr/local/lib -lpthread -lrt -lEGL -lOpenVG -lopenmaxil -lbcm_host -lavformat -lavcodec -lavutil -lavresample -ldl -lfontconfig
 
 OBJECTS += main.o threadp.o osdvector.o surfacevector.o osdopenvg.o ledraspberry.o mtdraspberry.o videoomx.o audioomx.o imageomx.o wjpegsimple.o remotelinux.o
-LIBS+=  -lfreetype -lMagick++
+LIBS+=  -lfreetype -lMagick++ 
 CROSSLIBS =
 INCLUDES = -DVOMP_PLATTFORM_RASPBERRY   -Irpi-root/opt/vc/include -Irpi-root/opt/vc/include/interface/vcos/pthreads -Irpi-root/usr/include -Irpi-root/usr/include/freetype2 -Irpi-root/usr/include/ImageMagick
 CXXFLAGS_DEV += -D__STDC_CONSTANT_MACROS -mfloat-abi=hard
index ef54b81ee96641cd16e0d55e4929f8857af4167f..f6ae46f59df38ceae46f1ae693fa510a081b5dea 100644 (file)
 #include "osdopenvg.h"
 #include <bcm_host.h>
 
+extern "C" {
+#include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
+}
+
 AudioOMX::AudioOMX()
 {
   initted = 0;
@@ -57,9 +62,10 @@ AudioOMX::AudioOMX()
 
   mp23codec_libav=NULL;
   mp23codec_context_libav=NULL;
-#ifdef USE_LIBRESAMPLE
+
   resam_con_libav=NULL;
-#endif
+
+
 
   decompress_buffer=NULL;
   decompress_buffer_size=0;
@@ -850,7 +856,7 @@ int AudioOMX::InitDecoderLibAV()
                libav_mutex.Unlock();
                return 0;
        }
-#ifdef USE_LIBRESAMPLE
+
        resam_con_libav = avresample_alloc_context();
        if (resam_con_libav == NULL) {
                Log::getInstance()->log("Audio", Log::DEBUG,
@@ -861,11 +867,12 @@ int AudioOMX::InitDecoderLibAV()
        av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO,  0); // our standard format
        av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
        av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
+       av_opt_set_int(resam_con_libav, "matrix_encoding",AV_MATRIX_ENCODING_DPLII,0);
 
        av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
        av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
        av_opt_set_int(resam_con_libav, "in_channel_layout",  AV_CH_LAYOUT_5POINT1, 0); //just an example
-#endif
+
 
         av_init_packet(&incoming_paket_libav);
         decode_frame_libav=avcodec_alloc_frame();
@@ -895,10 +902,10 @@ void AudioOMX::DeinitDecoderLibAV() {
                avcodec_close(mp23codec_context_libav);
                av_free(mp23codec_context_libav);
                mp23codec_context_libav = NULL;
-#ifdef USE_LIBRESAMPLE
-               avresample_free(resam_con_libav);
+
+               avresample_free(&resam_con_libav);
                resam_con_libav=NULL;
-#endif
+
 
        }
        libav_mutex.Unlock();
@@ -1693,54 +1700,7 @@ unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int si
        }
        return size;
 }
-#ifndef USE_LIBRESAMPLE
-#define SQRT3_2      1.22474487139158904909
 
-void AudioOMX::getDownMixMatrix(unsigned long long channels,
-               int *left_mat,int *right_mat)
-{
-       int i,j;
-       double downmix_matrix[2][64];
-       for (i=0;i<64;i++) {
-               for (j=0;j<2;j++) {
-                       downmix_matrix[j][i]=0.;
-               }
-       }
-       downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
-       downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
-       downmix_matrix[0/*links*/]  [/*FRONT_CENTER*/2] = M_SQRT1_2;
-       downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
-
-       if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
-               downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
-               downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
-       } else {
-               downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
-               downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
-       }
-       downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
-    downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
-    downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
-    downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
-    downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
-    downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
-    downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
-    downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
-    downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
-    downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
-    downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
-    downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
-
-    for (i=0,j=0;i<64;i++) {
-       if ((1ULL << i)& channels) {
-               left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
-               right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
-               j++;
-       }
-    }
-}
-
-#endif
 
 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
 {
@@ -2209,7 +2169,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
 
                                int dsize = av_samples_get_buffer_size(NULL,
                                                /*current_context->channels*/2, decode_frame_libav->nb_samples,
-                                               current_context->sample_fmt, 1);
+                                               AV_SAMPLE_FMT_S16, 1);
                                int dsize_in = av_samples_get_buffer_size(NULL,
                                                                                current_context->channels, decode_frame_libav->nb_samples,
                                                                                current_context->sample_fmt, 1);
@@ -2257,73 +2217,25 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
                                }
 
                                //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
-                               if (current_context->channels==2) {
-                                       memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
-                                                       decode_frame_libav->data[0], dsize);
-                               }
-#ifndef USE_LIBRESAMPLE
-                               else if (current_context->channels==1) { //convert to stereo
-                                       short* startbuffer=(short* )decode_frame_libav->data[0];
-                                       short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
-                                       short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
-                                       while (startbuffer!=endbuffer) {
-                                               unsigned short temp=*startbuffer;
-                                               *destbuffer=temp;
-                                               destbuffer++;
-                                               *destbuffer=temp;
-                                               destbuffer++;
-                                               startbuffer++;
-                                       }
-                               } else {
-                                       unsigned int channels=current_context->channels;
-                                       int left_mat[channels];
-                                       int right_mat[channels];
-                                       getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
-
-                       short* startbuffer=(short* )decode_frame_libav->data[0];
-                                       short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
-                                       short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
-                                       while (startbuffer!=endbuffer) {
-                                               short* cur_buf=startbuffer;
-                                               short* cur_buf_end=startbuffer+channels;
-                                               int work1=0.;
-                                               int work2=0.;
-                                               int *mat1=left_mat;
-                                               int *mat2=right_mat;
-                                               while (cur_buf!=cur_buf_end) {
-                                                       work1+= ((*mat1)*(*cur_buf));
-                                                       work2+= ((*mat2)*(*cur_buf));
-                                                       cur_buf++;
-                                                       mat1++;
-                                                       mat2++;
-                                               }
-                                               *destbuffer=work1>>16;
-                                               destbuffer++;
-                                               *destbuffer=work2>>16;
-                                               destbuffer++;
-                                               startbuffer+=channels;
 
-                                       }
 
-                               }
-#else
-                               else {
-                                       //untested for future use
-                                       av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
-                                       av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
-                                       av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
-                                       int ret=avresample_open(resam_con_libav);
-                                       if (ret<0) {
-                                               Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
-                                       } else {
-                                               avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
-                                                               dsize, decode_frame_libav->nb_samples,
-                                                               decode_frame_libav->data[0],  dsize_in,  decode_frame_libav->nb_samples);
-                                               avresample_close(resam_con_libav);
-                                       }
+                               av_opt_set_int(resam_con_libav, "in_sample_rate",decode_frame_libav->sample_rate,0);
+                               av_opt_set_int(resam_con_libav, "in_sample_fmt",decode_frame_libav->format,0);
+                               av_opt_set_int(resam_con_libav, "in_channel_layout",decode_frame_libav->channel_layout, 0);
+                               //Log::getInstance()->log("Audio", Log::ERR,"AV resampledata %d %d %d %d",current_context->channels,current_context->sample_rate,current_context->sample_fmt,current_context->channel_layout);
+                               //Log::getInstance()->log("Audio", Log::ERR,"AV resampledata2 %d %d %d",decode_frame_libav->sample_rate,decode_frame_libav->format,decode_frame_libav->channel_layout);
 
+                               int ret=avresample_open(resam_con_libav);
+                               if (ret<0) {
+                                       Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
+                               } else {
+                                       uint8_t *output=cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen;
+
+                                       avresample_convert(resam_con_libav, &output,
+                                                       dsize, decode_frame_libav->nb_samples,
+                                                       decode_frame_libav->extended_data,  decode_frame_libav->linesize[0],  decode_frame_libav->nb_samples);
+                                       avresample_close(resam_con_libav);
                                }
-#endif
 
                                //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
                                cur_input_buf_omx->nFilledLen += dsize;
index b6b01e06f3daf2df69015e752ab6a5b080fba2b1..6c16d647dfec1e4f1167de71ee98552e09d8047d 100644 (file)
 #include "audio.h"
 #include "videoomx.h"
 
-//#define USE_LIBRESAMPLE // untested code for future use
 
 extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
-#ifdef USE_LIBRESAMPLE
 #include <libavresample/avresample.h>
-#endif
 }
 
 
@@ -187,11 +184,8 @@ class AudioOMX : public Audio
     AVCodecContext *mp23codec_context_libav;
     AVPacket incoming_paket_libav;
     AVFrame *decode_frame_libav;
-#ifdef USE_LIBRESAMPLE
     AVAudioResampleContext *resam_con_libav;
-#else
-    void getDownMixMatrix(unsigned long long channels,int *left_mat,int *right_mat);
-#endif
+
 
     UCHAR * decompress_buffer;
     unsigned int decompress_buffer_size;
index a91579116c191402355731e76f41c50739bd2363..fbbb69c74c86e18cf0212e643762befd25bc2436 100644 (file)
@@ -2,7 +2,7 @@ Source: vompclient
 Section: unknown
 Priority: extra
 Maintainer: Marten Richter <marten.richter@freenet.de>
-Build-Depends: debhelper (>= 8.0.0), libcec-dev (>= 1.8.1), libraspberrypi-dev, libfreetype6-dev, libmagick++-dev, libavformat-dev, libavutil-dev, libavcodec-dev
+Build-Depends: debhelper (>= 8.0.0), libcec-dev (>= 1.8.1), libraspberrypi-dev, libfreetype6-dev, libmagick++-dev, libavformat-dev, libavutil-dev, libavcodec-dev, libavresample-dev
 Standards-Version: 3.9.3
 Homepage: www.loggytronic.com/vomp.php
 Vcs-Git: http://git.vomp.tv/vompclient-raspi.git
@@ -10,7 +10,7 @@ Vcs-Browser: http://git.vomp.tv/gitweb/
 
 Package: vompclient-raspi
 Architecture: armhf
-Depends: ${shlibs:Depends}, ${misc:Depends}, libcec1 (>= 1.8.1), libraspberrypi-bin, libfreetype6, libmagick++5, libavformat53, libavutil51, libavcodec53
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcec1 (>= 1.8.1), libraspberrypi-bin, libfreetype6, libmagick++5, libavformat54, libavutil51, libavcodec54, libavresample1
 Description: vompclient for raspberry pi
  This is the vompclient binary for the raspberry pi platform.
  It connects to the  server with the vdr software including
index cd9ac395a87a01e0ca046ace326f7d046fdad143..ac272b8fc85b1e9acd7fab50874de9663ec18a59 100644 (file)
--- a/event.cc
+++ b/event.cc
@@ -25,6 +25,9 @@
 #include "seriesinfo.h"
 #include "vdr.h"
 
+MovieInfo* Event::movieInfo = NULL;
+SeriesInfo* Event::seriesInfo = NULL;
+
 Event::Event()
 {
   id = 0;
@@ -34,8 +37,9 @@ Event::Event()
   title = NULL;
   subtitle = NULL;
   description = NULL;
-  movieInfo = NULL;
-  seriesInfo = NULL;
+  index = -1;
+  movieID = 0;
+  seriesID =0;
 }
 
 Event::~Event()
@@ -43,8 +47,6 @@ Event::~Event()
   if (title) delete[] title;
   if (subtitle) delete[] subtitle;
   if (description) delete[] description;
-  if (movieInfo) delete movieInfo;
-  if (seriesInfo) delete seriesInfo;
 }
 
 void Event::settitle(const char* s)
@@ -77,13 +79,14 @@ void Event::loadinfos(UINT channelid)
 
        movieInfo = NULL;
        seriesInfo = NULL;
-       movieID = 0;
-       seriesID =0;
 
-       vdr->getScraperEventType(channelid, id, movieID, seriesID, episodeID);
-       Log::getInstance()->log("Event", Log::DEBUG, "Got Scraper EventType %d %d, %d %d %d",
-                       id, channelid,
-                       movieID, seriesID, episodeID);
+
+       if (movieID == 0 && seriesID == 0) {
+               vdr->getScraperEventType(channelid, id, movieID, seriesID, episodeID);
+               Log::getInstance()->log("Event", Log::DEBUG, "Got Scraper EventType %d %d, %d %d %d",
+                               id, channelid,
+                               movieID, seriesID, episodeID);
+       }
 
        if (!vdr->isConnected()) Command::getInstance()->connectionLost();
 
diff --git a/event.h b/event.h
index 7d8b4e78105ff9559c23438f3fb32412a4aa2567..e2ad9344380f2582c73eb5de3a6101dddfc2ae0c 100644 (file)
--- a/event.h
+++ b/event.h
@@ -55,8 +55,10 @@ class Event
     char* subtitle;
     char* description;
 
-    MovieInfo *movieInfo;
-    SeriesInfo *seriesInfo;
+    int index;
+
+    static MovieInfo *movieInfo;
+    static SeriesInfo *seriesInfo;
     int movieID;
     int seriesID;
     int episodeID;
index bd75d6eb4525bf1a93716cfdea4e491ca72846a9..5668cf38acb8bb449266885b3b358747cfd4f0a8 100644 (file)
@@ -238,9 +238,9 @@ int ImageOMX::AllocateCodecsOMX(unsigned char * buffer, unsigned int length)
 
 
 
-bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
+unsigned char* ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
 {
-       if (pictInfValid) return false; // does support only one image at a Time;
+       if (pictInfValid) return buffer; // does support only one image at a Time;
 //     Log::getInstance()->log("Image", Log::DEBUG,
 //                                     "decodePicture 1");
        EGLPictureCreator * pictcreat =dynamic_cast<EGLPictureCreator*>(Osd::getInstance());
@@ -268,7 +268,8 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i
        pthread_setcanceltype(oldcanceltype, NULL);
        if (ret && freemem) free(buffer);
 
-       return ret;
+       if (ret) return NULL;
+       else return buffer;
 }
 
 
index 1921c402a483b0bec9565b49cde9043883671079..25021fa7e6d8d74255ac3619e47e196716fda21a 100644 (file)
@@ -51,7 +51,7 @@ class ImageOMX : public OsdVector::PictureDecoder
     void init();
     void shutdown();
 
-    bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
+    unsigned char* decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
     bool getDecodedPicture(struct OsdVector::PictureInfo& pict_inf);
     void freeReference(void * ref);
 
index 7b6fec54cf0142a7032295d217960127041ddfb8..e74efec8f79ae84c5efa28127c6f0605ae96f629 100644 (file)
@@ -6,7 +6,7 @@ OBJECTS1 = command.o  tcp.o dsock.o thread.o timers.o i18n.o       \
            demuxer.o demuxervdr.o demuxerts.o stream.o            \
            region.o colour.o boxstack.o boxx.o tbboxx.o                          \
            vinfo.o vquestion.o vrecordinglist.o vrecordinglistclassic.o vrecordinglistadvanced.o vrecording.o \
-           vepgsummary.o \
+           vepgsummary.o vepglistadvanced.o \
            vmute.o vvolume.o vtimerlist.o vtimeredit.o vrecordingmenu.o          \
            vchannellist.o vwelcome.o vvideorec.o vepgsettimer.o                  \
            vchannelselect.o vserverselect.o vconnect.o vepg.o vrecmove.o         \
index 5caf58152c2f22ca86b41e61c6557383902aee0e..6c85934d1a49ae9a3882dcfd7a0e050e54a34afb 100644 (file)
@@ -1039,6 +1039,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command)
                VGImage input=vgCreateImage(VG_A_8,command.param1, command.param2,
                                VG_IMAGE_QUALITY_NONANTIALIASED|
                                VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
+               //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create palette  %d %d %x %d",command.param1,command.param2,vgGetError(),input);
                vgImageSubData(input,command.data,command.param1,
                                                        VG_A_8,0,0,command.param1, command.param2); // upload palettized image data
                VGImage handle=vgCreateImage(VG_sRGBA_8888,command.param1, command.param2,
index 07022891af9df7ad45572ae2af8a6eaabe6d8574..28e1d215ca06dd56bc34052ac6cc80b51fc0a942 100644 (file)
@@ -35,7 +35,7 @@ class MagickDecoder: public OsdVector::PictureDecoder {
 public:
        MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;};
 
-       bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
+       unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
 
     bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
 
@@ -46,15 +46,15 @@ protected:
        bool pictInfValid;
 };
 
-bool MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
+unsigned char * MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
 {
-       if (pictInfValid) return false; // does support only one image at a Time;
+       if (pictInfValid) return buffer; // does support only one image at a Time;
        Image magicimage;
        Blob *imageblob = new Blob();
-
+       Blob myblob;
        try{
                Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
-               Blob myblob;
+
                if (freemem) myblob.updateNoCopy(buffer,length,Blob::MallocAllocator);
                else myblob.update(buffer,length);
                magicimage.read(myblob);
@@ -65,8 +65,10 @@ bool MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsig
        {
                Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what());
                delete imageblob;
-
-               return false;
+               Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
+               unsigned char* newbuffer=(unsigned char*) malloc(length);
+               memcpy(newbuffer,myblob.data(),length);
+               return newbuffer;
        }
        pictInf.reference = (void*) imageblob;
        pictInf.width = magicimage.columns();
@@ -80,7 +82,7 @@ bool MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsig
 
 
        // I can handle everything, so the return value is always true
-       return true;
+       return NULL;
 }
 void MagickDecoder::freeReference(void * ref)
 {
@@ -159,6 +161,7 @@ int OsdVector::restore()
        //jpegs.clear();
        styles.clear();
        styles_ref.clear();
+       palettepics.clear();
 
        tvmedias.clear();
        loadindex_ref.clear();
@@ -431,6 +434,18 @@ void OsdVector::cleanupOrphanedRefs()
                } else ++litty;
        }
 
+       list<ImageIndex>::iterator pitty=palettepics.begin();
+       while (pitty!=palettepics.end()) {
+               map<ImageIndex,int>::iterator curitty=images_ref.find((*pitty));
+               int count=(*curitty).second;
+               if (count==0) {
+                       ImageIndex ref=(*curitty).first;
+                       palettepics.erase(pitty++);
+                       images_ref.erase(curitty++);
+                       destroyImageRef(ref);
+               } else ++pitty;
+       }
+
 
        map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
        while (sitty!=styles.end()) {
@@ -551,6 +566,9 @@ LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
                        index = ((long long) tvmedia.getPrimaryID()) << 32LL;
                        reader.addStaticImage(tvmedia.getPrimaryID());
                } break;
+               case 5:
+                       index=VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
+               break;
                default:
                        index=VDR::getInstance()->loadTVMedia(tvmedia);
                        break;
@@ -640,6 +658,7 @@ ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char
 {
        ImageIndex image_handle;
        image_handle=createImagePalette(width,height,image_data,palette_data);
+       palettepics.push_back(image_handle);
        incImageRef(image_handle);
        return image_handle;
 }
@@ -789,15 +808,15 @@ bool OsdVector::PictureReader::processReceivedPictures()
                        ULONG length=vresp->getUserDataLength();
                        std::list<PictureDecoder*>::iterator itty=decoders.begin();
                        while (itty!=decoders.end()) {
-                               if ((*itty)->decodePicture(vresp->getStreamID(),
-                                       userdata, length)){
+                               userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length);
+                               if (!userdata){
                                        decoded=true;
                                        break;
                                }
                                itty++;
                        }
-                       if (!decoded ){
-                               free(vresp->getUserData());
+                       if (!decoded && userdata ){
+                               free(userdata);
                        }
                }
                //else  osd->informPicture(vresp->getStreamID(), 0);
@@ -821,7 +840,7 @@ bool OsdVector::PictureReader::processReceivedPictures()
                {
                        std::list<PictureDecoder*>::iterator itty=decoders.begin();
                        while (itty!=decoders.end()) {
-                               if ((*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){
+                               if (!(*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){
                                        decoded=true;
                                        break;
                                }
index ad2a0b92c8540fdf14f6269ed2940897108925d9..b8d3f2156fe093788a9c2698633fa4d9685d41c8 100644 (file)
@@ -280,7 +280,7 @@ class OsdVector : public Osd
        virtual ~PictureDecoder() {};
 
        // its is always guaranted, that after getDecodedPicture a call to decodePicture follows, if the return value was true;
-       virtual bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem=true)=0;
+       virtual unsigned char * decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem=true)=0;
 
        virtual bool getDecodedPicture(struct PictureInfo& pict_inf)=0;
        virtual void freeReference(void * ref)=0;
@@ -360,6 +360,7 @@ protected:
        map<void *,ImageIndex> monobitmaps;
        //map<string,ImageIndex> jpegs;
        map<TVMediaInfo,ImageIndex> tvmedias;
+       list<ImageIndex> palettepics;
 
 
 
index 72fc69864304df0b9e76e47b261e434ab28847bf..29bee4d59ca93ea444769627ad72d1178b3d71f0 100644 (file)
@@ -193,6 +193,9 @@ void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  w
        command_mutex.Lock();
        ImageIndex image=0;
        LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
+       if (width!=0 && height!=0) {
+               removeCommands(x,y,width,height);
+       }
        if (image) {
                //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
                commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
@@ -274,6 +277,7 @@ void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegio
        tw*=scalex;
        th*=scaley;
        SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
+       removeCommands(tx,ty,tw,th);
        commands.push_back(temp);
        command_mutex.Unlock();
 }
@@ -289,6 +293,7 @@ void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int hei
        command_mutex.Lock();
        ImageIndex image=osd->getMonoBitmapRef(base,width,height);
        unsigned int ref=osd->getStyleRef(nextColour);
+       removeCommands(dx,dy,width,height);
        commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
        command_mutex.Unlock();
 }
@@ -301,6 +306,8 @@ int SurfaceVector::removeCommands(float x,float y,float width,float height)
        while (itty!=commands.end())
        {
                if ((*itty).Test(x,y,width,height)  && (*itty).instr != DrawClipping) {
+                       //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
+                       //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
                        osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
                        ImageIndex ii=(*itty).getImageIndex();
                        if (ii) osd->removeImageRef(ii);
index 7bf8896ad83f9218e01c690e213e8de1dae8cd6c..fb0ab22561375ed91a4a80c9b1ea012ee236f62a 100644 (file)
@@ -73,6 +73,19 @@ void TVMediaInfo::setDefaultJpeg(int jpeg_index)
        primary_id=jpeg_index;
 }
 
+void TVMediaInfo::setPosterThumb(int channel, int eventid)
+{
+       type=5;
+       primary_id=channel;
+       secondary_id=eventid;
+}
+
+void TVMediaInfo::setChannelLogo(int channel)
+{
+       type=6;
+       primary_id=channel;
+}
+
 bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
 {
        if (rhs.type==lhs.type) {
index 99c65e1d1ae69c39e14e576723c88a775d97e017..42af1eaadd3b98e0cd11e099ceaf545c0df0e18c 100644 (file)
--- a/tvmedia.h
+++ b/tvmedia.h
@@ -44,9 +44,12 @@ public:
        void setMovieInfo(const MovieInfo * mi);
        void setSeriesInfo(const SeriesInfo * si);
        void setPosterThumb(const char* recname);
+       void setPosterThumb(int channel, int eventid);
+       void setChannelLogo(int channel);
        void setDefaultJpeg(int jpeg_index);
        int getType() {return type;};
        int getPrimaryID() {return primary_id;};
+       int getSecondaryID() {return secondary_id;};
 
 private:
        int type; // 1 movie or 2 series or 3 unknown recording or 4 static artwork
diff --git a/vdr.cc b/vdr.cc
index e20dda0baf6da34ade383eedfe2269c68889fddc..46fecfbaeaceaf442a5cc0a1ad61416f6ddc0eba 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
@@ -1054,7 +1054,7 @@ EventList* VDR::getChannelSchedule(ULONG number, time_t start, ULONG duration)
 
   VDR_ResponsePacket* vresp = RequestResponse(&vrp);
   if (vresp->noResponse()) { delete vresp; return NULL; }
-  
+
   // received a ulong(0) - schedules error in the plugin
   if (vresp->serverError())
   {
diff --git a/vepg.cc b/vepg.cc
index 5af3e0d5452641e44f37a26b989c6989224c9008..94605e99e4739ec90f77987233fe18a9427f66d9 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -50,7 +50,7 @@
 
 VEpg* VEpg::instance = NULL;
 
-VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType)
+VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ChannelList* tchanList)
 {
   instance = this;
   currentChannelIndex = tcurrentChannelIndex;
@@ -96,7 +96,7 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType)
   boxstack = BoxStack::getInstance();
   parent = tparent;
   eventList = NULL;
-  chanList = VDR::getInstance()->getChannelsList(streamType); //TODO want to be able to display video and radio together
+  chanList = tchanList;
   e = 0;
 
   eventLista.resize(gridRows);
@@ -674,6 +674,11 @@ void VEpg::updateEventList()
     if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
       continue;
     chan = (*chanList)[listTop + listIndex];
+    if (eventLista[listIndex])
+    {
+       (eventLista)[listIndex]->clear();
+        delete eventLista[listIndex];
+    }
     eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, ltime - 1, window_width * 60 + 2); // ltime - 1 to get prog before window (allows cursor left past ltime). + 2 to get prog after window
   }
 }
diff --git a/vepg.h b/vepg.h
index b3bbf090fe94eae6df5d9e8de2dbd0e54b27716c..adc6f7eb2b1a0671091fc82aae554cf755ff67bd 100644 (file)
--- a/vepg.h
+++ b/vepg.h
@@ -45,7 +45,7 @@ class VVideoLive;
 class VEpg : public Boxx, public TimerReceiver
 {
   public:
-    VEpg(void* parent, UINT currentChannel, ULONG streamType);
+    VEpg(void* parent, UINT currentChannel, ChannelList* tchanList);
     ~VEpg();
     static VEpg* getInstance();
 
diff --git a/vepglistadvanced.cc b/vepglistadvanced.cc
new file mode 100644 (file)
index 0000000..a15f283
--- /dev/null
@@ -0,0 +1,844 @@
+/*
+    Copyright 2004-2007 Chris Tallon, 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "vepglistadvanced.h"
+
+#include "boxstack.h"
+#include "remote.h"
+#include "wsymbol.h"
+#include "boxstack.h"
+#include "vdr.h"
+#include "colour.h"
+#include "video.h"
+#include "i18n.h"
+#include "command.h"
+#include "log.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
+#include "event.h"
+#include "channel.h"
+#include "vepgsummary.h"
+#include "vepgsettimer.h"
+#include "vepg.h"
+
+#include <sstream>
+
+
+VEpgListAdvanced::VEpgListAdvanced(VVideoLiveTV *tvideolive, ChannelList* tchanList,ULONG initialChannelNumber)
+{
+       channelNumber = initialChannelNumber;
+       chanList = tchanList;
+       videolive = tvideolive;
+       boxstack = BoxStack::getInstance();
+
+       mode = OneChannel;
+
+       setSize(640, 500); //old   setSize(570, 420);
+       createBuffer();
+
+       setPosition(40, 40);
+
+       setTitleBarOn(1);
+       setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
+
+       sl.setPosition(10, 30 + 5);
+       sl.setSize(area.w*42/100 - 20, area.h - 30 - 15 - 30);
+       sl.setLinesPerOption(2.4f);
+       add(&sl);
+
+       Region slarea=sl.getRegionR();
+
+       epg.setParaMode(true);
+       epg.setPosition(slarea.x  +slarea.w+10 ,30+5);
+       epg.setSize(area.w -slarea.x -slarea.w -10, area.h - 30 - 15 - 30);
+       add(&epg);
+       epg.setText("");
+       epg.setBackgroundColour(DrawStyle::VIEWBACKGROUND);
+
+       epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
+       epgTVmedia.setSize(100,150/Osd::getInstance()->getPixelAspect());
+       epg.add(&epgTVmedia);
+
+       boxRed.setBackgroundColour(DrawStyle::RED);
+       boxRed.setPosition(165 /*54*/, sl.getY2()+8);
+       boxRed.setSize(18, 16);
+       add(&boxRed);
+
+       textRed.setPosition(boxRed.getX2(), sl.getY2()+4);
+       textRed.setSize(116, 30);
+
+       add(&textRed);
+
+       boxGreen.setBackgroundColour(DrawStyle::GREEN);
+       boxGreen.setPosition(165 +1*110, sl.getY2()+8);
+       boxGreen.setSize(18, 16);
+       add(&boxGreen);
+
+       textGreen.setPosition(boxGreen.getX2(), sl.getY2()+4);
+       textGreen.setSize(116, 30);
+       add(&textGreen);
+
+       boxYellow.setBackgroundColour(DrawStyle::YELLOW);
+       boxYellow.setPosition(165 +2*110, sl.getY2()+8);
+       boxYellow.setSize(18, 16);
+       add(&boxYellow);
+
+       textYellow.setPosition(boxYellow.getX2(), sl.getY2()+4);
+       textYellow.setSize(116, 30);
+       add(&textYellow);
+
+       boxBlue.setBackgroundColour(DrawStyle::BLUE);
+       boxBlue.setPosition(165 +3*110, sl.getY2()+8);
+       boxBlue.setSize(18, 16);
+       add(&boxBlue);
+
+       textBlue.setPosition(boxBlue.getX2(), sl.getY2()+4);
+       textBlue.setSize(116, 30);
+       add(&textBlue);
+
+       setButtonText();
+
+
+       updateEpgDataChannel();
+}
+
+VEpgListAdvanced::~VEpgListAdvanced()
+{
+       clearEventList();
+}
+
+
+void VEpgListAdvanced::setButtonText()
+{
+       switch (mode)
+       {
+       case OneChannel: {
+               textRed.setText(tr("Record"));
+               textGreen.setText(tr("Now"));
+               textYellow.setText(tr("Next"));
+               textBlue.setText(tr("Guide"));
+
+       } break;
+       case Now: {
+               textRed.setText(tr("Record"));
+               textGreen.setText(tr("Next"));
+               textYellow.setText(tr("Schedule"));
+               textBlue.setText(tr("Switch"));
+       } break;
+       case Next: {
+               textRed.setText(tr("Record"));
+               textGreen.setText(tr("Now"));
+               textYellow.setText(tr("Schedule"));
+               textBlue.setText(tr("Switch"));
+       } break;
+
+       };
+}
+
+void VEpgListAdvanced::doRed()
+{
+       doRecord();
+}
+
+void VEpgListAdvanced::doGreen()
+{
+       switch (mode)
+       {
+       case Now: {
+               doNext();
+       } break;
+       case OneChannel:
+       case Next: {
+               doNow();
+       } break;
+       };
+}
+
+void VEpgListAdvanced::doYellow()
+{
+       switch (mode)
+       {
+       case OneChannel: {
+               doNext();
+       } break;
+       case Next:
+       case Now: {
+               doProgramm();
+       } break;
+       };
+}
+
+void VEpgListAdvanced::doBlue()
+{
+       switch (mode)
+       {
+       case OneChannel: {
+               doGrid();
+       } break;
+       case Next:
+       case Now: {
+               doSwitch();
+       } break;
+       };
+}
+
+void VEpgListAdvanced::doNext()
+{
+       Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNext");
+       if (mode!=OneChannel) {
+               Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
+               channelNumber = chan->number;
+       }
+       mode=Next;
+       updateEpgDataNowNext(true);
+       setButtonText();
+       draw(true);
+       boxstack->update(this);
+}
+void VEpgListAdvanced::doNow()
+{
+       Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doNow");
+       if (mode!=OneChannel) {
+               Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
+               channelNumber = chan->number;
+       }
+       mode=Now;
+       updateEpgDataNowNext(true);
+       setButtonText();
+       draw(true);
+       boxstack->update(this);
+}
+
+void VEpgListAdvanced::doProgramm()
+{
+       Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doProgram");
+       mode=OneChannel;
+
+       Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
+       channelNumber = chan->number;
+       updateEpgDataChannel();
+       setButtonText();
+       draw(true);
+       boxstack->update(this);
+}
+
+void VEpgListAdvanced::doSwitch()
+{
+
+       if (videolive)
+       {
+               if (mode!=OneChannel) {
+                       Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
+                       channelNumber = chan->number;
+               }
+               Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "doSwitch %d", channelNumber);
+               Message* m = new Message(); // Must be done after this view deleted
+               m->from = this;
+               m->to = videolive;
+               m->message = Message::CHANNEL_CHANGE;
+               m->parameter = channelNumber;
+               m->tag = 0;
+               Command::getInstance()->postMessageNoLock(m);
+       }
+}
+
+void VEpgListAdvanced::doRecord()
+{
+       int channel;
+       Event* current = getCurrentOptionEvent(channel);
+       if (current)
+       {
+               Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
+               unsigned int chanlistsize=chanList->size();
+               Channel * chan;
+               UINT listIndex;
+               for(listIndex = 0; listIndex < chanlistsize; listIndex++)
+               {
+                       chan = (*chanList)[listIndex];
+                       if (chan->number == channel) break;
+               }
+
+               Log::getInstance()->log("VEpgSummary", Log::DEBUG, "ID %lu TIME %lu DURATION %lu TITLE %s", current->id, current->time,
+                               current->duration, current->title);
+               VEpgSetTimer* vs = new VEpgSetTimer(current, chan);
+               vs->draw();
+               BoxStack *boxstack=BoxStack::getInstance();
+               boxstack->add(vs);
+               boxstack->update(vs);
+       }
+
+}
+
+void VEpgListAdvanced::doGrid()
+{
+       Video* video=Video::getInstance();
+       video->setMode(Video::QUARTER);
+       video->setPosition(170, 5); //TODO add stack for these changes
+       if (mode!=OneChannel) {
+               Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
+               channelNumber = chan->number;
+       }
+
+       VEpg* vepg = new VEpg(videolive, channelNumber, chanList);
+       vepg->draw();
+       boxstack->add(vepg);
+       boxstack->update(vepg);
+
+}
+
+void VEpgListAdvanced::clearEventList()
+{
+       std::vector<EventList*>::iterator itty = eventLista.begin();
+       while (itty!= eventLista.end()) {
+               if (*itty) {
+                       (*itty)->clear();
+                       delete (*itty);
+               }
+               itty++;
+       }
+       eventLista.clear();
+
+}
+
+
+/* Prototype
+ *
+ *   if (!chanList) return;
+  Channel* chan;
+  for(UINT listIndex = 0; listIndex < gridRows; listIndex++)
+  {
+    if(listTop + listIndex >= UINT(chanListbox.getBottomOption()))
+      continue;
+    chan = (*chanList)[listTop + listIndex];
+    eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, ltime - 1, window_width * 60 + 2); // ltime - 1 to get prog before window (allows cursor left past ltime). + 2 to get prog after window
+  }
+
+ */
+
+void VEpgListAdvanced::updateEpgData()
+{
+       switch (mode)
+       {
+       case OneChannel: {
+               //updateEpgDataChannel();
+       } break;
+       case Next:
+       case Now: {
+               updateEpgDataNowNext(false);
+       } break;
+       };
+
+}
+
+void VEpgListAdvanced::updateEpgDataNowNext(bool changeState)
+{
+       int startupdate=0;
+       int endupdate=0;
+
+       unsigned int chanlistsize=chanList->size();
+       if (changeState) {
+               clearEventList();
+               eventLista.resize(chanList->size());
+               Channel* chan;
+               for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
+               {
+                       if (listIndex < 0) continue;
+                       if (listIndex >= chanlistsize) continue;
+                       chan = (*chanList)[listIndex];
+                       if (chan->number == channelNumber) {
+                               startupdate = listIndex-sl.getNumOptionsDisplayable()-2;
+                               endupdate = listIndex+sl.getNumOptionsDisplayable()+2;
+                               break;
+                       }
+               }
+       } else {
+               startupdate=sl.getTopOption()-2;
+               endupdate=sl.getBottomOption()+1;
+       }
+
+       time_t now;
+       time(&now);
+
+       Channel* chan;
+       for(int listIndex = startupdate; listIndex < endupdate; listIndex++)
+       {
+               if (listIndex < 0) continue;
+               if (listIndex >= chanlistsize) continue;
+
+           chan = (*chanList)[listIndex];
+               if (!eventLista[listIndex]) eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, now, 4 * 60 *60);
+
+       }
+
+}
+
+void VEpgListAdvanced::updateEpgDataChannel()
+{
+       clearEventList();
+       eventLista.resize(1);
+       time_t now;
+       time(&now);
+       eventLista[0] = VDR::getInstance()->getChannelSchedule(channelNumber, now, 24 * 60 *60 *30); // one month
+       Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Eventlist %x %d", eventLista[0],channelNumber);
+
+}
+
+void VEpgListAdvanced::drawData(bool doIndexPop)
+{
+       switch (mode)
+       {
+       case OneChannel: {
+               drawDataChannel(doIndexPop);
+       } break;
+       case Next: {
+               drawDataNowNext(true, doIndexPop);
+       } break;
+       case Now: {
+               drawDataNowNext(false, doIndexPop);
+       } break;
+       };
+
+}
+
+void VEpgListAdvanced::drawDataChannel(bool doIndexPop)
+{
+  int saveIndex = sl.getCurrentOption();
+  int saveTop = sl.getTopOption();
+  sl.clear();
+  sl.addColumn(0);
+  sl.addColumn(25 );
+  sl.addColumn(25 + 7);
+  //sl.addColumn(118);
+
+  int first = 1;
+
+  char tempA[300]; // FIXME  this is guesswork!
+  char tempB[300]; // FIXME
+  char tempC[300]; // FIXME
+  struct tm* btime;
+
+
+
+  Event* currentEvent;
+  EventList::iterator j;
+  EventList* eventList = eventLista[0];
+  if (eventList) {
+         for (j = eventList->begin(); j != eventList->end(); j++)
+         {
+                 currentEvent = *j;
+                 time_t eventStartTime = (time_t)currentEvent->time;
+                 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
+
+                 btime = localtime(&eventStartTime);
+                 strftime(tempA, 299, "%d/%m/%y %H:%M ", btime);
+                 btime = localtime(&eventEndTime);
+                 strftime(tempB, 299, "- %H:%M ", btime);
+                 //#endif
+                 sprintf(tempC, "%s\n \t%s%s", currentEvent->title,tempA,tempB);
+                 // New TVMedia stuff
+                 TVMediaInfo *info= new TVMediaInfo();
+                 info->setPosterThumb(channelNumber, currentEvent->id);
+                 currentEvent->index = sl.addOption(tempC, currentEvent->id, first, info);
+                 first = 0;
+         }
+  }
+
+  if (doIndexPop)
+  {
+    sl.hintSetCurrent(0);
+  }
+  else
+  {
+    sl.hintSetCurrent(saveIndex);
+    sl.hintSetTop(saveTop);
+  }
+  updateSelection();
+  sl.draw();
+  epg.draw();
+}
+
+void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
+{
+  int saveIndex = sl.getCurrentOption();
+  int saveTop = sl.getTopOption();
+  sl.clear();
+  sl.addColumn(0);
+  sl.addColumn(25 );
+  sl.addColumn(160);
+
+  int first = 1;
+
+  char tempA[300]; // FIXME  this is guesswork!
+  char tempB[300]; // FIXME
+  char tempC[300]; // FIXME
+  struct tm* btime;
+
+
+
+  Event* currentEvent;
+  EventList::iterator j;
+  int minevents=1;
+  if (next) minevents++;
+  int setcurrenthelper =0;
+
+  unsigned int chanlistsize=chanList->size();
+  for(UINT listIndex = 0; listIndex < chanlistsize; listIndex++)
+  {
+         Channel* chan;
+         chan = (*chanList)[listIndex];
+
+         EventList* eventList = eventLista[listIndex];
+         if (eventList && eventList->size()>=minevents) {
+                 j = eventList->begin();
+
+                 currentEvent = j[minevents-1];
+                 time_t eventStartTime = (time_t)currentEvent->time;
+                 time_t eventEndTime = (time_t)(currentEvent->time + currentEvent->duration);
+
+                 btime = localtime(&eventStartTime);
+                 strftime(tempA, 299, "%H:%M ", btime);
+                 btime = localtime(&eventEndTime);
+                 strftime(tempB, 299, "- %H:%M ", btime);
+                 //#endif
+                 sprintf(tempC, "%s\n%s\t %s%s", currentEvent->title, chan->name,tempA,tempB);
+
+         } else {
+                 sprintf(tempC, "\n%s", chan->name);
+
+         }
+         TVMediaInfo *info= new TVMediaInfo();
+         if ((*chanList)[listIndex]->number == channelNumber) {
+                 first = 1;
+                 setcurrenthelper = listIndex;
+         }
+         info->setChannelLogo((*chanList)[listIndex]->number);
+         currentEvent->index = sl.addOption(tempC, listIndex, first, info);
+         first = 0;
+  }
+
+  if (doIndexPop)
+  {
+    sl.hintSetCurrent(setcurrenthelper);
+  }
+  else
+  {
+    sl.hintSetCurrent(saveIndex);
+    sl.hintSetTop(saveTop);
+  }
+  updateSelection();
+  sl.draw();
+  epg.draw();
+}
+
+void VEpgListAdvanced::draw(bool doIndexPop)
+{
+
+       // Single channel mode
+       switch (mode) {
+       case OneChannel: {
+               char tempA[300];
+                unsigned int chanlistsize=chanList->size();
+                Channel * chan;
+                UINT listIndex;
+                for(listIndex = 0; listIndex < chanlistsize; listIndex++)
+                {
+                        chan = (*chanList)[listIndex];
+                        if (chan->number == channelNumber) break;
+                }
+               sprintf(tempA, tr("Schedule - %s"), (*chanList)[listIndex]->name);
+               setTitleText(tempA);
+       } break;
+       case Now: {
+               setTitleText(tr("Now"));
+       } break;
+       case Next: {
+               setTitleText(tr("Next"));
+       } break;
+       };
+
+
+
+
+       TBBoxx::draw();
+
+
+       char freeSpace[50];
+       struct tm* btime;
+       time_t now;
+       time(&now);
+       btime = localtime(&now);
+       strftime(freeSpace, 299, "%d/%m/%y", btime);
+       drawTextRJ(freeSpace, 560+70, 5, DrawStyle::LIGHTTEXT);
+       // Symbols
+
+       WSymbol w;
+       TEMPADD(&w);
+       w.nextSymbol = WSymbol::UP;
+       w.setPosition(20, area.h-35);
+       w.draw();
+       w.nextSymbol = WSymbol::DOWN;
+       w.setPosition(50, area.h-35);
+       w.draw();
+       w.nextSymbol = WSymbol::SKIPBACK;
+       w.setPosition(85, area.h-35);
+       w.draw();
+       w.nextSymbol = WSymbol::SKIPFORWARD;
+       w.setPosition(115, area.h-35);
+       w.draw();
+
+       drawTextRJ(tr("[ok] = info"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
+
+       // All static stuff done
+       drawData(doIndexPop);
+
+}
+
+Event* VEpgListAdvanced::getCurrentOptionEvent(int& channel)
+{
+       // version for channel
+       Event* currentEvent = NULL;
+       EventList::iterator j;
+       EventList* eventList = NULL;
+       switch (mode)
+       {
+       case OneChannel: {
+               eventList = eventLista[0];
+               if (eventList) {
+                       channel = channelNumber;
+                       for (j = eventList->begin(); j != eventList->end(); j++)
+                       {
+                               currentEvent = *j;
+                               if (currentEvent->index == sl.getCurrentOption()) return currentEvent;
+                       }
+
+
+               } break;
+       case Next: {
+               eventList = eventLista[sl.getCurrentOptionData()];
+               channel = (*chanList)[sl.getCurrentOptionData()]->number;
+
+
+               if (eventList && eventList->size()>1) {
+                       j = eventList->begin();
+                       currentEvent = j[1];
+               } else {
+                       currentEvent = NULL;
+               }
+       } break;
+       case Now: {
+               eventList = eventLista[sl.getCurrentOptionData()];
+               channel = (*chanList)[sl.getCurrentOptionData()]->number;
+
+               if (eventList && eventList->size()>0) {
+                       j = eventList->begin();
+                       currentEvent = j[0];
+               } else {
+                       currentEvent = NULL;
+               }
+       } break;
+       };
+
+
+  }
+  return currentEvent;
+}
+
+
+
+void VEpgListAdvanced::updateSelection()
+{
+       updateEpgData();
+       int channel=0;
+       Event* toShow = getCurrentOptionEvent(channel);
+       if (toShow)
+       {
+               toShow->loadinfos(channel);
+               std::stringstream description;
+
+               description << "\n"<< toShow->title  << "\n\n";
+               description << toShow->subtitle <<"\n";
+               description << toShow->description;
+
+               TVMedia poster;
+               poster.height=0;
+               if (toShow->movieInfo) {
+                       poster=toShow->movieInfo->poster;
+               }
+               if (toShow->seriesInfo) {
+                       if (toShow->seriesInfo->seasonposter.height) {
+                               poster=toShow->seriesInfo->seasonposter;
+                       }
+                       else if (toShow->seriesInfo->posters.size()) {
+                               poster=toShow->seriesInfo->posters[0];
+                       }
+               }
+               if (poster.height) {
+                       epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal);
+                       epgTVmedia.setVisible(true);
+               } else {
+                       epgTVmedia.setVisible(false);
+               }
+
+               epg.setText(description.str().c_str());
+       } else {
+               epg.setText("");
+               epgTVmedia.setVisible(false);
+       }
+
+}
+
+int VEpgListAdvanced::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::DF_UP:
+    case Remote::UP:
+    {
+      sl.up();
+      quickUpdate();
+
+      boxstack->update(this);
+      return 2;
+    }
+    case Remote::DF_DOWN:
+    case Remote::DOWN:
+    {
+      sl.down();
+      quickUpdate();
+
+      boxstack->update(this);
+      return 2;
+    }
+    case Remote::SKIPBACK:
+    {
+      sl.pageUp();
+      quickUpdate();
+
+      boxstack->update(this);
+      return 2;
+    }
+    case Remote::SKIPFORWARD:
+    {
+      sl.pageDown();
+      quickUpdate();
+
+      boxstack->update(this);
+      return 2;
+    }
+    case Remote::RED:
+    {
+       doRed();
+       return 2;
+    }
+    case Remote::GREEN:
+    {
+       doGreen();
+       return 2;
+    }
+    case Remote::YELLOW:
+    {
+       doYellow();
+       return 2;
+    }
+    case Remote::BLUE:
+    {
+       doBlue();
+       return 2;
+    }
+    case Remote::OK:
+    {
+      if (sl.getNumOptions() == 0) return 2;
+
+
+      int channel;
+      Event* current = getCurrentOptionEvent(channel);
+      if (current)
+      {
+         Log::getInstance()->log("VEventListAdvanced", Log::DEBUG, "Found the option you pointed at. %s %d", current->title, current->id);
+         unsigned int chanlistsize=chanList->size();
+         Channel * chan;
+         UINT listIndex;
+         for(listIndex = 0; listIndex < chanlistsize; listIndex++)
+         {
+                 chan = (*chanList)[listIndex];
+                 if (chan->number == channel) break;
+         }
+
+         VEpgSummary* vr = new VEpgSummary(current, (*chanList)[listIndex]);
+         vr->draw();
+         boxstack->add(vr);
+         boxstack->update(vr);
+
+         return 2;
+      }
+      // should not get to here
+      return 1;
+    }
+    case Remote::BACK:
+    {
+        return 4;
+    }
+  }
+  // stop command getting to any more views
+  return 1;
+}
+
+void VEpgListAdvanced::processMessage(Message* m)
+{
+  Log::getInstance()->log("VEpgListAdvanced", Log::DEBUG, "Got message value %lu", m->message);
+
+  if (m->message == Message::MOUSE_MOVE)
+  {
+    if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
+    {
+      quickUpdate();
+      boxstack->update(this);
+    }
+  }
+  else if (m->message == Message::MOUSE_LBDOWN)
+  {
+    if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
+    {
+      boxstack->handleCommand(Remote::OK); //simulate OK press
+    }
+    else
+    {
+      //check if press is outside this view! then simulate cancel
+      int x=(m->parameter>>16)-getScreenX();
+      int y=(m->parameter&0xFFFF)-getScreenY();
+      if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
+      {
+        boxstack->handleCommand(Remote::BACK); //simulate cancel press
+      }
+    }
+  }
+}
+
+
+
+void VEpgListAdvanced::quickUpdate() { //only quick for plattform that need it!
+       updateSelection();
+#ifdef GRADIENT_DRAWING
+      draw();
+#else
+      sl.draw();
+      epg.draw();
+#endif
+}
diff --git a/vepglistadvanced.h b/vepglistadvanced.h
new file mode 100644 (file)
index 0000000..5b48149
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+    Copyright 2004-2005 Chris Tallon, 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef VEPGLIST_ADVANCED_H
+#define VEPGLIST_ADVANCED_H
+
+
+#include <stack>
+
+#include "tbboxx.h"
+#include "wtextbox.h"
+#include "wselectlist.h"
+#include "wtvmedia.h"
+
+class BoxStack;
+class VVideoLiveTV;
+
+class VEpgListAdvanced : public TBBoxx
+{
+  public:
+       VEpgListAdvanced(VVideoLiveTV *tvideolive, ChannelList* tchanList, ULONG initialChannelNumber);
+    virtual ~VEpgListAdvanced();
+
+    void draw(bool doIndexPop = false);
+    bool load();
+    void drawData(bool doIndexPop = false);
+
+  protected:
+
+    enum EpgMode {
+       OneChannel,
+       Now,
+       Next
+    };
+
+    enum EpgMode mode;
+
+    void quickUpdate();
+    void updateSelection();
+
+    void setButtonText();
+
+    void clearEventList();
+
+    void updateEpgData();
+    void updateEpgDataChannel();
+    void updateEpgDataNowNext(bool changestate);
+    void drawDataChannel(bool doIndexPop);
+    void drawDataNowNext(bool next, bool doIndexPop);
+
+    int handleCommand(int command);
+    void processMessage(Message* m);
+
+    void doRed();
+    void doGreen();
+    void doYellow();
+    void doBlue();
+
+    void doNext();
+    void doNow();
+    void doProgramm();
+    void doSwitch();
+    void doRecord();
+    void doGrid();
+
+    WTextbox epg;
+    WTVMedia epgTVmedia;
+
+    BoxStack* boxstack;
+    bool loading;
+
+    WSelectList sl;
+
+    Event* getCurrentOptionEvent(int& channel);
+
+    ChannelList* chanList;
+    ULONG channelNumber;
+    VVideoLiveTV *videolive;
+
+    Boxx boxRed;
+    Boxx boxGreen;
+    Boxx boxYellow;
+    Boxx boxBlue;
+
+    WTextbox textRed;
+    WTextbox textGreen;
+    WTextbox textYellow;
+    WTextbox textBlue;
+
+    std::vector<EventList*> eventLista;
+
+
+
+};
+
+#endif
index 84c066981240a3c75ad051dab320a40a610a9e85..796a700f9a3b7fae11d9b0e7ff1358dc64d778ed 100644 (file)
@@ -123,7 +123,7 @@ VEpgSummary::VEpgSummary(Event *tevent, Channel* tchannel)
   epgTVmedia.setSize(130,195/Osd::getInstance()->getPixelAspect());
   summary->add(&epgTVmedia);
   if (movieview) movieview->add(&epgTVmedia);
-  if (seriesview) movieview->add(&epgTVmedia);
+  if (seriesview) seriesview->add(&epgTVmedia);
   TVMedia poster;
   poster.height=0;
   if (event->movieInfo) {
index bf550c2aea9a28fbd2720b673925a76a74571a03..471844937169c39a72656a19c3aad75ac37b5ebd 100644 (file)
@@ -43,6 +43,7 @@
 #include "log.h"
 #include "vteletextview.h"
 #include "vepgsummary.h"
+#include "vepglistadvanced.h"
 
 VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, VChannelList* tvchannelList)
 : osdBack(0, 0, 0, 128)
@@ -707,13 +708,21 @@ void VVideoLiveTV::doEPG()
 {
   if (osd.getVisible()) clearScreen();
 
-  video->setMode(Video::QUARTER);
-  video->setPosition(170, 5); //TODO need to deal with 4:3 switching
+  if (!Command::getInstance()->advMenues()) {
+         video->setMode(Video::QUARTER);
+         video->setPosition(170, 5); //TODO need to deal with 4:3 switching
 
-  VEpg* vepg = new VEpg(this, currentChannelIndex, streamType);
-  vepg->draw();
-  boxstack->add(vepg);
-  boxstack->update(vepg);
+         VEpg* vepg = new VEpg(this, currentChannelIndex, chanList);
+         vepg->draw();
+         boxstack->add(vepg);
+         boxstack->update(vepg);
+  } else {
+         Channel* currentChannel = (*chanList)[osdChannelIndex];
+         VEpgListAdvanced  *vepg= new VEpgListAdvanced(this, chanList, currentChannel->number);
+         vepg->draw();
+         boxstack->add(vepg);
+         boxstack->update(vepg);
+  }
 }
 
 void VVideoLiveTV::setNowNextData()
index f8ecc137af692f99a66d8160f99a74d01d0cd9fa..3037dfcffec5aea8159b4c6892b55de860db9c0f 100644 (file)
@@ -270,6 +270,11 @@ ULONG WSelectList::getCurrentOptionData()
   return options[selectedOption].data;
 }
 
+int WSelectList::getNumOptionsDisplayable()
+{
+       return numOptionsDisplayable;
+}
+
 bool WSelectList::mouseAndroidScroll(int x, int y,int sx, int sy)
 {
 /*     int fontHeight = getFontHeight();
index 455622ba8d630b36ceeafdd8954574aa9f3bb971..9106484feb495e3d09ee90160b1ce6361f613cc6 100644 (file)
@@ -63,6 +63,7 @@ class WSelectList : public Boxx
     int getTopOption();
     int getNumOptions();
     int getBottomOption();     // actually returns bottom + 1 i.e. the one just past display ?!
+    int getNumOptionsDisplayable();
     int getCurrentOption();
     ULONG getCurrentOptionData();