]> git.vomp.tv Git - vompclient.git/blob - videoomx.cc
Preparations for dynamic mode switching
[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                         selectVideoMode(demux->getInterlaced());
643                         Osd::getInstance()->restore();
644                         Osd::getInstance()->init((void*)"");
645                         BoxStack::getInstance()->redrawAllBoxes();
646                         initted=1;
647
648                 }
649
650         }
651 }
652
653
654 int VideoOMX::play() {
655         if (!initted)
656                 return 0;
657         iframemode = false;
658         Log::getInstance()->log("Video", Log::DEBUG, "enter play");
659
660         interlaceSwitch4Demux();
661
662         if (AllocateCodecsOMX()) {
663                 return 1;
664                 // Otherwise fall back to libav
665         } else {
666                 if (h264) {
667                         omx_h264 = false;
668                         Log::getInstance()->log("Video", Log::NOTICE,
669                                         "Allocate Codecs OMX failed assume h264 unsupported");
670                 } else {
671                         omx_mpeg2 = false;
672                         Log::getInstance()->log("Video", Log::NOTICE,
673                                         "Allocate Codecs OMX failed assume mpeg2 unsupported");
674                 }
675         }
676
677         return 0;
678
679 }
680
681
682 int VideoOMX::initClock()
683 {
684         OMX_ERRORTYPE error;
685         clock_mutex.Lock();
686         if (clock_references==0)
687         {
688
689                 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
690                 omx_events.clear();
691
692                 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
693
694                 if (error!=OMX_ErrorNone) {
695                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
696                         clock_mutex.Unlock();
697                         DeAllocateCodecsOMX();
698                         return 0;
699                 }
700
701                 /* TODO Clock config to separate method */
702                 OMX_PORT_PARAM_TYPE p_param;
703                 memset(&p_param,0,sizeof(p_param));
704                 p_param.nSize=sizeof(p_param);
705                 p_param.nVersion.nVersion=OMX_VERSION;
706                 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
707                 if (error!=OMX_ErrorNone) {
708                         Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
709                         clock_mutex.Unlock();
710                         DeAllocateCodecsOMX();
711                         return 0;
712                 }
713                 omx_clock_output_port=p_param.nStartPortNumber;
714
715                 for (unsigned int i=0;i<p_param.nPorts;i++) {
716                         if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
717                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
718                                 clock_mutex.Unlock();
719                                 DeAllocateCodecsOMX();
720                                 return 0;
721                         }
722                 }
723
724
725
726
727         }
728         Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
729         clock_references++;
730         clock_mutex.Unlock();
731         return 1;
732 }
733
734 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
735 {
736         OMX_ERRORTYPE error;
737         *p_omx_clock=NULL;
738         *p_omx_clock_output_port=0;
739
740         if (!initClock()) {
741                 return 0;
742         }
743         clock_mutex.Lock();
744
745         OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
746         memset(&refclock,0,sizeof(refclock));
747         refclock.nSize=sizeof(refclock);
748         refclock.nVersion.nVersion=OMX_VERSION;
749
750         refclock.eClock=OMX_TIME_RefClockAudio;
751
752         //refclock.eClock=OMX_TIME_RefClockVideo;
753         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
754         if (error!=OMX_ErrorNone){
755                 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
756                 clock_mutex.Unlock();
757                 DeAllocateCodecsOMX();
758                 return 0;
759         }
760
761         OMX_PORT_PARAM_TYPE p_param;
762         memset(&p_param,0,sizeof(p_param));
763         p_param.nSize=sizeof(p_param);
764         p_param.nVersion.nVersion=OMX_VERSION;
765         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
766         if (error!=OMX_ErrorNone){
767                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
768                 clock_mutex.Unlock();
769                 DeAllocateCodecsOMX();
770                 return 0;
771         }
772
773         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
774         memset(&clock_conf,0,sizeof(clock_conf));
775         clock_conf.nSize=sizeof(clock_conf);
776         clock_conf.nVersion.nVersion=OMX_VERSION;
777         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
778         clock_conf.nStartTime=intToOMXTicks(0);
779         clock_conf.nOffset=intToOMXTicks(0);
780         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
781         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
782         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
783         if (error!=OMX_ErrorNone) {
784                 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
785         }
786
787
788         *p_omx_clock_output_port=p_param.nStartPortNumber+1;
789         *p_omx_clock=omx_clock;
790         clock_mutex.Unlock();
791         return 1;
792 }
793
794 int VideoOMX::getClockVideoandInit()
795 {
796         OMX_ERRORTYPE error;
797
798         if (!initClock()) {
799                 return 0;
800         }
801         clock_mutex.Lock();
802
803         if (clock_references==1) { // only if no audio is attached to this clock!
804                 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
805                 memset(&refclock,0,sizeof(refclock));
806                 refclock.nSize=sizeof(refclock);
807                 refclock.nVersion.nVersion=OMX_VERSION;
808
809                 //refclock.eClock=OMX_TIME_RefClockAudio;
810
811                 refclock.eClock=OMX_TIME_RefClockVideo;
812                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
813                 if (error!=OMX_ErrorNone) {
814                         Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
815                         clock_mutex.Unlock();
816                         DeAllocateCodecsOMX();
817                         return 0;
818                 }
819         }
820
821         OMX_PORT_PARAM_TYPE p_param;
822         memset(&p_param,0,sizeof(p_param));
823         p_param.nSize=sizeof(p_param);
824         p_param.nVersion.nVersion=OMX_VERSION;
825         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
826         if (error!=OMX_ErrorNone){
827                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
828                 clock_mutex.Unlock();
829                 DeAllocateCodecsOMX();
830                 return 0;
831         }
832
833
834         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
835         memset(&clock_conf,0,sizeof(clock_conf));
836         clock_conf.nSize=sizeof(clock_conf);
837         clock_conf.nVersion.nVersion=OMX_VERSION;
838         clock_conf.eState=OMX_TIME_ClockStateStopped;
839         clock_conf.nStartTime=intToOMXTicks(0);
840         clock_conf.nOffset=intToOMXTicks(0);
841         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
842         if (error!=OMX_ErrorNone) {
843                 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
844         }
845
846
847         memset(&clock_conf,0,sizeof(clock_conf));
848         clock_conf.nSize=sizeof(clock_conf);
849         clock_conf.nVersion.nVersion=OMX_VERSION;
850         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
851         clock_conf.nStartTime=intToOMXTicks(0);
852         clock_conf.nOffset=intToOMXTicks(0);
853         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
854         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
855         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
856         if (error!=OMX_ErrorNone) {
857                 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
858         }
859
860         omx_clock_output_port=p_param.nStartPortNumber;
861         clock_mutex.Unlock();
862
863         return 1;
864 }
865
866 void VideoOMX::clockUnpause()
867 {
868         OMX_ERRORTYPE error;
869         clock_mutex.Lock();
870         if (clock_references>0) {
871                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
872                 memset(&clock_conf,0,sizeof(clock_conf));
873                 clock_conf.nSize=sizeof(clock_conf);
874                 clock_conf.nVersion.nVersion=OMX_VERSION;
875                 clock_conf.eState=OMX_TIME_ClockStateRunning;
876                 clock_conf.nStartTime=intToOMXTicks(0);
877                 clock_conf.nOffset=intToOMXTicks(0);
878                 clock_conf.nWaitMask=OMX_CLOCKPORT1;
879                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
880                 if (error!=OMX_ErrorNone) {
881                         Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
882                 }
883         }
884         clock_mutex.Unlock();
885 }
886
887
888 void VideoOMX::clockPause()
889 {
890         OMX_ERRORTYPE error;
891         clock_mutex.Lock();
892         if (clock_references>0) {
893                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
894                 memset(&clock_conf,0,sizeof(clock_conf));
895                 clock_conf.nSize=sizeof(clock_conf);
896                 clock_conf.nVersion.nVersion=OMX_VERSION;
897                 clock_conf.eState=OMX_TIME_ClockStateStopped;
898                 clock_conf.nStartTime=intToOMXTicks(0);
899                 clock_conf.nOffset=intToOMXTicks(0);
900                 clock_conf.nWaitMask=OMX_CLOCKPORT1;
901                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
902                 if (error!=OMX_ErrorNone) {
903                         Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
904                 }
905         }
906         clock_mutex.Unlock();
907 }
908
909
910
911 int VideoOMX::AllocateCodecsOMX()
912 {
913         OMX_ERRORTYPE error;
914         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
915
916         Demuxer* demux=Demuxer::getInstance();
917
918         dodeint=false;
919         deint_first_frame=false;
920
921         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
922         //Clock, move later to audio including events
923
924         Log::getInstance()->log("Video", Log::NOTICE, "VideoType %d x %d i: %d", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
925         if (deinterlace!=0 && (demux->getHorizontalSize()<=720 ) && demux->getInterlaced()) { //only deinterlace SD material
926                 dodeint=true;
927                 deint_first_frame=true;
928
929                 Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
930
931         }
932
933
934         if (!getClockVideoandInit()){
935                 return 0;// get the clock and init it if necessary
936         }
937
938
939         if (!idleClock()) {
940                 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
941                 return 0;
942         }
943         /* TODO end */
944
945         clock_mutex.Lock();
946         if (h264) {
947                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
948         } else {
949                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
950         }
951
952         if (error!=OMX_ErrorNone){
953                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
954                 clock_mutex.Unlock();
955                 DeAllocateCodecsOMX();
956                 return 0;
957         }
958
959
960         Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
961         OMX_PORT_PARAM_TYPE p_param;
962         memset(&p_param,0,sizeof(p_param));
963         p_param.nSize=sizeof(p_param);
964         p_param.nVersion.nVersion=OMX_VERSION;
965         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
966         if (error!=OMX_ErrorNone){
967                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
968                 clock_mutex.Unlock();
969                 DeAllocateCodecsOMX();
970             return 0;
971         }
972         omx_codec_input_port=p_param.nStartPortNumber;
973         omx_codec_output_port=p_param.nStartPortNumber+1;
974
975         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
976                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
977                 clock_mutex.Unlock();
978                 DeAllocateCodecsOMX();
979                 return 0;
980         }
981
982         Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
983
984         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
985         memset(&conceal,0,sizeof(conceal));
986         conceal.nSize=sizeof(conceal);
987         conceal.nVersion.nVersion=OMX_VERSION;
988         conceal.bStartWithValidFrame=OMX_FALSE;
989
990         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
991         if (error!=OMX_ErrorNone){
992                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
993                 clock_mutex.Unlock();
994                 DeAllocateCodecsOMX();
995                 return 0;
996         }
997
998         if (dodeint) {
999                 error = OMX_GetHandle(&omx_vid_deint, VPE_OMX_VIDEO_DEINTERLACE, NULL,
1000                                 &callbacks);
1001                 if (error != OMX_ErrorNone) {
1002                         Log::getInstance()->log("Video", Log::DEBUG,
1003                                         "Init OMX video deinterlacer failed %x", error);
1004                         clock_mutex.Unlock();
1005                         DeAllocateCodecsOMX();
1006                         return 0;
1007                 }
1008
1009                 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1010                                 &p_param);
1011                 if (error != OMX_ErrorNone) {
1012                         Log::getInstance()->log("Video", Log::DEBUG,
1013                                         "Init OMX video deinterlacer OMX_GetParameter failed %x",
1014                                         error);
1015                         clock_mutex.Unlock();
1016                         DeAllocateCodecsOMX();
1017                         return 0;
1018                 }
1019                 omx_deint_input_port = p_param.nStartPortNumber;
1020                 omx_deint_output_port = p_param.nStartPortNumber + 1;
1021
1022                 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1023                                 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1024                         Log::getInstance()->log("Video", Log::DEBUG,
1025                                         "Disable Ports OMX video deint failed");
1026                         clock_mutex.Unlock();
1027                         DeAllocateCodecsOMX();
1028                         return 0;
1029                 }
1030
1031         }
1032
1033
1034         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1035         if (error!=OMX_ErrorNone){
1036                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1037                 clock_mutex.Unlock();
1038                 DeAllocateCodecsOMX();
1039                 return 0;
1040         }
1041
1042
1043
1044         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1045         if (error!=OMX_ErrorNone){
1046                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1047                 clock_mutex.Unlock();
1048                 DeAllocateCodecsOMX();
1049                 return 0;
1050         }
1051         omx_shed_input_port=p_param.nStartPortNumber;
1052         omx_shed_output_port=p_param.nStartPortNumber+1;
1053
1054
1055         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1056         if (error!=OMX_ErrorNone){
1057                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1058                 clock_mutex.Unlock();
1059                 DeAllocateCodecsOMX();
1060                 return 0;
1061         }
1062         omx_shed_clock_port=p_param.nStartPortNumber;
1063         Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1064
1065
1066         if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1067                         || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1068                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1069                 clock_mutex.Unlock();
1070                 DeAllocateCodecsOMX();
1071                 return 0;
1072         }
1073
1074
1075         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1076         if (error!=OMX_ErrorNone){
1077                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1078                 clock_mutex.Unlock();
1079                 DeAllocateCodecsOMX();
1080                 return 0;
1081         }
1082
1083         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1084         if (error!=OMX_ErrorNone){
1085                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1086                 clock_mutex.Unlock();
1087                 DeAllocateCodecsOMX();
1088                 return 0;
1089         }
1090         omx_rend_input_port=p_param.nStartPortNumber;
1091         //omx_rend_output_port=p_param.nStartPortNumber+1;
1092
1093
1094         if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1095                                 ) {
1096                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1097                 clock_mutex.Unlock();
1098                 DeAllocateCodecsOMX();
1099                 return 0;
1100         }
1101
1102         //Setuo chain
1103
1104
1105
1106         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1107         if (error!=OMX_ErrorNone){
1108                 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);
1109                 clock_mutex.Unlock();
1110                 DeAllocateCodecsOMX();
1111                 return 0;
1112         }
1113
1114         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1115                                         ) {
1116                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1117                 clock_mutex.Unlock();
1118                 DeAllocateCodecsOMX();
1119                 return 0;
1120         }
1121
1122
1123         Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
1124         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1125                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1126                 clock_mutex.Unlock();
1127                 DeAllocateCodecsOMX();
1128                 return 0;
1129         }
1130
1131
1132
1133         Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
1134         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1135                 clock_mutex.Unlock();
1136                 DeAllocateCodecsOMX();
1137                 return 0;
1138         }
1139
1140
1141
1142
1143         Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
1144         if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1145                 clock_mutex.Unlock();
1146                 DeAllocateCodecsOMX();
1147                 return 0;
1148         }
1149
1150
1151
1152         Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
1153
1154
1155 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1156         if (error!=OMX_ErrorNone){
1157                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1158                 return 0;
1159         }*/
1160
1161         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1162         memset(&ft_type,0,sizeof(ft_type));
1163         ft_type.nSize=sizeof(ft_type);
1164         ft_type.nVersion.nVersion=OMX_VERSION;
1165
1166         ft_type.nPortIndex=omx_codec_input_port;
1167         if (h264) {
1168                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1169         } else {
1170                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1171         }
1172
1173
1174
1175     ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1176     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1177         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1178         if (error!=OMX_ErrorNone){
1179                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1180                 clock_mutex.Unlock();
1181                 DeAllocateCodecsOMX();
1182                 return 0;
1183         }
1184
1185
1186         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1187                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1188                 clock_mutex.Unlock();
1189                 DeAllocateCodecsOMX();
1190                 return 0;
1191         }
1192
1193
1194         if (!PrepareInputBufsOMX()) {
1195                 clock_mutex.Unlock();
1196                 DeAllocateCodecsOMX();
1197                 return 0;
1198         }
1199
1200         if (!dodeint) {
1201                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1202                 if (error!=OMX_ErrorNone){
1203                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1204                         clock_mutex.Unlock();
1205                         DeAllocateCodecsOMX();
1206                         return 0;
1207                 }
1208
1209
1210
1211                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1212                 ) {
1213                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1214                         clock_mutex.Unlock();
1215                         DeAllocateCodecsOMX();
1216                         return 0;
1217                 }
1218
1219                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1220                         clock_mutex.Unlock();
1221                         DeAllocateCodecsOMX();
1222                         return 0;
1223                 }
1224
1225         } else {
1226
1227                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1228                 if (error!=OMX_ErrorNone){
1229                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
1230                         clock_mutex.Unlock();
1231                         DeAllocateCodecsOMX();
1232                         return 0;
1233                 }
1234
1235
1236
1237                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1238                 ) {
1239                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
1240                         clock_mutex.Unlock();
1241                         DeAllocateCodecsOMX();
1242                         return 0;
1243                 }
1244
1245                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1246                         clock_mutex.Unlock();
1247                         DeAllocateCodecsOMX();
1248                         return 0;
1249                 }
1250
1251                 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1252                         Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
1253                         clock_mutex.Unlock();
1254                         DeAllocateCodecsOMX();
1255                         return 0;
1256                 }
1257
1258                 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1259                 memset(&imagefilter,0,sizeof(imagefilter));
1260                 imagefilter.nSize=sizeof(imagefilter);
1261                 imagefilter.nVersion.nVersion=OMX_VERSION;
1262
1263                 imagefilter.nPortIndex=omx_deint_output_port;
1264                 imagefilter.nNumParams=1;
1265                 imagefilter.nParams[0]=3;//???
1266                 switch (deinterlace) {
1267                 case 1:
1268                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1269                 case 2:
1270                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1271                 case 3:
1272                         imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1273                 }
1274
1275
1276                 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1277                 if (error!=OMX_ErrorNone){
1278                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
1279                         clock_mutex.Unlock();
1280                         DeAllocateCodecsOMX();
1281                         return 0;
1282                 }
1283
1284
1285                 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1286                 if (error!=OMX_ErrorNone){
1287                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
1288                         clock_mutex.Unlock();
1289                         DeAllocateCodecsOMX();
1290                         return 0;
1291                 }
1292
1293                 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1294                 ) {
1295                         Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
1296                         clock_mutex.Unlock();
1297                         DeAllocateCodecsOMX();
1298                         return 0;
1299                 }
1300
1301                 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1302                         clock_mutex.Unlock();
1303                         DeAllocateCodecsOMX();
1304                         return 0;
1305                 }
1306
1307         }
1308
1309         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1310                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1311                 clock_mutex.Unlock();
1312                 DeAllocateCodecsOMX();
1313                 return 0;
1314         }
1315
1316         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1317         if (error!=OMX_ErrorNone){
1318                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1319                 clock_mutex.Unlock();
1320                 DeAllocateCodecsOMX();
1321                 return 0;
1322         }
1323
1324         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1325                                                         ) {
1326                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1327                 clock_mutex.Unlock();
1328                 DeAllocateCodecsOMX();
1329                 return 0;
1330         }
1331
1332         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1333                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1334                 clock_mutex.Unlock();
1335                 DeAllocateCodecsOMX();
1336                 return 0;
1337         }
1338
1339         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1340                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1341                 clock_mutex.Unlock();
1342                 DeAllocateCodecsOMX();
1343                 return 0;
1344         }
1345
1346         if (dodeint) {
1347                 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1348                         Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
1349                         clock_mutex.Unlock();
1350                         DeAllocateCodecsOMX();
1351                         return 0;
1352                 }
1353                 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1354                 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1355         }
1356
1357         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1358                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1359                 clock_mutex.Unlock();
1360                 DeAllocateCodecsOMX();
1361                 return 0;
1362         }
1363
1364         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1365                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1366                 clock_mutex.Unlock();
1367                 DeAllocateCodecsOMX();
1368                 return 0;
1369         }
1370
1371         //raspbi specifif
1372         /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1373         memset(&dispconf,0,sizeof(dispconf));
1374         dispconf.nSize=sizeof(dispconf);
1375         dispconf.nVersion.nVersion=OMX_VERSION;
1376
1377         dispconf.nPortIndex=omx_rend_input_port;
1378
1379         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1380         dispconf.layer=1;
1381         error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1382         if (error!=OMX_ErrorNone){
1383                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1384                 clock_mutex.Unlock();
1385                 DeAllocateCodecsOMX();
1386                 return 0;
1387         }*/
1388
1389 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1390         dispconf.fullscreen=OMX_FALSE;
1391         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1392         if (error!=OMX_ErrorNone){
1393                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1394                 clock_mutex.Unlock();
1395                 DeAllocateCodecsOMX();
1396                 return 0;
1397         }
1398
1399         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1400         dispconf.dest_rect.x_offset=100;
1401         dispconf.dest_rect.y_offset=100;
1402         dispconf.dest_rect.width=640;
1403         dispconf.dest_rect.height=480;
1404         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1405         if (error!=OMX_ErrorNone){
1406                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1407                 clock_mutex.Unlock();
1408                 DeAllocateCodecsOMX();
1409                 return 0;
1410         }*/
1411
1412
1413         //playbacktimeoffset=-GetCurrentSystemTime();
1414         paused=false;
1415         iframemode=false;
1416         omx_running=true;
1417         clock_mutex.Unlock();
1418         updateMode();
1419
1420         setClockExecutingandRunning();
1421
1422
1423
1424
1425
1426         return 1;
1427 }
1428
1429 int VideoOMX::idleClock()
1430 {
1431         OMX_ERRORTYPE error;
1432         OMX_STATETYPE temp_state;
1433         clock_mutex.Lock();
1434         OMX_GetState(omx_clock,&temp_state);
1435
1436         if (temp_state!=OMX_StateIdle) {
1437                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1438                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1439                         clock_mutex.Unlock();
1440                         return 0;
1441                 }
1442         }
1443         clock_mutex.Unlock();
1444         return 1;
1445 }
1446
1447 int VideoOMX::setClockExecutingandRunning()
1448 {
1449         OMX_ERRORTYPE error;
1450         OMX_STATETYPE temp_state;
1451         clock_mutex.Lock();
1452         OMX_GetState(omx_clock,&temp_state);
1453
1454         if (temp_state!=OMX_StateExecuting) {
1455                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1456                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1457                         clock_mutex.Unlock();
1458                         DeAllocateCodecsOMX();
1459                         return 0;
1460                 }
1461         }
1462
1463         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1464         memset(&clock_conf,0,sizeof(clock_conf));
1465         clock_conf.nSize=sizeof(clock_conf);
1466         clock_conf.nVersion.nVersion=OMX_VERSION;
1467         clock_conf.eState=OMX_TIME_ClockStateRunning;
1468         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1469         if (error!=OMX_ErrorNone) {
1470                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1471                 clock_mutex.Unlock();
1472                 DeAllocateCodecsOMX();
1473                 return 0;
1474         }
1475         clock_mutex.Unlock();
1476         return 1;
1477
1478 }
1479
1480
1481 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1482 {
1483         OMX_ERRORTYPE error;
1484         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1485         if (error!=OMX_ErrorNone){
1486                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1487                 return 0;
1488         }
1489
1490         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1491                 return 0;
1492         }
1493
1494         return 1;
1495 }
1496
1497
1498 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1499 {
1500         OMX_ERRORTYPE error;
1501         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1502         if (error!=OMX_ErrorNone){
1503                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1504                 return 0;
1505         }
1506
1507         if (!wait) return 1;
1508         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1509                 return 0;
1510         }
1511
1512         return 1;
1513 }
1514
1515
1516 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1517 {
1518         OMX_ERRORTYPE error;
1519         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1520         if (error!=OMX_ErrorNone){
1521                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1522                 return 0;
1523         }
1524
1525         if (!wait) return 1;
1526         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1527                 return 0;
1528         }
1529
1530
1531         return 1;
1532 }
1533
1534 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex
1535 {
1536         int i=0;
1537         while (i<1000) {
1538                 omx_event_mutex.Lock();
1539                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1540                 while (itty!=omx_events.end()) {
1541
1542                         VPE_OMX_EVENT current=*itty;
1543                         if (current.handle==handle) { //this is ours
1544                                 if (current.event_type==OMX_EventError) {
1545                                         omx_events.erase(itty);
1546                                         omx_event_mutex.Unlock();
1547                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1548                                         return 0;
1549
1550                                 } else if (current.event_type==event) {
1551                                         omx_events.erase(itty);
1552                                         omx_event_mutex.Unlock();
1553                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1554                                         return 1;
1555                                 }
1556                         }
1557                         itty++;
1558
1559                 }
1560                 omx_event_mutex.Unlock();
1561                 MILLISLEEP(2);
1562                 i++;
1563
1564         }
1565         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1566         return 0;
1567
1568 }
1569
1570 int VideoOMX::clearEvents()
1571 {
1572         omx_event_mutex.Lock();
1573         omx_events.clear();
1574         omx_event_mutex.Unlock();
1575
1576         return 1;
1577 }
1578
1579
1580 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1581 {
1582         int i=0;
1583         while (i<1000) {
1584                 omx_event_mutex.Lock();
1585                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1586                 while (itty!=omx_events.end()) {
1587
1588                         VPE_OMX_EVENT current=*itty;
1589                         if (current.handle==handle) { //this is ours
1590                                 if (current.event_type==OMX_EventError) {
1591                                         omx_events.erase(itty);
1592                                         omx_event_mutex.Unlock();
1593                                         Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1);
1594                                         return 0;
1595
1596                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1597                                         omx_events.erase(itty);
1598                                         omx_event_mutex.Unlock();
1599                                         //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1600                                         return 1;
1601                                 }
1602                         }
1603                         itty++;
1604
1605                 }
1606                 omx_event_mutex.Unlock();
1607                 MILLISLEEP(2);
1608                 i++;
1609
1610         }
1611         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1612         return 0;
1613
1614 }
1615
1616
1617
1618
1619
1620 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1621 {
1622         OMX_ERRORTYPE error;
1623         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1624         memset(&port_def_type,0,sizeof(port_def_type));
1625         port_def_type.nSize=sizeof(port_def_type);
1626         port_def_type.nVersion.nVersion=OMX_VERSION;
1627         port_def_type.nPortIndex=omx_codec_input_port;
1628
1629         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1630
1631         if (error!=OMX_ErrorNone){
1632                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1633         }
1634 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1635                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1636                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1637
1638         port_def_type.nBufferCountActual=100;
1639         port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1640
1641         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1642
1643         if (error!=OMX_ErrorNone){
1644                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1645         }
1646
1647
1648         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1649         if (error!=OMX_ErrorNone){
1650                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1651                 return 0;
1652         }
1653
1654         input_bufs_omx_mutex.Lock();
1655         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1656
1657         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1658                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1659         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1660                 if (error!=OMX_ErrorNone){
1661                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1662                         input_bufs_omx_mutex.Unlock();
1663                         return 0;
1664                 }*/
1665                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1666                 if (error!=OMX_ErrorNone){
1667                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1668                                 input_bufs_omx_mutex.Unlock();
1669                         return 0;
1670                 }
1671                 input_bufs_omx_all.push_back(buf_head);
1672                 input_bufs_omx_free.push_back(buf_head);
1673         }
1674         omx_first_frame=true;
1675
1676         firstsynched=false;
1677         cur_input_buf_omx=NULL;
1678         input_bufs_omx_mutex.Unlock();
1679
1680
1681         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1682         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1683                 return 0;
1684         }
1685         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1686
1687         return 1;
1688 }
1689
1690 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
1691 {
1692         OMX_ERRORTYPE error;
1693
1694         cur_input_buf_omx=NULL;
1695         input_bufs_omx_mutex.Lock();
1696         for (int i=0; i< input_bufs_omx_all.size();i++) {
1697         //      free(input_bufs_omx_all[i]->pBuffer);
1698         //      input_bufs_omx_all[i]->pBuffer=NULL;
1699                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1700                 if (error!=OMX_ErrorNone){
1701                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1702                         input_bufs_omx_mutex.Unlock();
1703                         return 0;
1704                 }
1705
1706         }
1707         input_bufs_omx_all.clear();
1708         input_bufs_omx_free.clear();
1709         input_bufs_omx_mutex.Unlock();
1710
1711 }
1712
1713
1714 int VideoOMX::FlushRenderingPipe()
1715 {
1716         OMX_ERRORTYPE error;
1717
1718         if (!dodeint) {
1719
1720                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1721                                 omx_codec_output_port, NULL);
1722                 if (error != OMX_ErrorNone) {
1723                         Log::getInstance()->log("Video", Log::DEBUG,
1724                                         "OMX_Flush codec out 1 failed %x", error);
1725
1726                 }
1727
1728                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1729                                 omx_shed_input_port, NULL);
1730                 if (error != OMX_ErrorNone) {
1731                         Log::getInstance()->log("Video", Log::DEBUG,
1732                                         "OMX_Flush shed in 2 failed %x", error);
1733
1734                 }
1735
1736                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1737                                 omx_codec_output_port)) {
1738                         Log::getInstance()->log("Video", Log::DEBUG,
1739                                         "flush cmd codec  3 failed");
1740                 }
1741
1742                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1743                                 omx_shed_input_port)) {
1744                         Log::getInstance()->log("Video", Log::DEBUG,
1745                                         "flush cmd  shed 4 failed");
1746                 }
1747         } else {
1748                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1749                                 omx_codec_output_port, NULL);
1750                 if (error != OMX_ErrorNone) {
1751                         Log::getInstance()->log("Video", Log::DEBUG,
1752                                         "OMX_Flush codec out 5 failed %x", error);
1753
1754                 }
1755
1756                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1757                                 omx_deint_input_port, NULL);
1758                 if (error != OMX_ErrorNone) {
1759                         Log::getInstance()->log("Video", Log::DEBUG,
1760                                         "OMX_Flush deint in 6 failed %x", error);
1761
1762                 }
1763
1764                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1765                                 omx_codec_output_port)) {
1766                         Log::getInstance()->log("Video", Log::DEBUG,
1767                                         "flush cmd codec  7 failed");
1768                 }
1769
1770                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1771                                 omx_deint_input_port)) {
1772                         Log::getInstance()->log("Video", Log::DEBUG,
1773                                         "flush cmd  deint 8 failed");
1774                 }
1775
1776                 //m
1777                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1778                                 omx_deint_output_port, NULL);
1779                 if (error != OMX_ErrorNone) {
1780                         Log::getInstance()->log("Video", Log::DEBUG,
1781                                         "OMX_Flush deint out 9 failed %x", error);
1782
1783                 }
1784
1785                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1786                                 omx_shed_input_port, NULL);
1787                 if (error != OMX_ErrorNone) {
1788                         Log::getInstance()->log("Video", Log::DEBUG,
1789                                         "OMX_Flush shed in 10 failed %x", error);
1790
1791                 }
1792
1793                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1794                                 omx_deint_output_port)) {
1795                         Log::getInstance()->log("Video", Log::DEBUG,
1796                                         "flush cmd deint 11 failed");
1797                 }
1798
1799                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1800                                 omx_shed_input_port)) {
1801                         Log::getInstance()->log("Video", Log::DEBUG,
1802                                         "flush cmd  shed 12 failed");
1803                 }
1804
1805
1806
1807         }
1808
1809
1810
1811
1812         error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
1813                         omx_rend_input_port, NULL);
1814         if (error != OMX_ErrorNone) {
1815                 Log::getInstance()->log("Video", Log::DEBUG,
1816                                 "OMX_Flush rend in failed %x", error);
1817
1818         }
1819
1820         error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1821                         omx_shed_output_port, NULL);
1822         if (error != OMX_ErrorNone) {
1823                 Log::getInstance()->log("Video", Log::DEBUG,
1824                                 "OMX_Flush shed out failed %x", error);
1825
1826         }
1827
1828
1829
1830         if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
1831                         omx_rend_input_port)) {
1832                 Log::getInstance()->log("Video", Log::DEBUG,
1833                                 "flush cmd shed rend failed");
1834         }
1835
1836         if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1837                         omx_shed_output_port)) {
1838                 Log::getInstance()->log("Video", Log::DEBUG,
1839                                 "flush cmd shed rend failed");
1840         }
1841 }
1842
1843
1844 int VideoOMX::DeAllocateCodecsOMX()
1845 {
1846         OMX_ERRORTYPE error;
1847         omx_running=false;
1848           Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1849
1850    if (cur_input_buf_omx) {
1851                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1852                 OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1853                 if (error!=OMX_ErrorNone) {
1854                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1855                 }
1856
1857                 cur_input_buf_omx=NULL;//write out old data
1858         }
1859    clock_mutex.Lock();
1860    clearEvents();
1861         if (omx_vid_dec) {
1862                 // first stop the omx elements
1863                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1864                         Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1865
1866                 }
1867                 clock_mutex.Unlock();
1868
1869                 idleClock();
1870                 clock_mutex.Lock();
1871
1872                 if (dodeint) {
1873                         if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
1874                                 Log::getInstance()->log("Video", Log::DEBUG,
1875                                                 "vid_deint ChangeComponentState");
1876
1877                         }
1878                 }
1879
1880
1881                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1882                         Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
1883
1884                 }
1885
1886                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1887                         Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1888
1889                 }
1890
1891
1892
1893         // TODO proper deinit sequence
1894                 // first flush all buffers
1895                 FlushRenderingPipe();
1896
1897
1898
1899
1900
1901                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1902                 if (error!=OMX_ErrorNone){
1903                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1904
1905                 }
1906
1907                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1908                 if (error!=OMX_ErrorNone){
1909                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1910
1911                 }
1912
1913                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1914                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1915                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1916                 }
1917
1918
1919
1920
1921                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1922                                 omx_codec_input_port, NULL);
1923                 if (error != OMX_ErrorNone) {
1924                         Log::getInstance()->log("Video", Log::DEBUG,
1925                                         "OMX_Flush codec out failed %x", error);
1926
1927                 }
1928
1929
1930
1931
1932                 DestroyInputBufsOMX();
1933
1934                 //todo flushing
1935                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1936                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1937                 }
1938                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1939                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1940                 }
1941
1942
1943
1944
1945                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1946                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1947                 }
1948
1949
1950
1951                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1952                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1953                 }
1954
1955                 if (dodeint) {
1956                         if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
1957                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
1958                         }
1959
1960
1961
1962                         if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
1963                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
1964                         }
1965                 }
1966
1967
1968
1969                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1970                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1971                 }
1972
1973                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1974                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1975                 }
1976
1977                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1978                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1979                 }
1980
1981
1982
1983
1984                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1985                 if (error!=OMX_ErrorNone) {
1986                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1987
1988                 }
1989
1990                 if (dodeint) {
1991                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,NULL);
1992                         if (error!=OMX_ErrorNone) {
1993                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1994                         }
1995
1996
1997                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,NULL);
1998                         if (error!=OMX_ErrorNone) {
1999                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2000                         }
2001                 }
2002
2003                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
2004                 if (error!=OMX_ErrorNone) {
2005                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2006
2007                 }
2008
2009
2010                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
2011                 if (error!=OMX_ErrorNone) {
2012                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2013
2014                 }
2015
2016                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
2017                 if (error!=OMX_ErrorNone) {
2018                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2019
2020                 }
2021
2022
2023                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
2024                 if (error!=OMX_ErrorNone) {
2025                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2026
2027                 }
2028
2029                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
2030                 if (error!=OMX_ErrorNone) {
2031                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2032
2033                 }
2034
2035
2036
2037
2038                 error=OMX_FreeHandle(omx_vid_dec);
2039                 error=OMX_FreeHandle(omx_vid_sched);
2040                 error=OMX_FreeHandle(omx_vid_rend);
2041                 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2042                 omx_vid_dec=NULL;
2043                 clock_mutex.Unlock();
2044                 destroyClock();
2045                 if (error!=OMX_ErrorNone) {
2046                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2047                 }
2048         } else  clock_mutex.Unlock();
2049           Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2050
2051         return 1;
2052 }
2053
2054
2055 void VideoOMX::destroyClock()
2056 {
2057         clock_mutex.Lock();
2058         if (clock_references>0) {
2059                 clock_references--;
2060                 if (clock_references==0) {
2061                         OMX_ERRORTYPE error;
2062                         Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2063                         error=OMX_FreeHandle(omx_clock);
2064                         if (error!=OMX_ErrorNone) {
2065                                 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2066                         }
2067
2068                 }
2069         }
2070         clock_mutex.Unlock();
2071
2072 }
2073
2074 int VideoOMX::stop()
2075 {
2076   if (!initted) return 0;
2077   iframemode=false;
2078
2079   //Check if libav mode
2080   DeAllocateCodecsOMX();
2081
2082
2083
2084
2085 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2086   return 1;
2087 }
2088
2089 int VideoOMX::reset()
2090 {
2091   if (!initted) return 0;
2092
2093   iframemode=false;
2094   DeAllocateCodecsOMX();
2095 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2096   return 1;
2097 }
2098
2099 int VideoOMX::pause()
2100 {
2101   if (!initted) return 0;
2102   Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2103   if (!paused) {
2104           paused=true;
2105           //maybe also change omx clock?
2106           //pausetimecode=GetCurrentSystemTime();
2107
2108   }
2109   return 1;
2110 }
2111
2112 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2113 {
2114   if (!initted) return 0;
2115   Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2116
2117   if (paused) {
2118         //  playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
2119           paused=false; // may be also change omx clock
2120   }
2121
2122   return 1;
2123 }
2124
2125 int VideoOMX::fastForward()
2126 {
2127   if (!initted) return 0;
2128
2129 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2130   return 1;
2131 }
2132
2133 int VideoOMX::unFastForward()
2134 {
2135   if (!initted) return 0;
2136
2137 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2138
2139  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2140   return 1;
2141 }
2142
2143 int VideoOMX::attachFrameBuffer()
2144 {
2145   if (!initted) return 0;
2146
2147 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2148   return 1;
2149 }
2150
2151 int VideoOMX::blank(void)
2152 {
2153 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2154 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2155   return 1;
2156 }
2157
2158 ULLONG VideoOMX::getCurrentTimestamp() {
2159         if (iframemode)
2160                 return 0;
2161         long long ncur_clock_time = cur_clock_time;
2162         if (omx_running) {
2163                 int oldcancelstate;
2164                 int oldcanceltype;
2165                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2166                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2167                 clock_mutex.Lock();
2168                 OMX_ERRORTYPE error;
2169                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2170                 memset(&clock_conf, 0, sizeof(clock_conf));
2171                 clock_conf.nSize = sizeof(clock_conf);
2172                 clock_conf.nVersion.nVersion = OMX_VERSION;
2173                 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2174                                 &clock_conf);
2175                 if (error != OMX_ErrorNone) {
2176                         Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error);
2177                 }
2178
2179                 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2180
2181                         OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2182                         memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2183                         cur_time_stamp.nSize = sizeof(cur_time_stamp);
2184                         cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2185                         cur_time_stamp.nPortIndex = omx_clock_output_port;
2186                         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2187                                         &cur_time_stamp);
2188                         if (error != OMX_ErrorNone) {
2189                                 Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error);
2190                         } else {
2191                                 long long temp = cur_time_stamp.nTimestamp.nLowPart
2192                                                 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2193                                 ncur_clock_time = cur_clock_time = temp * 10LL;
2194                         }
2195                 }
2196                 clock_mutex.Unlock();
2197                 pthread_setcancelstate(oldcancelstate, NULL);
2198                 pthread_setcanceltype(oldcanceltype, NULL);
2199         }
2200
2201         //ncur_clock_time -= startoffset;
2202         ncur_clock_time -= lastreftimeOMX;
2203         long long result = lastreftimePTS;
2204         if (lastreftimePTS==0) return 0; // invalid time
2205         result += (long long) (ncur_clock_time / 10000LL * 90LL);
2206         if (result < 0)
2207                 result = (1LL << 33) - result;
2208         //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2209
2210         return result;
2211
2212 }
2213
2214 // to be removed
2215 /*
2216 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2217 {
2218   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2219   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2220 }
2221
2222 */
2223 #ifdef DEV
2224 int VideoOMX::test()
2225 {
2226   return 0;
2227
2228 //  ULLONG stc = 0;
2229 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2230 /*
2231  // reset();
2232   return 1;
2233 */
2234 }
2235
2236 int VideoOMX::test2()
2237 {
2238   return 0;
2239 }
2240 #endif
2241
2242
2243
2244 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2245 {
2246   *rsync=false;
2247   if (offsetnotset) {
2248     startoffset=curreftime;//offset is set for audio
2249     offsetnotset=false;
2250     offsetvideonotset=false;
2251   } else {
2252     if (offsetvideonotset) {
2253       offsetvideonotset=false;
2254       *rsync=true;
2255     } else {
2256       if ( (curreftime-lastrefvideotime)>10000000LL
2257         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2258         startoffset+=curreftime-lastrefvideotime;
2259         lastrefaudiotime+=curreftime-lastrefvideotime;
2260         //*rsync=true;
2261         offsetaudionotset=true;
2262
2263       }
2264     }
2265
2266   }
2267
2268   lastrefvideotime=curreftime;
2269
2270   return startoffset;
2271
2272 }
2273
2274 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2275 {
2276   *rsync=false;
2277   if (offsetnotset) {
2278     startoffset=curreftime;
2279     offsetnotset=false;
2280     offsetaudionotset=false;
2281   }else {
2282     if (offsetaudionotset) {
2283       offsetaudionotset=false;
2284       *rsync=true;
2285     } else {
2286       if ( (curreftime-lastrefaudiotime)>10000000LL
2287         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2288         startoffset+=curreftime-lastrefaudiotime;
2289         lastrefvideotime+=curreftime-lastrefaudiotime;
2290         //*rsync=true;
2291         offsetvideonotset=true;
2292
2293       }
2294     }
2295
2296   }
2297   lastrefaudiotime=curreftime;
2298   return startoffset;
2299
2300 }
2301
2302 void VideoOMX::ResetTimeOffsets() {
2303   offsetnotset=true; //called from demuxer
2304   offsetvideonotset=true;
2305   offsetaudionotset=true;
2306   startoffset=0;
2307   lastrefaudiotime=0;
2308   lastrefvideotime=0;
2309   lastreftimeOMX=0;
2310   lastreftimePTS=0;
2311 }
2312
2313
2314 void VideoOMX::DeinterlaceFix()
2315 {
2316         int oldcancelstate;
2317         int oldcanceltype;
2318         Demuxer* demux=Demuxer::getInstance();
2319         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2320         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2321         clock_mutex.Lock();
2322         OMX_ERRORTYPE error;
2323         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2324         memset(&port_def_type,0,sizeof(port_def_type));
2325         port_def_type.nSize=sizeof(port_def_type);
2326         port_def_type.nVersion.nVersion=OMX_VERSION;
2327         port_def_type.nPortIndex=omx_codec_output_port;
2328
2329         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2330         if (error != OMX_ErrorNone) {
2331                 Log::getInstance()->log("Video", Log::DEBUG,
2332                                 "OMX_IndexParamPortDefinition fix failed %x", error);
2333                 clock_mutex.Unlock();
2334                 return;
2335         }
2336
2337         if (port_def_type.format.video.nFrameWidth == demux->getHorizontalSize()
2338                         && port_def_type.format.video.nFrameHeight == demux->getVerticalSize()){
2339                 Log::getInstance()->log("Video", Log::DEBUG,
2340                                                         "Deinit first frame fix");
2341                 deint_first_frame=false;
2342
2343                 WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2344                 DisablePort(omx_vid_dec,omx_codec_output_port,false);
2345                 DisablePort(omx_vid_sched,omx_shed_input_port,false);
2346                 DisablePort(omx_vid_deint,omx_deint_output_port,false);
2347                 DisablePort(omx_vid_deint,omx_deint_input_port,false);
2348
2349                 port_def_type.nPortIndex=omx_deint_input_port;
2350                 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2351                                 &port_def_type);
2352                 if (error != OMX_ErrorNone) {
2353                         Log::getInstance()->log("Video", Log::DEBUG,
2354                                         "Set OMX_IndexParamPortDefinition1 failed %x", error);
2355                         clock_mutex.Unlock();
2356                         pthread_setcancelstate(oldcancelstate, NULL);
2357                         pthread_setcanceltype(oldcanceltype, NULL);
2358                         return;
2359                 }
2360
2361                 port_def_type.nPortIndex=omx_deint_output_port;
2362                 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2363                                 &port_def_type);
2364                 if (error != OMX_ErrorNone) {
2365                         Log::getInstance()->log("Video", Log::DEBUG,
2366                                         "Set OMX_IndexParamPortDefinition2 failed %x", error);
2367                         clock_mutex.Unlock();
2368                         pthread_setcancelstate(oldcancelstate, NULL);
2369                         pthread_setcanceltype(oldcanceltype, NULL);
2370                         return;
2371                 }
2372
2373
2374                 EnablePort(omx_vid_dec,omx_codec_output_port,false);
2375                 EnablePort(omx_vid_deint,omx_deint_input_port,false);
2376                 EnablePort(omx_vid_deint,omx_deint_output_port,false);
2377                 EnablePort(omx_vid_sched,omx_shed_input_port,false);
2378         }
2379         clock_mutex.Unlock();
2380         pthread_setcancelstate(oldcancelstate, NULL);
2381         pthread_setcanceltype(oldcanceltype, NULL);
2382
2383
2384
2385 }
2386
2387
2388 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2389 {
2390
2391         OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2392         if (error != OMX_ErrorNone) {
2393                 Log::getInstance()->log("Video", Log::DEBUG,
2394                                 "OMX_EmptyThisBuffer failed %x", error);
2395         }
2396         if (deint_first_frame && dodeint) DeinterlaceFix();
2397
2398 }
2399
2400 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2401 {
2402         // protect the call to empty this buffer
2403         int oldcancelstate;
2404         int oldcanceltype;
2405 /*      long long temp =buffer->nTimeStamp.nLowPart
2406                                                         | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2407
2408         //pthread_testcancel();
2409         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2410         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2411         clock_mutex.Lock();
2412 // Diagnosis code
2413 /*      OMX_ERRORTYPE error;
2414         OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2415         memset(&timestamp, 0, sizeof(timestamp));
2416         timestamp.nSize = sizeof(timestamp);
2417         timestamp.nVersion.nVersion = OMX_VERSION;
2418         timestamp.nPortIndex =omx_clock_output_port;
2419
2420         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2421                         &timestamp);
2422
2423         if (error != OMX_ErrorNone) {
2424                 Log::getInstance()->log("Audio", Log::DEBUG,
2425                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
2426                                 omx_rend_input_port);
2427         }
2428         long long temp2 =timestamp.nTimestamp.nLowPart
2429                                                                 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2430
2431
2432         Log::getInstance()->log("Video", Log::NOTICE, "OMXETB %x %lld %lld %x",handle,temp,temp2,buffer->nFlags);*/
2433         OMX_ERRORTYPE ret_val;
2434         ret_val=OMX_EmptyThisBuffer(handle,buffer);
2435         clock_mutex.Unlock();
2436         pthread_setcancelstate(oldcancelstate, NULL);
2437         pthread_setcanceltype(oldcanceltype, NULL);
2438         //pthread_testcancel();
2439         return ret_val;
2440 }
2441
2442 bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length)
2443 {
2444         const UCHAR* curbuf=buffer;
2445         const UCHAR* curbufend=buffer+length;
2446         unsigned int detector=0xFFFFFFFF;
2447         bool gotaud=false; // have seen access unit delimiter
2448
2449         while (curbuf!=curbufend) {
2450                 detector<<=8;
2451                 detector|=*curbuf;
2452                 if (h264) {
2453                         if (detector==0x00000109) {
2454                                 gotaud=true;
2455                                 detector=0xFFFFFFFF;
2456                         } else if (gotaud &&detector==0x00000001) {
2457                                 curbuf++;
2458                                 if (curbuf!=curbufend) {
2459                                         unsigned char picttype=(*curbuf)& 0x1F;
2460                                         return picttype==0x07;
2461                                 }
2462                         }
2463                 } else {
2464                         if (detector==0x00000100) {
2465                                 curbuf++;
2466                                 if (curbuf==curbufend) return false;
2467                                 curbuf++;
2468                                 if (curbuf==curbufend) return false;
2469                                 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2470                                 return picttype==1;
2471                         }
2472                 }
2473                 curbuf++;
2474         }
2475
2476         return false; // no frame found
2477 }
2478
2479 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2480 {
2481         
2482         mediapackets.clear();
2483         list<MediaPacket>::const_iterator begin=mplist.begin();
2484         list<MediaPacket>::const_iterator itty=mplist.begin();
2485         advance(itty,min(mplist.size(),10));
2486         mediapackets.insert(mediapackets.begin(),begin,itty);//front
2487         
2488 }
2489
2490 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2491 {
2492         int consumed=0;
2493         while (consumed<mediapackets.size()) {
2494             DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2495             if (*samplepos == mediapackets[consumed].length) {
2496                 *samplepos = 0;
2497                 consumed++;
2498                 //return 1;
2499             } else return consumed;
2500         }
2501         return consumed;
2502 }
2503
2504 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2505                 const UCHAR* buffer,
2506                 UINT *samplepos)
2507 {
2508         if (packet.type == MPTYPE_VIDEO_H264)
2509         {
2510                 h264=true;
2511         }
2512         else
2513         {
2514                 h264=false;
2515         }
2516
2517
2518         //Later add fail back code for libav
2519 /*      if (!videoon) {
2520                 *samplepos+=packet.length;
2521                 return packet.length;
2522         }*/
2523
2524
2525         if (!omx_running) return 0; // if we are not runnig do not do this
2526         if (paused) return 0; //Block if we pause
2527
2528 //      Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 1");
2529         //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
2530
2531
2532         OMX_ERRORTYPE error;
2533
2534         /*First Check, if we have an video sample*/
2535         if (iframemode) {
2536                 //samplepos=0;
2537                 MILLISLEEP(10);
2538                 return 0; //Not in iframe mode!
2539         }
2540
2541         UINT headerstrip=0;
2542         if (packet.disconti) {
2543                 firstsynched=false;
2544                 if (cur_input_buf_omx) {
2545                         PutBufferToPres(cur_input_buf_omx);
2546                         cur_input_buf_omx=NULL;
2547                 }
2548         }
2549         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2");
2550         /*Inspect PES-Header */
2551
2552 //      OMX_STATETYPE temp_state;
2553 //      OMX_GetState(omx_vid_dec,&temp_state);
2554
2555         if (*samplepos==0) {//stripheader
2556                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2557         //      if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2558         //                      buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2559                 *samplepos+=headerstrip;
2560                 if ( packet.synched ) {
2561                         if (!firstsynched) {
2562                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2a");
2563                           // check if this is an I frame, the decoder does not like non I frames at startup!
2564                           if (!detectIFrame(buffer,packet.length)) {
2565                                   *samplepos=packet.length;//if we have not processed at least one
2566                                   //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 3");
2567                                   return packet.length;//synched packet ignore it!
2568                           }
2569                         }
2570                         if (cur_input_buf_omx) {
2571                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4a");
2572                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
2573                                 PutBufferToPres(cur_input_buf_omx);
2574                                 cur_input_buf_omx=NULL;//write out old data
2575
2576                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4b");
2577
2578                         }
2579                         firstsynched=true;
2580                 } else {
2581                         if (!firstsynched) {//
2582                                 *samplepos=packet.length;//if we have not processed at least one
2583                                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 5");
2584                                 return packet.length;//synched packet ignore it!
2585                         }
2586                 }
2587         }
2588         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 6");
2589         if (!cur_input_buf_omx) {
2590                 input_bufs_omx_mutex.Lock();
2591                 if (input_bufs_omx_free.size()==0) {
2592                         input_bufs_omx_mutex.Unlock();
2593                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2594                         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 7");
2595                         return 0; // we do not have a free media sample
2596
2597                 }
2598                 cur_input_buf_omx=input_bufs_omx_free.front();
2599                 cur_input_buf_omx->nFilledLen=0;
2600                 cur_input_buf_omx->nOffset=0;
2601                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2602                 input_bufs_omx_free.pop_front();
2603                 input_bufs_omx_mutex.Unlock();
2604         }
2605
2606
2607
2608
2609         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2610                 if (packet.synched) {
2611                 //      Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
2612
2613                         //lastreftimePTS=packet.pts;
2614                    if (omx_first_frame) { // TODO time
2615                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2616                            Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
2617                            omx_first_frame=false;
2618                    } else {
2619                            cur_input_buf_omx->nFlags=0;
2620                            //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
2621                    }
2622                    lastreftimeOMX=packet.presentation_time;
2623                   // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
2624                    lastreftimePTS=packet.pts;
2625                    cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
2626                 }
2627                 else
2628                 {
2629                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2630                         cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2631                         //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
2632                 }
2633                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
2634
2635
2636
2637         }
2638         unsigned int haveToCopy=packet.length-*samplepos;
2639         //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 8");
2640
2641         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2642                 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
2643                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2644                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2645                 haveToCopy-=cancopy;
2646                 cur_input_buf_omx->nFilledLen+=cancopy;
2647                 *samplepos+=cancopy;
2648                 // push old buffer out
2649                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 9");
2650
2651                 PutBufferToPres(cur_input_buf_omx);
2652                 cur_input_buf_omx=NULL;
2653                 // get5 new buffer
2654                 input_bufs_omx_mutex.Lock();
2655                 if (input_bufs_omx_free.size()==0) {
2656                         input_bufs_omx_mutex.Unlock();
2657                 //      Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
2658                         return *samplepos; // we do not have a free media sample
2659                 }
2660                 cur_input_buf_omx=input_bufs_omx_free.front();
2661                 cur_input_buf_omx->nFilledLen=0;
2662                 cur_input_buf_omx->nOffset=0;
2663                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2664                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2665                 input_bufs_omx_free.pop_front();
2666                 input_bufs_omx_mutex.Unlock();
2667                 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 10");
2668
2669         }
2670         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2671                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2672         cur_input_buf_omx->nFilledLen+=haveToCopy;
2673
2674 //      Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 11");
2675
2676         *samplepos+=haveToCopy;
2677
2678         return *samplepos;
2679
2680 }
2681
2682
2683
2684
2685 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
2686         if (!omx_running) return false;
2687         if (!iframemode)
2688                 EnterIframePlayback();
2689
2690         int haveToCopy = length;
2691
2692         if (!cur_input_buf_omx) {
2693                 input_bufs_omx_mutex.Lock();
2694                 if (input_bufs_omx_free.size() == 0) {
2695                         input_bufs_omx_mutex.Unlock();
2696                 //      Log::getInstance()->log("Video", Log::DEBUG,
2697                         //              "Deliver MediaPacket no free sample");
2698                         return false; // we do not have a free media sample
2699
2700                 }
2701                 cur_input_buf_omx = input_bufs_omx_free.front();
2702                 cur_input_buf_omx->nFilledLen = 0;
2703                 cur_input_buf_omx->nOffset = 0;
2704                 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2705                 input_bufs_omx_free.pop_front();
2706                 input_bufs_omx_mutex.Unlock();
2707         }
2708
2709         int read_pos = 0;
2710         unsigned int pattern, packet_length;
2711         unsigned int headerstrip = 0;
2712         bool first = true;
2713         if (length < 4){
2714                 return false;
2715         }
2716         //Now we strip the pes header
2717         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
2718         while (read_pos + 7 <= length) {
2719                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
2720                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
2721                         read_pos++;
2722                         continue;
2723                 } else {
2724                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
2725                         packet_length = ((buffer[read_pos + 4] << 8)
2726                                         | (buffer[read_pos + 5])) + 6;
2727                         if (read_pos + packet_length > length)
2728                                 read_pos = length;
2729                         else {
2730                                 if ((headerstrip < packet_length)
2731                                                 && (cur_input_buf_omx->nFilledLen + packet_length
2732                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
2733                                         if (first) {
2734                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2735
2736                                         } else {
2737                                                 cur_input_buf_omx->nFlags
2738                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2739
2740                                         }
2741                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2742                                         PutBufferToPres(cur_input_buf_omx);
2743                                         cur_input_buf_omx = NULL;
2744
2745                                         if (!cur_input_buf_omx) {
2746                                                 int count = 0;
2747                                                 while (count < 100 && omx_running && iframemode) {
2748                                                         count++;
2749
2750                                                         input_bufs_omx_mutex.Lock();
2751                                                         if (input_bufs_omx_free.size() == 0) {
2752                                                                 input_bufs_omx_mutex.Unlock();
2753                                         //                      Log::getInstance()->log("Video", Log::DEBUG,
2754                                                 //                              "Ifrane no free sample");
2755                                                                 MILLISLEEP(5);
2756                                                                 if (!omx_running) return false;
2757                                                                 continue;
2758                                                         }
2759                                                         cur_input_buf_omx = input_bufs_omx_free.front();
2760                                                         cur_input_buf_omx->nFilledLen = 0;
2761                                                         cur_input_buf_omx->nOffset = 0;
2762                                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2763                                                         cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
2764                                                         input_bufs_omx_free.pop_front();
2765                                                         input_bufs_omx_mutex.Unlock();
2766                                                         break;
2767                                                 }
2768                                                 if (!cur_input_buf_omx)
2769                                                         return false;
2770                                         }
2771
2772                                 }
2773                                 if (packet_length > headerstrip) {
2774                                         memcpy(
2775                                                         cur_input_buf_omx->pBuffer
2776                                                                         + cur_input_buf_omx->nFilledLen,
2777                                                         buffer + read_pos + headerstrip,
2778                                                         packet_length - headerstrip);
2779                                         cur_input_buf_omx->nFilledLen += packet_length
2780                                                         - headerstrip;
2781                                 }
2782                                 read_pos += packet_length;
2783
2784                                 pattern = (buffer[read_pos] << 16)
2785                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
2786                         }
2787                 }
2788         }
2789
2790         if (first) {
2791                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2792
2793         } else {
2794                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2795
2796         }
2797         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2798         
2799         PutBufferToPres(cur_input_buf_omx);
2800         cur_input_buf_omx = NULL;
2801
2802
2803         MILLISLEEP(40); //Block a bit
2804         return true;
2805 }
2806
2807 int VideoOMX::EnterIframePlayback()
2808 {
2809         Log::getInstance()->log("Video", Log::DEBUG,
2810                                                 "EnterIframePlayback");
2811         if (cur_input_buf_omx) {
2812                 PutBufferToPres(cur_input_buf_omx);
2813                 cur_input_buf_omx = NULL;
2814         }
2815         Log::getInstance()->log("Video", Log::DEBUG,
2816                                                         "EnterIframePlayback 2");
2817         ((AudioOMX*)Audio::getInstance())->DeAllocateCodecsOMX();
2818         DeAllocateCodecsOMX();
2819         AllocateCodecsOMX();
2820         Log::getInstance()->log("Video", Log::DEBUG,
2821                                                         "leave IframePlayback");
2822
2823         iframemode=true;
2824
2825         return 1;
2826 }
2827