]> git.vomp.tv Git - vompclient.git/blob - videovpeogl.cc
Add basic audio playback (stereo), fast forward, ThreadP bugfix and Stream interface...
[vompclient.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
35 #ifdef VPE_OMX_SUPPORT
36   omx_running=false;
37
38   omx_vid_dec=0;
39   cur_input_buf_omx=NULL;
40   omx_h264=omx_mpeg2=true;
41   clock_references=0;
42 #endif
43
44 #ifdef VPE_LIBAV_SUPPORT
45   mpeg2codec_context_libav=NULL;
46   libav_running=false;
47   dec_frame_libav_uploading_framebuf=NULL;
48   dec_frame_libav_decoding=NULL;
49   ogl_frame_outside=false;
50   //decoding_mode=VPE_NO_XVMC;
51   decoding_mode=VPE_XVMC_MOCOMP;
52   //decoding_mode=VPE_XVMC_IDCT;
53   framebuf_framenum=0;
54   moco_shader=NULL;
55
56   ogl_forward_ref_frame_num=0;
57   ogl_backward_ref_frame_num=0;
58   ogl_forward_ref_frame=NULL;
59   ogl_backward_ref_frame=NULL;
60 #endif
61
62 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
63          transcodecodec_libav=NULL;
64          transcodecodec_context_libav=NULL;
65 #endif
66
67          offsetnotset=true;
68          offsetvideonotset=true;
69          offsetaudionotset=true;
70          startoffset=0;
71          lastrefaudiotime=0;
72          lastrefvideotime=0;
73          lastreftimeOMX=0;
74          lastreftimePTS=0;
75          firstsynched=false;
76
77
78 #ifdef BENCHMARK_FPS
79         time_in_decoder=0;
80     num_frames=0;
81         time_in_decoder_gl=0;
82     num_frames_gl=0;
83 #endif
84
85 }
86
87 VideoVPEOGL::~VideoVPEOGL()
88 {
89   instance = NULL;
90 }
91
92 int VideoVPEOGL::init(UCHAR tformat)
93 {
94   if (initted) return 0;
95   initted = 1;
96
97   if (!setFormat(tformat))           { shutdown(); return 0; }
98   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
99   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
100   if (!setMode(NORMAL))              { shutdown(); return 0; }
101   if (!setSource())                  { shutdown(); return 0; }
102   if (!attachFrameBuffer())          { shutdown(); return 0; }
103
104   setTVsize(ASPECT4X3);
105
106
107
108
109
110   //stop();
111
112
113
114   return 1;
115 }
116
117 int VideoVPEOGL::initUsingOSDObjects()
118 {
119         EGLDisplay i_egl_display;
120         EGLSurface i_egl_surface;
121         EGLContext i_egl_context;
122         EGLConfig i_egl_config;
123         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
124         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
125         const EGLint attr_context[]={
126                         EGL_CONTEXT_CLIENT_VERSION,2,
127                 EGL_NONE
128         };
129
130         egl_display=i_egl_display;
131         egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
132         if (egl_context==EGL_NO_CONTEXT) {
133                  Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
134                  return 0;
135         }
136         // We create a dummy surface here, in order to allow two contexts
137         const EGLint attr_pbuffer[]={
138                         EGL_WIDTH, 1, EGL_HEIGHT,1,
139                     EGL_NONE
140         };
141         egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
142         if (egl_surface==EGL_NO_SURFACE) {
143                  Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
144                  return 0;
145         }
146
147
148
149
150         //egl_surface=i_egl_surface;
151         //egl_context=i_egl_context;
152
153
154 #ifdef VPE_OMX_SUPPORT
155 // we are called before the audio
156         OMX_ERRORTYPE error;
157         error=OMX_Init();
158         if (error!=OMX_ErrorNone) {
159                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
160                 return 0;
161         }
162
163         //our callbacks move to play?
164
165 #endif
166
167 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)
168         av_register_all();
169 #endif
170
171 #ifdef VPE_LIBAV_SUPPORT
172
173
174         if (decoding_mode==VPE_NO_XVMC) {
175                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
176         } else {
177                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
178         }
179         if (mpeg2codec_libav==NULL) {
180                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
181                 return 0;
182         }
183 #endif
184 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
185         transcodecodec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_MPEG4);
186         if (transcodecodec_libav==NULL) {
187                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 transcoder failed");
188                 return 0;
189         }
190 #endif
191
192
193         threadStart();
194         return 1;
195 }
196
197
198 #ifdef VPE_OMX_SUPPORT
199
200 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
201            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
202            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
203
204         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
205
206         struct VPE_OMX_EVENT  new_event;
207         new_event.handle=handle;
208         new_event.appdata=appdata;
209         new_event.event_type=event_type;
210         new_event.data1=data1;
211         new_event.data2=data2;
212         new_event.event_data=event_data;
213
214         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
215         video->AddOmxEvent(new_event);
216
217 /*      switch (event_type) {
218         case OMX_EventCmdComplete: {
219
220         } break;
221         }*/
222
223         return OMX_ErrorNone;
224
225 }
226
227 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
228 {
229         omx_event_mutex.Lock();
230     omx_events.push_back(new_event);
231         omx_event_mutex.Unlock();
232 }
233
234
235 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
236
237         //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
238         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
239         video->ReturnEmptyOMXBuffer(buffer);
240         return OMX_ErrorNone;
241
242 }
243
244 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
245         input_bufs_omx_mutex.Lock();
246         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
247         input_bufs_omx_free.push_back(buffer);
248         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
249         input_bufs_omx_mutex.Unlock();
250 }
251
252  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
253          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
254         return OMX_ErrorNone;
255 }
256
257 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
258
259  enum PixelFormat VideoVPEOGL::get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt)
260  {
261         enum PixelFormat ret_pix=PIX_FMT_NONE;
262
263         while (*fmt!=PIX_FMT_NONE) {
264                 if (*fmt== PIX_FMT_TRANSCODE ) {
265                         ret_pix=PIX_FMT_TRANSCODE;
266                 }
267                 fmt++;
268         }
269         return ret_pix;
270  }
271
272  int VideoVPEOGL::reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
273  {
274          Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!Not Implemented! \n");
275
276         return -1;
277  }
278
279  int VideoVPEOGL::get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
280  {
281
282         //reget logic from mplayer
283         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
284                 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!\n");
285                 return 0;
286         }
287
288
289         if (c->pix_fmt!=PIX_FMT_TRANSCODE ) {
290                 Log::getInstance()->log("Video", Log::DEBUG,"We only support transcode pixel fmt\n");
291                 return 0;
292         }
293         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
294         transcode_pix_fmt *pix_trans=NULL;
295         OMX_BUFFERHEADERTYPE* our_buf=video->GetFreeOMXBufferforlibav(&pix_trans);
296         if (our_buf==NULL|| pix_trans==NULL) {
297                 Log::getInstance()->log("Video", Log::DEBUG,"Getting buffer failed\n");
298                 return -1;
299         } else {
300
301         }
302
303
304
305
306         //populate pict
307         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
308
309         pic->base[0]=(uint8_t*)our_buf; // our buf
310         //pic->extended_data=pic->data;
311         if(c->pkt) pic->pkt_pts=c->pkt->pts;
312         else pic->pkt_pts=AV_NOPTS_VALUE;
313         pic->width=c->width;
314         pic->height=c->height;
315         pic->format=c->pix_fmt;
316         pic->sample_aspect_ratio=c->sample_aspect_ratio;
317         pic->reordered_opaque= c->reordered_opaque;
318         //pic->age=INT_MAX;
319         pic->data[0]=(uint8_t*)pix_trans;
320         pix_trans->transcode_id=AV_TRANSCODE_ID;
321         pix_trans->packet.data=(uint8_t*)our_buf->pBuffer;
322         pix_trans->packet.size=our_buf->nAllocLen;
323         //that is all folks
324
325         return 0;
326
327  }
328
329  OMX_BUFFERHEADERTYPE* VideoVPEOGL::GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans)
330  {
331          OMX_BUFFERHEADERTYPE* returned_buf=NULL;
332          *pix_trans=NULL;
333          int time_out=0;
334
335          while (returned_buf==NULL && time_out<100){
336                  input_bufs_omx_mutex.Lock();
337                   if (input_bufs_omx_free.size()!=0) {
338                             returned_buf=input_bufs_omx_free.front();
339                             returned_buf->nFilledLen=0;
340                             returned_buf->nOffset=0;
341                             returned_buf->nTimeStamp=0;
342                                 input_bufs_omx_free.pop_front();
343                                 input_bufs_omx_in_libav.push_back(returned_buf);
344                                 input_bufs_omx_mutex.Unlock();
345                                 returned_buf->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
346                                 break;
347                   }
348                   input_bufs_omx_mutex.Unlock();
349                  Log::getInstance()->log("Video", Log::DEBUG, "GetFreeOMXBuffer_libav no free sample block");
350                  time_out++;
351                  MILLISLEEP(20);
352          }
353          if (returned_buf) {
354          *pix_trans=pix_fmt_omx_free.front();
355           pix_fmt_omx_free.pop_front(); // we assume that there is always a twin
356          }
357          return returned_buf;
358  }
359
360  void VideoVPEOGL::release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
361  {
362          VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
363          video->ReturnEmptyOMXBuffer_libav((OMX_BUFFERHEADERTYPE*) pic->base[0],(transcode_pix_fmt *)pic->data[0]);
364          pic->data[0]=NULL; //without doing this avcodec is going to cry
365  }
366
367  void VideoVPEOGL::ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt){
368         input_bufs_omx_mutex.Lock();
369         // We only return it, if it was not passed to OMX!
370         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
371         pix_fmt_omx_free.push_back(pix_fmt);
372         list<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_in_libav.begin();
373         while (itty!=input_bufs_omx_in_libav.end()) {
374                 if (*itty==buffer) {
375                         input_bufs_omx_in_libav.remove(buffer);
376                         input_bufs_omx_free.push_back(buffer);
377                         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
378                         break;
379                 }
380         }
381         input_bufs_omx_mutex.Unlock();
382  }
383
384
385 #endif
386
387 #endif
388
389 int VideoVPEOGL::shutdown()
390 {
391   if (!initted) return 0;
392   initted = 0;
393   threadCancel();
394
395   decoding_backend=0;
396 #ifdef VPE_OMX_SUPPORT
397   DeAllocateCodecsOMX();
398   OMX_Deinit();
399 #endif
400 #ifdef VPE_LIBAV_SUPPORT
401   DeAllocateCodecsLibav();
402 #endif
403   eglDestroyContext(egl_display,egl_context);
404 //  close(fdVideo);
405   return 1;
406 }
407 #ifdef VPE_LIBAV_SUPPORT
408 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
409 {
410         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
411         // Y
412         glGenTextures(1, &outframe->textures[0]);
413         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
414         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
415                                 GL_UNSIGNED_BYTE, NULL);
416         // U
417         glGenTextures(1, &outframe->textures[1]);
418         glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
419         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
420                                 GL_UNSIGNED_BYTE, NULL);
421         // V
422         glGenTextures(1, &outframe->textures[2]);
423         glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
424         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
425                         GL_UNSIGNED_BYTE, NULL);
426         outframe->height=height;
427         outframe->width=width;
428         outframe->stride=stride;
429         outframe->type=1;
430         return 1;
431 }
432
433 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
434 {
435         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
436         // Y
437         glGenTextures(1, &outframe->textures[0]);
438         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
439         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
440                                 GL_UNSIGNED_BYTE, NULL);
441         outframe->textures[1]=outframe->textures[2]=0; // no handles here
442
443
444
445
446         outframe->type=2;
447         outframe->height=height;
448         outframe->width=width;
449         outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
450         return 1;
451 }
452
453
454 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
455         VPEOGLFrame *return_obj=NULL;
456         ogl_frame_mutex.Lock();
457         if (ready_ogl_frames.size()>0) {
458                 return_obj=ready_ogl_frames.front();
459                 ready_ogl_frames.pop_front();
460                 //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing  num: %d",return_obj->pict_num);
461                 ogl_frame_outside=true;
462         }
463         ogl_frame_mutex.Unlock();
464         return return_obj;
465 }
466
467 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
468 {
469         ogl_frame_mutex.Lock();
470         if (frame) {
471                 ogl_frame_outside=false;
472                 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
473                 if (frame->pict_num==ogl_forward_ref_frame_num ||
474                                 frame->pict_num==ogl_backward_ref_frame_num ) {
475                         recycle_ref_ogl_frames.push_back(frame);
476                 } else {
477                         free_ogl_frames.push_back(frame);
478                 }
479         }
480         ogl_frame_mutex.Unlock();
481 }
482
483 void VideoVPEOGL::recycleOGLRefFrames()
484 {
485         // This function recycles frames formerly used as reference frame
486         ogl_frame_mutex.Lock();
487         list<VPEOGLFrame*> keep;
488         list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
489         while (itty!=recycle_ref_ogl_frames.end()) {
490         //      Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
491                 if ((*itty)->pict_num==ogl_forward_ref_frame_num
492                                 || (*itty)->pict_num==ogl_backward_ref_frame_num)
493                 {
494                         // ok we have to keep this
495                         keep.push_back(*itty);
496                 } else {
497                         free_ogl_frames.push_back(*itty);
498                 }
499                 itty++;
500         }
501         recycle_ref_ogl_frames.clear();
502         recycle_ref_ogl_frames=keep;
503
504         ogl_frame_mutex.Unlock();
505
506
507 }
508 #endif
509
510 void VideoVPEOGL::threadMethod()
511 {
512         if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
513                 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
514                 return;
515         }
516         long long run=0;
517         while (1) {
518                 bool sleep=true;
519
520                 run++;
521 #ifdef VPE_LIBAV_SUPPORT
522                 bool upload=false;
523                 bool view=false;
524                 dec_frame_libav_mutex.Lock();
525                 AVFrame* dec_frame_libav_uploading_int=NULL;
526
527
528                 if (dec_frame_libav_upload_and_view_pending.size()>0  ) {
529
530                         dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
531                         dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
532                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
533                 //                      dec_frame_libav_uploading_framebuf);
534                 //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
535                 //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
536
537                         view=true;
538                         if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC  ) {
539                                 dec_frame_libav_upload_and_view_pending.pop_front();
540                                 if (decoding_mode==VPE_NO_XVMC) upload=true;
541                         } else {
542                                 dec_frame_libav_uploading_framebuf=NULL;
543                                 dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
544                                 view=false; //do the upload
545                         //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
546                         }
547                 }
548
549                 if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
550
551                         dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
552                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
553                                 //      dec_frame_libav_uploading_framebuf);
554                         dec_frame_libav_upload_only_pending.pop_front();
555                         view=false;
556                         upload=true;
557                 /*      if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
558                                 upload=false;
559                                 dec_frame_libav_uploading=NULL; //do not upload again
560                         }*/
561                 }
562
563
564
565
566
567
568                 if (dec_frame_libav_upload_and_view_pending.size()>0
569                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
570
571                 dec_frame_libav_mutex.Unlock();
572
573
574                 if (dec_frame_libav_uploading_framebuf) {
575
576                         //Code Block for debugging if needed
577                 /*      Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
578                         ogl_frame_mutex.Lock();
579                         list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
580                         while (itty!=free_ogl_frames.end()) {
581                                 Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
582
583                                 itty++;
584                         }
585
586                         itty=recycle_ref_ogl_frames.begin();
587                         while (itty!=recycle_ref_ogl_frames.end()) {
588                                 Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
589
590                                 itty++;
591                         }
592                         itty=ready_ogl_frames.begin();
593                         while (itty!=ready_ogl_frames.end()) {
594                                 Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
595
596                                 itty++;
597                         }
598                         ogl_frame_mutex.Unlock();*/
599
600
601                         if (upload) {
602                                 int width,height,pixfmt;
603                                 //First get a free ogl image
604                                 VPEOGLFrame* out_frame=NULL;
605                                 //int msleep=0;
606                                 while (!out_frame) {
607                                         ogl_frame_mutex.Lock();
608                                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
609                                         //                                                              recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
610                                         if (all_ogl_frames.size()==0) {
611                                                 ogl_frame_mutex.Unlock(); break;
612                                         }
613
614                                         if (free_ogl_frames.size()>0) {
615                                                 width=libavwidth;
616                                                 height=libavheight;
617                                                 pixfmt=libavpixfmt;
618                                                 out_frame=free_ogl_frames.front();
619                                                 free_ogl_frames.pop_front();
620                                         } else {
621                                                 ogl_frame_mutex.Unlock();
622                                                 MILLISLEEP(2);
623                                         //      msleep+=2;
624                                                 ogl_frame_mutex.Lock();
625                                         }
626                                 //      if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
627                                         ogl_frame_mutex.Unlock();
628                                 }
629                                 bool failed=false;
630                                 if (out_frame) {
631                                 //      Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
632                                         if (out_frame->textures[0]==0 || out_frame->width!=width ||
633                                                         out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
634                                                 if (out_frame->textures[0]!=0) {
635                                                         glDeleteTextures(1,&out_frame->textures[0]);
636                                                         out_frame->textures[0]=0;
637                                                 }
638                                                 if (out_frame->textures[1]!=0) {
639                                                         glDeleteTextures(1,&out_frame->textures[1]);
640                                                         out_frame->textures[1]=0;
641                                                 }
642                                                 if (out_frame->textures[2]!=0) {
643                                                         glDeleteTextures(1,&out_frame->textures[2]);
644                                                         out_frame->textures[2]=0;
645                                                 }
646
647                                                 if (decoding_mode==VPE_NO_XVMC) {
648                                                         if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
649                                                 } else {
650                                                         if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
651                                                         // the shaders are easier to implement
652                                                 }
653                                         }
654                                         dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
655                                         dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
656
657
658                                         if (!failed) {
659                                                 //up to now only YUV data, this is for reference only, since the pi is too slow.
660                                                 if (decoding_mode==VPE_NO_XVMC) {
661                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
662                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
663                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
664                                                                         out_frame->stride,out_frame->height,
665                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
666                                                                         dec_frame_libav_uploading_framebuf->data[0]);
667
668                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
669                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
670                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
671                                                                         out_frame->stride>>1,out_frame->height>>1,
672                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
673                                                                         dec_frame_libav_uploading_framebuf->data[1]);
674
675                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
676                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
677                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
678                                                                         out_frame->stride>>1,out_frame->height>>1,
679                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
680                                                                         dec_frame_libav_uploading_framebuf->data[2]);
681                                                 } else {
682                                                         //XVMC case
683                                                         xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
684                                                         if (moco_shader && pix_fmt) {
685
686 #ifdef BENCHMARK_FPS
687                                                                 int cur_time=getTimeMS();
688 #endif
689                                                                 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
690                                                                                 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
691                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
692                                                                 //                                                      pix_fmt->p_past_surface,pix_fmt->p_future_surface);
693
694                                                                 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
695                                                                 {
696                                                                         //Now determine the frame, that fits
697                                                                         ogl_frame_mutex.Lock();
698                                                                         bool found=false;
699                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
700                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
701                                                                                 {
702                                                                                         ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
703                                                                                         ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
704                                                                                         ogl_backward_ref_frame=all_ogl_frames[i];
705                                                                                         ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
706                                                                                         found=true;
707                                                                                         break;
708                                                                                 }
709                                                                         }
710                                                                 //      if (!found) {// for debugging
711                                                                 //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
712                                                                 //              exit(0);
713                                                                 //      }
714
715                                                                         ogl_frame_mutex.Unlock();
716                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
717                                                                 }
718                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
719
720 /*
721                                                                 if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
722                                                                 {
723
724                                                                 }*/
725
726                                                                 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
727                                                                 {
728                                                                         //Now determine the frame, that fits
729                                                                         ogl_frame_mutex.Lock();
730                                                                         bool found=false;
731                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
732                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
733                                                                                 {
734                                                                                         ogl_forward_ref_frame=all_ogl_frames[i];
735                                                                                         ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
736                                                                                         found=true;
737                                                                                         break;
738                                                                                 }
739                                                                         }
740                                                                 //      if (!found) {
741                                                                 //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
742                                                                 //                              ((int)pix_fmt->p_past_surface));
743                                                                 //              exit(0);
744                                                                 //      }
745
746                                                                         ogl_frame_mutex.Unlock();
747                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
748
749                                                                 }
750                                                                 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
751
752                                                                 if (decoding_mode==VPE_XVMC_MOCOMP)
753                                                                 {
754                                                                         //DCT Blocks upload
755
756                                                                 } else {
757                                                                         //DCT Blocks upload
758                                                                 }
759                                                                 out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
760
761                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
762
763                                                                 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
764                                                                                 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
765
766 #ifdef BENCHMARK_FPS
767                                                                 time_in_decoder_gl+=getTimeMS()-cur_time;
768                                                                 num_frames_gl++;
769                                                                 if ((num_frames_gl%100)==0) {
770                                                                         float fps=1000./(float)(time_in_decoder_gl);
771                                                                         fps*=((float)num_frames_gl);
772                                                                         Log::getInstance()->log("Video", Log::NOTICE, "Current GL Decoding FPS %g", fps);
773                                                                 }
774 #endif
775
776                                                                 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
777                                                                 // Excute motion compensation
778                                                         } else {
779                                                                 //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
780                                                                 //                                      exit(0);
781                                                         }
782                                                 }
783
784
785
786                                         }
787                                 }
788
789                         }
790
791
792
793                         if (view) {
794
795                                 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
796                                 VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
797                                 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
798                         /*      Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
799                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
800                                 Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
801
802                                 releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
803                                 ogl_frame_mutex.Lock();
804                                 ready_ogl_frames.push_back(out_frame);
805                                 ogl_frame_mutex.Unlock();
806                                 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
807
808                                 dec_frame_libav_mutex.Lock();
809                                 dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
810                                 dec_frame_libav_mutex.Unlock();
811                         }
812
813
814                         dec_frame_libav_mutex.Lock();
815                         dec_frame_libav_uploading_framebuf=NULL;
816
817                         if (dec_frame_libav_upload_and_view_pending.size()>0
818                                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
819
820                         dec_frame_libav_mutex.Unlock();
821
822
823
824                 }
825 #endif
826
827                 if (sleep) {
828                         struct timespec target_time;
829                         int ts=20; //20 ms
830                         clock_gettime(CLOCK_REALTIME,&target_time);
831                         target_time.tv_nsec+=1000000LL*ts;
832                         if (target_time.tv_nsec>999999999) {
833                                 target_time.tv_nsec-=1000000000L;
834                                 target_time.tv_sec+=1;
835                         }
836                         threadWaitForSignalTimed(&target_time);
837                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
838                 }
839                 threadCheckExit();
840         }
841
842 }
843
844
845 void VideoVPEOGL::threadPostStopCleanup()
846 {
847         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
848 #ifdef VPE_LIBAV_SUPPORT
849         dec_frame_libav_uploading_framebuf=NULL;
850 #endif
851 }
852
853
854
855
856 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
857 {
858 /*  tvsize = ttvsize;
859
860   // Override the aspect ratio usage, temporarily use to set the video chip mode
861   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
862   close(fdVideo);
863   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
864   if (!setSource())                  { shutdown(); return 0; }
865   if (!attachFramebuffer())          { shutdown(); return 0; }
866
867   // Reopening the fd causes the scart aspect line to go back to 4:3
868   // Set this again to the same as the tv screen size
869   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
870
871   // mode == LETTERBOX is invalid if the TV is widescreen
872   if (tvsize == ASPECT16X9) setMode(NORMAL);
873 */
874   return 1;
875 }
876
877 int VideoVPEOGL::setDefaultAspect()
878 {
879   return setAspectRatio(tvsize);
880 }
881
882
883
884 int VideoVPEOGL::setFormat(UCHAR tformat)
885 {
886   if (!initted) return 0;
887   if ((tformat != PAL) && (tformat != NTSC)) return 0;
888   format = tformat;
889
890 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
891
892   if (format == NTSC)
893   {
894     screenWidth = 720;
895     screenHeight = 480;
896   }
897   if (format == PAL)
898   {
899     screenWidth = 720;
900     screenHeight = 576;
901   }
902
903   return 1;
904 }
905
906 int VideoVPEOGL::setConnection(UCHAR tconnection)
907 {
908   if (!initted) return 0;
909   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
910   connection = tconnection;
911
912 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
913   return 1;
914 }
915
916 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
917 {
918   if (!initted) return 0;
919   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
920   aspectRatio = taspectRatio;
921
922   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
923
924 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
925   return 1;
926 }
927
928 int VideoVPEOGL::setMode(UCHAR tmode)
929 {
930   if (!initted) return 0;
931
932   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
933
934   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
935       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
936   mode = tmode;
937
938 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
939   return 1;
940 }
941
942 int VideoVPEOGL::signalOff()
943 {
944 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
945   return 1;
946 }
947
948 int VideoVPEOGL::signalOn()
949 {
950 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
951   return 1;
952 }
953
954 int VideoVPEOGL::setSource()
955 {
956   if (!initted) return 0;
957
958   // What does this do...
959 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
960   return 1;
961 }
962
963 int VideoVPEOGL::setPosition(int x, int y)
964 {
965   if (!initted) return 0;
966
967 //  vid_pos_regs_t pos_d;
968 //  pos_d.x = x;
969 //  pos_d.y = y;
970
971 /*  vid_pos_regs_t pos_d;
972
973   memset(&pos_d, 0, sizeof(pos_d));
974
975   pos_d.dest.y = y;
976   pos_d.dest.x = x;
977 /*
978 typedef struct {
979   int w;
980   int h;
981   int scale;
982   int x1;
983   int y;
984   int x;
985   int y2;
986   int x3;
987   int y3;
988   int x4;
989   int y4;
990 } vid_pos_regs_t;
991 */
992
993 /*
994   pos_d.w = 100;
995   pos_d.h = 30;
996   pos_d.scale = 2;
997   pos_d.x1 = 0;
998   pos_d.y = 100;            // Top left X
999   pos_d.x = 50;            // Top left Y
1000   pos_d.y2 = 30;
1001   pos_d.x3 = 60;
1002   pos_d.y3 = 90;
1003   pos_d.x4 = 120;
1004   pos_d.y4 = 150;
1005 */
1006
1007 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
1008   return 1;
1009 }
1010
1011 int VideoVPEOGL::sync()
1012 {
1013   if (!initted) return 0;
1014
1015 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
1016   return 1;
1017 }
1018
1019
1020
1021
1022 int VideoVPEOGL::play()
1023 {
1024   if (!initted) return 0;
1025   decoding_backend=0;
1026   iframemode=false;
1027 #ifdef VPE_OMX_SUPPORT
1028   bool doomx=true;
1029   Log::getInstance()->log("Video", Log::DEBUG, "enter play");
1030   if (h264) {
1031           if (!omx_h264) doomx=false;
1032   } else {
1033           if (!omx_mpeg2) doomx=false;
1034   }
1035   if (doomx) {
1036           if (AllocateCodecsOMX()) {
1037                   //decoding_backend=VPE_DECODER_OMX;
1038                   return 1;
1039                   // Otherwise fall back to libav
1040           } else {
1041                   if (h264) {
1042                           omx_h264=false;
1043                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
1044                   } else {
1045                           omx_mpeg2=false;
1046                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
1047                   }
1048           }
1049   }
1050 #endif
1051 #ifdef VPE_LIBAV_SUPPORT
1052   if (AllocateCodecsLibav()) {
1053           decoding_backend=VPE_DECODER_libav;
1054           return 1;
1055                   // Otherwise fall back to libav
1056   }
1057 #endif
1058   return 0;
1059
1060
1061
1062 }
1063
1064 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1065
1066 int VideoVPEOGL::InitTranscoderLibAV() {
1067         transcodecodec_context_libav = avcodec_alloc_context3(transcodecodec_libav);
1068         if (!transcodecodec_context_libav) {
1069                 Log::getInstance()->log("Video", Log::DEBUG, "Alloc avcodec context failed!");
1070                 return 0;
1071         }
1072
1073         transcodecodec_context_libav->slice_flags = SLICE_FLAG_CODED_ORDER;
1074
1075         transcodecodec_context_libav->pix_fmt = PIX_FMT_TRANSCODE;
1076         transcodecodec_context_libav->get_format = get_format_transcode;
1077         transcodecodec_context_libav->get_buffer = get_buffer_transcode;
1078         transcodecodec_context_libav->reget_buffer = reget_buffer_transcode;
1079         transcodecodec_context_libav->release_buffer = release_buffer_transcode;
1080         //transcodecodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
1081         //transcodecodec_context_libav->time_base.den=9000; //pts values 90 KHz Clock /10;
1082
1083         int avc_ret = avcodec_open2(transcodecodec_context_libav, transcodecodec_libav, NULL);
1084         if (avc_ret < 0) {
1085                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed \n");
1086                 return 0;
1087         }
1088
1089         memset(&incom_packet_libav, 0, sizeof(incom_packet_libav));
1090         incom_packet_libav_size = 200000;
1091         incom_packet_libav.data = (uint8_t*) av_malloc(incom_packet_libav_size + FF_INPUT_BUFFER_PADDING_SIZE);
1092
1093         return 1;
1094 }
1095
1096
1097
1098 int VideoVPEOGL::DeInitTranscoderLibAV() {
1099
1100         av_free(incom_packet_libav.data);
1101         incom_packet_libav.data=NULL;
1102         incom_packet_libav_size=0;
1103
1104         if (transcodecodec_context_libav) {
1105                 avcodec_close(transcodecodec_context_libav);
1106                 av_free(transcodecodec_context_libav);
1107                 transcodecodec_context_libav=NULL;
1108
1109         }
1110
1111         return 1;
1112 }
1113
1114 #endif
1115
1116 #ifdef VPE_OMX_SUPPORT
1117
1118 int VideoVPEOGL::initClock()
1119 {
1120         OMX_ERRORTYPE error;
1121         clock_mutex.Lock();
1122         if (clock_references==0)
1123         {
1124
1125                 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1126                 omx_events.clear();
1127
1128                 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
1129
1130                 if (error!=OMX_ErrorNone) {
1131                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
1132                         clock_mutex.Unlock();
1133                         DeAllocateCodecsOMX();
1134                         return 0;
1135                 }
1136
1137                 /* TODO Clock config to separate method */
1138                 OMX_PORT_PARAM_TYPE p_param;
1139                 memset(&p_param,0,sizeof(p_param));
1140                 p_param.nSize=sizeof(p_param);
1141                 p_param.nVersion.nVersion=OMX_VERSION;
1142                 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1143                 if (error!=OMX_ErrorNone) {
1144                         Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1145                         clock_mutex.Unlock();
1146                         DeAllocateCodecsOMX();
1147                         return 0;
1148                 }
1149                 omx_clock_output_port=p_param.nStartPortNumber;
1150
1151                 for (unsigned int i=0;i<p_param.nPorts;i++) {
1152                         if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
1153                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
1154                                 clock_mutex.Unlock();
1155                                 DeAllocateCodecsOMX();
1156                                 return 0;
1157                         }
1158                 }
1159
1160
1161
1162
1163         }
1164         Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
1165         clock_references++;
1166         clock_mutex.Unlock();
1167         return 1;
1168 }
1169
1170 int VideoVPEOGL::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
1171 {
1172         OMX_ERRORTYPE error;
1173         *p_omx_clock=NULL;
1174         *p_omx_clock_output_port=0;
1175
1176         if (!initClock()) {
1177                 return 0;
1178         }
1179         clock_mutex.Lock();
1180
1181         OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1182         memset(&refclock,0,sizeof(refclock));
1183         refclock.nSize=sizeof(refclock);
1184         refclock.nVersion.nVersion=OMX_VERSION;
1185
1186         refclock.eClock=OMX_TIME_RefClockAudio;
1187
1188         //refclock.eClock=OMX_TIME_RefClockVideo;
1189         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1190         if (error!=OMX_ErrorNone){
1191                 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1192                 clock_mutex.Unlock();
1193                 DeAllocateCodecsOMX();
1194                 return 0;
1195         }
1196
1197         OMX_PORT_PARAM_TYPE p_param;
1198         memset(&p_param,0,sizeof(p_param));
1199         p_param.nSize=sizeof(p_param);
1200         p_param.nVersion.nVersion=OMX_VERSION;
1201         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1202         if (error!=OMX_ErrorNone){
1203                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1204                 clock_mutex.Unlock();
1205                 DeAllocateCodecsOMX();
1206                 return 0;
1207         }
1208
1209         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1210         memset(&clock_conf,0,sizeof(clock_conf));
1211         clock_conf.nSize=sizeof(clock_conf);
1212         clock_conf.nVersion.nVersion=OMX_VERSION;
1213         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1214         clock_conf.nStartTime=0;
1215         clock_conf.nOffset=0;
1216         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
1217         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1218         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1219         if (error!=OMX_ErrorNone) {
1220                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1221         }
1222
1223
1224         *p_omx_clock_output_port=p_param.nStartPortNumber+1;
1225         *p_omx_clock=omx_clock;
1226         clock_mutex.Unlock();
1227         return 1;
1228 }
1229
1230 int VideoVPEOGL::getClockVideoandInit()
1231 {
1232         OMX_ERRORTYPE error;
1233
1234         if (!initClock()) {
1235                 return 0;
1236         }
1237         clock_mutex.Lock();
1238
1239         if (clock_references==1) { // only if no audio is attached to this clock!
1240                 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1241                 memset(&refclock,0,sizeof(refclock));
1242                 refclock.nSize=sizeof(refclock);
1243                 refclock.nVersion.nVersion=OMX_VERSION;
1244
1245                 //refclock.eClock=OMX_TIME_RefClockAudio;
1246
1247                 refclock.eClock=OMX_TIME_RefClockVideo;
1248                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1249                 if (error!=OMX_ErrorNone) {
1250                         Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1251                         clock_mutex.Unlock();
1252                         DeAllocateCodecsOMX();
1253                         return 0;
1254                 }
1255         }
1256
1257         OMX_PORT_PARAM_TYPE p_param;
1258         memset(&p_param,0,sizeof(p_param));
1259         p_param.nSize=sizeof(p_param);
1260         p_param.nVersion.nVersion=OMX_VERSION;
1261         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1262         if (error!=OMX_ErrorNone){
1263                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1264                 clock_mutex.Unlock();
1265                 DeAllocateCodecsOMX();
1266                 return 0;
1267         }
1268
1269
1270         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1271         memset(&clock_conf,0,sizeof(clock_conf));
1272         clock_conf.nSize=sizeof(clock_conf);
1273         clock_conf.nVersion.nVersion=OMX_VERSION;
1274         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1275         clock_conf.nStartTime=0;
1276         clock_conf.nOffset=0;
1277         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1278         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1279         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1280         if (error!=OMX_ErrorNone) {
1281                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1282         }
1283
1284         omx_clock_output_port=p_param.nStartPortNumber;
1285         clock_mutex.Unlock();
1286
1287         return 1;
1288 }
1289
1290 void VideoVPEOGL::clockUnpause()
1291 {
1292         OMX_ERRORTYPE error;
1293         clock_mutex.Lock();
1294         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1295         memset(&clock_conf,0,sizeof(clock_conf));
1296         clock_conf.nSize=sizeof(clock_conf);
1297         clock_conf.nVersion.nVersion=OMX_VERSION;
1298         clock_conf.eState=OMX_TIME_ClockStateRunning;
1299         clock_conf.nStartTime=0;
1300         clock_conf.nOffset=0;
1301         clock_conf.nWaitMask=OMX_CLOCKPORT1;
1302         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1303         if (error!=OMX_ErrorNone) {
1304                 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
1305         }
1306
1307         clock_mutex.Unlock();
1308 }
1309
1310
1311 void VideoVPEOGL::clockPause()
1312 {
1313         OMX_ERRORTYPE error;
1314         clock_mutex.Lock();
1315         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1316         memset(&clock_conf,0,sizeof(clock_conf));
1317         clock_conf.nSize=sizeof(clock_conf);
1318         clock_conf.nVersion.nVersion=OMX_VERSION;
1319         clock_conf.eState=OMX_TIME_ClockStateStopped;
1320         clock_conf.nStartTime=0;
1321         clock_conf.nOffset=0;
1322         clock_conf.nWaitMask=OMX_CLOCKPORT1;
1323         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1324         if (error!=OMX_ErrorNone) {
1325                 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
1326         }
1327         clock_mutex.Unlock();
1328 }
1329
1330
1331
1332 int VideoVPEOGL::AllocateCodecsOMX()
1333 {
1334         OMX_ERRORTYPE error;
1335         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1336
1337         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1338         //Clock, move later to audio including events
1339
1340         Log::getInstance()->log("Video", Log::DEBUG, "Nmark1 ");
1341         if (!getClockVideoandInit()){
1342                 return 0;// get the clock and init it if necessary
1343         }
1344         Log::getInstance()->log("Video", Log::DEBUG, "Nmark2 ");
1345
1346         if (!idleClock()) {
1347                 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
1348                 return 0;
1349         }
1350         /* TODO end */
1351
1352
1353         clock_mutex.Lock();
1354         if (h264) {
1355                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
1356         } else {
1357                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1358         }
1359
1360         if (error!=OMX_ErrorNone){
1361                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1362                 clock_mutex.Unlock();
1363                 DeAllocateCodecsOMX();
1364                 return 0;
1365         }
1366
1367
1368         Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
1369         OMX_PORT_PARAM_TYPE p_param;
1370         memset(&p_param,0,sizeof(p_param));
1371         p_param.nSize=sizeof(p_param);
1372         p_param.nVersion.nVersion=OMX_VERSION;
1373         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1374         if (error!=OMX_ErrorNone){
1375                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1376                 clock_mutex.Unlock();
1377                 DeAllocateCodecsOMX();
1378             return 0;
1379         }
1380         omx_codec_input_port=p_param.nStartPortNumber;
1381         omx_codec_output_port=p_param.nStartPortNumber+1;
1382
1383         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1384                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1385                 clock_mutex.Unlock();
1386                 DeAllocateCodecsOMX();
1387                 return 0;
1388         }
1389
1390         Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
1391
1392         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1393         memset(&conceal,0,sizeof(conceal));
1394         conceal.nSize=sizeof(conceal);
1395         conceal.nVersion.nVersion=OMX_VERSION;
1396         conceal.bStartWithValidFrame=OMX_FALSE;
1397
1398         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1399         if (error!=OMX_ErrorNone){
1400                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1401                 clock_mutex.Unlock();
1402                 DeAllocateCodecsOMX();
1403                 return 0;
1404         }
1405
1406
1407         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1408         if (error!=OMX_ErrorNone){
1409                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1410                 clock_mutex.Unlock();
1411                 DeAllocateCodecsOMX();
1412                 return 0;
1413         }
1414
1415
1416
1417         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1418         if (error!=OMX_ErrorNone){
1419                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1420                 clock_mutex.Unlock();
1421                 DeAllocateCodecsOMX();
1422                 return 0;
1423         }
1424         omx_shed_input_port=p_param.nStartPortNumber;
1425         omx_shed_output_port=p_param.nStartPortNumber+1;
1426
1427
1428         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1429         if (error!=OMX_ErrorNone){
1430                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1431                 clock_mutex.Unlock();
1432                 DeAllocateCodecsOMX();
1433                 return 0;
1434         }
1435         omx_shed_clock_port=p_param.nStartPortNumber;
1436         Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1437
1438
1439         if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1440                         || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1441                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1442                 clock_mutex.Unlock();
1443                 DeAllocateCodecsOMX();
1444                 return 0;
1445         }
1446
1447
1448         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1449         if (error!=OMX_ErrorNone){
1450                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1451                 clock_mutex.Unlock();
1452                 DeAllocateCodecsOMX();
1453                 return 0;
1454         }
1455
1456         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1457         if (error!=OMX_ErrorNone){
1458                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1459                 clock_mutex.Unlock();
1460                 DeAllocateCodecsOMX();
1461                 return 0;
1462         }
1463         omx_rend_input_port=p_param.nStartPortNumber;
1464         //omx_rend_output_port=p_param.nStartPortNumber+1;
1465
1466
1467         if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1468                                 ) {
1469                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1470                 clock_mutex.Unlock();
1471                 DeAllocateCodecsOMX();
1472                 return 0;
1473         }
1474
1475         //Setuo chain
1476
1477
1478
1479         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1480         if (error!=OMX_ErrorNone){
1481                 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);
1482                 clock_mutex.Unlock();
1483                 DeAllocateCodecsOMX();
1484                 return 0;
1485         }
1486
1487         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1488                                         ) {
1489                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1490                 clock_mutex.Unlock();
1491                 DeAllocateCodecsOMX();
1492                 return 0;
1493         }
1494
1495
1496         Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
1497         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1498                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1499                 clock_mutex.Unlock();
1500                 DeAllocateCodecsOMX();
1501                 return 0;
1502         }
1503
1504
1505
1506         Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
1507         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1508                 clock_mutex.Unlock();
1509                 DeAllocateCodecsOMX();
1510                 return 0;
1511         }
1512
1513
1514
1515
1516         Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
1517         if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1518                 clock_mutex.Unlock();
1519                 DeAllocateCodecsOMX();
1520                 return 0;
1521         }
1522         clock_mutex.Unlock();
1523
1524
1525         Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
1526
1527
1528 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1529         if (error!=OMX_ErrorNone){
1530                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1531                 return 0;
1532         }*/
1533
1534         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1535         memset(&ft_type,0,sizeof(ft_type));
1536         ft_type.nSize=sizeof(ft_type);
1537         ft_type.nVersion.nVersion=OMX_VERSION;
1538
1539         ft_type.nPortIndex=omx_codec_input_port;
1540         if (h264) {
1541                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1542         } else {
1543 #ifndef VPE_LIBAV_MPEG2_TRANSCODING
1544                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1545 #else
1546                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
1547                 decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
1548                 InitTranscoderLibAV();
1549 #endif
1550         }
1551
1552         Demuxer* demux=Demuxer::getInstance();
1553
1554     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1555     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1556         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1557         if (error!=OMX_ErrorNone){
1558                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1559                 clock_mutex.Unlock();
1560                 DeAllocateCodecsOMX();
1561                 return 0;
1562         }
1563
1564
1565         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1566                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1567                 clock_mutex.Unlock();
1568                 DeAllocateCodecsOMX();
1569                 return 0;
1570         }
1571
1572
1573         if (!PrepareInputBufsOMX()) {
1574                 clock_mutex.Unlock();
1575                 DeAllocateCodecsOMX();
1576                 return 0;
1577         }
1578
1579
1580         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1581         if (error!=OMX_ErrorNone){
1582                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1583                 clock_mutex.Unlock();
1584                 DeAllocateCodecsOMX();
1585                 return 0;
1586         }
1587
1588
1589
1590         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1591                                                 ) {
1592                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1593                 clock_mutex.Unlock();
1594                 DeAllocateCodecsOMX();
1595                 return 0;
1596         }
1597
1598         if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1599                 clock_mutex.Unlock();
1600                 DeAllocateCodecsOMX();
1601                 return 0;
1602         }
1603
1604         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1605                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1606                 clock_mutex.Unlock();
1607                 DeAllocateCodecsOMX();
1608                 return 0;
1609         }
1610
1611         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1612         if (error!=OMX_ErrorNone){
1613                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1614                 clock_mutex.Unlock();
1615                 DeAllocateCodecsOMX();
1616                 return 0;
1617         }
1618
1619         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1620                                                         ) {
1621                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1622                 clock_mutex.Unlock();
1623                 DeAllocateCodecsOMX();
1624                 return 0;
1625         }
1626
1627         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1628                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1629                 clock_mutex.Unlock();
1630                 DeAllocateCodecsOMX();
1631                 return 0;
1632         }
1633
1634         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1635                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1636                 clock_mutex.Unlock();
1637                 DeAllocateCodecsOMX();
1638                 return 0;
1639         }
1640
1641
1642         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1643                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1644                 clock_mutex.Unlock();
1645                 DeAllocateCodecsOMX();
1646                 return 0;
1647         }
1648
1649         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1650                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1651                 clock_mutex.Unlock();
1652                 DeAllocateCodecsOMX();
1653                 return 0;
1654         }
1655
1656         //raspbi specifif
1657         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1658         memset(&dispconf,0,sizeof(dispconf));
1659         dispconf.nSize=sizeof(dispconf);
1660         dispconf.nVersion.nVersion=OMX_VERSION;
1661
1662         dispconf.nPortIndex=omx_rend_input_port;
1663
1664         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1665         dispconf.layer=1;
1666         error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1667         if (error!=OMX_ErrorNone){
1668                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1669                 clock_mutex.Unlock();
1670                 DeAllocateCodecsOMX();
1671                 return 0;
1672         }
1673
1674 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1675         dispconf.fullscreen=OMX_FALSE;
1676         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1677         if (error!=OMX_ErrorNone){
1678                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1679                 clock_mutex.Unlock();
1680                 DeAllocateCodecsOMX();
1681                 return 0;
1682         }
1683
1684         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1685         dispconf.dest_rect.x_offset=100;
1686         dispconf.dest_rect.y_offset=100;
1687         dispconf.dest_rect.width=640;
1688         dispconf.dest_rect.height=480;
1689         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1690         if (error!=OMX_ErrorNone){
1691                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1692                 clock_mutex.Unlock();
1693                 DeAllocateCodecsOMX();
1694                 return 0;
1695         }*/
1696
1697         if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
1698
1699         playbacktimeoffset=-GetCurrentSystemTime();
1700         paused=false;
1701         iframemode=false;
1702         omx_running=true;
1703         clock_mutex.Unlock();
1704
1705         setClockExecutingandRunning();
1706
1707
1708
1709
1710
1711         return 1;
1712 }
1713
1714 int VideoVPEOGL::idleClock()
1715 {
1716         OMX_ERRORTYPE error;
1717         OMX_STATETYPE temp_state;
1718         clock_mutex.Lock();
1719         OMX_GetState(omx_clock,&temp_state);
1720
1721         if (temp_state!=OMX_StateIdle) {
1722                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1723                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1724                         clock_mutex.Unlock();
1725                         return 0;
1726                 }
1727         }
1728         clock_mutex.Unlock();
1729         return 1;
1730 }
1731
1732 int VideoVPEOGL::setClockExecutingandRunning()
1733 {
1734         OMX_ERRORTYPE error;
1735         OMX_STATETYPE temp_state;
1736         clock_mutex.Lock();
1737         OMX_GetState(omx_clock,&temp_state);
1738
1739         if (temp_state!=OMX_StateExecuting) {
1740                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1741                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1742                         clock_mutex.Unlock();
1743                         DeAllocateCodecsOMX();
1744                         return 0;
1745                 }
1746         }
1747
1748         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1749         memset(&clock_conf,0,sizeof(clock_conf));
1750         clock_conf.nSize=sizeof(clock_conf);
1751         clock_conf.nVersion.nVersion=OMX_VERSION;
1752         clock_conf.eState=OMX_TIME_ClockStateRunning;
1753         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1754         if (error!=OMX_ErrorNone) {
1755                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1756                 clock_mutex.Unlock();
1757                 DeAllocateCodecsOMX();
1758                 return 0;
1759         }
1760         clock_mutex.Unlock();
1761         return 1;
1762
1763 }
1764
1765
1766 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1767 {
1768         OMX_ERRORTYPE error;
1769         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1770         if (error!=OMX_ErrorNone){
1771                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1772                 return 0;
1773         }
1774
1775         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1776                 return 0;
1777         }
1778
1779         return 1;
1780 }
1781
1782
1783 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1784 {
1785         OMX_ERRORTYPE error;
1786         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1787         if (error!=OMX_ErrorNone){
1788                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1789                 return 0;
1790         }
1791
1792         if (!wait) return 1;
1793         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1794                 return 0;
1795         }
1796
1797         return 1;
1798 }
1799
1800
1801 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1802 {
1803         OMX_ERRORTYPE error;
1804         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1805         if (error!=OMX_ErrorNone){
1806                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1807                 return 0;
1808         }
1809
1810         if (!wait) return 1;
1811         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1812                 return 0;
1813         }
1814
1815
1816         return 1;
1817 }
1818
1819
1820
1821
1822 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1823 {
1824         int i=0;
1825         while (i<1000) {
1826                 omx_event_mutex.Lock();
1827                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1828                 while (itty!=omx_events.end()) {
1829
1830                         VPE_OMX_EVENT current=*itty;
1831                         if (current.handle==handle) { //this is ours
1832                                 if (current.event_type==OMX_EventError) {
1833                                         omx_events.erase(itty);
1834                                         omx_event_mutex.Unlock();
1835                                         Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
1836                                         return 0;
1837
1838                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1839                                         omx_events.erase(itty);
1840                                         omx_event_mutex.Unlock();
1841                                         //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1842                                         return 1;
1843                                 }
1844                         }
1845                         itty++;
1846
1847                 }
1848                 omx_event_mutex.Unlock();
1849                 MILLISLEEP(2);
1850                 i++;
1851
1852         }
1853         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1854         return 0;
1855
1856 }
1857
1858
1859
1860
1861
1862 int VideoVPEOGL::PrepareInputBufsOMX() //needs to be called with locked mutex
1863 {
1864         OMX_ERRORTYPE error;
1865         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1866         memset(&port_def_type,0,sizeof(port_def_type));
1867         port_def_type.nSize=sizeof(port_def_type);
1868         port_def_type.nVersion.nVersion=OMX_VERSION;
1869         port_def_type.nPortIndex=omx_codec_input_port;
1870
1871         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1872
1873         if (error!=OMX_ErrorNone){
1874                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1875         }
1876 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1877                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1878                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1879
1880         port_def_type.nBufferCountActual=60;
1881         port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1882
1883         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1884
1885         if (error!=OMX_ErrorNone){
1886                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1887         }
1888
1889
1890         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1891         if (error!=OMX_ErrorNone){
1892                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1893                 return 0;
1894         }
1895
1896         input_bufs_omx_mutex.Lock();
1897         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1898
1899         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1900                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1901         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1902                 if (error!=OMX_ErrorNone){
1903                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1904                         input_bufs_omx_mutex.Unlock();
1905                         return 0;
1906                 }*/
1907                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1908                 if (error!=OMX_ErrorNone){
1909                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1910                                 input_bufs_omx_mutex.Unlock();
1911                         return 0;
1912                 }
1913                 input_bufs_omx_all.push_back(buf_head);
1914                 input_bufs_omx_free.push_back(buf_head);
1915 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1916                 transcode_pix_fmt* new_pix=NULL;
1917                 new_pix=(transcode_pix_fmt*)malloc(sizeof(transcode_pix_fmt));
1918                 pix_fmt_omx_all.push_back(new_pix);
1919                 pix_fmt_omx_free.push_back(new_pix);
1920 #endif
1921         }
1922         omx_first_frame=true;
1923
1924         firstsynched=false;
1925         cur_input_buf_omx=NULL;
1926         input_bufs_omx_mutex.Unlock();
1927
1928
1929         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1930         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1931                 return 0;
1932         }
1933         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1934
1935         return 1;
1936 }
1937
1938 int VideoVPEOGL::DestroyInputBufsOMX() //need s to be called with locked mutex
1939 {
1940         OMX_ERRORTYPE error;
1941
1942         cur_input_buf_omx=NULL;
1943         input_bufs_omx_mutex.Lock();
1944         for (int i=0; i< input_bufs_omx_all.size();i++) {
1945         //      free(input_bufs_omx_all[i]->pBuffer);
1946         //      input_bufs_omx_all[i]->pBuffer=NULL;
1947                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1948                 if (error!=OMX_ErrorNone){
1949                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1950                         input_bufs_omx_mutex.Unlock();
1951                         return 0;
1952                 }
1953
1954 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1955                 free(pix_fmt_omx_all[i]);
1956 #endif
1957         }
1958         input_bufs_omx_all.clear();
1959         input_bufs_omx_free.clear();
1960 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1961         input_bufs_omx_in_libav.clear();
1962         pix_fmt_omx_all.clear();
1963         pix_fmt_omx_free.clear();
1964 #endif
1965         input_bufs_omx_mutex.Unlock();
1966
1967 }
1968
1969
1970
1971
1972 int VideoVPEOGL::DeAllocateCodecsOMX()
1973 {
1974         OMX_ERRORTYPE error;
1975         omx_running=false;
1976           Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1977 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1978    if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
1979             DeInitTranscoderLibAV();
1980 #endif
1981
1982    clock_mutex.Lock();
1983    if (cur_input_buf_omx) {
1984                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1985                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1986                 if (error!=OMX_ErrorNone) {
1987                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1988                 }
1989
1990                 cur_input_buf_omx=NULL;//write out old data
1991         }
1992
1993         if (omx_vid_dec) {
1994                 // first stop the omx elements
1995                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1996                         Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1997
1998                 }
1999                 clock_mutex.Unlock();
2000
2001                 idleClock();
2002                 clock_mutex.Lock();
2003
2004
2005                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2006                         Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
2007
2008                 }
2009
2010                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2011                         Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
2012
2013                 }
2014
2015
2016
2017         // TODO proper deinit sequence
2018                 // first flush all buffers
2019
2020                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
2021                 if (error!=OMX_ErrorNone) {
2022                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
2023
2024                 }
2025
2026                 if (!CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
2027                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
2028                 }
2029
2030                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
2031                 if (error!=OMX_ErrorNone){
2032                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
2033
2034                 }
2035
2036
2037
2038                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
2039                 if (error!=OMX_ErrorNone){
2040                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
2041
2042                 }
2043
2044                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
2045                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
2046                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
2047                 }
2048
2049
2050                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2051                 if (error!=OMX_ErrorNone){
2052                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
2053
2054                 }
2055
2056                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2057                 if (error!=OMX_ErrorNone){
2058                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
2059
2060                 }
2061
2062                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2063                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2064                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
2065                 }
2066
2067                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
2068                 if (error!=OMX_ErrorNone) {
2069                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
2070
2071                 }
2072
2073
2074
2075                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ) {
2076                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
2077                 }
2078
2079
2080
2081
2082
2083
2084                 DestroyInputBufsOMX();
2085
2086                 //todo flushing
2087                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2088                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
2089                 }
2090                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2091                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
2092                 }
2093
2094
2095
2096
2097                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2098                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
2099                 }
2100
2101
2102
2103                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2104                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
2105                 }
2106
2107
2108
2109
2110                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2111                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
2112                 }
2113
2114                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2115                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
2116                 }
2117
2118                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2119                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
2120                 }
2121
2122
2123
2124
2125                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
2126                 if (error!=OMX_ErrorNone) {
2127                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2128
2129                 }
2130
2131                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
2132                 if (error!=OMX_ErrorNone) {
2133                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2134
2135                 }
2136
2137
2138                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
2139                 if (error!=OMX_ErrorNone) {
2140                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2141
2142                 }
2143
2144                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
2145                 if (error!=OMX_ErrorNone) {
2146                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2147
2148                 }
2149
2150
2151                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
2152                 if (error!=OMX_ErrorNone) {
2153                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2154
2155                 }
2156
2157                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
2158                 if (error!=OMX_ErrorNone) {
2159                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2160
2161                 }
2162
2163
2164
2165
2166                 error=OMX_FreeHandle(omx_vid_dec);
2167                 error=OMX_FreeHandle(omx_vid_sched);
2168                 error=OMX_FreeHandle(omx_vid_rend);
2169                 omx_vid_dec=NULL;
2170                 clock_mutex.Unlock();
2171                 destroyClock();
2172                 if (error!=OMX_ErrorNone) {
2173                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2174                 }
2175         } else  clock_mutex.Unlock();
2176           Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2177
2178         return 1;
2179 }
2180
2181
2182 void VideoVPEOGL::destroyClock()
2183 {
2184         clock_mutex.Lock();
2185         if (clock_references>0) {
2186                 clock_references--;
2187                 if (clock_references==0) {
2188                         OMX_ERRORTYPE error;
2189                         Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2190                         error=OMX_FreeHandle(omx_clock);
2191                         if (error!=OMX_ErrorNone) {
2192                                 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2193                         }
2194
2195                 }
2196         }
2197         clock_mutex.Unlock();
2198
2199 }
2200
2201 #endif
2202
2203
2204 #ifdef VPE_LIBAV_SUPPORT
2205
2206 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
2207 {
2208         int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
2209         enum PixelFormat ret_pix=PIX_FMT_NONE;
2210         if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
2211         while (*fmt!=PIX_FMT_NONE) {
2212                 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
2213                         ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
2214                 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
2215                         ret_pix=PIX_FMT_XVMC_MPEG2_MC;
2216                 }
2217                 fmt++;
2218         }
2219         return ret_pix;
2220 }
2221
2222 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
2223 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
2224 {
2225         if ((y+height)==src->height) {
2226         /*      Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
2227                                 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
2228                 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
2229                         Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
2230                 }
2231                 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
2232         }
2233
2234 }
2235
2236 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2237 {
2238         Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
2239         return -1;
2240 }
2241
2242 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2243 {
2244         unsigned int want_sizes[4]={0,0,0,0};
2245         AVPicture pict;
2246         bool normal_pixs=false;
2247         int num_blocks=0;
2248         int num_dct_blocks=0;
2249
2250         int s_a[4];
2251         //reget logic from mplayer
2252         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
2253                 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
2254                 return 0;
2255         }
2256
2257
2258         if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
2259                 normal_pixs=true;
2260                 // standard pixel format
2261                 // this is written using much inspiration from libav util.c, so portions from there
2262                 int width,height;
2263
2264                 width=c->width;
2265                 height=c->height;
2266
2267                 avcodec_align_dimensions2(c, &width, &height, s_a);
2268                 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
2269                         width+=2*16;
2270                         height+=2*16;
2271                 }
2272                 // Now we have to determine alignment size
2273                 bool unaligned=true;
2274                 while (unaligned) {
2275                         av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
2276                         width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
2277                         unaligned=false;
2278                         for (int i=0;i<4;i++) {
2279                                 if ((pict.linesize[i]%s_a[i])!=0) {
2280                                         unaligned=true;
2281                                         break;
2282                                 }
2283                         }
2284                 }
2285                 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
2286                 for (int i=0;i<4 ;i++) {
2287                         if (i<3 && pict.data[i+1]) {
2288                                 want_sizes[i]=pict.data[i+1]-pict.data[i];
2289                                 want_sizes[i]+=16;
2290                         } else {
2291                                 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
2292                                 want_sizes[i]+=16;
2293                                 break;
2294                         }
2295                 }
2296
2297         } else {
2298                 //TODO set linesizes!
2299
2300                 num_blocks=((c->width+15)/16)*((c->height+15)/16);
2301                 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
2302
2303                 want_sizes[2]=sizeof(xvmc_pix_fmt);
2304                 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
2305                 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
2306                 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
2307
2308         }
2309
2310         VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
2311         frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
2312         frame_buf->ogl_uploaded=false; //not uploaded yet
2313         frame_buf->width=pic->width;
2314         frame_buf->height=pic->height;
2315         frame_buf->stride=pic->linesize[0];
2316
2317         //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
2318         if (!frame_buf) {
2319                 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
2320                 return -1;
2321         }
2322
2323
2324         //populate pict
2325         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
2326         int hchr_shift,vchr_shift;
2327         avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
2328         const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
2329         for (int i=0;i<4;i++) {
2330                 pic->data[i]=(uint8_t*)frame_buf->data[i];
2331                 pic->linesize[i]=pict.linesize[i];
2332                 if (normal_pixs) {
2333
2334                         int edge_width=16;
2335                         int edge_height=16;
2336                         if (i!=0) {
2337                                 edge_width>>=hchr_shift;
2338                                 edge_height>>=vchr_shift;
2339                         }
2340                         pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
2341                 }
2342         }
2343
2344         pic->base[0]=(uint8_t*)frame_buf; // our structure
2345         //pic->extended_data=pic->data;
2346         if(c->pkt) pic->pkt_pts=c->pkt->pts;
2347         else pic->pkt_pts=AV_NOPTS_VALUE;
2348         pic->width=c->width;
2349         pic->height=c->height;
2350         pic->format=c->pix_fmt;
2351         pic->sample_aspect_ratio=c->sample_aspect_ratio;
2352         pic->reordered_opaque= c->reordered_opaque;
2353         pic->age=INT_MAX;
2354         if (!normal_pixs) {
2355                 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
2356                 pix_xvmc->xvmc_id=AV_XVMC_ID;
2357                 pix_xvmc->data_blocks=(short*)pic->data[1];
2358                 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
2359                 pix_xvmc->allocated_mv_blocks=num_blocks;
2360                 pix_xvmc->allocated_data_blocks=num_dct_blocks;
2361                 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
2362                 else pix_xvmc->idct=0;
2363                 pix_xvmc->unsigned_intra=1; // let see what happens
2364                 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
2365                 pix_xvmc->start_mv_blocks_num=0;
2366                 pix_xvmc->filled_mv_blocks_num=0;
2367                 pix_xvmc->next_free_data_block_num=0;
2368                 //that is all folks
2369
2370
2371         }
2372
2373         return 0;
2374
2375 }
2376
2377 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2378 {
2379 //      Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
2380         ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
2381         pic->base[0]=NULL;
2382         pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
2383
2384
2385 }
2386
2387 int VideoVPEOGL::AllocateCodecsLibav()
2388 {
2389         if (libav_running) DeAllocateCodecsLibav();
2390         libav_hastime=false;
2391         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
2392         mpeg2codec_context_libav=avcodec_alloc_context();
2393         if (mpeg2codec_context_libav==NULL) {
2394                 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
2395                 return 0;
2396         }
2397         if (decoding_mode!=VPE_NO_XVMC) {
2398                 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
2399                 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
2400                 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
2401                 mpeg2codec_context_libav->get_format=get_format_libav;
2402                 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
2403
2404         }
2405         mpeg2codec_context_libav->get_buffer=get_buffer_libav;
2406         mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
2407         mpeg2codec_context_libav->release_buffer=release_buffer_libav;
2408
2409
2410
2411         int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
2412         if (avc_ret<0) {
2413                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed ");
2414                 return 0;
2415         }
2416         memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
2417         incom_packet_libav_size=200000;
2418         incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2419
2420         dec_frame_libav_mutex.Lock();
2421         for (int i=0;i<3;i++) {
2422                         AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
2423                         if (!dec_frame_libav) {
2424                                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
2425                                 return 0;
2426                         }
2427                         dec_frame_libav_all.push_back(dec_frame_libav);
2428                         dec_frame_libav_free.push_back(dec_frame_libav);
2429         }
2430         dec_frame_libav_decoding=NULL;
2431         dec_frame_libav_mutex.Unlock();
2432
2433         ogl_frame_mutex.Lock();
2434         //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
2435         for (int i=0;i<5;i++) {
2436                 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
2437                 new_frame->type=1; //1 = YUV, 2 RGB
2438                 new_frame->textures[0]=0;
2439                 new_frame->textures[1]=0;
2440                 new_frame->textures[2]=0;
2441                 new_frame->width=new_frame->height=0;
2442                 all_ogl_frames.push_back(new_frame);
2443                 free_ogl_frames.push_back(new_frame);
2444
2445         }
2446         ogl_frame_outside=false;
2447
2448         ogl_frame_mutex.Unlock();
2449
2450         if (decoding_mode==VPE_XVMC_MOCOMP) {
2451                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2452                 osd->BeginPainting(); // get OpenGl context
2453                 moco_shader=new GLMocoShader();
2454                 moco_shader->init();
2455                 osd->EndPainting();
2456         }
2457
2458         libav_running=true;
2459
2460         return 1;
2461
2462 }
2463
2464 int VideoVPEOGL::DeAllocateCodecsLibav()
2465 {
2466         libav_running=false;
2467         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
2468         dec_frame_libav_mutex.Lock();
2469         dec_frame_libav_upload_and_view_pending.clear();
2470         dec_frame_libav_upload_only_pending.clear();
2471         dec_frame_libav_free.clear();
2472         dec_frame_libav_mutex.Unlock();
2473         while (dec_frame_libav_uploading_framebuf) {
2474                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
2475                 MILLISLEEP(20);
2476         }
2477         dec_frame_libav_mutex.Lock();
2478         for (int i=0; i< dec_frame_libav_all.size();i++) {
2479                 av_free(dec_frame_libav_all[i]);
2480         }
2481
2482         dec_frame_libav_all.clear();
2483
2484         av_free(incom_packet_libav.data);
2485         incom_packet_libav.data=NULL;
2486         incom_packet_libav_size=0;
2487
2488         dec_frame_libav_mutex.Unlock();
2489         dec_frame_libav_decoding=NULL;
2490         while (ogl_frame_outside) {
2491                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
2492                 MILLISLEEP(20);
2493         }
2494
2495         ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
2496         ogl_frame_mutex.Lock();
2497         for (int i=0; i< dec_frame_libav_all.size();i++) {
2498                 VPEOGLFrame * del_frame=all_ogl_frames[i];
2499                 if (del_frame->textures[0]==0) {
2500                         glDeleteTextures(1,&del_frame->textures[0]);
2501                         del_frame->textures[0]=0;
2502                 }
2503                 if (del_frame->textures[1]==0) {
2504                         glDeleteTextures(1,&del_frame->textures[1]);
2505                         del_frame->textures[1]=0;
2506                 }
2507                 if (del_frame->textures[2]==0) {
2508                         glDeleteTextures(1,&del_frame->textures[2]);
2509                         del_frame->textures[2]=0;
2510                 }
2511
2512                 free(all_ogl_frames[i]);
2513         }
2514         all_ogl_frames.clear();
2515         free_ogl_frames.clear();
2516         ready_ogl_frames.clear();
2517         recycle_ref_ogl_frames.clear();
2518         ogl_forward_ref_frame_num=0;
2519         ogl_backward_ref_frame_num=0;
2520         ogl_forward_ref_frame=NULL;
2521         ogl_backward_ref_frame=NULL;
2522
2523         ogl_frame_mutex.Unlock();
2524         ((OsdOpenGL*)Osd::getInstance())->EndPainting();
2525
2526
2527         if (mpeg2codec_context_libav) {
2528                 avcodec_close(mpeg2codec_context_libav);
2529                 av_free(mpeg2codec_context_libav);
2530                 mpeg2codec_context_libav=NULL;
2531
2532         }
2533
2534
2535
2536         vpe_framebuf_mutex.Lock();
2537
2538         for (int i=0;i<all_frame_bufs.size();i++) {
2539                 VPE_FrameBuf* current=all_frame_bufs[i];
2540                 for (int x=0;x<4;x++) {
2541                         if (current->data[x]) {
2542                                 av_free(current->data[x]);
2543                         }
2544                 }
2545                 free(current);
2546         }
2547         all_frame_bufs.clear();
2548         free_frame_bufs.clear();
2549         locked_libav_frame_buf.clear();
2550         locked_uploading_frame_buf.clear();
2551
2552         vpe_framebuf_mutex.Unlock();
2553
2554
2555
2556         if (moco_shader) {
2557                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2558                 osd->BeginPainting(); // get OpenGl context
2559                 moco_shader->deinit();
2560                 delete moco_shader;
2561                 moco_shader=NULL;
2562                 osd->EndPainting();
2563         }
2564
2565
2566
2567
2568
2569         return 1;
2570 }
2571
2572
2573 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
2574 { //for libav
2575         VPE_FrameBuf* current=NULL;
2576         vpe_framebuf_mutex.Lock();
2577         if (free_frame_bufs.size()>0) {
2578                 current=free_frame_bufs.front();
2579                 free_frame_bufs.pop_front();
2580         } else if (all_frame_bufs.size()<6) {
2581                 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
2582                 memset(current,0,sizeof(VPE_FrameBuf));
2583         } else {
2584                 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
2585                 vpe_framebuf_mutex.Unlock();
2586                 return NULL; // We do not have a frame buffer
2587         }
2588         locked_libav_frame_buf.push_back(current);
2589         vpe_framebuf_mutex.Unlock();
2590         //check if we need reallocation
2591         for (int x=0;x<4;x++) {
2592                 if (current->size[x]!=size[x]) {
2593                         current->data[x]=av_realloc(current->data[x],size[x]);
2594                         current->size[x]=size[x];
2595                 }
2596         }
2597         framebuf_framenum++;
2598         current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
2599         return current;
2600
2601 }
2602
2603 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
2604 {
2605         // first find frame_buf memory
2606
2607         //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
2608         VPE_FrameBuf* current=buf;
2609         vpe_framebuf_mutex.Lock();
2610         if (current) locked_uploading_frame_buf.push_back(current); //locked
2611         vpe_framebuf_mutex.Unlock();
2612
2613 }
2614
2615
2616 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
2617 {
2618         // first find frame_buf memory
2619         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
2620         VPE_FrameBuf* current=buf;
2621         vpe_framebuf_mutex.Lock();
2622         if (current) {
2623                 locked_libav_frame_buf.remove(current); //unlocked
2624                 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
2625                 bool inlist=false;
2626                 while (itty!=locked_uploading_frame_buf.end()) {
2627                         if (*itty==current) {
2628                                 inlist=true;
2629                                 break;
2630                         }
2631                         itty++;
2632                 }
2633                 if (!inlist) {
2634                         free_frame_bufs.push_back(current);
2635                 }
2636         }
2637         vpe_framebuf_mutex.Unlock();
2638 }
2639
2640 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
2641 {
2642         // first find frame_buf memory
2643         VPE_FrameBuf* current=buf;
2644         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
2645         vpe_framebuf_mutex.Lock();
2646         if (current) {
2647                 locked_uploading_frame_buf.remove(current); //unlocked
2648                 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
2649                 bool inlist=false;
2650                 while (itty!=locked_libav_frame_buf.end()) {
2651                         if (*itty==current) {
2652                                 inlist=true;
2653                                 break;
2654                         }
2655                         itty++;
2656                 }
2657                 if (!inlist) {
2658                         free_frame_bufs.push_back(current);
2659                 }
2660         }
2661         vpe_framebuf_mutex.Unlock();
2662 }
2663
2664 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
2665 {
2666         dec_frame_libav_mutex.Lock();
2667         libavwidth=s->width;
2668         libavheight=s->height;
2669         libavpixfmt=s->pix_fmt;
2670         //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
2671
2672         dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
2673         dec_frame_libav_mutex.Unlock();
2674         threadSignal();
2675 }
2676
2677
2678
2679
2680
2681 #endif
2682
2683 int VideoVPEOGL::stop()
2684 {
2685   if (!initted) return 0;
2686   iframemode=false;
2687
2688 #ifdef VPE_OMX_SUPPORT
2689   //Check if libav mode
2690   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2691   decoding_backend=0;
2692
2693 #endif
2694
2695
2696
2697 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2698   return 1;
2699 }
2700
2701 int VideoVPEOGL::reset()
2702 {
2703   if (!initted) return 0;
2704
2705   iframemode=false;
2706   DeAllocateCodecsOMX();
2707 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2708   return 1;
2709 }
2710
2711 int VideoVPEOGL::pause()
2712 {
2713   if (!initted) return 0;
2714   Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2715   if (!paused) {
2716           paused=true;
2717           //maybe also change omx clock?
2718           pausetimecode=GetCurrentSystemTime();
2719
2720   }
2721   return 1;
2722 }
2723
2724 int VideoVPEOGL::unPause() // FIXME get rid - same as play!! Not here!
2725 {
2726   if (!initted) return 0;
2727   Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2728
2729   if (paused) {
2730           playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
2731           paused=false; // may be also change omx clock
2732   }
2733
2734   return 1;
2735 }
2736
2737 int VideoVPEOGL::fastForward()
2738 {
2739   if (!initted) return 0;
2740
2741 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2742   return 1;
2743 }
2744
2745 int VideoVPEOGL::unFastForward()
2746 {
2747   if (!initted) return 0;
2748
2749 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2750
2751  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2752   return 1;
2753 }
2754
2755 int VideoVPEOGL::attachFrameBuffer()
2756 {
2757   if (!initted) return 0;
2758
2759 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2760   return 1;
2761 }
2762
2763 int VideoVPEOGL::blank(void)
2764 {
2765 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2766 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2767   return 1;
2768 }
2769
2770 ULLONG VideoVPEOGL::getCurrentTimestamp()
2771 {
2772   if (iframemode) return 0;
2773   return lastreftimePTS;
2774 }
2775
2776 // to be removed
2777 /*
2778 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2779 {
2780   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2781   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2782 }
2783
2784 */
2785 #ifdef DEV
2786 int VideoVPEOGL::test()
2787 {
2788   return 0;
2789
2790 //  ULLONG stc = 0;
2791 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2792 /*
2793  // reset();
2794   return 1;
2795 */
2796 }
2797
2798 int VideoVPEOGL::test2()
2799 {
2800   return 0;
2801 }
2802 #endif
2803
2804
2805
2806 long long VideoVPEOGL::SetStartOffset(long long curreftime, bool *rsync)
2807 {
2808   *rsync=false;
2809   if (offsetnotset) {
2810     startoffset=curreftime;//offset is set for audio
2811     offsetnotset=false;
2812     offsetvideonotset=false;
2813   } else {
2814     if (offsetvideonotset) {
2815       offsetvideonotset=false;
2816       *rsync=true;
2817     } else {
2818       if ( (curreftime-lastrefvideotime)>10000000LL
2819         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2820         startoffset+=curreftime-lastrefvideotime;
2821         lastrefaudiotime+=curreftime-lastrefvideotime;
2822         //*rsync=true;
2823         offsetaudionotset=true;
2824
2825       }
2826     }
2827
2828   }
2829
2830   lastrefvideotime=curreftime;
2831
2832   return startoffset;
2833
2834 }
2835
2836 long long VideoVPEOGL::SetStartAudioOffset(long long curreftime, bool *rsync)
2837 {
2838   *rsync=false;
2839   if (offsetnotset) {
2840     startoffset=curreftime;
2841     offsetnotset=false;
2842     offsetaudionotset=false;
2843   }else {
2844     if (offsetaudionotset) {
2845       offsetaudionotset=false;
2846       *rsync=true;
2847     } else {
2848       if ( (curreftime-lastrefaudiotime)>10000000LL
2849         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2850         startoffset+=curreftime-lastrefaudiotime;
2851         lastrefvideotime+=curreftime-lastrefaudiotime;
2852         //*rsync=true;
2853         offsetvideonotset=true;
2854
2855       }
2856     }
2857
2858   }
2859   lastrefaudiotime=curreftime;
2860   return startoffset;
2861
2862 }
2863
2864 void VideoVPEOGL::ResetTimeOffsets() {
2865   offsetnotset=true; //called from demuxer
2866   offsetvideonotset=true;
2867   offsetaudionotset=true;
2868   startoffset=0;
2869   lastrefaudiotime=0;
2870   lastrefvideotime=0;
2871   lastreftimeOMX=0;
2872   lastreftimePTS=0;
2873 }
2874
2875 long long VideoVPEOGL::GetCurrentSystemTime()
2876 {
2877         struct timespec ts;
2878         clock_gettime(CLOCK_MONOTONIC, &ts);
2879         return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
2880 }
2881
2882 void VideoVPEOGL::WaitUntil(long long time)
2883 {
2884         struct timespec interval;
2885         interval.tv_sec=time/10000000LL;
2886         interval.tv_nsec=(time %10000000LL)*100LL;
2887         while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
2888 }
2889
2890 void VideoVPEOGL::FrameWaitforDisplay(long long pts)
2891 {
2892         //ok first calculate the absolute time
2893         long long target_time=pts-playbacktimeoffset;
2894         // we have to wait untile the next frame
2895         long long offset=Demuxer::getInstance()->getFrameRate();
2896         long long current_time=GetCurrentSystemTime();
2897         if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
2898         if (offset==0) offset=25;
2899         offset=10000000LL/offset;
2900         target_time+=offset;
2901         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,
2902                         target_time-current_time);
2903
2904         WaitUntil(target_time);
2905         Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
2906 }
2907
2908 void VideoVPEOGL::AdjustAudioPTS(long long pts)
2909 {
2910         long long newplaybacktimeoffset=pts-GetCurrentSystemTime();
2911 /*      if ((newplaybacktimeoffset-1000000LL)>playbacktimeoffset
2912             || (newplaybacktimeoffset+1000000LL)<playbacktimeoffset) {
2913                 Log::getInstance()->log("Video", Log::DEBUG, "Adjust Playbackoffsettime o: %lld n: %lld",
2914                                 playbacktimeoffset,newplaybacktimeoffset);*/
2915                 playbacktimeoffset=newplaybacktimeoffset;
2916
2917         //}
2918 }
2919
2920
2921 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2922 {
2923   mediapacket = mplist.front();
2924 }
2925
2926 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2927 {
2928   DeliverMediaPacket(mediapacket, buffer, samplepos);
2929   if (*samplepos == mediapacket.length) {
2930     *samplepos = 0;
2931     return 1;
2932   }
2933   else return 0;
2934 }
2935
2936 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2937                 const UCHAR* buffer,
2938                 UINT *samplepos)
2939 {
2940         if (packet.type == MPTYPE_VIDEO_H264)
2941         {
2942                 h264=true;
2943         }
2944         else
2945         {
2946                 h264=false;
2947         }
2948         switch (decoding_backend) {
2949         default: case 0: return 0; // no backend runnigng
2950 #ifdef VPE_OMX_SUPPORT
2951         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2952 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
2953         case VPE_DECODER_OMX_libav_TRANSCODE: return DeliverMediaPacketOMXTranscode(packet,buffer,samplepos);
2954 #endif
2955 #endif
2956 #ifdef VPE_LIBAV_SUPPORT
2957         case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2958 #endif
2959         }
2960 }
2961
2962 #ifdef VPE_OMX_SUPPORT
2963 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2964                 const UCHAR* buffer,
2965                 UINT *samplepos)
2966 {
2967
2968
2969         //Later add fail back code for libav
2970 /*      if (!videoon) {
2971                 *samplepos+=packet.length;
2972                 return packet.length;
2973         }*/
2974
2975
2976         if (!omx_running) return 0; // if we are not runnig do not do this
2977         if (paused) return 0; //Block if we pause
2978
2979         long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
2980         if (packet.synched &&
2981                         (packet.presentation_time<0 /*|| // preroll skip frames
2982                         (packet.presentation_time+5000000LL)<(current_media_time)*/)) { // we are late skip
2983                 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
2984                 *samplepos=packet.length;
2985                 return packet.length;
2986         }
2987
2988         OMX_ERRORTYPE error;
2989
2990         /*First Check, if we have an video sample*/
2991         if (iframemode) {
2992                 //samplepos=0;
2993                 MILLISLEEP(10);
2994                 return 0; //Not in iframe mode!
2995         }
2996
2997         UINT headerstrip=0;
2998         if (packet.disconti) {
2999                 firstsynched=false;
3000                 if (cur_input_buf_omx) {
3001                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3002                         if (error!=OMX_ErrorNone){
3003                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3004                         }
3005                         FrameWaitforDisplay(lastreftimeOMX);
3006                         cur_input_buf_omx=NULL;
3007                 }
3008         }
3009
3010         /*Inspect PES-Header */
3011
3012 //      OMX_STATETYPE temp_state;
3013 //      OMX_GetState(omx_vid_dec,&temp_state);
3014
3015         if (*samplepos==0) {//stripheader
3016                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3017                 if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
3018                                 buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
3019                 *samplepos+=headerstrip;
3020                 if ( packet.synched ) {
3021                         if (cur_input_buf_omx) {
3022                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3023                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3024                                 if (error!=OMX_ErrorNone){
3025                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3026                                 }
3027                                 cur_input_buf_omx=NULL;//write out old data
3028                                 FrameWaitforDisplay(lastreftimeOMX);
3029
3030
3031                         }
3032                         firstsynched=true;
3033                 } else {
3034                         if (!firstsynched) {//
3035                                 *samplepos=packet.length;//if we have not processed at least one
3036                                 return packet.length;//synched packet ignore it!
3037                         }
3038                 }
3039         }
3040
3041         if (!cur_input_buf_omx) {
3042                 input_bufs_omx_mutex.Lock();
3043                 if (input_bufs_omx_free.size()==0) {
3044                         input_bufs_omx_mutex.Unlock();
3045                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3046                         return 0; // we do not have a free media sample
3047
3048                 }
3049                 cur_input_buf_omx=input_bufs_omx_free.front();
3050                 cur_input_buf_omx->nFilledLen=0;
3051                 cur_input_buf_omx->nOffset=0;
3052                 cur_input_buf_omx->nTimeStamp=0;
3053                 input_bufs_omx_free.pop_front();
3054                 input_bufs_omx_mutex.Unlock();
3055         }
3056
3057
3058
3059
3060         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3061                 if (packet.synched) {
3062                         Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
3063
3064                         //lastreftimePTS=packet.pts;
3065                    if (omx_first_frame) { // TODO time
3066                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3067                            Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
3068                            omx_first_frame=false;
3069                    } else {
3070                            //cur_input_buf_omx->nFlags=0;
3071                            cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3072                    }
3073                    lastreftimeOMX=packet.presentation_time;
3074                    Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
3075                    lastreftimePTS=packet.pts;
3076                    cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
3077                 }
3078                 else
3079                 {
3080                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3081                         cur_input_buf_omx->nTimeStamp=0;
3082
3083
3084                         //  ms->SetSyncPoint(TRUE);
3085                 }
3086                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3087
3088
3089
3090         }
3091         unsigned int haveToCopy=packet.length-*samplepos;
3092
3093         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3094                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3095                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3096                 haveToCopy-=cancopy;
3097                 cur_input_buf_omx->nFilledLen+=cancopy;
3098                 *samplepos+=cancopy;
3099                 // push old buffer out
3100
3101                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3102                 if (error!=OMX_ErrorNone){
3103                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3104                 }
3105                 // get5 new buffer
3106                 input_bufs_omx_mutex.Lock();
3107                 if (input_bufs_omx_free.size()==0) {
3108                         input_bufs_omx_mutex.Unlock();
3109                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3110                         return *samplepos; // we do not have a free media sample
3111                 }
3112                 cur_input_buf_omx=input_bufs_omx_free.front();
3113                 cur_input_buf_omx->nFilledLen=0;
3114                 cur_input_buf_omx->nOffset=0;
3115                 cur_input_buf_omx->nTimeStamp=0;
3116                 input_bufs_omx_free.pop_front();
3117                 input_bufs_omx_mutex.Unlock();
3118
3119                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3120
3121         }
3122         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3123                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
3124         cur_input_buf_omx->nFilledLen+=haveToCopy;
3125
3126
3127
3128         *samplepos+=haveToCopy;
3129
3130         return *samplepos;
3131
3132 }
3133
3134 #endif
3135
3136 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
3137
3138
3139
3140 int VideoVPEOGL::DecodePacketOMXTranscode()
3141 {
3142         unsigned int haveToCopy=incom_packet_libav.size;
3143         if (incom_packet_libav.size==0) return 1; // we are already empty
3144
3145
3146         while (haveToCopy>0) {
3147                 int dec_bytes=0;
3148                 int frame_ready=0;
3149
3150         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
3151
3152 #ifdef BENCHMARK_FPS
3153             int cur_time=getTimeMS();
3154 #endif
3155                 dec_bytes=avcodec_decode_video2(transcodecodec_context_libav, &transcode_frame_libav,
3156                                 &frame_ready, &incom_packet_libav);
3157 #ifdef BENCHMARK_FPS
3158                 time_in_decoder+=getTimeMS()-cur_time;
3159                 if (frame_ready) num_frames++;
3160                 if ((num_frames%100)==0) {
3161                         float fps=1000./(float)(time_in_decoder);
3162                         fps*=((float)num_frames);
3163                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
3164                 }
3165 #endif
3166                 if (dec_bytes<0) {
3167                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
3168                         return 0;
3169                 }
3170                 haveToCopy-=dec_bytes;
3171                 if (frame_ready) {
3172                         struct transcode_pix_fmt *transcode=(struct transcode_pix_fmt *)transcode_frame_libav.data[0];
3173                         //if (!benchmark) fwrite(transcode->packet.data,transcode->packet.size,1,output_file);
3174
3175
3176                     //add omx magic, this should be an omx packet
3177                         OMX_BUFFERHEADERTYPE* omx_packet=(OMX_BUFFERHEADERTYPE*)transcode_frame_libav.base[0];
3178                         omx_packet->nFilledLen=transcode->packet.size;
3179
3180                         input_bufs_omx_mutex.Lock();
3181                         input_bufs_omx_in_libav.remove(omx_packet); // say that it  is passed down to the decoder
3182                         input_bufs_omx_mutex.Unlock();
3183
3184                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,omx_packet);
3185                         if (error!=OMX_ErrorNone){
3186                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3187                         }
3188
3189
3190
3191                 }
3192
3193         }
3194         incom_packet_libav.size=0;
3195         return 1;
3196
3197 }
3198
3199
3200 UINT VideoVPEOGL::DeliverMediaPacketOMXTranscode(MediaPacket packet,
3201                 const UCHAR* buffer,
3202                 UINT *samplepos)
3203 {
3204         //Later add fail back code for libav
3205         /*if (!videoon) {
3206                 *samplepos+=packet.length;
3207                 return packet.length;
3208         }*/
3209
3210         if (!omx_running) return 0; // if we are not runnig do not do this
3211
3212
3213         if (iframemode) {
3214                 //samplepos=0;
3215                 MILLISLEEP(10);
3216                 return 0; //Not in iframe mode!
3217         }
3218
3219         UINT headerstrip=0;
3220         if (packet.disconti) {
3221                 firstsynched=false;
3222                 if (!DecodePacketOMXTranscode()) return 0;
3223         }
3224
3225         /*Inspect PES-Header */
3226         if (*samplepos==0) {//stripheader
3227                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3228                 *samplepos+=headerstrip;
3229                 if ( packet.synched ) {
3230
3231                         if (!DecodePacketOMXTranscode()) return 0; // WriteOut old Data
3232
3233
3234                         incom_packet_libav.pts=packet.pts/3600;
3235                         incom_packet_libav.dts=packet.dts/3600;
3236                 //      reftime1=packet.presentation_time;
3237                 //      reftime2=reftime1+1;
3238                         firstsynched=true;
3239                 } else {
3240                         incom_packet_libav.pts=0;
3241                         incom_packet_libav.dts=0;
3242                         if (!firstsynched) {//
3243                                 *samplepos=packet.length;//if we have not processed at least one
3244                                 return packet.length;//synched packet ignore it!
3245                         }
3246                 }
3247         }
3248
3249
3250
3251
3252
3253
3254         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3255                 /*if (packet.disconti) {
3256                         ms->SetDiscontinuity(TRUE);
3257                 } else {
3258                         ms->SetDiscontinuity(FALSE);
3259                 }*
3260                 //if (packet.synched) {
3261
3262                         //lastreftimePTS=packet.pts;
3263                    if (omx_first_frame) { // TODO time
3264                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3265                            omx_first_frame=false;
3266                    } else
3267
3268                 //}
3269                 //else
3270                 //{
3271                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3272
3273
3274                         //  ms->SetSyncPoint(TRUE);
3275                 //}
3276
3277         }*/
3278         unsigned int haveToCopy=packet.length-*samplepos;
3279
3280         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3281                 // if the buffer is to small reallocate
3282                 incom_packet_libav_size+=haveToCopy;
3283                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3284                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3285         }
3286         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3287         incom_packet_libav.size+=haveToCopy;
3288
3289         *samplepos+=haveToCopy;
3290
3291
3292         return *samplepos;
3293
3294
3295 }
3296
3297 #endif
3298
3299
3300 #ifdef VPE_LIBAV_SUPPORT
3301 int VideoVPEOGL::DecodePacketlibav()
3302 {
3303         unsigned int haveToCopy=incom_packet_libav.size;
3304         if (incom_packet_libav.size==0) return 1; // we are already empty
3305         while (haveToCopy>0) {
3306                 int dec_bytes=0;
3307                 int frame_ready=0;
3308
3309         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
3310
3311 #ifdef BENCHMARK_FPS
3312             int cur_time=getTimeMS();
3313 #endif
3314                 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
3315                                 &frame_ready, &incom_packet_libav);
3316 #ifdef BENCHMARK_FPS
3317                 time_in_decoder+=getTimeMS()-cur_time;
3318                 if (frame_ready) num_frames++;
3319                 if ((num_frames%100)==0) {
3320                         float fps=1000./(float)(time_in_decoder);
3321                         fps*=((float)num_frames);
3322                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
3323                 }
3324 #endif
3325                 if (dec_bytes<0) {
3326                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
3327                         return 0;
3328                 }
3329                 haveToCopy-=dec_bytes;
3330                 if (frame_ready) {
3331                 //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
3332
3333                         lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
3334                         dec_frame_libav_mutex.Lock();
3335                         libavwidth=mpeg2codec_context_libav->width;
3336                         libavheight=mpeg2codec_context_libav->height;
3337                         libavpixfmt=mpeg2codec_context_libav->pix_fmt;
3338                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
3339                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
3340                         //              ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
3341
3342
3343                         dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
3344                         dec_frame_libav_decoding=NULL;
3345                         if (dec_frame_libav_free.size()>0) {
3346                                 dec_frame_libav_decoding=dec_frame_libav_free.front();
3347                                 dec_frame_libav_free.pop_front();
3348                                 dec_frame_libav_mutex.Unlock();
3349                                 threadSignal();
3350                                 libav_hastime=false;
3351                         } else {
3352                                 libav_hastime=false;
3353                                 dec_frame_libav_mutex.Unlock();
3354                                 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
3355                                 threadSignal();
3356                                 // No free buffers
3357                                 return 0;
3358                         }
3359
3360
3361                 }
3362
3363         }
3364         incom_packet_libav.size=0;
3365         return 1;
3366
3367 }
3368
3369
3370 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
3371                 const UCHAR* buffer,
3372                 UINT *samplepos)
3373 {
3374         //Later add fail back code for libav
3375         /*if (!videoon) {
3376                 *samplepos+=packet.length;
3377                 return packet.length;
3378         }*/
3379
3380         if (!libav_running) return 0; // if we are not runnig do not do this
3381
3382
3383         if (iframemode) {
3384                 //samplepos=0;
3385                 MILLISLEEP(10);
3386                 return 0; //Not in iframe mode!
3387         }
3388
3389         UINT headerstrip=0;
3390         if (packet.disconti) {
3391                 firstsynched=false;
3392                 if (!DecodePacketlibav()) return 0;
3393         }
3394
3395         /*Inspect PES-Header */
3396         if (!dec_frame_libav_decoding) {
3397                 dec_frame_libav_mutex.Lock();
3398                 if (dec_frame_libav_free.size()>0) {
3399                         dec_frame_libav_decoding=dec_frame_libav_free.front();
3400                         dec_frame_libav_free.pop_front();
3401                         dec_frame_libav_mutex.Unlock();
3402                 } else {
3403                         Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
3404                         dec_frame_libav_mutex.Unlock();
3405                         // No free buffers
3406                         return 0;
3407                 }
3408         }
3409
3410
3411
3412         if (*samplepos==0) {//stripheader
3413                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3414                 *samplepos+=headerstrip;
3415                 if ( packet.synched ) {
3416
3417                         if (!DecodePacketlibav()) return 0; // WriteOut old Data
3418
3419                         libav_time=packet.presentation_time;
3420                         libav_hastime=true;
3421                 //      reftime1=packet.presentation_time;
3422                 //      reftime2=reftime1+1;
3423                         firstsynched=true;
3424                 } else {
3425                         if (!firstsynched) {//
3426                                 *samplepos=packet.length;//if we have not processed at least one
3427                                 return packet.length;//synched packet ignore it!
3428                         }
3429                 }
3430         }
3431
3432
3433
3434
3435
3436
3437         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3438                 /*if (packet.disconti) {
3439                         ms->SetDiscontinuity(TRUE);
3440                 } else {
3441                         ms->SetDiscontinuity(FALSE);
3442                 }*
3443                 //if (packet.synched) {
3444
3445                         //lastreftimePTS=packet.pts;
3446                    if (omx_first_frame) { // TODO time
3447                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3448                            omx_first_frame=false;
3449                    } else
3450
3451                 //}
3452                 //else
3453                 //{
3454                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3455
3456
3457                         //  ms->SetSyncPoint(TRUE);
3458                 //}
3459
3460         }*/
3461         unsigned int haveToCopy=packet.length-*samplepos;
3462
3463         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3464                 // if the buffer is to small reallocate
3465                 incom_packet_libav_size+=haveToCopy;
3466                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3467                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3468         }
3469         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3470         incom_packet_libav.size+=haveToCopy;
3471
3472         *samplepos+=haveToCopy;
3473
3474
3475         return *samplepos;
3476
3477
3478 }
3479
3480 #endif
3481
3482
3483 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length) {
3484         if (!omx_running) return false;
3485         if (!iframemode)
3486                 EnterIframePlayback();
3487
3488         int haveToCopy = length;
3489
3490         if (!cur_input_buf_omx) {
3491                 input_bufs_omx_mutex.Lock();
3492                 if (input_bufs_omx_free.size() == 0) {
3493                         input_bufs_omx_mutex.Unlock();
3494                         Log::getInstance()->log("Video", Log::DEBUG,
3495                                         "Deliver MediaPacket no free sample");
3496                         return false; // we do not have a free media sample
3497
3498                 }
3499                 cur_input_buf_omx = input_bufs_omx_free.front();
3500                 cur_input_buf_omx->nFilledLen = 0;
3501                 cur_input_buf_omx->nOffset = 0;
3502                 cur_input_buf_omx->nTimeStamp = 0;
3503                 input_bufs_omx_free.pop_front();
3504                 input_bufs_omx_mutex.Unlock();
3505         }
3506
3507         int read_pos = 0;
3508         unsigned int pattern, packet_length;
3509         unsigned int headerstrip = 0;
3510         bool first = true;
3511         if (length < 4){
3512                 return false;
3513         }
3514         //Now we strip the pes header
3515         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3516         while (read_pos + 7 <= length) {
3517                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3518                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3519                         read_pos++;
3520                         continue;
3521                 } else {
3522                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3523                         packet_length = ((buffer[read_pos + 4] << 8)
3524                                         | (buffer[read_pos + 5])) + 6;
3525                         if (read_pos + packet_length > length)
3526                                 read_pos = length;
3527                         else {
3528                                 if ((headerstrip < packet_length)
3529                                                 && (cur_input_buf_omx->nFilledLen + packet_length
3530                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3531                                         if (first) {
3532                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3533
3534                                         } else {
3535                                                 cur_input_buf_omx->nFlags
3536                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3537
3538                                         }
3539                                         cur_input_buf_omx->nTimeStamp = 0;
3540                                         OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
3541                                                         cur_input_buf_omx);
3542                                         if (error != OMX_ErrorNone) {
3543                                                 Log::getInstance()->log("Video", Log::DEBUG,
3544                                                                 "OMX_EmptyThisBuffer failed %x", error);
3545                                         }
3546                                         cur_input_buf_omx = NULL;
3547
3548                                         if (!cur_input_buf_omx) {
3549                                                 int count = 0;
3550                                                 while (count < 100 && omx_running && iframemode) {
3551                                                         count++;
3552
3553                                                         input_bufs_omx_mutex.Lock();
3554                                                         if (input_bufs_omx_free.size() == 0) {
3555                                                                 input_bufs_omx_mutex.Unlock();
3556                                                                 Log::getInstance()->log("Video", Log::DEBUG,
3557                                                                                 "Ifrane no free sample");
3558                                                                 MILLISLEEP(5);
3559                                                                 if (!omx_running) return false;
3560                                                                 continue;
3561                                                         }
3562                                                         cur_input_buf_omx = input_bufs_omx_free.front();
3563                                                         cur_input_buf_omx->nFilledLen = 0;
3564                                                         cur_input_buf_omx->nOffset = 0;
3565                                                         cur_input_buf_omx->nTimeStamp = 0;
3566                                                         input_bufs_omx_free.pop_front();
3567                                                         input_bufs_omx_mutex.Unlock();
3568                                                         break;
3569                                                 }
3570                                                 if (!cur_input_buf_omx)
3571                                                         return false;
3572                                         }
3573
3574                                 }
3575                                 if (packet_length > headerstrip) {
3576                                         memcpy(
3577                                                         cur_input_buf_omx->pBuffer
3578                                                                         + cur_input_buf_omx->nFilledLen,
3579                                                         buffer + read_pos + headerstrip,
3580                                                         packet_length - headerstrip);
3581                                         cur_input_buf_omx->nFilledLen += packet_length
3582                                                         - headerstrip;
3583                                 }
3584                                 read_pos += packet_length;
3585
3586                                 pattern = (buffer[read_pos] << 16)
3587                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3588                         }
3589                 }
3590         }
3591
3592         if (first) {
3593                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3594
3595         } else {
3596                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3597
3598         }
3599         cur_input_buf_omx->nTimeStamp = 0;
3600         OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
3601         if (error != OMX_ErrorNone) {
3602                 Log::getInstance()->log("Video", Log::DEBUG,
3603                                 "OMX_EmptyThisBuffer failed %x", error);
3604         }
3605         cur_input_buf_omx = NULL;
3606
3607
3608         MILLISLEEP(40); //Block a bit
3609         return true;
3610 }
3611
3612 int VideoVPEOGL::EnterIframePlayback()
3613 {
3614         clock_mutex.Lock();
3615         if (cur_input_buf_omx) {
3616                 OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
3617                                 cur_input_buf_omx);
3618                 if (error != OMX_ErrorNone) {
3619                         Log::getInstance()->log("Video", Log::DEBUG,
3620                                         "OMX_EmptyThisBuffer failed %x", error);
3621                 }
3622
3623                 cur_input_buf_omx = NULL;
3624         }
3625         clock_mutex.Unlock();
3626         iframemode=true;
3627
3628         return 1;
3629 }
3630