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