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