]> git.vomp.tv Git - vompclient.git/blob - videoomx.cc
Remove thread from videoomx, Code cleanup, Fix remote keys (could crash server!).
[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
1328         setClockExecutingandRunning();
1329
1330
1331
1332
1333
1334         return 1;
1335 }
1336
1337 int VideoOMX::idleClock()
1338 {
1339         OMX_ERRORTYPE error;
1340         OMX_STATETYPE temp_state;
1341         clock_mutex.Lock();
1342         OMX_GetState(omx_clock,&temp_state);
1343
1344         if (temp_state!=OMX_StateIdle) {
1345                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1346                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1347                         clock_mutex.Unlock();
1348                         return 0;
1349                 }
1350         }
1351         clock_mutex.Unlock();
1352         return 1;
1353 }
1354
1355 int VideoOMX::setClockExecutingandRunning()
1356 {
1357         OMX_ERRORTYPE error;
1358         OMX_STATETYPE temp_state;
1359         clock_mutex.Lock();
1360         OMX_GetState(omx_clock,&temp_state);
1361
1362         if (temp_state!=OMX_StateExecuting) {
1363                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1364                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1365                         clock_mutex.Unlock();
1366                         DeAllocateCodecsOMX();
1367                         return 0;
1368                 }
1369         }
1370
1371         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1372         memset(&clock_conf,0,sizeof(clock_conf));
1373         clock_conf.nSize=sizeof(clock_conf);
1374         clock_conf.nVersion.nVersion=OMX_VERSION;
1375         clock_conf.eState=OMX_TIME_ClockStateRunning;
1376         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1377         if (error!=OMX_ErrorNone) {
1378                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1379                 clock_mutex.Unlock();
1380                 DeAllocateCodecsOMX();
1381                 return 0;
1382         }
1383         clock_mutex.Unlock();
1384         return 1;
1385
1386 }
1387
1388
1389 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1390 {
1391         OMX_ERRORTYPE error;
1392         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1393         if (error!=OMX_ErrorNone){
1394                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1395                 return 0;
1396         }
1397
1398         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1399                 return 0;
1400         }
1401
1402         return 1;
1403 }
1404
1405
1406 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1407 {
1408         OMX_ERRORTYPE error;
1409         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1410         if (error!=OMX_ErrorNone){
1411                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1412                 return 0;
1413         }
1414
1415         if (!wait) return 1;
1416         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1417                 return 0;
1418         }
1419
1420         return 1;
1421 }
1422
1423
1424 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1425 {
1426         OMX_ERRORTYPE error;
1427         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1428         if (error!=OMX_ErrorNone){
1429                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1430                 return 0;
1431         }
1432
1433         if (!wait) return 1;
1434         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1435                 return 0;
1436         }
1437
1438
1439         return 1;
1440 }
1441
1442 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex
1443 {
1444         int i=0;
1445         while (i<1000) {
1446                 omx_event_mutex.Lock();
1447                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1448                 while (itty!=omx_events.end()) {
1449
1450                         VPE_OMX_EVENT current=*itty;
1451                         if (current.handle==handle) { //this is ours
1452                                 if (current.event_type==OMX_EventError) {
1453                                         omx_events.erase(itty);
1454                                         omx_event_mutex.Unlock();
1455                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1456                                         return 0;
1457
1458                                 } else if (current.event_type==event) {
1459                                         omx_events.erase(itty);
1460                                         omx_event_mutex.Unlock();
1461                                         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1462                                         return 1;
1463                                 }
1464                         }
1465                         itty++;
1466
1467                 }
1468                 omx_event_mutex.Unlock();
1469                 MILLISLEEP(2);
1470                 i++;
1471
1472         }
1473         Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1474         return 0;
1475
1476 }
1477
1478 int VideoOMX::clearEvents()
1479 {
1480         omx_event_mutex.Lock();
1481         omx_events.clear();
1482         omx_event_mutex.Unlock();
1483
1484         return 1;
1485 }
1486
1487
1488 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1489 {
1490         int i=0;
1491         while (i<1000) {
1492                 omx_event_mutex.Lock();
1493                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1494                 while (itty!=omx_events.end()) {
1495
1496                         VPE_OMX_EVENT current=*itty;
1497                         if (current.handle==handle) { //this is ours
1498                                 if (current.event_type==OMX_EventError) {
1499                                         omx_events.erase(itty);
1500                                         omx_event_mutex.Unlock();
1501                                         Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1);
1502                                         return 0;
1503
1504                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1505                                         omx_events.erase(itty);
1506                                         omx_event_mutex.Unlock();
1507                                         //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1508                                         return 1;
1509                                 }
1510                         }
1511                         itty++;
1512
1513                 }
1514                 omx_event_mutex.Unlock();
1515                 MILLISLEEP(2);
1516                 i++;
1517
1518         }
1519         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1520         return 0;
1521
1522 }
1523
1524
1525
1526
1527
1528 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1529 {
1530         OMX_ERRORTYPE error;
1531         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1532         memset(&port_def_type,0,sizeof(port_def_type));
1533         port_def_type.nSize=sizeof(port_def_type);
1534         port_def_type.nVersion.nVersion=OMX_VERSION;
1535         port_def_type.nPortIndex=omx_codec_input_port;
1536
1537         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1538
1539         if (error!=OMX_ErrorNone){
1540                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1541         }
1542 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1543                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1544                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1545
1546         port_def_type.nBufferCountActual=100;
1547         port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1548
1549         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1550
1551         if (error!=OMX_ErrorNone){
1552                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1553         }
1554
1555
1556         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1557         if (error!=OMX_ErrorNone){
1558                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1559                 return 0;
1560         }
1561
1562         input_bufs_omx_mutex.Lock();
1563         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1564
1565         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1566                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1567         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1568                 if (error!=OMX_ErrorNone){
1569                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1570                         input_bufs_omx_mutex.Unlock();
1571                         return 0;
1572                 }*/
1573                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1574                 if (error!=OMX_ErrorNone){
1575                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1576                                 input_bufs_omx_mutex.Unlock();
1577                         return 0;
1578                 }
1579                 input_bufs_omx_all.push_back(buf_head);
1580                 input_bufs_omx_free.push_back(buf_head);
1581         }
1582         omx_first_frame=true;
1583
1584         firstsynched=false;
1585         cur_input_buf_omx=NULL;
1586         input_bufs_omx_mutex.Unlock();
1587
1588
1589         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1590         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1591                 return 0;
1592         }
1593         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1594
1595         return 1;
1596 }
1597
1598 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
1599 {
1600         OMX_ERRORTYPE error;
1601
1602         cur_input_buf_omx=NULL;
1603         input_bufs_omx_mutex.Lock();
1604         for (int i=0; i< input_bufs_omx_all.size();i++) {
1605         //      free(input_bufs_omx_all[i]->pBuffer);
1606         //      input_bufs_omx_all[i]->pBuffer=NULL;
1607                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1608                 if (error!=OMX_ErrorNone){
1609                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1610                         input_bufs_omx_mutex.Unlock();
1611                         return 0;
1612                 }
1613
1614         }
1615         input_bufs_omx_all.clear();
1616         input_bufs_omx_free.clear();
1617         input_bufs_omx_mutex.Unlock();
1618
1619 }
1620
1621
1622 int VideoOMX::FlushRenderingPipe()
1623 {
1624         OMX_ERRORTYPE error;
1625
1626         if (!dodeint) {
1627
1628                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1629                                 omx_codec_output_port, NULL);
1630                 if (error != OMX_ErrorNone) {
1631                         Log::getInstance()->log("Video", Log::DEBUG,
1632                                         "OMX_Flush codec out 1 failed %x", error);
1633
1634                 }
1635
1636                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1637                                 omx_shed_input_port, NULL);
1638                 if (error != OMX_ErrorNone) {
1639                         Log::getInstance()->log("Video", Log::DEBUG,
1640                                         "OMX_Flush shed in 2 failed %x", error);
1641
1642                 }
1643
1644                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1645                                 omx_codec_output_port)) {
1646                         Log::getInstance()->log("Video", Log::DEBUG,
1647                                         "flush cmd codec  3 failed");
1648                 }
1649
1650                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1651                                 omx_shed_input_port)) {
1652                         Log::getInstance()->log("Video", Log::DEBUG,
1653                                         "flush cmd  shed 4 failed");
1654                 }
1655         } else {
1656                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1657                                 omx_codec_output_port, NULL);
1658                 if (error != OMX_ErrorNone) {
1659                         Log::getInstance()->log("Video", Log::DEBUG,
1660                                         "OMX_Flush codec out 5 failed %x", error);
1661
1662                 }
1663
1664                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1665                                 omx_deint_input_port, NULL);
1666                 if (error != OMX_ErrorNone) {
1667                         Log::getInstance()->log("Video", Log::DEBUG,
1668                                         "OMX_Flush deint in 6 failed %x", error);
1669
1670                 }
1671
1672                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1673                                 omx_codec_output_port)) {
1674                         Log::getInstance()->log("Video", Log::DEBUG,
1675                                         "flush cmd codec  7 failed");
1676                 }
1677
1678                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1679                                 omx_deint_input_port)) {
1680                         Log::getInstance()->log("Video", Log::DEBUG,
1681                                         "flush cmd  deint 8 failed");
1682                 }
1683
1684                 //m
1685                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1686                                 omx_deint_output_port, NULL);
1687                 if (error != OMX_ErrorNone) {
1688                         Log::getInstance()->log("Video", Log::DEBUG,
1689                                         "OMX_Flush deint out 9 failed %x", error);
1690
1691                 }
1692
1693                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1694                                 omx_shed_input_port, NULL);
1695                 if (error != OMX_ErrorNone) {
1696                         Log::getInstance()->log("Video", Log::DEBUG,
1697                                         "OMX_Flush shed in 10 failed %x", error);
1698
1699                 }
1700
1701                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1702                                 omx_deint_output_port)) {
1703                         Log::getInstance()->log("Video", Log::DEBUG,
1704                                         "flush cmd deint 11 failed");
1705                 }
1706
1707                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1708                                 omx_shed_input_port)) {
1709                         Log::getInstance()->log("Video", Log::DEBUG,
1710                                         "flush cmd  shed 12 failed");
1711                 }
1712
1713
1714
1715         }
1716
1717
1718
1719
1720         error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
1721                         omx_rend_input_port, NULL);
1722         if (error != OMX_ErrorNone) {
1723                 Log::getInstance()->log("Video", Log::DEBUG,
1724                                 "OMX_Flush rend in failed %x", error);
1725
1726         }
1727
1728         error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1729                         omx_shed_output_port, NULL);
1730         if (error != OMX_ErrorNone) {
1731                 Log::getInstance()->log("Video", Log::DEBUG,
1732                                 "OMX_Flush shed out failed %x", error);
1733
1734         }
1735
1736
1737
1738         if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
1739                         omx_rend_input_port)) {
1740                 Log::getInstance()->log("Video", Log::DEBUG,
1741                                 "flush cmd shed rend failed");
1742         }
1743
1744         if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1745                         omx_shed_output_port)) {
1746                 Log::getInstance()->log("Video", Log::DEBUG,
1747                                 "flush cmd shed rend failed");
1748         }
1749 }
1750
1751
1752 int VideoOMX::DeAllocateCodecsOMX()
1753 {
1754         OMX_ERRORTYPE error;
1755         omx_running=false;
1756           Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1757
1758    if (cur_input_buf_omx) {
1759                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1760                 OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1761                 if (error!=OMX_ErrorNone) {
1762                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1763                 }
1764
1765                 cur_input_buf_omx=NULL;//write out old data
1766         }
1767    clock_mutex.Lock();
1768    clearEvents();
1769         if (omx_vid_dec) {
1770                 // first stop the omx elements
1771                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1772                         Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1773
1774                 }
1775                 clock_mutex.Unlock();
1776
1777                 idleClock();
1778                 clock_mutex.Lock();
1779
1780                 if (dodeint) {
1781                         if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
1782                                 Log::getInstance()->log("Video", Log::DEBUG,
1783                                                 "vid_deint ChangeComponentState");
1784
1785                         }
1786                 }
1787
1788
1789                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1790                         Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
1791
1792                 }
1793
1794                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1795                         Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1796
1797                 }
1798
1799
1800
1801         // TODO proper deinit sequence
1802                 // first flush all buffers
1803                 FlushRenderingPipe();
1804
1805
1806
1807
1808
1809                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1810                 if (error!=OMX_ErrorNone){
1811                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1812
1813                 }
1814
1815                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1816                 if (error!=OMX_ErrorNone){
1817                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1818
1819                 }
1820
1821                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1822                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1823                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1824                 }
1825
1826
1827
1828
1829                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1830                                 omx_codec_input_port, NULL);
1831                 if (error != OMX_ErrorNone) {
1832                         Log::getInstance()->log("Video", Log::DEBUG,
1833                                         "OMX_Flush codec out failed %x", error);
1834
1835                 }
1836
1837
1838
1839
1840                 DestroyInputBufsOMX();
1841
1842                 //todo flushing
1843                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1844                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1845                 }
1846                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1847                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1848                 }
1849
1850
1851
1852
1853                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1854                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1855                 }
1856
1857
1858
1859                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1860                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1861                 }
1862
1863                 if (dodeint) {
1864                         if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
1865                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
1866                         }
1867
1868
1869
1870                         if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
1871                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
1872                         }
1873                 }
1874
1875
1876
1877                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1878                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1879                 }
1880
1881                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1882                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1883                 }
1884
1885                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1886                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1887                 }
1888
1889
1890
1891
1892                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1893                 if (error!=OMX_ErrorNone) {
1894                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1895
1896                 }
1897
1898                 if (dodeint) {
1899                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_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                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,NULL);
1906                         if (error!=OMX_ErrorNone) {
1907                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1908                         }
1909                 }
1910
1911                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1912                 if (error!=OMX_ErrorNone) {
1913                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1914
1915                 }
1916
1917
1918                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_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                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1925                 if (error!=OMX_ErrorNone) {
1926                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1927
1928                 }
1929
1930
1931                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_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                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1938                 if (error!=OMX_ErrorNone) {
1939                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1940
1941                 }
1942
1943
1944
1945
1946                 error=OMX_FreeHandle(omx_vid_dec);
1947                 error=OMX_FreeHandle(omx_vid_sched);
1948                 error=OMX_FreeHandle(omx_vid_rend);
1949                 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
1950                 omx_vid_dec=NULL;
1951                 clock_mutex.Unlock();
1952                 destroyClock();
1953                 if (error!=OMX_ErrorNone) {
1954                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1955                 }
1956         } else  clock_mutex.Unlock();
1957           Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
1958
1959         return 1;
1960 }
1961
1962
1963 void VideoOMX::destroyClock()
1964 {
1965         clock_mutex.Lock();
1966         if (clock_references>0) {
1967                 clock_references--;
1968                 if (clock_references==0) {
1969                         OMX_ERRORTYPE error;
1970                         Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
1971                         error=OMX_FreeHandle(omx_clock);
1972                         if (error!=OMX_ErrorNone) {
1973                                 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1974                         }
1975
1976                 }
1977         }
1978         clock_mutex.Unlock();
1979
1980 }
1981
1982 int VideoOMX::stop()
1983 {
1984   if (!initted) return 0;
1985   iframemode=false;
1986
1987   //Check if libav mode
1988   DeAllocateCodecsOMX();
1989
1990
1991
1992
1993 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1994   return 1;
1995 }
1996
1997 int VideoOMX::reset()
1998 {
1999   if (!initted) return 0;
2000
2001   iframemode=false;
2002   DeAllocateCodecsOMX();
2003 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2004   return 1;
2005 }
2006
2007 int VideoOMX::pause()
2008 {
2009   if (!initted) return 0;
2010   Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2011   if (!paused) {
2012           paused=true;
2013           //maybe also change omx clock?
2014           //pausetimecode=GetCurrentSystemTime();
2015
2016   }
2017   return 1;
2018 }
2019
2020 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2021 {
2022   if (!initted) return 0;
2023   Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2024
2025   if (paused) {
2026         //  playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
2027           paused=false; // may be also change omx clock
2028   }
2029
2030   return 1;
2031 }
2032
2033 int VideoOMX::fastForward()
2034 {
2035   if (!initted) return 0;
2036
2037 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2038   return 1;
2039 }
2040
2041 int VideoOMX::unFastForward()
2042 {
2043   if (!initted) return 0;
2044
2045 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2046
2047  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2048   return 1;
2049 }
2050
2051 int VideoOMX::attachFrameBuffer()
2052 {
2053   if (!initted) return 0;
2054
2055 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2056   return 1;
2057 }
2058
2059 int VideoOMX::blank(void)
2060 {
2061 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2062 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2063   return 1;
2064 }
2065
2066 ULLONG VideoOMX::getCurrentTimestamp() {
2067         if (iframemode)
2068                 return 0;
2069         long long ncur_clock_time = cur_clock_time;
2070         if (omx_running) {
2071                 clock_mutex.Lock();
2072                 OMX_ERRORTYPE error;
2073                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2074                 memset(&clock_conf, 0, sizeof(clock_conf));
2075                 clock_conf.nSize = sizeof(clock_conf);
2076                 clock_conf.nVersion.nVersion = OMX_VERSION;
2077                 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2078                                 &clock_conf);
2079                 if (error != OMX_ErrorNone) {
2080                         Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error);
2081                 }
2082
2083                 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2084
2085                         OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2086                         memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2087                         cur_time_stamp.nSize = sizeof(cur_time_stamp);
2088                         cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2089                         cur_time_stamp.nPortIndex = omx_clock_output_port;
2090                         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2091                                         &cur_time_stamp);
2092                         if (error != OMX_ErrorNone) {
2093                                 Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error);
2094                         } else {
2095                                 long long temp = cur_time_stamp.nTimestamp.nLowPart
2096                                                 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2097                                 ncur_clock_time = cur_clock_time = temp * 10LL;
2098                         }
2099                 }
2100                 clock_mutex.Unlock();
2101         }
2102
2103         //ncur_clock_time -= startoffset;
2104         ncur_clock_time -= lastreftimeOMX;
2105         long long result = lastreftimePTS;
2106         result += (long long) (ncur_clock_time / 10000LL * 90LL);
2107         if (result < 0)
2108                 result = (1LL << 33) - result;
2109         //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2110
2111         return result;
2112
2113 }
2114
2115 // to be removed
2116 /*
2117 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2118 {
2119   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2120   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2121 }
2122
2123 */
2124 #ifdef DEV
2125 int VideoOMX::test()
2126 {
2127   return 0;
2128
2129 //  ULLONG stc = 0;
2130 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2131 /*
2132  // reset();
2133   return 1;
2134 */
2135 }
2136
2137 int VideoOMX::test2()
2138 {
2139   return 0;
2140 }
2141 #endif
2142
2143
2144
2145 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2146 {
2147   *rsync=false;
2148   if (offsetnotset) {
2149     startoffset=curreftime;//offset is set for audio
2150     offsetnotset=false;
2151     offsetvideonotset=false;
2152   } else {
2153     if (offsetvideonotset) {
2154       offsetvideonotset=false;
2155       *rsync=true;
2156     } else {
2157       if ( (curreftime-lastrefvideotime)>10000000LL
2158         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2159         startoffset+=curreftime-lastrefvideotime;
2160         lastrefaudiotime+=curreftime-lastrefvideotime;
2161         //*rsync=true;
2162         offsetaudionotset=true;
2163
2164       }
2165     }
2166
2167   }
2168
2169   lastrefvideotime=curreftime;
2170
2171   return startoffset;
2172
2173 }
2174
2175 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2176 {
2177   *rsync=false;
2178   if (offsetnotset) {
2179     startoffset=curreftime;
2180     offsetnotset=false;
2181     offsetaudionotset=false;
2182   }else {
2183     if (offsetaudionotset) {
2184       offsetaudionotset=false;
2185       *rsync=true;
2186     } else {
2187       if ( (curreftime-lastrefaudiotime)>10000000LL
2188         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2189         startoffset+=curreftime-lastrefaudiotime;
2190         lastrefvideotime+=curreftime-lastrefaudiotime;
2191         //*rsync=true;
2192         offsetvideonotset=true;
2193
2194       }
2195     }
2196
2197   }
2198   lastrefaudiotime=curreftime;
2199   return startoffset;
2200
2201 }
2202
2203 void VideoOMX::ResetTimeOffsets() {
2204   offsetnotset=true; //called from demuxer
2205   offsetvideonotset=true;
2206   offsetaudionotset=true;
2207   startoffset=0;
2208   lastrefaudiotime=0;
2209   lastrefvideotime=0;
2210   lastreftimeOMX=0;
2211   lastreftimePTS=0;
2212 }
2213
2214
2215 void VideoOMX::DeinterlaceFix()
2216 {
2217
2218         Demuxer* demux=Demuxer::getInstance();
2219         clock_mutex.Lock();
2220         OMX_ERRORTYPE error;
2221         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2222         memset(&port_def_type,0,sizeof(port_def_type));
2223         port_def_type.nSize=sizeof(port_def_type);
2224         port_def_type.nVersion.nVersion=OMX_VERSION;
2225         port_def_type.nPortIndex=omx_codec_output_port;
2226
2227         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2228         if (error != OMX_ErrorNone) {
2229                 Log::getInstance()->log("Video", Log::DEBUG,
2230                                 "OMX_IndexParamPortDefinition fix failed %x", error);
2231                 clock_mutex.Unlock();
2232                 return;
2233         }
2234
2235         if (port_def_type.format.video.nFrameWidth == demux->getHorizontalSize()
2236                         && port_def_type.format.video.nFrameHeight == demux->getVerticalSize()){
2237                 Log::getInstance()->log("Video", Log::DEBUG,
2238                                                         "Deinit first frame fix");
2239                 deint_first_frame=false;
2240
2241                 WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2242                 DisablePort(omx_vid_dec,omx_codec_output_port,false);
2243                 DisablePort(omx_vid_sched,omx_shed_input_port,false);
2244                 DisablePort(omx_vid_deint,omx_deint_output_port,false);
2245                 DisablePort(omx_vid_deint,omx_deint_input_port,false);
2246
2247                 port_def_type.nPortIndex=omx_deint_input_port;
2248                 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2249                                 &port_def_type);
2250                 if (error != OMX_ErrorNone) {
2251                         Log::getInstance()->log("Video", Log::DEBUG,
2252                                         "Set OMX_IndexParamPortDefinition1 failed %x", error);
2253                         clock_mutex.Unlock();
2254                         return;
2255                 }
2256
2257                 port_def_type.nPortIndex=omx_deint_output_port;
2258                 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2259                                 &port_def_type);
2260                 if (error != OMX_ErrorNone) {
2261                         Log::getInstance()->log("Video", Log::DEBUG,
2262                                         "Set OMX_IndexParamPortDefinition2 failed %x", error);
2263                         clock_mutex.Unlock();
2264                         return;
2265                 }
2266
2267
2268                 EnablePort(omx_vid_dec,omx_codec_output_port,false);
2269                 EnablePort(omx_vid_deint,omx_deint_input_port,false);
2270                 EnablePort(omx_vid_deint,omx_deint_output_port,false);
2271                 EnablePort(omx_vid_sched,omx_shed_input_port,false);
2272         }
2273         clock_mutex.Unlock();
2274
2275
2276 }
2277
2278
2279 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2280 {
2281
2282         OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2283         if (error != OMX_ErrorNone) {
2284                 Log::getInstance()->log("Video", Log::DEBUG,
2285                                 "OMX_EmptyThisBuffer failed %x", error);
2286         }
2287         if (deint_first_frame && dodeint) DeinterlaceFix();
2288
2289 }
2290
2291 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2292 {
2293         // protect the call to empty this buffer
2294         int oldcancelstate;
2295         int oldcanceltype;
2296         pthread_testcancel();
2297         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2298         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2299         clock_mutex.Lock();
2300         OMX_ERRORTYPE ret_val;
2301         ret_val=OMX_EmptyThisBuffer(handle,buffer);
2302         clock_mutex.Unlock();
2303         pthread_setcancelstate(oldcancelstate, NULL);
2304         pthread_setcanceltype(oldcanceltype, NULL);
2305         pthread_testcancel();
2306         return ret_val;
2307 }
2308
2309 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2310 {
2311         
2312         mediapackets.clear();
2313         list<MediaPacket>::const_iterator begin=mplist.begin();
2314         list<MediaPacket>::const_iterator itty=mplist.begin();
2315         advance(itty,min(mplist.size(),10));
2316         mediapackets.insert(mediapackets.begin(),begin,itty);//front
2317         
2318 }
2319
2320 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2321 {
2322         int consumed=0;
2323         while (consumed<mediapackets.size()) {
2324             DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2325             if (*samplepos == mediapackets[consumed].length) {
2326                 *samplepos = 0;
2327                 consumed++;
2328                 //return 1;
2329             } else return consumed;
2330         }
2331         return consumed;
2332 }
2333
2334 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2335                 const UCHAR* buffer,
2336                 UINT *samplepos)
2337 {
2338         if (packet.type == MPTYPE_VIDEO_H264)
2339         {
2340                 h264=true;
2341         }
2342         else
2343         {
2344                 h264=false;
2345         }
2346
2347
2348         //Later add fail back code for libav
2349 /*      if (!videoon) {
2350                 *samplepos+=packet.length;
2351                 return packet.length;
2352         }*/
2353
2354
2355         if (!omx_running) return 0; // if we are not runnig do not do this
2356         if (paused) return 0; //Block if we pause
2357
2358         //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
2359         if (packet.synched && packet.presentation_time < 0) {
2360                 *samplepos = packet.length;
2361                 firstsynched = false;
2362                 Log::getInstance()->log("Video", Log::DEBUG,
2363                                 "DeliverMediaPacketOMX Frameskip");
2364                 return packet.length;
2365         }
2366
2367         /*if (packet.synched && FrameSkip(packet.presentation_time)) {
2368                 *samplepos=packet.length;
2369                 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Frameskip");
2370                                 *samplepos=packet.length;
2371                 return packet.length;
2372         }*/
2373         //long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
2374 /*      if (packet.synched &&
2375                         (packet.presentation_time<0 /*|| // preroll skip frames
2376                         (packet.presentation_time+5000000LL)<(current_media_time)*)) { // we are late skip
2377                 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
2378                 *samplepos=packet.length;
2379                 return packet.length;
2380         }*/
2381
2382         OMX_ERRORTYPE error;
2383
2384         /*First Check, if we have an video sample*/
2385         if (iframemode) {
2386                 //samplepos=0;
2387                 MILLISLEEP(10);
2388                 return 0; //Not in iframe mode!
2389         }
2390
2391         UINT headerstrip=0;
2392         if (packet.disconti) {
2393                 firstsynched=false;
2394                 if (cur_input_buf_omx) {
2395                         PutBufferToPres(cur_input_buf_omx);
2396                         cur_input_buf_omx=NULL;
2397                 }
2398         }
2399
2400         /*Inspect PES-Header */
2401
2402 //      OMX_STATETYPE temp_state;
2403 //      OMX_GetState(omx_vid_dec,&temp_state);
2404
2405         if (*samplepos==0) {//stripheader
2406                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2407         //      if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2408         //                      buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2409                 *samplepos+=headerstrip;
2410                 if ( packet.synched ) {
2411                         if (cur_input_buf_omx) {
2412                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
2413                                 PutBufferToPres(cur_input_buf_omx);
2414                                 cur_input_buf_omx=NULL;//write out old data
2415
2416
2417                         }
2418                         firstsynched=true;
2419                 } else {
2420                         if (!firstsynched) {//
2421                                 *samplepos=packet.length;//if we have not processed at least one
2422                                 return packet.length;//synched packet ignore it!
2423                         }
2424                 }
2425         }
2426
2427         if (!cur_input_buf_omx) {
2428                 input_bufs_omx_mutex.Lock();
2429                 if (input_bufs_omx_free.size()==0) {
2430                         input_bufs_omx_mutex.Unlock();
2431                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2432                         return 0; // we do not have a free media sample
2433
2434                 }
2435                 cur_input_buf_omx=input_bufs_omx_free.front();
2436                 cur_input_buf_omx->nFilledLen=0;
2437                 cur_input_buf_omx->nOffset=0;
2438                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2439                 input_bufs_omx_free.pop_front();
2440                 input_bufs_omx_mutex.Unlock();
2441         }
2442
2443
2444
2445
2446         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2447                 if (packet.synched) {
2448                 //      Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
2449
2450                         //lastreftimePTS=packet.pts;
2451                    if (omx_first_frame) { // TODO time
2452                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2453                            Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
2454                            omx_first_frame=false;
2455                    } else {
2456                            cur_input_buf_omx->nFlags=0;
2457                            //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
2458                    }
2459                    lastreftimeOMX=packet.presentation_time;
2460                   // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
2461                    lastreftimePTS=packet.pts;
2462                    cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
2463                 }
2464                 else
2465                 {
2466                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2467                         cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2468                         //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
2469                 }
2470                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
2471
2472
2473
2474         }
2475         unsigned int haveToCopy=packet.length-*samplepos;
2476
2477         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2478                 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
2479                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2480                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2481                 haveToCopy-=cancopy;
2482                 cur_input_buf_omx->nFilledLen+=cancopy;
2483                 *samplepos+=cancopy;
2484                 // push old buffer out
2485
2486                 PutBufferToPres(cur_input_buf_omx);
2487                 cur_input_buf_omx=NULL;
2488                 // get5 new buffer
2489                 input_bufs_omx_mutex.Lock();
2490                 if (input_bufs_omx_free.size()==0) {
2491                         input_bufs_omx_mutex.Unlock();
2492                 //      Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
2493                         return *samplepos; // we do not have a free media sample
2494                 }
2495                 cur_input_buf_omx=input_bufs_omx_free.front();
2496                 cur_input_buf_omx->nFilledLen=0;
2497                 cur_input_buf_omx->nOffset=0;
2498                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2499                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
2500                 input_bufs_omx_free.pop_front();
2501                 input_bufs_omx_mutex.Unlock();
2502
2503         }
2504         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2505                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2506         cur_input_buf_omx->nFilledLen+=haveToCopy;
2507
2508
2509
2510         *samplepos+=haveToCopy;
2511
2512         return *samplepos;
2513
2514 }
2515
2516
2517
2518
2519 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
2520         if (!omx_running) return false;
2521         if (!iframemode)
2522                 EnterIframePlayback();
2523
2524         int haveToCopy = length;
2525
2526         if (!cur_input_buf_omx) {
2527                 input_bufs_omx_mutex.Lock();
2528                 if (input_bufs_omx_free.size() == 0) {
2529                         input_bufs_omx_mutex.Unlock();
2530                 //      Log::getInstance()->log("Video", Log::DEBUG,
2531                         //              "Deliver MediaPacket no free sample");
2532                         return false; // we do not have a free media sample
2533
2534                 }
2535                 cur_input_buf_omx = input_bufs_omx_free.front();
2536                 cur_input_buf_omx->nFilledLen = 0;
2537                 cur_input_buf_omx->nOffset = 0;
2538                 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2539                 input_bufs_omx_free.pop_front();
2540                 input_bufs_omx_mutex.Unlock();
2541         }
2542
2543         int read_pos = 0;
2544         unsigned int pattern, packet_length;
2545         unsigned int headerstrip = 0;
2546         bool first = true;
2547         if (length < 4){
2548                 return false;
2549         }
2550         //Now we strip the pes header
2551         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
2552         while (read_pos + 7 <= length) {
2553                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
2554                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
2555                         read_pos++;
2556                         continue;
2557                 } else {
2558                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
2559                         packet_length = ((buffer[read_pos + 4] << 8)
2560                                         | (buffer[read_pos + 5])) + 6;
2561                         if (read_pos + packet_length > length)
2562                                 read_pos = length;
2563                         else {
2564                                 if ((headerstrip < packet_length)
2565                                                 && (cur_input_buf_omx->nFilledLen + packet_length
2566                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
2567                                         if (first) {
2568                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2569
2570                                         } else {
2571                                                 cur_input_buf_omx->nFlags
2572                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2573
2574                                         }
2575                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2576                                         PutBufferToPres(cur_input_buf_omx);
2577                                         cur_input_buf_omx = NULL;
2578
2579                                         if (!cur_input_buf_omx) {
2580                                                 int count = 0;
2581                                                 while (count < 100 && omx_running && iframemode) {
2582                                                         count++;
2583
2584                                                         input_bufs_omx_mutex.Lock();
2585                                                         if (input_bufs_omx_free.size() == 0) {
2586                                                                 input_bufs_omx_mutex.Unlock();
2587                                         //                      Log::getInstance()->log("Video", Log::DEBUG,
2588                                                 //                              "Ifrane no free sample");
2589                                                                 MILLISLEEP(5);
2590                                                                 if (!omx_running) return false;
2591                                                                 continue;
2592                                                         }
2593                                                         cur_input_buf_omx = input_bufs_omx_free.front();
2594                                                         cur_input_buf_omx->nFilledLen = 0;
2595                                                         cur_input_buf_omx->nOffset = 0;
2596                                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2597                                                         cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
2598                                                         input_bufs_omx_free.pop_front();
2599                                                         input_bufs_omx_mutex.Unlock();
2600                                                         break;
2601                                                 }
2602                                                 if (!cur_input_buf_omx)
2603                                                         return false;
2604                                         }
2605
2606                                 }
2607                                 if (packet_length > headerstrip) {
2608                                         memcpy(
2609                                                         cur_input_buf_omx->pBuffer
2610                                                                         + cur_input_buf_omx->nFilledLen,
2611                                                         buffer + read_pos + headerstrip,
2612                                                         packet_length - headerstrip);
2613                                         cur_input_buf_omx->nFilledLen += packet_length
2614                                                         - headerstrip;
2615                                 }
2616                                 read_pos += packet_length;
2617
2618                                 pattern = (buffer[read_pos] << 16)
2619                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
2620                         }
2621                 }
2622         }
2623
2624         if (first) {
2625                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2626
2627         } else {
2628                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2629
2630         }
2631         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
2632         
2633         PutBufferToPres(cur_input_buf_omx);
2634         cur_input_buf_omx = NULL;
2635
2636
2637         MILLISLEEP(40); //Block a bit
2638         return true;
2639 }
2640
2641 int VideoOMX::EnterIframePlayback()
2642 {
2643         Log::getInstance()->log("Video", Log::DEBUG,
2644                                                 "EnterIframePlayback");
2645         if (cur_input_buf_omx) {
2646                 PutBufferToPres(cur_input_buf_omx);
2647                 cur_input_buf_omx = NULL;
2648         }
2649         Log::getInstance()->log("Video", Log::DEBUG,
2650                                                         "EnterIframePlayback 2");
2651         ((AudioOMX*)Audio::getInstance())->DeAllocateCodecsOMX();
2652         DeAllocateCodecsOMX();
2653         AllocateCodecsOMX();
2654         Log::getInstance()->log("Video", Log::DEBUG,
2655                                                         "leave IframePlayback");
2656
2657         iframemode=true;
2658
2659         return 1;
2660 }
2661