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