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