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