]> git.vomp.tv Git - vompclient.git/blob - videoomx.cc
WIN32 compatibility
[vompclient.git] / videoomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009-12 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "videoomx.h"
21 #include "audioomx.h"
22 #include "demuxer.h"
23 #include "vdr.h"
24 #include "woptionpane.h"
25 #include "osdopenvg.h"
26 #include "boxstack.h"
27 #include "inputman.h"
28
29 #include <bcm_host.h>
30
31 #include <linux/fb.h>
32
33 // temp
34 #include "log.h"
35
36 //A lot of parts of this file are heavily inspired by xbmc omx implementations
37
38 VideoOMX::VideoOMX() {
39
40         omx_running = false;
41
42         omx_vid_dec = 0;
43         cur_input_buf_omx = NULL;
44         omx_h264 = omx_mpeg2 = true;
45         clock_references = 0;
46
47         omx_vid_stalled = false;
48
49         offsetnotset = true;
50         offsetvideonotset = true;
51         offsetaudionotset = true;
52         startoffset = 0;
53         lastrefaudiotime = 0;
54         lastrefvideotime = 0;
55         lastreftimeOMX = 0;
56         lastreftimePTS = 0;
57         firstsynched = false;
58         cur_clock_time=0;
59         mpeg2_supported=false;
60         //cur_pts=0;
61
62         mode=NORMAL;
63         xpos=ypos=0.f;
64         deinterlace=2; //advanced
65
66         signalon=false;
67         outputinterlaced=0;
68
69         strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
70         strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
71         strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
72         strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
73         strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
74         strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
75 }
76
77 VideoOMX::~VideoOMX()
78 {
79   instance = NULL;
80 }
81
82 int VideoOMX::init(UCHAR tformat)
83 {
84   if (initted) return 0;
85   initted = 1;
86
87   // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
88   // Seems safe to call it more than once.
89   bcm_host_init();
90
91   int ret=vc_gencmd_send("codec_enabled MPG2");
92   if (ret!=0) {
93           Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_send failed %x",ret);
94   } else {
95           char buffer[1024];
96           ret=vc_gencmd_read_response(buffer,sizeof(buffer));
97           if (ret!=0) {
98                   Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_read_response failed %x",ret);
99           } else {
100                   if (STRCASECMP(buffer,"MPG2=enabled")==0) {
101                           mpeg2_supported=true;
102                   } else if (STRCASECMP(buffer,"MPG2=disabled")==0) {
103                           mpeg2_supported=false;
104                   } else {
105                           Log::getInstance()->log("Video", Log::DEBUG, "Undefined mpg codec answer %s",buffer);
106                   }
107           }
108   }
109
110   if (!setFormat(tformat))           { shutdown(); return 0; }
111   if (!setConnection(HDMI))  { shutdown(); return 0; }
112   if (!setAspectRatio(ASPECT4X3,12,11))    { shutdown(); return 0; }
113   if (!setMode(NORMAL))              { shutdown(); return 0; }
114   if (!setSource())                  { shutdown(); return 0; }
115   if (!attachFrameBuffer())          { shutdown(); return 0; }
116
117   setTVsize(ASPECT16X9);
118   selectVideoMode(0);
119
120
121   OMX_ERRORTYPE error;
122         error = OMX_Init();
123         if (error != OMX_ErrorNone) {
124                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x",
125                                 error);
126                 return 0;
127         }
128
129
130
131
132
133   //stop();
134
135
136
137   return 1;
138 }
139
140
141
142
143 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
144            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
145            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
146
147         //Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
148
149         struct VPE_OMX_EVENT  new_event;
150         new_event.handle=handle;
151         new_event.appdata=appdata;
152         new_event.event_type=event_type;
153         new_event.data1=data1;
154         new_event.data2=data2;
155         new_event.event_data=event_data;
156
157         VideoOMX *video=(VideoOMX *)getInstance();
158         video->AddOmxEvent(new_event);
159
160 /*      switch (event_type) {
161         case OMX_EventCmdComplete: {
162
163         } break;
164         }*/
165
166         return OMX_ErrorNone;
167
168 }
169
170 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT  new_event)
171 {
172         omx_event_mutex.lock();
173     omx_events.push_back(new_event);
174         omx_event_mutex.unlock();
175         omx_event_ready_signal.signal();
176 }
177
178
179 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
180
181 //      Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
182         VideoOMX *video=(VideoOMX *)getInstance();
183 /*      long long temp =buffer->nTimeStamp.nLowPart
184                                                                 | ((long long) buffer->nTimeStamp.nHighPart << 32);
185         Log::getInstance()->log("Video", Log::NOTICE, "EBD Video %lld  %x",temp,buffer->nFlags);*/
186         video->ReturnEmptyOMXBuffer(buffer);
187         return OMX_ErrorNone;
188
189 }
190
191 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
192         input_bufs_omx_mutex.lock();
193         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d",input_bufs_omx_free.size(),input_bufs_omx_all.size());
194         input_bufs_omx_free.push_back(buffer);
195         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
196         input_bufs_omx_mutex.unlock();
197         omx_event_ready_signal.signal();
198 }
199
200  OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
201          //Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
202         return OMX_ErrorNone;
203 }
204
205
206
207 int VideoOMX::shutdown()
208 {
209   if (!initted) return 0;
210   initted = 0;
211   Log::getInstance()->log("Video", Log::NOTICE, "Shutdown video module");
212
213   DeAllocateCodecsOMX();
214   OMX_Deinit();
215   //vc_tv_show_info(0); // back to console
216   // Restore console
217   int fd_fbset=0;
218   struct fb_var_screeninfo screeninfo;
219   fd_fbset=open("/dev/fb0",O_RDONLY);
220   if (fd_fbset<0) {
221           Log::getInstance()->log("Video", Log::CRIT, "Could not open frame buffer device %d", fd_fbset);
222           return 0;
223   }
224   if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)){
225           close(fd_fbset);
226           Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOGET_VSCREENINFO frame buffer device");
227           return 0;
228   }
229   screeninfo.bits_per_pixel=8;
230   if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
231           Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
232   }
233   screeninfo.bits_per_pixel=16;
234   if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
235           Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
236   }
237   close(fd_fbset);
238   return 1;
239 }
240
241
242
243 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
244 {
245         Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
246     char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
247
248     if (name != NULL) {
249                 if (STRCASECMP(name, "None") == 0) {
250                         deinterlace = 0;
251                 }/* else if (STRCASECMP(name, "LineDouble") == 0) {
252                         deinterlace = 1;
253                 }*/ else if (STRCASECMP(name, "Advanced") == 0) {
254                         deinterlace = 2;
255                 } /*else if (STRCASECMP(name, "Crazy") == 0) {
256                         deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
257                 }*/ else if (STRCASECMP(name, "Fast") == 0) {
258                         deinterlace = 4;
259                 }
260                 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
261                 delete[] name;
262         }
263
264    return true;
265
266 }
267
268 bool VideoOMX::handleOptionChanges(Option* option)
269 {
270     if (Video::handleOptionChanges(option))
271                 return true;
272         switch (option->id) {
273         case 1: {
274                 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
275                         deinterlace = 0;
276                 } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
277                                 == 0) {
278                         deinterlace = 1;
279                 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
280                                 == 0) {
281                         deinterlace = 2;
282                 } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
283                                 == 0) {
284                         deinterlace = 3;
285                 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Fast")
286                         == 0) {
287                         deinterlace = 4;
288                 }
289                 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
290                 return true;
291         }
292         break;
293         };
294         return false;
295
296 }
297
298 bool VideoOMX::saveOptionstoServer()
299 {
300
301     switch (deinterlace) {
302         case 0:
303                 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
304                 break;
305         /*case 1:
306                 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
307                 break;*/
308         case 2:
309                 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
310                 break;
311         /*case 3:
312                 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
313                 break;*/
314         case 4:
315                 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
316                 break;
317         };
318
319     return true;
320 }
321
322 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
323            UINT numChoices, UINT defaultChoice, UINT startInt,
324            const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
325
326 bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
327 {
328     if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
329
330
331     Option* option;
332     if (panenumber == 2)
333     {
334                 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
335         option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/3,2,0,deinterlaceopts,NULL,false,this);
336         options->push_back(option);
337         pane->addOptionLine(option);
338     }
339
340     return true;
341 }
342
343
344
345 int VideoOMX::setTVsize(UCHAR ttvsize)
346 {
347   if (tvsize!=ttvsize) pendingmodechange=true;
348   tvsize=ttvsize;
349   return 1;
350 }
351
352 UCHAR VideoOMX::getTVsize()       {
353         /*if (hdmi)*/
354         return ASPECT16X9; // in order that aspect ratio changes are reported
355         //return tvsize;
356 }
357
358 void VideoOMX::executePendingModeChanges()
359 {
360         if (pendingmodechange) {
361                 Log::getInstance()->log("Video", Log::NOTICE, "Execute pending mode change");
362                 Osd::getInstance()->shutdown();
363                 selectVideoMode(0);
364                 Osd::getInstance()->restore();
365                 Osd::getInstance()->init();
366                 BoxStack::getInstance()->redrawAllBoxes();
367                 initted = 1;
368         }
369 }
370
371 int VideoOMX::setDefaultAspect()
372 {
373   return setAspectRatio(tvsize,parx,pary);
374 }
375
376
377
378 int VideoOMX::setFormat(UCHAR tformat)
379 {
380   if (!initted) return 0;
381   if ((tformat != PAL) && (tformat != NTSC)
382                   && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
383   format = PAL;
384   tvsystem = tformat;
385
386   if (format == PAL)
387   {
388     screenWidth = 720;
389     screenHeight = 576;
390   }
391
392 //  selectVideoMode(0);
393
394   return 1;
395 }
396
397 void VideoOMX::selectVideoMode(int interlaced)
398 {
399         TV_GET_STATE_RESP_T tvstate;
400         vc_tv_get_state(&tvstate);
401
402         if ((tvstate.state & VC_HDMI_UNPLUGGED)) {
403                 hdmi = false;
404                 Log::getInstance()->log("Video", Log::NOTICE, "HDMI unplugged");
405         } else {
406                 hdmi = true;
407                 Log::getInstance()->log("Video", Log::NOTICE, "HDMI plugged");
408                 if (connection==COMPOSITERGB) {
409                         hdmi=false;
410                         Log::getInstance()->log("Video", Log::NOTICE, "SDTV set");
411                 } else {
412                         hdmi=true;
413                         Log::getInstance()->log("Video", Log::NOTICE, "HDMI set");
414                 }
415         }
416
417
418         if (hdmi) {
419                 TV_SUPPORTED_MODE_T all_supp_modes[200];
420                 HDMI_RES_GROUP_T pref_group;
421                 TV_SUPPORTED_MODE_T  *mymode=NULL;
422                 TV_SUPPORTED_MODE_T  *mymode_second_best=NULL;
423                 // bool got_optimum=false;
424                 uint32_t pref_mode;
425                 HDMI_RES_GROUP_T group=HDMI_RES_GROUP_CEA;
426                 int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
427                                 all_supp_modes,200,
428                                 &pref_group,&pref_mode);
429                 if (all_my_modes<=0) {
430                         group=HDMI_RES_GROUP_DMT;
431                         all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
432                                         all_supp_modes,200,
433                                         &pref_group,&pref_mode);
434                         Log::getInstance()->log("Video", Log::NOTICE, "No CEA fall back to DMT modes ");
435                 }
436
437
438
439
440                 int target_fps=50;
441                 if (format==PAL)target_fps=50;
442                 else if (format==NTSC) target_fps=60;
443
444                 //Now first determine native resolution
445                 int native_width=1920;
446                 int native_height=1080;
447                 for (int i=0;i<all_my_modes;i++) {
448                         if (all_supp_modes[i].native) {
449                                 mymode=all_supp_modes+i;
450                                 Log::getInstance()->log("Video", Log::NOTICE, "Found native mode %dx%d %d Hz i: %d",
451                                                 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
452                                 native_width=mymode->width;
453                                 native_height=mymode->height;
454                         }
455
456                 }
457                 //Now find the mode which matches best
458                 for (int i=0;i<all_my_modes;i++) {
459                         TV_SUPPORTED_MODE_T  *curmode=all_supp_modes+i;
460                         if (curmode->width==native_width &&
461                                         curmode->height==native_height &&
462                                         curmode->frame_rate==target_fps) {
463                                 if(curmode->scan_mode==interlaced) {
464                                         //got_optimum=true;
465                                         mymode=curmode;
466                                         Log::getInstance()->log("Video", Log::NOTICE, "Found optimum mode %dx%d %d Hz i: %d",
467                                                         mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
468                                 } else {
469                                         mymode_second_best=curmode;
470                                         Log::getInstance()->log("Video", Log::NOTICE, "Found close to optimum mode %dx%d %d Hz i: %d",
471                                                         mymode_second_best->width,mymode_second_best->height,
472                                                         mymode_second_best->frame_rate,mymode_second_best->scan_mode);
473                                 }
474
475                         }
476                 }
477                 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
478                 vc_tv_power_off();
479                 if (mymode) {
480                         Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode");
481                         vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode->code);
482                 } else if (mymode_second_best) {
483                         Log::getInstance()->log("Video", Log::NOTICE, "Switch to close to optimum mode");
484                         vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode_second_best->code);
485                 } else {
486                         Log::getInstance()->log("Video", Log::NOTICE, "Switch to prefered mode");
487                         vc_tv_hdmi_power_on_best(1920,1080,target_fps,interlaced?HDMI_INTERLACED:HDMI_NONINTERLACED,
488                                         (EDID_MODE_MATCH_FLAG_T)(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE));
489                 }
490                 hdmi=true;
491                 outputinterlaced=interlaced;
492         } else {
493                 /* analog tv case */
494                 Log::getInstance()->log("Video", Log::NOTICE, "Analog tv case");
495                 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?             vc_tv_power_off();
496                 SDTV_MODE_T setmode=SDTV_MODE_PAL;
497                 SDTV_OPTIONS_T options;
498
499                 switch (tvsize) {
500                 default:
501                 case ASPECT16X9:
502                         Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 16:9");
503                         options.aspect=SDTV_ASPECT_16_9; break;
504                 case ASPECT4X3:
505                         Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 4:3");
506                         options.aspect=SDTV_ASPECT_4_3; break;
507                 case ASPECT14X9:
508                         Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 14:9");
509                         options.aspect=SDTV_ASPECT_14_9; break;
510                 };
511
512                 if (format==PAL) setmode=SDTV_MODE_PAL;
513                 else if (format==NTSC) setmode=SDTV_MODE_NTSC;
514                 else if (format==PAL_M)setmode=SDTV_MODE_PAL_M;
515                 else if (format==NTSC_J) setmode=SDTV_MODE_NTSC_J;
516                 vc_tv_sdtv_power_on(setmode,&options);
517                 hdmi=false;
518         }
519
520 //      InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
521     // If this was just to reinit CEC then funcitons should be made to do that
522
523
524         signalon=true;
525         pendingmodechange=false;
526
527 }
528
529
530 int VideoOMX::setConnection(UCHAR tconnection)
531 {
532   if (!initted) return 0;
533   if ((tconnection != COMPOSITERGB)  && (tconnection != HDMI)) return 0;
534   if (connection!=tconnection) pendingmodechange=true;
535   connection = tconnection;
536
537 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
538   return 1;
539 }
540
541 int VideoOMX::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
542 {
543   if (!initted) return 0;
544   //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
545   aspectRatio = taspectRatio;
546   parx=tparx;
547   pary=tpary;
548
549   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i: PAR %d %d", aspectRatio,parx,pary);
550
551   updateMode();
552 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
553   return 1;
554 }
555
556 int VideoOMX::setMode(UCHAR tmode)
557 {
558   if (!initted) return 0;
559   if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode;
560   updateMode();
561   return 1;
562 }
563
564 bool VideoOMX::setVideoDisplay(VideoDisplay display)
565 {
566         if (!initted) return false;
567         switch (display.mode)
568         {
569         case None: return true; //??
570         case Fullscreen: {
571                 windowed = false;
572
573         } break;
574         case Quarter: {
575                 windowed =true;
576                 xpos = ((float) display.x) / ((float) screenWidth);
577                 ypos = ((float) display.y) / ((float) screenHeight);
578                 width = 0.5f;
579                 height = 0.5f;
580         } break;
581
582         case Eighth: {
583                 windowed =true;
584                 xpos = ((float) display.x) / ((float) screenWidth);
585                 ypos = ((float) display.y) / ((float) screenHeight);
586                 width = 0.25f;
587                 height = 0.25f;
588         } break;
589
590         case Window: {
591                 windowed =true;
592                 xpos = ((float) display.x) / ((float) screenWidth);
593                 ypos = ((float) display.y) / ((float) screenHeight);
594                 width = ((float) display.width) / ((float) screenWidth);
595                 height = ((float) display.height) / ((float) screenHeight);
596         }break;
597         }
598         updateMode();
599         return true;
600 }
601
602
603 void VideoOMX::updateMode()
604 {
605         clock_mutex.lock();
606         if (omx_running) {
607                 int oldcancelstate;
608                 int oldcanceltype;
609                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
610                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
611                 OMX_ERRORTYPE error;
612                 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
613                 memset(&dispconf, 0, sizeof(dispconf));
614                 dispconf.nSize = sizeof(dispconf);
615                 dispconf.nVersion.nVersion = OMX_VERSION;
616                 dispconf.nPortIndex = omx_rend_input_port;
617                 dispconf.layer = 1;
618                 dispconf.set = OMX_DISPLAY_SET_LAYER;
619                 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
620                                 &dispconf);
621                 if (error != OMX_ErrorNone) {
622                         Log::getInstance()->log("Video", Log::DEBUG,
623                                         "Set OMX_IndexConfigDisplayRegion1 failed %x", error);
624                         pthread_setcancelstate(oldcancelstate, NULL);
625                         pthread_setcanceltype(oldcanceltype, NULL);
626                         clock_mutex.unlock();
627                         return;
628                 }
629
630
631                 dispconf.pixel_x =parx;
632                 dispconf.pixel_y=pary;
633                 dispconf.set = OMX_DISPLAY_SET_PIXEL;
634                 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
635                                 &dispconf);
636                 if (error != OMX_ErrorNone) {
637                         Log::getInstance()->log("Video", Log::DEBUG,
638                                         "Set OMX_IndexConfigDisplayRegion5 failed %x", error);
639                         pthread_setcancelstate(oldcancelstate, NULL);
640                         pthread_setcanceltype(oldcanceltype, NULL);
641                         clock_mutex.unlock();
642                         return;
643                 }
644
645
646
647                 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
648                 if (!windowed) {
649                         //Set Fullscreen
650                         dispconf.fullscreen = OMX_TRUE;
651                 } else {
652                         dispconf.fullscreen = OMX_FALSE;
653                 }
654                 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
655                                 &dispconf);
656                 if (error != OMX_ErrorNone) {
657                         Log::getInstance()->log("Video", Log::DEBUG,
658                                         "Set OMX_IndexConfigDisplayRegion2 failed %x", error);
659                         pthread_setcancelstate(oldcancelstate, NULL);
660                         pthread_setcanceltype(oldcanceltype, NULL);
661                         clock_mutex.unlock();
662                         return;
663                 }
664
665                 dispconf.set = OMX_DISPLAY_SET_MODE;
666                 if (!windowed) {
667                         dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
668                                         : OMX_DISPLAY_MODE_LETTERBOX;
669                 } else {
670                         dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
671                 }
672                 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
673                                 &dispconf);
674                 if (error != OMX_ErrorNone) {
675                         Log::getInstance()->log("Video", Log::DEBUG,
676                                         "Set OMX_IndexConfigDisplayRegion3 failed %x", error);
677                         pthread_setcancelstate(oldcancelstate, NULL);
678                         pthread_setcanceltype(oldcanceltype, NULL);
679                         clock_mutex.unlock();
680                         return;
681                 }
682
683                 if (windowed) {
684                         unsigned int display_width, display_height;
685                         display_width = display_height = 0;
686                         if (graphics_get_display_size(0, &display_width, &display_height)
687                                         < 0) {
688                                 Log::getInstance()->log("OSD", Log::WARN,
689                                                 "Getting display size failed! (BCM API) ");
690                                 pthread_setcancelstate(oldcancelstate, NULL);
691                                 pthread_setcanceltype(oldcanceltype, NULL);
692                                 clock_mutex.unlock();
693                                 return;
694                         }
695                         //UnSetFullscreen with window
696                         dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
697                         dispconf.dest_rect.x_offset
698                                         = (int) (xpos * ((float) display_width));
699                         dispconf.dest_rect.y_offset = (int) (ypos
700                                         * ((float) display_height));
701                         dispconf.dest_rect.width = (int) (width * ((float) display_width));
702                         dispconf.dest_rect.height = (int) (height * ((float) display_height));
703                         Log::getInstance()->log("Video", Log::DEBUG,
704                                                                         "Set dest_rect as %d %d %d %d", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset,
705                                                                         dispconf.dest_rect.width , dispconf.dest_rect.height);
706
707                         error = OMX_SetParameter(omx_vid_rend,
708                                         OMX_IndexConfigDisplayRegion, &dispconf);
709                         if (error != OMX_ErrorNone) {
710                                 Log::getInstance()->log("Video", Log::DEBUG,
711                                                 "Set OMX_IndexConfigDisplayRegion failed %x", error);
712                                 pthread_setcancelstate(oldcancelstate, NULL);
713                                 pthread_setcanceltype(oldcanceltype, NULL);
714                                 clock_mutex.unlock();
715                                 return;
716                         }
717                 }
718                 pthread_setcancelstate(oldcancelstate, NULL);
719                 pthread_setcanceltype(oldcanceltype, NULL);
720
721         }
722         clock_mutex.unlock();
723 }
724
725 int VideoOMX::signalOff()
726 {
727         //TODO reinit osd
728         Log::getInstance()->log("Video", Log::NOTICE, "signalOff");
729         Osd::getInstance()->stopUpdate(); // turn off drawing thread
730         InputMan::getInstance()->shutdown();
731         vc_tv_power_off();
732         InputMan::getInstance()->init(); // FIXME
733         signalon=false;
734     return 1;
735 }
736
737 int VideoOMX::signalOn()
738 {
739   if (!signalon)  {
740           Osd::getInstance()->shutdown();
741           Log::getInstance()->log("Video", Log::NOTICE, "signalOn");
742           selectVideoMode(0);
743           Osd::getInstance()->restore();
744           Osd::getInstance()->init();
745           BoxStack::getInstance()->redrawAllBoxes();
746           initted=1;
747
748   }
749   return 1;
750 }
751
752 int VideoOMX::setSource()
753 {
754   if (!initted) return 0;
755
756   // What does this do...
757 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
758   return 1;
759 }
760
761 int VideoOMX::setPosition(int x, int y) {
762         if (!initted)
763                 return 0;
764         xpos = ((float) x*2.f) / ((float) screenWidth);
765         ypos = ((float) y*2.f) / ((float) screenHeight);
766
767         updateMode();
768         return 1;
769 }
770
771 int VideoOMX::sync()
772 {
773   if (!initted) return 0;
774
775 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
776   return 1;
777 }
778
779 void VideoOMX::interlaceSwitch4Demux() {
780         return;
781         Demuxer *demux=Demuxer::getInstance();
782
783         if (hdmi) { // only switch if hdmi and HD or interlaced SD material
784
785
786                 //OMX_Deinit();
787                 int set_interlaced=0;
788                 if (demux->getHorizontalSize()>720  && demux->getInterlaced()) {
789                         set_interlaced=1;
790                 }
791                 Log::getInstance()->log("Video", Log::NOTICE, "switch interlacing %d %d %d",demux->getInterlaced(),outputinterlaced,set_interlaced);
792                 if (outputinterlaced!=set_interlaced) {
793                         selectVideoMode(set_interlaced);
794                         Osd::getInstance()->shutdown();
795                         Osd::getInstance()->restore();
796                         Osd::getInstance()->init();
797                         BoxStack::getInstance()->redrawAllBoxes();
798                         initted=1;
799                 }
800                 //OMX_Init();
801
802
803         }
804
805
806 }
807
808
809 int VideoOMX::play() {
810         if (!initted)
811                 return 0;
812         iframemode = false;
813         Log::getInstance()->log("Video", Log::DEBUG, "enter play");
814
815         interlaceSwitch4Demux();
816
817         if (AllocateCodecsOMX()) {
818                 return 1;
819                 // Otherwise fall back to libav
820         } else {
821                 if (h264) {
822                         omx_h264 = false;
823                         Log::getInstance()->log("Video", Log::NOTICE,
824                                         "Allocate Codecs OMX failed assume h264 unsupported");
825                 } else {
826                         omx_mpeg2 = false;
827                         Log::getInstance()->log("Video", Log::NOTICE,
828                                         "Allocate Codecs OMX failed assume mpeg2 unsupported");
829                 }
830         }
831
832         return 0;
833
834 }
835
836
837 int VideoOMX::initClock()
838 {
839         OMX_ERRORTYPE error;
840         clock_mutex.lock();
841         if (clock_references==0)
842         {
843
844                 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
845                 omx_event_mutex.lock();
846                 omx_events.clear();
847                 omx_event_mutex.unlock();
848
849                 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
850
851                 if (error!=OMX_ErrorNone) {
852                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
853                         clock_mutex.unlock();
854                         DeAllocateCodecsOMX();
855                         return 0;
856                 }
857
858                 /* TODO Clock config to separate method */
859                 OMX_PORT_PARAM_TYPE p_param;
860                 memset(&p_param,0,sizeof(p_param));
861                 p_param.nSize=sizeof(p_param);
862                 p_param.nVersion.nVersion=OMX_VERSION;
863                 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
864                 if (error!=OMX_ErrorNone) {
865                         Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
866                         clock_mutex.unlock();
867                         DeAllocateCodecsOMX();
868                         return 0;
869                 }
870                 omx_clock_output_port=p_param.nStartPortNumber;
871
872                 for (unsigned int i=0;i<p_param.nPorts;i++) {
873                         if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
874                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
875                                 clock_mutex.unlock();
876                                 DeAllocateCodecsOMX();
877                                 return 0;
878                         }
879                 }
880
881
882
883
884         }
885         Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
886         clock_references++;
887         clock_mutex.unlock();
888         return 1;
889 }
890
891 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
892 {
893         OMX_ERRORTYPE error;
894         *p_omx_clock=NULL;
895         *p_omx_clock_output_port=0;
896
897         if (!initClock()) {
898                 return 0;
899         }
900         clock_mutex.lock();
901
902         OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
903         memset(&refclock,0,sizeof(refclock));
904         refclock.nSize=sizeof(refclock);
905         refclock.nVersion.nVersion=OMX_VERSION;
906
907         refclock.eClock=OMX_TIME_RefClockAudio;
908
909         //refclock.eClock=OMX_TIME_RefClockVideo;
910         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
911         if (error!=OMX_ErrorNone){
912                 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
913                 clock_mutex.unlock();
914                 DeAllocateCodecsOMX();
915                 return 0;
916         }
917
918         OMX_PORT_PARAM_TYPE p_param;
919         memset(&p_param,0,sizeof(p_param));
920         p_param.nSize=sizeof(p_param);
921         p_param.nVersion.nVersion=OMX_VERSION;
922         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
923         if (error!=OMX_ErrorNone){
924                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
925                 clock_mutex.unlock();
926                 DeAllocateCodecsOMX();
927                 return 0;
928         }
929
930         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
931         memset(&clock_conf,0,sizeof(clock_conf));
932         clock_conf.nSize=sizeof(clock_conf);
933         clock_conf.nVersion.nVersion=OMX_VERSION;
934         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
935         clock_conf.nStartTime=intToOMXTicks(0);
936         clock_conf.nOffset=intToOMXTicks(0);
937         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
938         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
939         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
940         if (error!=OMX_ErrorNone) {
941                 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
942         }
943
944
945         *p_omx_clock_output_port=p_param.nStartPortNumber+1;
946         *p_omx_clock=omx_clock;
947         clock_mutex.unlock();
948         return 1;
949 }
950
951 int VideoOMX::getClockVideoandInit()
952 {
953         OMX_ERRORTYPE error;
954
955         if (!initClock()) {
956                 return 0;
957         }
958         clock_mutex.lock();
959
960         if (clock_references==1) { // only if no audio is attached to this clock!
961                 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
962                 memset(&refclock,0,sizeof(refclock));
963                 refclock.nSize=sizeof(refclock);
964                 refclock.nVersion.nVersion=OMX_VERSION;
965
966                 //refclock.eClock=OMX_TIME_RefClockAudio;
967
968                 refclock.eClock=OMX_TIME_RefClockVideo;
969                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
970                 if (error!=OMX_ErrorNone) {
971                         Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
972                         clock_mutex.unlock();
973                         DeAllocateCodecsOMX();
974                         return 0;
975                 }
976         }
977
978         OMX_PORT_PARAM_TYPE p_param;
979         memset(&p_param,0,sizeof(p_param));
980         p_param.nSize=sizeof(p_param);
981         p_param.nVersion.nVersion=OMX_VERSION;
982         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
983         if (error!=OMX_ErrorNone){
984                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
985                 clock_mutex.unlock();
986                 DeAllocateCodecsOMX();
987                 return 0;
988         }
989
990
991         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
992         memset(&clock_conf,0,sizeof(clock_conf));
993         clock_conf.nSize=sizeof(clock_conf);
994         clock_conf.nVersion.nVersion=OMX_VERSION;
995         clock_conf.eState=OMX_TIME_ClockStateStopped;
996         clock_conf.nStartTime=intToOMXTicks(0);
997         clock_conf.nOffset=intToOMXTicks(0);
998         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
999         if (error!=OMX_ErrorNone) {
1000                 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1001         }
1002
1003
1004         memset(&clock_conf,0,sizeof(clock_conf));
1005         clock_conf.nSize=sizeof(clock_conf);
1006         clock_conf.nVersion.nVersion=OMX_VERSION;
1007         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1008         clock_conf.nStartTime=intToOMXTicks(0);
1009         clock_conf.nOffset=intToOMXTicks(0);
1010         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1011         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1012         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1013         if (error!=OMX_ErrorNone) {
1014                 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1015         }
1016
1017         omx_clock_output_port=p_param.nStartPortNumber;
1018         clock_mutex.unlock();
1019
1020         return 1;
1021 }
1022
1023 void VideoOMX::clockUnpause()
1024 {
1025         OMX_ERRORTYPE error;
1026         Log::getInstance()->log("Video", Log::NOTICE, "enter Clockunpause");
1027         clock_mutex.lock();
1028         if (clock_references>0 && clockpaused) {
1029                 OMX_TIME_CONFIG_SCALETYPE scale_type;
1030                 memset(&scale_type,0,sizeof(scale_type));
1031                 scale_type.nSize=sizeof(scale_type);
1032                 scale_type.nVersion.nVersion=OMX_VERSION;
1033                 scale_type.xScale=1<<16;
1034                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1035                 if (error!=OMX_ErrorNone) {
1036                         Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause OMX_IndexConfigTimeScale failed %x", error);
1037                 }
1038                 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockUnpause");
1039                 clockpaused=false;
1040         }
1041         clock_mutex.unlock();
1042 }
1043
1044
1045 void VideoOMX::clockPause()
1046 {
1047         OMX_ERRORTYPE error;
1048         Log::getInstance()->log("Video", Log::NOTICE, "enter ClockPause");
1049         clock_mutex.lock();
1050         if (clock_references>0 && !clockpaused) {
1051                 OMX_TIME_CONFIG_SCALETYPE scale_type;
1052                 memset(&scale_type,0,sizeof(scale_type));
1053                 scale_type.nSize=sizeof(scale_type);
1054                 scale_type.nVersion.nVersion=OMX_VERSION;
1055                 scale_type.xScale=0;
1056                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1057                 if (error!=OMX_ErrorNone) {
1058                         Log::getInstance()->log("Video", Log::DEBUG, "ClockPause OMX_IndexConfigTimeScale failed %x", error);
1059                 }
1060                 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockPause");
1061                 clockpaused=true;
1062         }
1063         clock_mutex.unlock();
1064 }
1065
1066
1067
1068 int VideoOMX::AllocateCodecsOMX()
1069 {
1070         OMX_ERRORTYPE error;
1071         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1072
1073         Demuxer* demux=Demuxer::getInstance();
1074
1075         dodeint=false;
1076         first_frame=true;
1077
1078         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1079         //Clock, move later to audio including events
1080
1081         Log::getInstance()->log("Video", Log::NOTICE, "Deinter VideoType %d x %d i: %d", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1082         if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) { 
1083                 dodeint=true;
1084
1085
1086                 Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
1087
1088         }
1089
1090
1091         if (!getClockVideoandInit()){
1092                 return 0;// get the clock and init it if necessary
1093         }
1094
1095
1096         if (!idleClock()) {
1097                 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
1098                 return 0;
1099         }
1100         /* TODO end */
1101
1102         clock_mutex.lock();
1103         if (h264) {
1104                 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1105         } else {
1106                 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1107         }
1108
1109         if (error!=OMX_ErrorNone){
1110                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1111                 clock_mutex.unlock();
1112                 DeAllocateCodecsOMX();
1113                 return 0;
1114         }
1115
1116
1117         Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
1118         OMX_PORT_PARAM_TYPE p_param;
1119         memset(&p_param,0,sizeof(p_param));
1120         p_param.nSize=sizeof(p_param);
1121         p_param.nVersion.nVersion=OMX_VERSION;
1122         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1123         if (error!=OMX_ErrorNone){
1124                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1125                 clock_mutex.unlock();
1126                 DeAllocateCodecsOMX();
1127             return 0;
1128         }
1129         omx_codec_input_port=p_param.nStartPortNumber;
1130         omx_codec_output_port=p_param.nStartPortNumber+1;
1131
1132         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1133                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1134                 clock_mutex.unlock();
1135                 DeAllocateCodecsOMX();
1136                 return 0;
1137         }
1138
1139         Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
1140
1141         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1142         memset(&conceal,0,sizeof(conceal));
1143         conceal.nSize=sizeof(conceal);
1144         conceal.nVersion.nVersion=OMX_VERSION;
1145         conceal.bStartWithValidFrame=OMX_FALSE;
1146
1147         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1148         if (error!=OMX_ErrorNone){
1149                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1150                 clock_mutex.unlock();
1151                 DeAllocateCodecsOMX();
1152                 return 0;
1153         }
1154
1155         if (dodeint) {
1156                 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1157                                 &callbacks);
1158                 if (error != OMX_ErrorNone) {
1159                         Log::getInstance()->log("Video", Log::DEBUG,
1160                                         "Init OMX video deinterlacer failed %x", error);
1161                         clock_mutex.unlock();
1162                         DeAllocateCodecsOMX();
1163                         return 0;
1164                 }
1165
1166                 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1167                                 &p_param);
1168                 if (error != OMX_ErrorNone) {
1169                         Log::getInstance()->log("Video", Log::DEBUG,
1170                                         "Init OMX video deinterlacer OMX_GetParameter failed %x",
1171                                         error);
1172                         clock_mutex.unlock();
1173                         DeAllocateCodecsOMX();
1174                         return 0;
1175                 }
1176                 omx_deint_input_port = p_param.nStartPortNumber;
1177                 omx_deint_output_port = p_param.nStartPortNumber + 1;
1178
1179                 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1180                                 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1181                         Log::getInstance()->log("Video", Log::DEBUG,
1182                                         "Disable Ports OMX video deint failed");
1183                         clock_mutex.unlock();
1184                         DeAllocateCodecsOMX();
1185                         return 0;
1186                 }
1187
1188         }
1189
1190
1191         error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1192         if (error!=OMX_ErrorNone){
1193                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1194                 clock_mutex.unlock();
1195                 DeAllocateCodecsOMX();
1196                 return 0;
1197         }
1198
1199
1200
1201         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1202         if (error!=OMX_ErrorNone){
1203                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1204                 clock_mutex.unlock();
1205                 DeAllocateCodecsOMX();
1206                 return 0;
1207         }
1208         omx_shed_input_port=p_param.nStartPortNumber;
1209         omx_shed_output_port=p_param.nStartPortNumber+1;
1210
1211
1212         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1213         if (error!=OMX_ErrorNone){
1214                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1215                 clock_mutex.unlock();
1216                 DeAllocateCodecsOMX();
1217                 return 0;
1218         }
1219         omx_shed_clock_port=p_param.nStartPortNumber;
1220         Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1221
1222
1223         if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1224                         || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1225                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1226                 clock_mutex.unlock();
1227                 DeAllocateCodecsOMX();
1228                 return 0;
1229         }
1230
1231
1232         error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1233         if (error!=OMX_ErrorNone){
1234                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1235                 clock_mutex.unlock();
1236                 DeAllocateCodecsOMX();
1237                 return 0;
1238         }
1239
1240         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1241         if (error!=OMX_ErrorNone){
1242                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1243                 clock_mutex.unlock();
1244                 DeAllocateCodecsOMX();
1245                 return 0;
1246         }
1247         omx_rend_input_port=p_param.nStartPortNumber;
1248         //omx_rend_output_port=p_param.nStartPortNumber+1;
1249
1250
1251         if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1252                                 ) {
1253                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1254                 clock_mutex.unlock();
1255                 DeAllocateCodecsOMX();
1256                 return 0;
1257         }
1258
1259         //Setuo chain
1260
1261
1262
1263         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1264         if (error!=OMX_ErrorNone){
1265                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
1266                 clock_mutex.unlock();
1267                 DeAllocateCodecsOMX();
1268                 return 0;
1269         }
1270
1271         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1272                                         ) {
1273                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1274                 clock_mutex.unlock();
1275                 DeAllocateCodecsOMX();
1276                 return 0;
1277         }
1278
1279
1280
1281         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1282                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1283                 clock_mutex.unlock();
1284                 DeAllocateCodecsOMX();
1285                 return 0;
1286         }
1287
1288
1289
1290
1291         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1292                 clock_mutex.unlock();
1293                 DeAllocateCodecsOMX();
1294                 return 0;
1295         }
1296
1297
1298
1299
1300
1301         if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1302                 clock_mutex.unlock();
1303                 DeAllocateCodecsOMX();
1304                 return 0;
1305         }
1306
1307
1308
1309 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1310         if (error!=OMX_ErrorNone){
1311                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1312                 return 0;
1313         }*/
1314
1315         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1316         memset(&ft_type,0,sizeof(ft_type));
1317         ft_type.nSize=sizeof(ft_type);
1318         ft_type.nVersion.nVersion=OMX_VERSION;
1319
1320         ft_type.nPortIndex=omx_codec_input_port;
1321         if (h264) {
1322                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1323         } else {
1324                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1325         }
1326
1327
1328
1329     ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1330     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1331         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1332         if (error!=OMX_ErrorNone){
1333                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1334                 clock_mutex.unlock();
1335                 DeAllocateCodecsOMX();
1336                 return 0;
1337         }
1338
1339
1340         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1341                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1342                 clock_mutex.unlock();
1343                 DeAllocateCodecsOMX();
1344                 return 0;
1345         }
1346
1347         OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1348         memset(&stall_conf,0,sizeof(stall_conf));
1349         stall_conf.nSize=sizeof(stall_conf);
1350         stall_conf.nVersion.nVersion=OMX_VERSION;
1351         stall_conf.nPortIndex=omx_codec_output_port;
1352         stall_conf.nDelay=1500*1000;
1353         error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1354         if (error!=OMX_ErrorNone){
1355                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigBufferStall failed %x", error);
1356                 clock_mutex.unlock();
1357                 DeAllocateCodecsOMX();
1358                 return 0;
1359         }
1360         omx_vid_stalled = false;
1361
1362         OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1363         memset(&req_callback,0,sizeof(req_callback));
1364         req_callback.nSize=sizeof(req_callback);
1365         req_callback.nVersion.nVersion=OMX_VERSION;
1366         req_callback.nPortIndex=omx_codec_output_port;
1367         req_callback.nIndex=OMX_IndexConfigBufferStall;
1368         req_callback.bEnable=OMX_TRUE;
1369         error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1370         if (error!=OMX_ErrorNone){
1371                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigRequestCallback  failed %x", error);
1372                 clock_mutex.unlock();
1373                 DeAllocateCodecsOMX();
1374                 return 0;
1375         }
1376
1377
1378
1379         if (!PrepareInputBufsOMX()) {
1380                 clock_mutex.unlock();
1381                 DeAllocateCodecsOMX();
1382                 return 0;
1383         }
1384
1385         if (!dodeint) {
1386                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1387                 if (error!=OMX_ErrorNone){
1388                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1389                         clock_mutex.unlock();
1390                         DeAllocateCodecsOMX();
1391                         return 0;
1392                 }
1393
1394
1395
1396                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1397                 ) {
1398                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1399                         clock_mutex.unlock();
1400                         DeAllocateCodecsOMX();
1401                         return 0;
1402                 }
1403
1404                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1405                         clock_mutex.unlock();
1406                         DeAllocateCodecsOMX();
1407                         return 0;
1408                 }
1409
1410         } else {
1411
1412                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1413                 if (error!=OMX_ErrorNone){
1414                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
1415                         clock_mutex.unlock();
1416                         DeAllocateCodecsOMX();
1417                         return 0;
1418                 }
1419
1420
1421
1422                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1423                 ) {
1424                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
1425                         clock_mutex.unlock();
1426                         DeAllocateCodecsOMX();
1427                         return 0;
1428                 }
1429
1430                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1431                         clock_mutex.unlock();
1432                         DeAllocateCodecsOMX();
1433                         return 0;
1434                 }
1435
1436                 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1437                         Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
1438                         clock_mutex.unlock();
1439                         DeAllocateCodecsOMX();
1440                         return 0;
1441                 }
1442
1443                 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1444                 memset(&imagefilter,0,sizeof(imagefilter));
1445                 imagefilter.nSize=sizeof(imagefilter);
1446                 imagefilter.nVersion.nVersion=OMX_VERSION;
1447
1448                 imagefilter.nPortIndex=omx_deint_output_port;
1449                 imagefilter.nNumParams=4;
1450                 imagefilter.nParams[0]=3;//???
1451                 imagefilter.nParams[1]=0;//default frame interval
1452                 imagefilter.nParams[2]=0;// frame rate
1453                 if (demux->getHorizontalSize() <= 720){
1454                         imagefilter.nParams[3] = 1;//use qpus
1455                 }
1456                 else 
1457                 {
1458                         imagefilter.nParams[3] = 0;//use qpus
1459                 }
1460
1461                 switch (deinterlace) {
1462                 case 1:
1463                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1464                 case 2:
1465                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1466                 case 3:
1467                         imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1468                 case 4:
1469                         imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1470                 }
1471
1472
1473                 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1474                 if (error!=OMX_ErrorNone){
1475                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
1476                         clock_mutex.unlock();
1477                         DeAllocateCodecsOMX();
1478                         return 0;
1479                 }
1480
1481
1482                 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1483                 if (error!=OMX_ErrorNone){
1484                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
1485                         clock_mutex.unlock();
1486                         DeAllocateCodecsOMX();
1487                         return 0;
1488                 }
1489
1490                 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1491                 ) {
1492                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
1493                         clock_mutex.unlock();
1494                         DeAllocateCodecsOMX();
1495                         return 0;
1496                 }
1497
1498                 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1499                         clock_mutex.unlock();
1500                         DeAllocateCodecsOMX();
1501                         return 0;
1502                 }
1503
1504         }
1505
1506         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1507                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1508                 clock_mutex.unlock();
1509                 DeAllocateCodecsOMX();
1510                 return 0;
1511         }
1512
1513         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1514         if (error!=OMX_ErrorNone){
1515                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1516                 clock_mutex.unlock();
1517                 DeAllocateCodecsOMX();
1518                 return 0;
1519         }
1520
1521         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1522                                                         ) {
1523                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1524                 clock_mutex.unlock();
1525                 DeAllocateCodecsOMX();
1526                 return 0;
1527         }
1528
1529         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1530                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1531                 clock_mutex.unlock();
1532                 DeAllocateCodecsOMX();
1533                 return 0;
1534         }
1535
1536         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1537                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1538                 clock_mutex.unlock();
1539                 DeAllocateCodecsOMX();
1540                 return 0;
1541         }
1542
1543         if (dodeint) {
1544                 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1545                         Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
1546                         clock_mutex.unlock();
1547                         DeAllocateCodecsOMX();
1548                         return 0;
1549                 }
1550                 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1551                 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1552         }
1553
1554         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1555                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1556                 clock_mutex.unlock();
1557                 DeAllocateCodecsOMX();
1558                 return 0;
1559         }
1560
1561         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1562                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1563                 clock_mutex.unlock();
1564                 DeAllocateCodecsOMX();
1565                 return 0;
1566         }
1567
1568         //raspbi specifif
1569         /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1570         memset(&dispconf,0,sizeof(dispconf));
1571         dispconf.nSize=sizeof(dispconf);
1572         dispconf.nVersion.nVersion=OMX_VERSION;
1573
1574         dispconf.nPortIndex=omx_rend_input_port;
1575
1576         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1577         dispconf.layer=1;
1578         error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1579         if (error!=OMX_ErrorNone){
1580                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1581                 clock_mutex.unlock();
1582                 DeAllocateCodecsOMX();
1583                 return 0;
1584         }*/
1585
1586 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1587         dispconf.fullscreen=OMX_FALSE;
1588         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1589         if (error!=OMX_ErrorNone){
1590                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1591                 clock_mutex.unlock();
1592                 DeAllocateCodecsOMX();
1593                 return 0;
1594         }
1595
1596         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1597         dispconf.dest_rect.x_offset=100;
1598         dispconf.dest_rect.y_offset=100;
1599         dispconf.dest_rect.width=640;
1600         dispconf.dest_rect.height=480;
1601         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1602         if (error!=OMX_ErrorNone){
1603                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1604                 clock_mutex.unlock();
1605                 DeAllocateCodecsOMX();
1606                 return 0;
1607         }*/
1608
1609
1610         //playbacktimeoffset=-GetCurrentSystemTime();
1611
1612         iframemode=false;
1613         omx_running=true;
1614         clock_mutex.unlock();
1615         clockUnpause();
1616         updateMode();
1617
1618         setClockExecutingandRunning();
1619
1620
1621
1622
1623
1624         return 1;
1625 }
1626
1627 int VideoOMX::idleClock()
1628 {
1629         //OMX_ERRORTYPE error;
1630         OMX_STATETYPE temp_state;
1631         clock_mutex.lock();
1632         OMX_GetState(omx_clock,&temp_state);
1633
1634         if (temp_state!=OMX_StateIdle) {
1635                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1636                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1637                         clock_mutex.unlock();
1638                         return 0;
1639                 }
1640         }
1641         clock_mutex.unlock();
1642         return 1;
1643 }
1644
1645 int VideoOMX::setClockExecutingandRunning()
1646 {
1647         OMX_ERRORTYPE error;
1648         OMX_STATETYPE temp_state;
1649         clock_mutex.lock();
1650         OMX_GetState(omx_clock,&temp_state);
1651
1652         if (temp_state!=OMX_StateExecuting) {
1653                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1654                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1655                         clock_mutex.unlock();
1656                         DeAllocateCodecsOMX();
1657                         return 0;
1658                 }
1659         }
1660
1661         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1662         memset(&clock_conf,0,sizeof(clock_conf));
1663         clock_conf.nSize=sizeof(clock_conf);
1664         clock_conf.nVersion.nVersion=OMX_VERSION;
1665         clock_conf.eState=OMX_TIME_ClockStateRunning;
1666         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1667         if (error!=OMX_ErrorNone) {
1668                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1669                 clock_mutex.unlock();
1670                 DeAllocateCodecsOMX();
1671                 return 0;
1672         }
1673         clock_mutex.unlock();
1674         return 1;
1675
1676 }
1677
1678
1679 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1680 {
1681         OMX_ERRORTYPE error;
1682         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1683         if (error!=OMX_ErrorNone){
1684                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1685                 return 0;
1686         }
1687
1688         if (wait) {
1689                 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1690                         return 0;
1691                 }
1692         }
1693
1694         return 1;
1695 }
1696
1697
1698 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1699 {
1700         OMX_ERRORTYPE error;
1701         bool skip=false;
1702
1703         OMX_PARAM_PORTDEFINITIONTYPE pdt;
1704         memset(&pdt,0,sizeof(pdt));
1705         pdt.nSize=sizeof(pdt);
1706         pdt.nVersion.nVersion=OMX_VERSION;
1707         pdt.nPortIndex=port;
1708         error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1709         if (error==OMX_ErrorNone) {
1710                 if(pdt.bEnabled==OMX_TRUE) {
1711                         skip=true; //already disabled;
1712                 }
1713
1714         }
1715
1716         if (!skip) {
1717                 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1718                 if (error!=OMX_ErrorNone){
1719                         Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1720                         return 0;
1721                 }
1722
1723                 if (!wait) return 1;
1724                 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1725                         return 0;
1726                 }
1727
1728         }
1729         return 1;
1730 }
1731
1732
1733 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1734 {
1735         OMX_ERRORTYPE error;
1736         bool skip=false;
1737
1738         OMX_PARAM_PORTDEFINITIONTYPE pdt;
1739         memset(&pdt,0,sizeof(pdt));
1740         pdt.nSize=sizeof(pdt);
1741         pdt.nVersion.nVersion=OMX_VERSION;
1742         pdt.nPortIndex=port;
1743         error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1744         if (error==OMX_ErrorNone) {
1745                 if(pdt.bEnabled==OMX_FALSE) {
1746                         skip=true; //already disabled;
1747                 }
1748
1749         }
1750
1751
1752         if (!skip) {
1753                 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1754                 if (error!=OMX_ErrorNone){
1755                         Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1756                         return 0;
1757                 }
1758
1759                 if (!wait) return 1;
1760                 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1761                         return 0;
1762                 }
1763         }
1764
1765         return 1;
1766 }
1767
1768 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1769 {
1770         int i=0;
1771         int iend=(wait/5+1);
1772         while (i<iend) {
1773                 omx_event_mutex.lock();
1774                 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1775                 while (itty!=omx_events.end()) {
1776
1777                         VPE_OMX_EVENT current=*itty;
1778                         if (current.handle==handle) { //this is ours
1779                                 if (current.event_type==OMX_EventError) {
1780                                         omx_events.erase(itty);
1781                                         omx_event_mutex.unlock();
1782                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1783                                         return 0;
1784
1785                                 } else if (current.event_type==event) {
1786                                         omx_events.erase(itty);
1787                                         omx_event_mutex.unlock();
1788                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1789                                         return 1;
1790                                 }
1791                         }
1792                         itty++;
1793
1794                 }
1795                 omx_event_mutex.unlock();
1796                 omx_event_ready_signal.waitForSignalTimed(10);
1797                 //MILLISLEEP(2);
1798                 i++;
1799
1800         }
1801         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1802         return 0;
1803
1804 }
1805
1806 int VideoOMX::clearEvents()
1807 {
1808         omx_event_mutex.lock();
1809         omx_events.clear();
1810         omx_event_mutex.unlock();
1811
1812         return 1;
1813 }
1814
1815 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1816 {
1817         omx_event_mutex.lock();
1818         std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1819         while (itty!=omx_events.end()) {
1820                 VPE_OMX_EVENT current=*itty;
1821                 if (current.handle==handle) { //this is ours
1822                         itty=omx_events.erase(itty);
1823                         continue;
1824                 }
1825                 itty++;
1826
1827         }
1828         omx_event_mutex.unlock();
1829         return 1;
1830 }
1831
1832 void VideoOMX::checkForStalledBuffers()
1833 {
1834         //Log::getInstance()->log("Video", Log::DEBUG, "Check stalled");
1835         clock_mutex.lock();
1836         omx_event_mutex.lock();
1837         std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1838         while (itty!=omx_events.end()) {
1839                 VPE_OMX_EVENT current=*itty;
1840                 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1841                                 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1842                         OMX_ERRORTYPE error;
1843                         OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1844                         memset(&stall_conf,0,sizeof(stall_conf));
1845                         stall_conf.nSize=sizeof(stall_conf);
1846                         stall_conf.nVersion.nVersion=OMX_VERSION;
1847                         stall_conf.nPortIndex=omx_codec_output_port;
1848                         stall_conf.nDelay=200000;
1849
1850                         error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1851                         if (error!=OMX_ErrorNone){
1852                                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX_IndexConfigBufferStall failed %x", error);
1853                                         clock_mutex.unlock();
1854                                         omx_event_mutex.unlock();
1855                                         return ;
1856                                 }
1857                         if (stall_conf.bStalled==OMX_TRUE) {
1858                                 omx_vid_stalled=true;
1859                                 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder stalled! %d", stall_conf.nDelay);
1860                         } else {
1861                                 omx_vid_stalled=false;
1862                                 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder unstalled! %d",stall_conf.nDelay);
1863                         }
1864                         omx_events.erase(itty);
1865                         break;
1866                 }
1867                 itty++;
1868         }
1869         omx_event_mutex.unlock();
1870         clock_mutex.unlock();
1871 }
1872
1873
1874
1875
1876 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1877 {
1878         int i=0;
1879         while (i<200/*1000*/) {
1880                 omx_event_mutex.lock();
1881                 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1882                 while (itty!=omx_events.end()) {
1883
1884                         VPE_OMX_EVENT current=*itty;
1885                         if (current.handle==handle) { //this is ours
1886                                 if (current.event_type==OMX_EventError) {
1887                                         omx_events.erase(itty);
1888                                         omx_event_mutex.unlock();
1889                                         Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1);
1890                                         return 0;
1891
1892                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1893                                         omx_events.erase(itty);
1894                                         omx_event_mutex.unlock();
1895                                         //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1896                                         return 1;
1897                                 }
1898                         }
1899                         itty++;
1900
1901                 }
1902                 omx_event_mutex.unlock();
1903                 omx_event_ready_signal.waitForSignalTimed(10);
1904                 //MILLISLEEP(2);
1905                 i++;
1906
1907         }
1908         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1909         return 0;
1910
1911 }
1912
1913
1914
1915 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1916 {
1917         OMX_ERRORTYPE error;
1918         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1919         memset(&port_def_type,0,sizeof(port_def_type));
1920         port_def_type.nSize=sizeof(port_def_type);
1921         port_def_type.nVersion.nVersion=OMX_VERSION;
1922         port_def_type.nPortIndex=omx_codec_input_port;
1923
1924         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1925
1926         if (error!=OMX_ErrorNone){
1927                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1928         }
1929 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1930                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1931                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1932
1933         port_def_type.nBufferCountActual=100;
1934         port_def_type.nBufferSize=max(port_def_type.nBufferSize,150000); // for transcoder important
1935
1936         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1937
1938         if (error!=OMX_ErrorNone){
1939                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1940         }
1941
1942
1943         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1944         if (error!=OMX_ErrorNone){
1945                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1946                 return 0;
1947         }
1948
1949         input_bufs_omx_mutex.lock();
1950         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1951
1952         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1953                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1954         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1955                 if (error!=OMX_ErrorNone){
1956                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1957                         input_bufs_omx_mutex.unlock();
1958                         return 0;
1959                 }*/
1960                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1961                 if (error!=OMX_ErrorNone){
1962                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1963                                 input_bufs_omx_mutex.unlock();
1964                         return 0;
1965                 }
1966                 input_bufs_omx_all.push_back(buf_head);
1967                 input_bufs_omx_free.push_back(buf_head);
1968         }
1969         omx_first_frame=true;
1970
1971         firstsynched=false;
1972         cur_input_buf_omx=NULL;
1973         input_bufs_omx_mutex.unlock();
1974
1975
1976         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1977         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1978                 return 0;
1979         }
1980         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1981
1982         return 1;
1983 }
1984
1985 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
1986 {
1987         OMX_ERRORTYPE error;
1988
1989         cur_input_buf_omx=NULL;
1990         input_bufs_omx_mutex.lock();
1991         for (UINT i=0; i< input_bufs_omx_all.size();i++) {
1992         //      free(input_bufs_omx_all[i]->pBuffer);
1993         //      input_bufs_omx_all[i]->pBuffer=NULL;
1994                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1995                 if (error!=OMX_ErrorNone){
1996                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1997                         input_bufs_omx_mutex.unlock();
1998                         return 0;
1999                 }
2000
2001         }
2002         input_bufs_omx_all.clear();
2003         input_bufs_omx_free.clear();
2004         input_bufs_omx_mutex.unlock();
2005
2006         return 1;
2007 }
2008
2009
2010
2011 int VideoOMX::FlushRenderingPipe()
2012 {
2013         OMX_ERRORTYPE error;
2014
2015         if (!dodeint) {
2016
2017                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2018                                 omx_codec_output_port, NULL);
2019                 if (error != OMX_ErrorNone) {
2020                         Log::getInstance()->log("Video", Log::DEBUG,
2021                                         "OMX_Flush codec out 1 failed %x", error);
2022
2023                 }
2024
2025                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2026                                 omx_shed_input_port, NULL);
2027                 if (error != OMX_ErrorNone) {
2028                         Log::getInstance()->log("Video", Log::DEBUG,
2029                                         "OMX_Flush shed in 2 failed %x", error);
2030
2031                 }
2032
2033                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2034                                 omx_codec_output_port)) {
2035                         Log::getInstance()->log("Video", Log::DEBUG,
2036                                         "flush cmd codec  3 failed");
2037                 }
2038
2039                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2040                                 omx_shed_input_port)) {
2041                         Log::getInstance()->log("Video", Log::DEBUG,
2042                                         "flush cmd  shed 4 failed");
2043                 }
2044         } else {
2045                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2046                                 omx_codec_output_port, NULL);
2047                 if (error != OMX_ErrorNone) {
2048                         Log::getInstance()->log("Video", Log::DEBUG,
2049                                         "OMX_Flush codec out 5 failed %x", error);
2050
2051                 }
2052
2053                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2054                                 omx_deint_input_port, NULL);
2055                 if (error != OMX_ErrorNone) {
2056                         Log::getInstance()->log("Video", Log::DEBUG,
2057                                         "OMX_Flush deint in 6 failed %x", error);
2058
2059                 }
2060
2061                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2062                                 omx_codec_output_port)) {
2063                         Log::getInstance()->log("Video", Log::DEBUG,
2064                                         "flush cmd codec  7 failed");
2065                 }
2066
2067                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2068                                 omx_deint_input_port)) {
2069                         Log::getInstance()->log("Video", Log::DEBUG,
2070                                         "flush cmd  deint 8 failed");
2071                 }
2072
2073                 //m
2074                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2075                                 omx_deint_output_port, NULL);
2076                 if (error != OMX_ErrorNone) {
2077                         Log::getInstance()->log("Video", Log::DEBUG,
2078                                         "OMX_Flush deint out 9 failed %x", error);
2079
2080                 }
2081
2082                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2083                                 omx_shed_input_port, NULL);
2084                 if (error != OMX_ErrorNone) {
2085                         Log::getInstance()->log("Video", Log::DEBUG,
2086                                         "OMX_Flush shed in 10 failed %x", error);
2087
2088                 }
2089
2090                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2091                                 omx_deint_output_port)) {
2092                         Log::getInstance()->log("Video", Log::DEBUG,
2093                                         "flush cmd deint 11 failed");
2094                 }
2095
2096                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2097                                 omx_shed_input_port)) {
2098                         Log::getInstance()->log("Video", Log::DEBUG,
2099                                         "flush cmd  shed 12 failed");
2100                 }
2101
2102         }
2103
2104
2105
2106
2107         error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2108                         omx_rend_input_port, NULL);
2109         if (error != OMX_ErrorNone) {
2110                 Log::getInstance()->log("Video", Log::DEBUG,
2111                                 "OMX_Flush rend in failed %x", error);
2112
2113         }
2114
2115         error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2116                         omx_shed_output_port, NULL);
2117         if (error != OMX_ErrorNone) {
2118                 Log::getInstance()->log("Video", Log::DEBUG,
2119                                 "OMX_Flush shed out failed %x", error);
2120
2121         }
2122
2123
2124
2125         if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2126                         omx_rend_input_port)) {
2127                 Log::getInstance()->log("Video", Log::DEBUG,
2128                                 "flush cmd shed rend failed");
2129         }
2130
2131         if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2132                         omx_shed_output_port)) {
2133                 Log::getInstance()->log("Video", Log::DEBUG,
2134                                 "flush cmd shed rend failed");
2135         }
2136
2137         return 1;
2138 }
2139
2140
2141 int VideoOMX::DeAllocateCodecsOMX()
2142 {
2143         OMX_ERRORTYPE error;
2144         omx_running=false;
2145           Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
2146
2147    if (cur_input_buf_omx) {
2148                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2149                 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2150                 if (error!=OMX_ErrorNone) {
2151                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2152                 }
2153
2154                 cur_input_buf_omx=NULL;//write out old data
2155         }
2156    clock_mutex.lock();
2157    clearEvents();
2158         if (omx_vid_dec) {
2159                 // first stop the omx elements
2160                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2161                         Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
2162
2163                 }
2164                 clock_mutex.unlock();
2165
2166                 idleClock();
2167                 clock_mutex.lock();
2168
2169                 if (dodeint) {
2170                         if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2171                                 Log::getInstance()->log("Video", Log::DEBUG,
2172                                                 "vid_deint ChangeComponentState");
2173
2174                         }
2175                 }
2176
2177
2178                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2179                         Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
2180
2181                 }
2182
2183                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2184                         Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
2185
2186                 }
2187
2188
2189
2190         // TODO proper deinit sequence
2191                 // first flush all buffers
2192                 FlushRenderingPipe();
2193
2194
2195
2196
2197
2198                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2199                 if (error!=OMX_ErrorNone){
2200                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
2201
2202                 }
2203
2204                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2205                 if (error!=OMX_ErrorNone){
2206                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
2207
2208                 }
2209
2210                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2211                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2212                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
2213                 }
2214
2215
2216
2217
2218                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2219                                 omx_codec_input_port, NULL);
2220                 if (error != OMX_ErrorNone) {
2221                         Log::getInstance()->log("Video", Log::DEBUG,
2222                                         "OMX_Flush codec out failed %x", error);
2223
2224                 }
2225
2226
2227
2228
2229                 DestroyInputBufsOMX();
2230
2231                 //todo flushing
2232                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2233                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
2234                 }
2235                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2236                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
2237                 }
2238
2239
2240
2241
2242                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2243                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
2244                 }
2245
2246
2247
2248                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2249                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
2250                 }
2251
2252                 if (dodeint) {
2253                         if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2254                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
2255                         }
2256
2257
2258
2259                         if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2260                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
2261                         }
2262                 }
2263
2264
2265
2266                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2267                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
2268                 }
2269
2270                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2271                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
2272                 }
2273
2274                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2275                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
2276                 }
2277
2278
2279
2280
2281                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2282                 if (error!=OMX_ErrorNone) {
2283                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2284
2285                 }
2286
2287                 if (dodeint) {
2288                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2289                         if (error!=OMX_ErrorNone) {
2290                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2291                         }
2292
2293
2294                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2295                         if (error!=OMX_ErrorNone) {
2296                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2297                         }
2298                 }
2299
2300                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2301                 if (error!=OMX_ErrorNone) {
2302                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2303
2304                 }
2305
2306
2307                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2308                 if (error!=OMX_ErrorNone) {
2309                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2310
2311                 }
2312
2313                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2314                 if (error!=OMX_ErrorNone) {
2315                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2316
2317                 }
2318
2319
2320                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2321                 if (error!=OMX_ErrorNone) {
2322                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2323
2324                 }
2325
2326                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2327                 if (error!=OMX_ErrorNone) {
2328                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2329
2330                 }
2331
2332
2333
2334
2335                 error=OMX_FreeHandle(omx_vid_dec);
2336                 error=OMX_FreeHandle(omx_vid_sched);
2337                 error=OMX_FreeHandle(omx_vid_rend);
2338                 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2339                 omx_vid_dec=NULL;
2340                 clock_mutex.unlock();
2341                 destroyClock();
2342                 if (error!=OMX_ErrorNone) {
2343                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2344                 }
2345         } else  clock_mutex.unlock();
2346           Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2347
2348         return 1;
2349 }
2350
2351
2352 void VideoOMX::destroyClock()
2353 {
2354         clock_mutex.lock();
2355         if (clock_references>0) {
2356                 clock_references--;
2357                 if (clock_references==0) {
2358                         OMX_ERRORTYPE error;
2359                         Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2360                         error=OMX_FreeHandle(omx_clock);
2361                         if (error!=OMX_ErrorNone) {
2362                                 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2363                         }
2364
2365                 }
2366         }
2367         clock_mutex.unlock();
2368
2369 }
2370
2371 int VideoOMX::stop()
2372 {
2373   if (!initted) return 0;
2374   iframemode=false;
2375
2376   //Check if libav mode
2377   DeAllocateCodecsOMX();
2378
2379
2380
2381
2382 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2383   return 1;
2384 }
2385
2386 int VideoOMX::reset()
2387 {
2388   if (!initted) return 0;
2389
2390   iframemode=false;
2391   DeAllocateCodecsOMX();
2392 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2393   return 1;
2394 }
2395
2396 int VideoOMX::pause()
2397 {
2398   if (!initted) return 0;
2399   Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2400  // clockPause();
2401   // ignore it audio handles this
2402   return 1;
2403 }
2404
2405 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2406 {
2407   if (!initted) return 0;
2408   Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2409
2410   //clockUnpause();
2411   //ignore it audio handles this
2412
2413   return 1;
2414 }
2415
2416 int VideoOMX::fastForward()
2417 {
2418   if (!initted) return 0;
2419
2420 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2421   return 1;
2422 }
2423
2424 int VideoOMX::unFastForward()
2425 {
2426   if (!initted) return 0;
2427
2428 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2429
2430  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2431   return 1;
2432 }
2433
2434 int VideoOMX::attachFrameBuffer()
2435 {
2436   if (!initted) return 0;
2437
2438 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2439   return 1;
2440 }
2441
2442 int VideoOMX::blank(void)
2443 {
2444 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2445 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2446   return 1;
2447 }
2448
2449 ULLONG VideoOMX::getCurrentTimestamp() {
2450         if (iframemode)
2451                 return 0;
2452         long long ncur_clock_time = cur_clock_time;
2453         if (omx_running) {
2454                 int oldcancelstate;
2455                 int oldcanceltype;
2456                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2457                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2458                 clock_mutex.lock();
2459                 OMX_ERRORTYPE error;
2460                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2461                 memset(&clock_conf, 0, sizeof(clock_conf));
2462                 clock_conf.nSize = sizeof(clock_conf);
2463                 clock_conf.nVersion.nVersion = OMX_VERSION;
2464                 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2465                                 &clock_conf);
2466                 if (error != OMX_ErrorNone) {
2467                         Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error);
2468                 }
2469
2470                 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2471
2472                         OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2473                         memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2474                         cur_time_stamp.nSize = sizeof(cur_time_stamp);
2475                         cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2476                         cur_time_stamp.nPortIndex = omx_clock_output_port;
2477                         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2478                                         &cur_time_stamp);
2479                         if (error != OMX_ErrorNone) {
2480                                 Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error);
2481                         } else {
2482                                 long long temp = cur_time_stamp.nTimestamp.nLowPart
2483                                                 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2484                                 ncur_clock_time = cur_clock_time = temp * 10LL;
2485                         }
2486                 }
2487                 clock_mutex.unlock();
2488                 pthread_setcancelstate(oldcancelstate, NULL);
2489                 pthread_setcanceltype(oldcanceltype, NULL);
2490         }
2491
2492         //ncur_clock_time -= startoffset;
2493         ncur_clock_time -= lastreftimeOMX;
2494         long long result = lastreftimePTS;
2495         if (lastreftimePTS==0) return 0; // invalid time
2496         result += (long long) (ncur_clock_time / 10000LL * 90LL);
2497         if (result < 0)
2498                 result = (1LL << 33) - result;
2499         //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2500
2501         return result;
2502
2503 }
2504
2505 // to be removed
2506 /*
2507 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2508 {
2509   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2510   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2511 }
2512
2513 */
2514 #ifdef DEV
2515 int VideoOMX::test()
2516 {
2517   return 0;
2518
2519 //  ULLONG stc = 0;
2520 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2521 /*
2522  // reset();
2523   return 1;
2524 */
2525 }
2526
2527 int VideoOMX::test2()
2528 {
2529   return 0;
2530 }
2531 #endif
2532
2533
2534
2535 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2536 {
2537   *rsync=false;
2538   if (offsetnotset) {
2539     startoffset=curreftime;//offset is set for audio
2540     offsetnotset=false;
2541     offsetvideonotset=false;
2542   } else {
2543     if (offsetvideonotset) {
2544       offsetvideonotset=false;
2545       *rsync=true;
2546     } else {
2547       if ( (curreftime-lastrefvideotime)>10000000LL
2548         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2549         startoffset+=curreftime-lastrefvideotime;
2550         lastrefaudiotime+=curreftime-lastrefvideotime;
2551         //*rsync=true;
2552         offsetaudionotset=true;
2553
2554       }
2555     }
2556
2557   }
2558
2559   lastrefvideotime=curreftime;
2560
2561   return startoffset;
2562
2563 }
2564
2565 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2566 {
2567   *rsync=false;
2568   if (offsetnotset) {
2569     startoffset=curreftime;
2570     offsetnotset=false;
2571     offsetaudionotset=false;
2572   }else {
2573     if (offsetaudionotset) {
2574       offsetaudionotset=false;
2575       *rsync=true;
2576     } else {
2577       if ( (curreftime-lastrefaudiotime)>10000000LL
2578         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2579         startoffset+=curreftime-lastrefaudiotime;
2580         lastrefvideotime+=curreftime-lastrefaudiotime;
2581         //*rsync=true;
2582         offsetvideonotset=true;
2583
2584       }
2585     }
2586
2587   }
2588   lastrefaudiotime=curreftime;
2589   return startoffset;
2590
2591 }
2592
2593 void VideoOMX::ResetTimeOffsets() {
2594   offsetnotset=true; //called from demuxer
2595   offsetvideonotset=true;
2596   offsetaudionotset=true;
2597   startoffset=0;
2598   lastrefaudiotime=0;
2599   lastrefvideotime=0;
2600   lastreftimeOMX=0;
2601   lastreftimePTS=0;
2602 }
2603
2604
2605 void VideoOMX::FirstFrameFix()
2606 {
2607         int oldcancelstate;
2608         int oldcanceltype;
2609         Demuxer* demux=Demuxer::getInstance();
2610         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2611         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2612         clock_mutex.lock();
2613         if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2614                 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2615                 OMX_ERRORTYPE error;
2616                 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2617                 memset(&port_def_type,0,sizeof(port_def_type));
2618                 port_def_type.nSize=sizeof(port_def_type);
2619                 port_def_type.nVersion.nVersion=OMX_VERSION;
2620                 port_def_type.nPortIndex=omx_codec_output_port;
2621
2622                 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2623                 if (error != OMX_ErrorNone) {
2624                         Log::getInstance()->log("Video", Log::DEBUG,
2625                                         "OMX_IndexParamPortDefinition fix failed %x", error);
2626                         clock_mutex.unlock();
2627                         return;
2628                 }
2629
2630
2631                 Log::getInstance()->log("Video", Log::DEBUG,
2632                                                         "Deinit first frame fix %d %d %d %d %d %d %d %d",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2633                                                         port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2634                                                         port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2635                                                          port_def_type.format.video.bFlagErrorConcealment );
2636                 Log::getInstance()->log("Video", Log::DEBUG,
2637                                                                         "Deinit first frame fix2 %d  %d",
2638                                                                         port_def_type.format.video.eCompressionFormat ,
2639                                                                         port_def_type.format.video.eColorFormat );
2640                 first_frame=false;
2641
2642                 // we cause the video_decode to determine the interlacing properties
2643                 OMX_CONFIG_INTERLACETYPE il;
2644                 memset(&il,0,sizeof(il));
2645                 il.nSize=sizeof(il);
2646                 il.nVersion.nVersion=OMX_VERSION;
2647                 il.nPortIndex=omx_codec_output_port;
2648                 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2649                 if (error != OMX_ErrorNone) {
2650                         Log::getInstance()->log("Video", Log::DEBUG,
2651                                         "OMX_IndexConfigCommonInterlace fix failed %x", error);
2652                 }
2653
2654
2655                 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2656                 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2657                 if (dodeint) {
2658
2659                         DisablePort(omx_vid_deint,omx_deint_input_port,true);
2660                         // This is a dirty hack
2661                         DisablePort(omx_vid_deint,omx_deint_output_port,true);
2662
2663
2664                         port_def_type.nPortIndex=omx_deint_output_port;
2665                         error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2666                                         &port_def_type);
2667                         if (error != OMX_ErrorNone) {
2668                                 Log::getInstance()->log("Video", Log::DEBUG,
2669                                                 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2670                                 clock_mutex.unlock();
2671                                 pthread_setcancelstate(oldcancelstate, NULL);
2672                                 pthread_setcanceltype(oldcanceltype, NULL);
2673                                 return;
2674                         }
2675                         // dirty hack end
2676
2677
2678                         port_def_type.nPortIndex=omx_deint_input_port;
2679                         error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2680                                         &port_def_type);
2681                         if (error != OMX_ErrorNone) {
2682                                 Log::getInstance()->log("Video", Log::DEBUG,
2683                                                 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2684                                 clock_mutex.unlock();
2685                                 pthread_setcancelstate(oldcancelstate, NULL);
2686                                 pthread_setcanceltype(oldcanceltype, NULL);
2687                                 return;
2688                         }
2689                 //      WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2690
2691                         Log::getInstance()->log("Video", Log::DEBUG,
2692                                                                         "Marker");
2693                         EnablePort(omx_vid_deint,omx_deint_input_port,true);
2694                         WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2695                         port_def_type.nPortIndex=omx_deint_output_port;
2696                         error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2697                                         &port_def_type);
2698                         if (error != OMX_ErrorNone) {
2699                                 Log::getInstance()->log("Video", Log::DEBUG,
2700                                                 "Get OMX_IndexParamPortDefinition2 failed %x", error);
2701                                 clock_mutex.unlock();
2702                                 pthread_setcancelstate(oldcancelstate, NULL);
2703                                 pthread_setcanceltype(oldcanceltype, NULL);
2704                                 return;
2705                         }
2706                         Log::getInstance()->log("Video", Log::DEBUG,
2707                                         "Deinit first frame fix3 %d %d %d %d %d %d %d ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2708                                         port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2709                                         port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2710                                         port_def_type.format.image.bFlagErrorConcealment );
2711                         Log::getInstance()->log("Video", Log::DEBUG,
2712                                         "Deinit first frame fix4 %d  %d",
2713                                         port_def_type.format.image.eCompressionFormat ,
2714                                         port_def_type.format.image.eColorFormat );
2715                         DisablePort(omx_vid_deint,omx_deint_output_port,true);
2716
2717                 }
2718                 port_def_type.nPortIndex=omx_shed_input_port;
2719                 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2720                                         &port_def_type);
2721                 if (error != OMX_ErrorNone) {
2722                         Log::getInstance()->log("Video", Log::DEBUG,
2723                                         "Set OMX_IndexParamPortDefinition3 failed %x", error);
2724                         clock_mutex.unlock();
2725                         pthread_setcancelstate(oldcancelstate, NULL);
2726                         pthread_setcanceltype(oldcanceltype, NULL);
2727                         return;
2728                 }
2729                 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2730
2731
2732                 if (dodeint) {
2733                         EnablePort(omx_vid_deint,omx_deint_output_port,true);
2734                 }
2735                 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2736                 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2737         }
2738         clock_mutex.unlock();
2739         pthread_setcancelstate(oldcancelstate, NULL);
2740         pthread_setcanceltype(oldcanceltype, NULL);
2741
2742
2743
2744 }
2745
2746
2747 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2748 {
2749
2750         OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2751         if (error != OMX_ErrorNone) {
2752                 Log::getInstance()->log("Video", Log::DEBUG,
2753                                 "OMX_EmptyThisBuffer failed %x", error);
2754         }
2755         if (first_frame) FirstFrameFix();
2756
2757 }
2758
2759 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2760 {
2761         // protect the call to empty this buffer
2762         int oldcancelstate;
2763         int oldcanceltype;
2764 /*      long long temp =buffer->nTimeStamp.nLowPart
2765                                                         | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2766
2767         //pthread_testcancel();
2768         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2769         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2770         clock_mutex.lock();
2771 // Diagnosis code
2772 /*      OMX_ERRORTYPE error;
2773         OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2774         memset(&timestamp, 0, sizeof(timestamp));
2775         timestamp.nSize = sizeof(timestamp);
2776         timestamp.nVersion.nVersion = OMX_VERSION;
2777         timestamp.nPortIndex =omx_clock_output_port;
2778
2779         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2780                         &timestamp);
2781
2782         if (error != OMX_ErrorNone) {
2783                 Log::getInstance()->log("Audio", Log::DEBUG,
2784                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
2785                                 omx_rend_input_port);
2786         }
2787         long long temp2 =timestamp.nTimestamp.nLowPart
2788                                                                 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2789
2790
2791         Log::getInstance()->log("Video", Log::NOTICE, "OMXETB %x %lld %lld %x",handle,temp,temp2,buffer->nFlags);*/
2792         OMX_ERRORTYPE ret_val;
2793         ret_val=OMX_EmptyThisBuffer(handle,buffer);
2794         clock_mutex.unlock();
2795         pthread_setcancelstate(oldcancelstate, NULL);
2796         pthread_setcanceltype(oldcanceltype, NULL);
2797         //pthread_testcancel();
2798         return ret_val;
2799 }
2800
2801 bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length)
2802 {
2803         const UCHAR* curbuf=buffer;
2804         const UCHAR* curbufend=buffer+length;
2805         unsigned int detector=0xFFFFFFFF;
2806         bool gotaud=false; // have seen access unit delimiter
2807
2808         while (curbuf!=curbufend) {
2809                 detector<<=8;
2810                 detector|=*curbuf;
2811                 if (h264) {
2812                         if (detector==0x00000109) {
2813                                 gotaud=true;
2814                                 detector=0xFFFFFFFF;
2815                         } else if (gotaud &&detector==0x00000001) {
2816                                 curbuf++;
2817                                 if (curbuf!=curbufend) {
2818                                         unsigned char picttype=(*curbuf)& 0x1F;
2819                                         return picttype==0x07;
2820                                 }
2821                         }
2822                 } else {
2823                         if (detector==0x00000100) {
2824                                 curbuf++;
2825                                 if (curbuf==curbufend) return false;
2826                                 curbuf++;
2827                                 if (curbuf==curbufend) return false;
2828                                 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2829                                 return picttype==1;
2830                         }
2831                 }
2832                 curbuf++;
2833         }
2834
2835         return false; // no frame found
2836 }
2837
2838
2839
2840 bool VideoOMX::DrainTargetBufferFull()
2841 {
2842         //Check, if we have OMX output buffers
2843         bool full;
2844         input_bufs_omx_mutex.lock();
2845         full=(input_bufs_omx_free.size()==0);
2846         input_bufs_omx_mutex.unlock();
2847         checkForStalledBuffers(); // check if the decoder has a problem
2848         if (full && omx_vid_stalled && !omx_first_frame) {
2849                 omx_vid_stalled=false;
2850                 Log::getInstance()->log("Video", Log::DEBUG, "Decoder is stalled, do a reset!");
2851
2852                 int oldcancelstate;
2853                 int oldcanceltype;
2854                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2855                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2856
2857                 clock_mutex.lock();
2858                 FlushRenderingPipe();
2859                 omx_first_frame=true;
2860                 clock_mutex.unlock();
2861
2862                 pthread_setcancelstate(oldcancelstate, NULL);
2863                 pthread_setcanceltype(oldcanceltype, NULL);
2864         }
2865         return full;
2866
2867 }
2868
2869 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2870 {
2871
2872         mediapackets.clear();
2873         std::list<MediaPacket>::const_iterator begin=mplist.begin();
2874         std::list<MediaPacket>::const_iterator itty=mplist.begin();
2875         advance(itty,min(mplist.size(),10));
2876         mediapackets.insert(mediapackets.begin(),begin,itty);//front
2877
2878 }
2879
2880 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2881 {
2882         int consumed=0;
2883         while (consumed < (int)mediapackets.size()) {
2884             DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2885             if (*samplepos == mediapackets[consumed].length) {
2886                 *samplepos = 0;
2887                 consumed++;
2888                 //return 1;
2889             } else return consumed;
2890         }
2891         return consumed;
2892 }
2893
2894 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2895                 const UCHAR* buffer,
2896                 UINT *samplepos)
2897 {
2898         if (packet.type == MPTYPE_VIDEO_H264)
2899         {
2900                 h264=true;
2901         }
2902         else
2903         {
2904                 h264=false;
2905         }
2906
2907
2908         //Later add fail back code for libav
2909 /*      if (!videoon) {
2910                 *samplepos+=packet.length;
2911                 return packet.length;
2912         }*/
2913
2914
2915         if (!omx_running) return 0; // if we are not runnig do not do this
2916
2917         if (isClockPaused()) return 0; //Block if we pause
2918
2919 //      Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 1");
2920         //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
2921
2922
2923         /*First Check, if we have an video sample*/
2924         if (iframemode) {
2925                 //samplepos=0;
2926                 MILLISLEEP(10);
2927                 return 0; //Not in iframe mode!
2928         }
2929
2930         UINT headerstrip=0;
2931         if (packet.disconti) {
2932                 firstsynched=false;
2933                 if (cur_input_buf_omx) {
2934                         PutBufferToPres(cur_input_buf_omx);
2935                         cur_input_buf_omx=NULL;
2936                 }
2937         }
2938         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2");
2939         /*Inspect PES-Header */
2940
2941 //      OMX_STATETYPE temp_state;
2942 //      OMX_GetState(omx_vid_dec,&temp_state);
2943
2944         if (*samplepos==0) {//stripheader
2945                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2946         //      if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2947         //                      buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2948                 *samplepos+=headerstrip;
2949                 if (headerstrip>=packet.length) {
2950                      *samplepos=packet.length;// Packet is obviously damaged
2951                      return packet.length;//skip it!
2952                 }
2953                 if ( packet.synched ) {
2954                         if (!firstsynched) {
2955                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2a");
2956                           // check if this is an I frame, the decoder does not like non I frames at startup!
2957                           if (!detectIFrame(buffer,packet.length)) {
2958                                   *samplepos=packet.length;//if we have not processed at least one
2959                                   //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 3");
2960                                   return packet.length;//synched packet ignore it!
2961                           }
2962                         }
2963                         if (cur_input_buf_omx) {
2964                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4a");
2965                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
2966                                 PutBufferToPres(cur_input_buf_omx);
2967                                 cur_input_buf_omx=NULL;//write out old data
2968
2969                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4b");
2970
2971                         }
2972                         firstsynched=true;
2973                 } else {
2974                         if (!firstsynched) {//
2975                                 *samplepos=packet.length;//if we have not processed at least one
2976                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 5");
2977                                 return packet.length;//synched packet ignore it!
2978                         }
2979                 }
2980         }
2981         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 6");
2982         if (!cur_input_buf_omx) {
2983                 input_bufs_omx_mutex.lock();
2984                 if (input_bufs_omx_free.size()==0) {
2985                         input_bufs_omx_mutex.unlock();
2986                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2987                         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 7");
2988                         return 0; // we do not have a free media sample
2989
2990                 }
2991                 cur_input_buf_omx=input_bufs_omx_free.front();
2992                 cur_input_buf_omx->nFilledLen=0;
2993                 cur_input_buf_omx->nOffset=0;
2994                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2995                 input_bufs_omx_free.pop_front();
2996                 input_bufs_omx_mutex.unlock();
2997         }
2998
2999
3000
3001
3002         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3003                 if (packet.synched) {
3004                 //      Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
3005
3006                         //lastreftimePTS=packet.pts;
3007                    if (omx_first_frame) { // TODO time
3008                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3009                            Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
3010                            omx_first_frame=false;
3011                    } else {
3012                            cur_input_buf_omx->nFlags=0;
3013                            //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3014                    }
3015                    lastreftimeOMX=packet.presentation_time;
3016                   // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
3017                    lastreftimePTS=packet.pts;
3018                    cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3019                 }
3020                 else
3021                 {
3022                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3023                         cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3024                         //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
3025                 }
3026                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3027
3028
3029
3030         }
3031         unsigned int haveToCopy=packet.length-*samplepos;
3032         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 8");
3033
3034         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3035                 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3036                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3037                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3038                 haveToCopy-=cancopy;
3039                 cur_input_buf_omx->nFilledLen+=cancopy;
3040                 *samplepos+=cancopy;
3041                 // push old buffer out
3042                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 9");
3043
3044                 PutBufferToPres(cur_input_buf_omx);
3045                 cur_input_buf_omx=NULL;
3046                 // get5 new buffer
3047                 input_bufs_omx_mutex.lock();
3048                 if (input_bufs_omx_free.size()==0) {
3049                         input_bufs_omx_mutex.unlock();
3050                 //      Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
3051                         return *samplepos; // we do not have a free media sample
3052                 }
3053                 cur_input_buf_omx=input_bufs_omx_free.front();
3054                 cur_input_buf_omx->nFilledLen=0;
3055                 cur_input_buf_omx->nOffset=0;
3056                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3057                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3058                 input_bufs_omx_free.pop_front();
3059                 input_bufs_omx_mutex.unlock();
3060                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 10");
3061
3062         }
3063         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3064                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
3065         cur_input_buf_omx->nFilledLen+=haveToCopy;
3066
3067 //      Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 11");
3068
3069         *samplepos+=haveToCopy;
3070
3071         return *samplepos;
3072
3073 }
3074
3075
3076
3077
3078 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
3079         if (!omx_running) return false;
3080         if (!iframemode)
3081                 EnterIframePlayback();
3082
3083         //int haveToCopy = length;
3084
3085         if (!cur_input_buf_omx) {
3086                 input_bufs_omx_mutex.lock();
3087                 if (input_bufs_omx_free.size() == 0) {
3088                         input_bufs_omx_mutex.unlock();
3089                 //      Log::getInstance()->log("Video", Log::DEBUG,
3090                         //              "Deliver MediaPacket no free sample");
3091                         return false; // we do not have a free media sample
3092
3093                 }
3094                 cur_input_buf_omx = input_bufs_omx_free.front();
3095                 cur_input_buf_omx->nFilledLen = 0;
3096                 cur_input_buf_omx->nOffset = 0;
3097                 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3098                 input_bufs_omx_free.pop_front();
3099                 input_bufs_omx_mutex.unlock();
3100         }
3101
3102         int read_pos = 0;
3103         unsigned int pattern, packet_length;
3104         unsigned int headerstrip = 0;
3105         bool first = true;
3106         if (length < 4){
3107                 return false;
3108         }
3109         //Now we strip the pes header
3110         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3111         while ((read_pos + 7) <= (int)length) {
3112                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3113                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3114                         read_pos++;
3115                         continue;
3116                 } else {
3117                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3118                         packet_length = ((buffer[read_pos + 4] << 8)
3119                                         | (buffer[read_pos + 5])) + 6;
3120                         if (read_pos + packet_length > length)
3121                                 read_pos = length;
3122                         else {
3123                                 if ((headerstrip < packet_length)
3124                                                 && (cur_input_buf_omx->nFilledLen + packet_length
3125                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3126                                         if (first) {
3127                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3128
3129                                         } else {
3130                                                 cur_input_buf_omx->nFlags
3131                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3132
3133                                         }
3134                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3135                                         PutBufferToPres(cur_input_buf_omx);
3136                                         cur_input_buf_omx = NULL;
3137
3138                                         if (!cur_input_buf_omx) {
3139                                                 int count = 0;
3140                                                 while (count < 100 && omx_running && iframemode) {
3141                                                         count++;
3142
3143                                                         input_bufs_omx_mutex.lock();
3144                                                         if (input_bufs_omx_free.size() == 0) {
3145                                                                 input_bufs_omx_mutex.unlock();
3146                                         //                      Log::getInstance()->log("Video", Log::DEBUG,
3147                                                 //                              "Ifrane no free sample");
3148                                                                 MILLISLEEP(5);
3149                                                                 if (!omx_running) return false;
3150                                                                 continue;
3151                                                         }
3152                                                         cur_input_buf_omx = input_bufs_omx_free.front();
3153                                                         cur_input_buf_omx->nFilledLen = 0;
3154                                                         cur_input_buf_omx->nOffset = 0;
3155                                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3156                                                         cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3157                                                         input_bufs_omx_free.pop_front();
3158                                                         input_bufs_omx_mutex.unlock();
3159                                                         break;
3160                                                 }
3161                                                 if (!cur_input_buf_omx)
3162                                                         return false;
3163                                         }
3164
3165                                 }
3166                                 if (packet_length > headerstrip) {
3167                                         memcpy(
3168                                                         cur_input_buf_omx->pBuffer
3169                                                                         + cur_input_buf_omx->nFilledLen,
3170                                                         buffer + read_pos + headerstrip,
3171                                                         packet_length - headerstrip);
3172                                         cur_input_buf_omx->nFilledLen += packet_length
3173                                                         - headerstrip;
3174                                 }
3175                                 read_pos += packet_length;
3176
3177                                 pattern = (buffer[read_pos] << 16)
3178                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3179                         }
3180                 }
3181         }
3182
3183         if (first) {
3184                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3185
3186         } else {
3187                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3188
3189         }
3190         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3191
3192         PutBufferToPres(cur_input_buf_omx);
3193         cur_input_buf_omx = NULL;
3194
3195
3196         MILLISLEEP(40); //Block a bit
3197         return true;
3198 }
3199
3200 int VideoOMX::EnterIframePlayback()
3201 {
3202         Log::getInstance()->log("Video", Log::DEBUG,
3203                                                 "EnterIframePlayback");
3204         if (cur_input_buf_omx) {
3205                 PutBufferToPres(cur_input_buf_omx);
3206                 cur_input_buf_omx = NULL;
3207         }
3208         Log::getInstance()->log("Video", Log::DEBUG,
3209                                                         "EnterIframePlayback 2");
3210         dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3211         DeAllocateCodecsOMX();
3212         AllocateCodecsOMX();
3213         Log::getInstance()->log("Video", Log::DEBUG,
3214                                                         "leave IframePlayback");
3215
3216         iframemode=true;
3217
3218         return 1;
3219 }
3220