]> git.vomp.tv Git - vompserver.git/blob - picturereader.c
Support for channel logos
[vompserver.git] / picturereader.c
1 #include "picturereader.h"
2 #include <vdr/plugin.h>
3 #include <vdr/channels.h>
4 #include <sstream>
5
6
7 PictureReader::PictureReader(VompClient *client)
8 {
9   logger = Log::getInstance();
10   inittedOK = 0;
11   tcp = NULL;
12   x = client;
13
14   pthread_mutex_init(&pictureLock, NULL);
15 }  
16
17 int PictureReader::init(TCP* ttcp)
18 {
19   tcp = ttcp;
20   threadStart();
21
22   return inittedOK;
23 }
24
25 PictureReader::~PictureReader()
26 {
27    threadStop();
28 }
29
30 void PictureReader::addTVMediaRequest(TVMediaRequest& req)
31 {
32     logger->log("PictRead",Log::DEBUG,"Got TVMediaRequest, signal thread!");
33
34     pthread_mutex_lock(&pictureLock);
35     pictures.push(req);
36     threadSignal(); // Signal, that we have something to do!!!
37     pthread_mutex_unlock(&pictureLock);
38 }
39
40 std::string PictureReader::getPictName(TVMediaRequest & req)
41 {
42    logger->log("PictRead",Log::DEBUG,
43         "Request %d %d;  %d %d %d %d",req.primary_id,req.secondary_id,
44          req.type,req.type_pict,
45         req.container,req.container_member);
46
47    switch (req.type) {
48    case 0: { //serie
49       if (series.seriesId != req.primary_id ||
50           series.episodeId != req.secondary_id) {
51           series.actors.clear();
52           series.posters.clear();
53           series.banners.clear();
54           series.fanarts.clear();
55
56           series.seriesId = req.primary_id;
57           series.episodeId = req.secondary_id;
58           x->scraper->Service("GetSeries",&series);
59       }
60       if (req.type_pict == 0) {
61         switch (req.container) {
62         case 0: {
63            return series.episode.episodeImage.path;
64         } break;
65         case 1: {
66           if (series.actors.size()>req.container_member) {
67                 return series.actors[req.container_member].actorThumb.path;
68           }
69         } break;
70         case 2: {
71           if (series.posters.size()>req.container_member) {
72                 return series.posters[req.container_member].path;
73           }
74         } break;
75         case 3: {
76           if (series.banners.size()>req.container_member) {
77                 return series.banners[req.container_member].path;
78           }
79         } break;
80         case 4: {
81           if (series.fanarts.size()>req.container_member) {
82                 return series.fanarts[req.container_member].path;
83           }
84         } break;
85         case 5: {
86            return series.seasonPoster.path;
87         } break;
88         default: {
89            return std::string("");
90            } break;
91         };
92       } else if (req.type_pict == 1 && series.posters.size()) { //poster
93            std::string str=series.posters[0].path;
94            size_t  pos=str.rfind('/');
95            if (pos!=std::string::npos) {
96               str.resize(pos);
97               str=str+"poster_thumb.jpg";
98               return str;
99            }
100         } else if (req.type_pict == 2) { //poster
101            std::string str=series.seasonPoster.path;
102            size_t  pos=str.rfind('/');
103            if (pos!=std::string::npos) {
104               str.resize(pos);
105               std::ostringstream out;
106               out << str << "season_" <<series.episode.season <<"_thumb.jpg";
107               return out.str();
108            }
109         } 
110        return std::string("");
111    } break;
112    case 1: { //movie
113       if (movie.movieId != req.primary_id ) {
114           movie.actors.clear();
115           movie.movieId = req.primary_id;
116           x->scraper->Service("GetMovie",&movie);
117       }
118       if (req.type_pict == 0) {
119
120         switch (req.container) {
121         case 0: {
122            return movie.poster.path;
123         } break;
124         case 1: {
125            return movie.fanart.path;
126         } break;
127         case 2: {
128            return movie.collectionPoster.path;
129         } break;
130         case 3: {
131            return movie.collectionFanart.path;
132         } break;
133         case 4: {
134           if (movie.actors.size()>req.container_member) {
135                 return movie.actors[req.container_member].actorThumb.path;
136           }
137         } break;
138         default: {
139            return std::string("");
140            } break;
141         };
142     } else if (req.type_pict == 1) { //poster
143         std::string str=movie.poster.path;
144         size_t  pos=str.rfind('/');
145         if (pos!=std::string::npos) {
146            str.resize(pos);
147            str=str+"poster_thumb.jpg";
148            return str;
149         }
150     } 
151     return std::string("");
152       
153    
154    } break;
155    case 3: { // I do not know
156    // First get the recording
157       cRecordings Recordings;
158       Recordings.Load();
159       cRecording *recording = Recordings.GetByName((char*) req.primary_name.c_str());
160       ScraperGetPosterThumb getter;
161       getter.recording = recording;
162       getter.event = NULL;
163       if (x->scraper && recording) {
164         x->scraper->Service("GetPosterThumb",&getter);
165         return getter.poster.path;
166       } else {
167          return std::string("");
168       }
169    }; break;
170    case 4: { // I do not know
171    // First get the schedules
172       cSchedulesLock MutexLock;
173       const cSchedules *Schedules = cSchedules::Schedules(MutexLock);
174       const cSchedule *Schedule = NULL;
175       if (Schedules)
176       {
177         cChannel * channel = Channels.GetByChannelID(
178                        tChannelID::FromString(req.primary_name.c_str()));
179         Schedule = Schedules->GetSchedule(channel);
180       }
181       const cEvent *event = NULL;
182       if (Schedule) event=Schedule->GetEvent(req.primary_id);
183       ScraperGetPosterThumb getter;
184       getter.event = event;
185       getter.recording = NULL;
186
187       if (x->scraper && event) {
188         x->scraper->Service("GetPosterThumb",&getter);
189         return getter.poster.path;
190       } else {
191          return std::string("");
192       }
193    }; break;
194    
195    default:
196      return std::string("");
197      break;
198    };
199      
200    
201 }
202
203
204 void PictureReader::threadMethod()
205 {
206   ULONG *p;
207   ULONG headerLength = sizeof(ULONG) * 4;
208   UCHAR buffer[headerLength];
209   int amountReceived;
210
211 //   threadSetKillable(); ??
212
213   logger->log("PictRead",Log::DEBUG,"PictureReaderThread started");
214   while(1)
215   {
216     threadLock();
217     threadWaitForSignal();
218     threadUnlock();
219     threadCheckExit();
220     bool newpicture;
221     logger->log("PictRead",Log::DEBUG,"Thread was signaled, wake up");
222
223     do
224     {
225       newpicture = false;
226       TVMediaRequest req;
227       pthread_mutex_lock(&pictureLock);
228       if (!pictures.empty()) {
229          newpicture = true;
230          req = pictures.front();
231          pictures.pop();
232       }
233       pthread_mutex_unlock(&pictureLock);
234       if (!newpicture) break;
235       std::string pictname = getPictName(req);
236       UCHAR * mem = NULL;
237       ULONG memsize = 0;
238       ULONG flag = 2;
239       logger->log("PictRead",Log::DEBUG,"Load Pict %s",pictname.c_str());
240
241       
242       if (pictname.length()) {
243          struct stat st;
244          ULONG filesize = 0 ;
245
246          stat(pictname.c_str(), &st);
247          filesize = st.st_size;
248          memsize = filesize + headerLength;
249
250          if (memsize && memsize < 1000000) { // No pictures over 1 MB
251             mem = (UCHAR*)malloc(memsize);
252             if (mem) {
253                 FILE * file=fopen(pictname.c_str(),"r");
254
255                 if (file) {
256                     size_t size=fread(mem+headerLength,1,filesize,file);
257
258                     fclose(file);
259                     if (size!=filesize) memsize=headerLength; // error
260                     else flag = 0;
261                 }
262              }
263            } 
264        } 
265        if (!mem) {
266           mem = buffer;
267        }
268
269          
270     
271       p = (ULONG*)&mem[0]; *p = htonl(5); // stream channel
272       p = (ULONG*)&mem[4]; *p = htonl(req.streamID);
273       p = (ULONG*)&mem[8]; *p = htonl(flag); // here insert flag: 0 = ok, data follows
274       p = (ULONG*)&mem[12]; *p = htonl(memsize);
275
276       if (!tcp->sendPacket(mem, memsize + headerLength)) {
277           logger->log("PictRead",Log::DEBUG,"Sending Picture failed");
278       }
279
280       if (mem != buffer && mem) free(mem);
281
282     } while (newpicture);
283   }
284   logger->log("PictRead",Log::DEBUG,"PictureReaderThread ended");
285   
286 }
287