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