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