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