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