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