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