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