]> git.vomp.tv Git - vompclient-marten.git/blob - videovpeogl.cc
Fix compiling again
[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=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 #endif
56
57   ogl_forward_ref_frame_num=0;
58   ogl_backward_ref_frame_num=0;
59   ogl_forward_ref_frame=NULL;
60   ogl_backward_ref_frame=NULL;
61
62 #ifdef BENCHMARK_FPS
63         time_in_decoder=0;
64     num_frames=0;
65 #endif
66
67 }
68
69 VideoVPEOGL::~VideoVPEOGL()
70 {
71   instance = NULL;
72 }
73
74 int VideoVPEOGL::init(UCHAR tformat)
75 {
76   if (initted) return 0;
77   initted = 1;
78
79 //  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
80
81   if (!setFormat(tformat))           { shutdown(); return 0; }
82   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
83   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
84   if (!setMode(NORMAL))              { shutdown(); return 0; }
85   if (!setSource())                  { shutdown(); return 0; }
86   if (!attachFrameBuffer())          { shutdown(); return 0; }
87
88   setTVsize(ASPECT4X3);
89
90 /*  if (format == PAL) setLetterboxBorder("38");
91   else setLetterboxBorder("31");*/
92
93   /* new stulibav */
94
95
96
97
98   //stop();
99
100
101
102   return 1;
103 }
104
105 int VideoVPEOGL::initUsingOSDObjects()
106 {
107         EGLDisplay i_egl_display;
108         EGLSurface i_egl_surface;
109         EGLContext i_egl_context;
110         EGLConfig i_egl_config;
111         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
112         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
113         const EGLint attr_context[]={
114                         EGL_CONTEXT_CLIENT_VERSION,2,
115                 EGL_NONE
116         };
117
118         egl_display=i_egl_display;
119         egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
120         if (egl_context==EGL_NO_CONTEXT) {
121                  Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
122                  return 0;
123         }
124         // We create a dummy surface here, in order to allow two contexts
125         const EGLint attr_pbuffer[]={
126                         EGL_WIDTH, 1, EGL_HEIGHT,1,
127                     EGL_NONE
128         };
129         egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
130         if (egl_surface==EGL_NO_SURFACE) {
131                  Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
132                  return 0;
133         }
134
135
136
137
138         //egl_surface=i_egl_surface;
139         //egl_context=i_egl_context;
140
141
142 #ifdef VPE_OMX_SUPPORT
143 // we are called before the audio
144         OMX_ERRORTYPE error;
145         error=OMX_Init();
146         if (error!=OMX_ErrorNone) {
147                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
148                 return 0;
149         }
150
151         //our callbacks move to play?
152
153 #endif
154
155 #ifdef VPE_LIBAV_SUPPORT
156
157         av_register_all();
158         if (decoding_mode==VPE_NO_XVMC) {
159                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
160         } else {
161                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
162         }
163         if (mpeg2codec_libav==NULL) {
164                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
165                 return 0;
166         }
167
168 #endif
169         threadStart();
170         return 1;
171 }
172
173
174 #ifdef VPE_OMX_SUPPORT
175
176 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
177            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
178            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
179
180         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
181
182         struct VPE_OMX_EVENT  new_event;
183         new_event.handle=handle;
184         new_event.appdata=appdata;
185         new_event.event_type=event_type;
186         new_event.data1=data1;
187         new_event.data2=data2;
188         new_event.event_data=event_data;
189
190         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
191         video->AddOmxEvent(new_event);
192
193 /*      switch (event_type) {
194         case OMX_EventCmdComplete: {
195
196         } break;
197         }*/
198
199         return OMX_ErrorNone;
200
201 }
202
203 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
204 {
205         omx_event_mutex.Lock();
206     omx_events.push_back(new_event);
207         omx_event_mutex.Unlock();
208 }
209
210
211 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
212
213         Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
214         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
215         video->ReturnEmptyOMXBuffer(buffer);
216         return OMX_ErrorNone;
217
218 }
219
220 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
221         input_bufs_omx_mutex.Lock();
222         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
223         input_bufs_omx_free.push_back(buffer);
224         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
225         input_bufs_omx_mutex.Unlock();
226 }
227
228  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
229          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
230         return OMX_ErrorNone;
231 }
232
233 #endif
234
235 int VideoVPEOGL::shutdown()
236 {
237   if (!initted) return 0;
238   initted = 0;
239   threadCancel();
240
241   decoding_backend=0;
242 #ifdef VPE_OMX_SUPPORT
243   DeAllocateCodecsOMX();
244   OMX_Deinit();
245 #endif
246 #ifdef VPE_LIBAV_SUPPORT
247   DeAllocateCodecsLibav();
248 #endif
249   eglDestroyContext(egl_display,egl_context);
250 //  close(fdVideo);
251   return 1;
252 }
253
254 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
255 {
256         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
257         // Y
258         glGenTextures(1, &outframe->textures[0]);
259         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
260         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
261                                 GL_UNSIGNED_BYTE, NULL);
262         // U
263         glGenTextures(1, &outframe->textures[1]);
264         glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
265         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
266                                 GL_UNSIGNED_BYTE, NULL);
267         // V
268         glGenTextures(1, &outframe->textures[2]);
269         glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
270         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
271                         GL_UNSIGNED_BYTE, NULL);
272         outframe->height=height;
273         outframe->width=width;
274         outframe->stride=stride;
275         outframe->type=1;
276         return 1;
277 }
278
279 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height)
280 {
281         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
282         // Y
283         glGenTextures(1, &outframe->textures[0]);
284         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
285         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
286                                 GL_UNSIGNED_BYTE, NULL);
287         outframe->textures[1]=outframe->textures[2]=0; // no handles here
288
289
290
291
292         outframe->type=2;
293         outframe->height=height;
294         outframe->width=width;
295         outframe->stride=width; // does not make any sense otherwiese
296         return 1;
297 }
298
299
300 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
301         VPEOGLFrame *return_obj=NULL;
302         ogl_frame_mutex.Lock();
303         if (ready_ogl_frames.size()>0) {
304                 return_obj=ready_ogl_frames.front();
305                 ready_ogl_frames.pop_front();
306                 ogl_frame_outside=true;
307         }
308         ogl_frame_mutex.Unlock();
309         return return_obj;
310 }
311
312 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
313 {
314         ogl_frame_mutex.Lock();
315         if (frame) {
316                 ogl_frame_outside=false;
317                 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
318                 if (frame->pict_num==ogl_forward_ref_frame_num ||
319                                 frame->pict_num==ogl_backward_ref_frame_num ) {
320                         recycle_ref_ogl_frames.push_back(frame);
321                 } else {
322                         free_ogl_frames.push_back(frame);
323                 }
324         }
325         ogl_frame_mutex.Unlock();
326 }
327
328 void VideoVPEOGL::recycleOGLRefFrames()
329 {
330         // This function recycles frames formerly used as reference frame
331         ogl_frame_mutex.Lock();
332         list<VPEOGLFrame*> keep;
333         list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
334         while (itty!=recycle_ref_ogl_frames.end()) {
335                 Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
336                 if ((*itty)->pict_num==ogl_forward_ref_frame_num
337                                 || (*itty)->pict_num==ogl_backward_ref_frame_num)
338                 {
339                         // ok we have to keep this
340                         keep.push_back(*itty);
341                 } else {
342                         free_ogl_frames.push_back(*itty);
343                 }
344                 itty++;
345         }
346         recycle_ref_ogl_frames.clear();
347         recycle_ref_ogl_frames=keep;
348
349         ogl_frame_mutex.Unlock();
350
351
352 }
353
354 void VideoVPEOGL::threadMethod()
355 {
356         if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
357                 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
358                 return;
359         }
360         while (1) {
361                 bool sleep=true;
362                 bool upload=false;
363                 bool view=false;
364 #ifdef VPE_LIBAV_SUPPORT
365                 dec_frame_libav_mutex.Lock();
366
367
368                 if (dec_frame_libav_upload_and_view_pending.size()>0  ) {
369                         bool blocked=false;
370                         dec_frame_libav_uploading=dec_frame_libav_upload_and_view_pending.front();
371                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
372                 //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",
373                 //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front()->base[0])->pict_num);
374                         list<AVFrame*>::iterator itty=dec_frame_libav_upload_only_pending.begin();
375                         while (itty!=dec_frame_libav_upload_only_pending.end())
376                         {
377                                 if (*itty==dec_frame_libav_uploading) {
378                                         blocked=true;
379                                         break;
380                                 }
381                                 itty++;
382                         }
383                         if (!blocked) { // this assures that no frame without an upload is pushed out to rendering
384                                 dec_frame_libav_upload_and_view_pending.pop_front();
385                                 upload=view=true;
386                                 if (decoding_mode!=VPE_NO_XVMC) upload=false;
387                         } else {
388                                 dec_frame_libav_uploading=NULL;
389                         }
390                 }
391
392                 if (!view && dec_frame_libav_upload_only_pending.size()>0) {
393
394                         dec_frame_libav_uploading=dec_frame_libav_upload_only_pending.front();
395                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
396                         dec_frame_libav_upload_only_pending.pop_front();
397                         view=false;
398                         upload=true;
399                 }
400
401
402                 if (dec_frame_libav_upload_and_view_pending.size()>0
403                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
404
405                 dec_frame_libav_mutex.Unlock();
406
407
408                 if (dec_frame_libav_uploading) {
409
410                         if (upload) {
411                                 int width,height,pixfmt;
412                                 //First get a free ogl image
413                                 VPEOGLFrame* out_frame=NULL;
414                                 while (!out_frame) {
415                                         ogl_frame_mutex.Lock();
416                                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
417                                         //                                                              recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
418                                         if (all_ogl_frames.size()==0) {
419                                                 ogl_frame_mutex.Unlock(); break;
420                                         }
421
422                                         if (free_ogl_frames.size()>0) {
423                                                 width=libavwidth;
424                                                 height=libavheight;
425                                                 pixfmt=libavpixfmt;
426                                                 out_frame=free_ogl_frames.front();
427                                                 free_ogl_frames.pop_front();
428                                         } else MILLISLEEP(2);
429                                         ogl_frame_mutex.Unlock();
430                                 }
431                                 bool failed=false;
432                                 if (out_frame) {
433                                         if (out_frame->textures[0]==0 || out_frame->width!=width ||
434                                                         out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
435                                                 if (out_frame->textures[0]!=0) {
436                                                         glDeleteTextures(1,&out_frame->textures[0]);
437                                                         out_frame->textures[0]=0;
438                                                 }
439                                                 if (out_frame->textures[1]!=0) {
440                                                         glDeleteTextures(1,&out_frame->textures[1]);
441                                                         out_frame->textures[1]=0;
442                                                 }
443                                                 if (out_frame->textures[2]!=0) {
444                                                         glDeleteTextures(1,&out_frame->textures[2]);
445                                                         out_frame->textures[2]=0;
446                                                 }
447
448                                                 if (decoding_mode==VPE_NO_XVMC) {
449                                                         if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
450                                                 } else {
451                                                         if (!AllocateYUV444OglTexture(out_frame,width,height)) failed=true; //We use a YUV 444 texture in this case
452                                                         // the shaders are easier to implement
453                                                 }
454                                         }
455                                         ((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref=out_frame;
456                                         if (!failed) {
457                                                 //up to now only YUV data, this is for reference only, since the pi is too slow.
458                                                 if (decoding_mode==VPE_NO_XVMC) {
459                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
460                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
461                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
462                                                                         out_frame->stride,out_frame->height,
463                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
464                                                                         dec_frame_libav_uploading->data[0]);
465
466                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
467                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
468                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
469                                                                         out_frame->stride>>1,out_frame->height>>1,
470                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
471                                                                         dec_frame_libav_uploading->data[1]);
472
473                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
474                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
475                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
476                                                                         out_frame->stride>>1,out_frame->height>>1,
477                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
478                                                                         dec_frame_libav_uploading->data[2]);
479                                                 } else {
480                                                         //XVMC case
481                                                         xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
482                                                         if (moco_shader && pix_fmt) {
483
484                                                                 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
485                                                                                 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
486                                                                 Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
487                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
488
489                                                                 if (((int)pix_fmt->p_future_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_future_surface))
490                                                                 {
491                                                                         //Now determine the frame, that fits
492                                                                         ogl_frame_mutex.Lock();
493                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
494                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
495                                                                                 {
496                                                                                         ogl_backward_ref_frame=ogl_forward_ref_frame; //mpeg life time axioms
497                                                                                         ogl_backward_ref_frame_num=ogl_forward_ref_frame_num;
498                                                                                         ogl_forward_ref_frame=all_ogl_frames[i];
499                                                                                         ogl_forward_ref_frame_num=(int)pix_fmt->p_future_surface;
500                                                                                         break;
501                                                                                 }
502                                                                         }
503
504                                                                         ogl_frame_mutex.Unlock();
505                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
506                                                                 }
507
508
509                                                                 if (((int)pix_fmt->p_past_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_past_surface))
510                                                                 {
511                                                                         //Now determine the frame, that fits
512                                                                         ogl_frame_mutex.Lock();
513                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
514                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
515                                                                                 {
516                                                                                         ogl_backward_ref_frame=all_ogl_frames[i];
517                                                                                         ogl_backward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
518                                                                                         break;
519                                                                                 }
520                                                                         }
521
522                                                                         ogl_frame_mutex.Unlock();
523                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
524
525                                                                 }
526
527                                                                 if (decoding_mode==VPE_XVMC_MOCOMP)
528                                                                 {
529                                                                         //DCT Blocks upload
530
531                                                                 } else {
532                                                                         //DCT Blocks upload
533                                                                 }
534                                                                 out_frame->pict_num=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num;
535
536                                                                 moco_shader->doMoCo(out_frame,ogl_forward_ref_frame,ogl_backward_ref_frame);
537
538                                                                 // Excute motion compensation
539                                                         }
540                                                 }
541
542
543
544                                         }
545                                 }
546
547                         }
548
549
550
551                         if (view) {
552
553                                 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
554                                 VPEOGLFrame* out_frame=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref;
555                                 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
556                                 Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
557                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
558
559                                 releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
560                                 ogl_frame_mutex.Lock();
561                                 ready_ogl_frames.push_back(out_frame);
562                                 ogl_frame_mutex.Unlock();
563                                 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
564
565                                 dec_frame_libav_mutex.Lock();
566                                 dec_frame_libav_free.push_back(dec_frame_libav_uploading);
567                                 dec_frame_libav_mutex.Unlock();
568                         }
569
570
571                         dec_frame_libav_mutex.Lock();
572                         dec_frame_libav_uploading=NULL;
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
581                 }
582 #endif
583
584                 if (sleep) {
585                         threadWaitForSignal();
586                         Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
587                 }
588                 threadCheckExit();
589         }
590
591 }
592
593 void VideoVPEOGL::threadPostStopCleanup()
594 {
595         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
596 #ifdef VPE_LIBAV_SUPPORT
597         dec_frame_libav_uploading=NULL;
598 #endif
599 }
600
601
602
603
604 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
605 {
606 /*  tvsize = ttvsize;
607
608   // Override the aspect ratio usage, temporarily use to set the video chip mode
609   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
610   close(fdVideo);
611   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
612   if (!setSource())                  { shutdown(); return 0; }
613   if (!attachFramebuffer())          { shutdown(); return 0; }
614
615   // Reopening the fd causes the scart aspect line to go back to 4:3
616   // Set this again to the same as the tv screen size
617   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
618
619   // mode == LETTERBOX is invalid if the TV is widescreen
620   if (tvsize == ASPECT16X9) setMode(NORMAL);
621 */
622   return 1;
623 }
624
625 int VideoVPEOGL::setDefaultAspect()
626 {
627   return setAspectRatio(tvsize);
628 }
629
630
631
632 int VideoVPEOGL::setFormat(UCHAR tformat)
633 {
634   if (!initted) return 0;
635   if ((tformat != PAL) && (tformat != NTSC)) return 0;
636   format = tformat;
637
638 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
639
640   if (format == NTSC)
641   {
642     screenWidth = 720;
643     screenHeight = 480;
644   }
645   if (format == PAL)
646   {
647     screenWidth = 720;
648     screenHeight = 576;
649   }
650
651   return 1;
652 }
653
654 int VideoVPEOGL::setConnection(UCHAR tconnection)
655 {
656   if (!initted) return 0;
657   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
658   connection = tconnection;
659
660 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
661   return 1;
662 }
663
664 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
665 {
666   if (!initted) return 0;
667   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
668   aspectRatio = taspectRatio;
669
670   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
671
672 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
673   return 1;
674 }
675
676 int VideoVPEOGL::setMode(UCHAR tmode)
677 {
678   if (!initted) return 0;
679
680   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
681
682   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
683       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
684   mode = tmode;
685
686 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
687   return 1;
688 }
689
690 int VideoVPEOGL::signalOff()
691 {
692 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
693   return 1;
694 }
695
696 int VideoVPEOGL::signalOn()
697 {
698 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
699   return 1;
700 }
701
702 int VideoVPEOGL::setSource()
703 {
704   if (!initted) return 0;
705
706   // What does this do...
707 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
708   return 1;
709 }
710
711 int VideoVPEOGL::setPosition(int x, int y)
712 {
713   if (!initted) return 0;
714
715 //  vid_pos_regs_t pos_d;
716 //  pos_d.x = x;
717 //  pos_d.y = y;
718
719 /*  vid_pos_regs_t pos_d;
720
721   memset(&pos_d, 0, sizeof(pos_d));
722
723   pos_d.dest.y = y;
724   pos_d.dest.x = x;
725 /*
726 typedef struct {
727   int w;
728   int h;
729   int scale;
730   int x1;
731   int y;
732   int x;
733   int y2;
734   int x3;
735   int y3;
736   int x4;
737   int y4;
738 } vid_pos_regs_t;
739 */
740
741 /*
742   pos_d.w = 100;
743   pos_d.h = 30;
744   pos_d.scale = 2;
745   pos_d.x1 = 0;
746   pos_d.y = 100;            // Top left X
747   pos_d.x = 50;            // Top left Y
748   pos_d.y2 = 30;
749   pos_d.x3 = 60;
750   pos_d.y3 = 90;
751   pos_d.x4 = 120;
752   pos_d.y4 = 150;
753 */
754
755 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
756   return 1;
757 }
758
759 int VideoVPEOGL::sync()
760 {
761   if (!initted) return 0;
762
763 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
764   return 1;
765 }
766
767
768
769
770 int VideoVPEOGL::play()
771 {
772   if (!initted) return 0;
773   decoding_backend=0;
774 #ifdef VPE_OMX_SUPPORT
775   bool doomx=true;
776   if (h264) {
777           if (!omx_h264) doomx=false;
778   } else {
779           if (!omx_mpeg2) doomx=false;
780   }
781   if (doomx) {
782           if (AllocateCodecsOMX()) {
783                   decoding_backend=VPE_DECODER_OMX;
784                   return 1;
785                   // Otherwise fall back to libav
786           } else {
787                   if (h264) {
788                           omx_h264=false;
789                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
790                   } else {
791                           omx_mpeg2=false;
792                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
793                   }
794           }
795   }
796 #endif
797 #ifdef VPE_LIBAV_SUPPORT
798   if (AllocateCodecsLibav()) {
799           decoding_backend=VPE_DECODER_libav;
800           return 1;
801                   // Otherwise fall back to libav
802   }
803 #endif
804   return 0;
805
806
807
808 }
809
810 #ifdef VPE_OMX_SUPPORT
811 int VideoVPEOGL::AllocateCodecsOMX()
812 {
813         OMX_ERRORTYPE error;
814         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
815
816         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
817         //Clock, move later to audio
818
819         omx_events.clear();
820
821         error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
822
823
824         if (error!=OMX_ErrorNone){
825                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
826                 DeAllocateCodecsOMX();
827                 return 0;
828         }
829
830
831
832         OMX_PORT_PARAM_TYPE p_param;
833         memset(&p_param,0,sizeof(p_param));
834         p_param.nSize=sizeof(p_param);
835         p_param.nVersion.nVersion=OMX_VERSION;
836         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
837         if (error!=OMX_ErrorNone){
838                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
839                 DeAllocateCodecsOMX();
840                 return 0;
841         }
842         omx_clock_output_port=p_param.nStartPortNumber;
843
844         for (unsigned int i=0;i<p_param.nPorts;i++) {
845                 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
846                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
847                         DeAllocateCodecsOMX();
848                         return 0;
849                 }
850         }
851
852
853         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
854         memset(&clock_conf,0,sizeof(clock_conf));
855         clock_conf.nSize=sizeof(clock_conf);
856         clock_conf.nVersion.nVersion=OMX_VERSION;
857         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
858         clock_conf.nStartTime=0;
859         clock_conf.nOffset=0;
860         clock_conf.nWaitMask=OMX_CLOCKPORT0;
861         error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
862         if (error!=OMX_ErrorNone){
863                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
864                 DeAllocateCodecsOMX();
865                 return 0;
866         }
867
868
869
870         if (h264) {
871                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
872         } else {
873                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
874         }
875
876         if (error!=OMX_ErrorNone){
877                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
878                 DeAllocateCodecsOMX();
879                 return 0;
880         }
881
882
883
884         memset(&p_param,0,sizeof(p_param));
885         p_param.nSize=sizeof(p_param);
886         p_param.nVersion.nVersion=OMX_VERSION;
887         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
888         if (error!=OMX_ErrorNone){
889                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
890                 DeAllocateCodecsOMX();
891             return 0;
892         }
893         omx_codec_input_port=p_param.nStartPortNumber;
894         omx_codec_output_port=p_param.nStartPortNumber+1;
895
896         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
897                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
898                 DeAllocateCodecsOMX();
899                 return 0;
900         }
901
902
903         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
904         memset(&conceal,0,sizeof(conceal));
905         conceal.nSize=sizeof(conceal);
906         conceal.nVersion.nVersion=OMX_VERSION;
907         conceal.bStartWithValidFrame=OMX_FALSE;
908
909         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
910         if (error!=OMX_ErrorNone){
911                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
912                 DeAllocateCodecsOMX();
913                 return 0;
914         }
915
916
917         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
918         if (error!=OMX_ErrorNone){
919                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
920                 DeAllocateCodecsOMX();
921                 return 0;
922         }
923
924
925
926         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
927         if (error!=OMX_ErrorNone){
928                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
929                 DeAllocateCodecsOMX();
930                 return 0;
931         }
932         omx_shed_input_port=p_param.nStartPortNumber;
933         omx_shed_output_port=p_param.nStartPortNumber+1;
934
935
936         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
937         if (error!=OMX_ErrorNone){
938                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
939                 DeAllocateCodecsOMX();
940                 return 0;
941         }
942         omx_shed_clock_port=p_param.nStartPortNumber;
943
944
945         if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
946                         || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
947                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
948                 DeAllocateCodecsOMX();
949                 return 0;
950         }
951
952
953         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
954         if (error!=OMX_ErrorNone){
955                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
956                 DeAllocateCodecsOMX();
957                 return 0;
958         }
959
960         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
961         if (error!=OMX_ErrorNone){
962                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
963                 DeAllocateCodecsOMX();
964                 return 0;
965         }
966         omx_rend_input_port=p_param.nStartPortNumber;
967         //omx_rend_output_port=p_param.nStartPortNumber+1;
968
969
970         if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
971                                 ) {
972                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
973                 DeAllocateCodecsOMX();
974                 return 0;
975         }
976
977         //Setuo chain
978
979
980
981
982
983
984
985
986 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
987         if (error!=OMX_ErrorNone){
988                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
989                 return 0;
990         }*/
991
992
993
994
995         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
996         memset(&ft_type,0,sizeof(ft_type));
997         ft_type.nSize=sizeof(ft_type);
998         ft_type.nVersion.nVersion=OMX_VERSION;
999
1000         ft_type.nPortIndex=omx_codec_input_port;
1001         if (h264) {
1002                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1003         } else {
1004                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1005         }
1006
1007         Demuxer* demux=Demuxer::getInstance();
1008
1009     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1010     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1011         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1012         if (error!=OMX_ErrorNone){
1013                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1014                 DeAllocateCodecsOMX();
1015                 return 0;
1016         }
1017
1018
1019         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1020                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1021                 DeAllocateCodecsOMX();
1022                 return 0;
1023         }
1024
1025
1026         if (!PrepareInputBufsOMX()) {
1027                 DeAllocateCodecsOMX();
1028                 return 0;
1029         }
1030
1031
1032         if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1033                 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
1034                 DeAllocateCodecsOMX();
1035                 return 0;
1036         }
1037
1038         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1039         if (error!=OMX_ErrorNone){
1040                 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);
1041                 DeAllocateCodecsOMX();
1042                 return 0;
1043         }
1044
1045         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1046                                         ) {
1047                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1048                 DeAllocateCodecsOMX();
1049                 return 0;
1050         }
1051
1052         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1053                 DeAllocateCodecsOMX();
1054                 return 0;
1055         }
1056
1057         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1058         if (error!=OMX_ErrorNone){
1059                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1060                 DeAllocateCodecsOMX();
1061                 return 0;
1062         }
1063
1064
1065
1066         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1067                                                 ) {
1068                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1069                 DeAllocateCodecsOMX();
1070                 return 0;
1071         }
1072
1073         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1074                 return 0;
1075         }
1076         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1077                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1078                 DeAllocateCodecsOMX();
1079                 return 0;
1080         }
1081         if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
1082                         ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
1083                 DeAllocateCodecsOMX();
1084                 return 0;
1085         }
1086
1087         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1088                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1089                 DeAllocateCodecsOMX();
1090                 return 0;
1091         }
1092
1093         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1094         if (error!=OMX_ErrorNone){
1095                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1096                 DeAllocateCodecsOMX();
1097                 return 0;
1098         }
1099
1100         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1101                                                         ) {
1102                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1103                 DeAllocateCodecsOMX();
1104                 return 0;
1105         }
1106
1107         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1108                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1109                 DeAllocateCodecsOMX();
1110                 return 0;
1111         }
1112
1113         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1114                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1115                 DeAllocateCodecsOMX();
1116                 return 0;
1117         }
1118
1119
1120         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1121                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1122                 DeAllocateCodecsOMX();
1123                 return 0;
1124         }
1125
1126         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1127                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1128                 DeAllocateCodecsOMX();
1129                 return 0;
1130         }
1131
1132         //raspbi specifif
1133         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1134         memset(&dispconf,0,sizeof(dispconf));
1135         dispconf.nSize=sizeof(dispconf);
1136         dispconf.nVersion.nVersion=OMX_VERSION;
1137
1138         dispconf.nPortIndex=omx_rend_input_port;
1139
1140         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1141         dispconf.layer=1;
1142         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1143         if (error!=OMX_ErrorNone){
1144                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1145                 DeAllocateCodecsOMX();
1146                 return 0;
1147         }
1148
1149 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1150         dispconf.fullscreen=OMX_FALSE;
1151         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1152         if (error!=OMX_ErrorNone){
1153                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1154                 DeAllocateCodecsOMX();
1155                 return 0;
1156         }
1157
1158         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1159         dispconf.dest_rect.x_offset=100;
1160         dispconf.dest_rect.y_offset=100;
1161         dispconf.dest_rect.width=640;
1162         dispconf.dest_rect.height=480;
1163         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1164         if (error!=OMX_ErrorNone){
1165                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1166                 DeAllocateCodecsOMX();
1167                 return 0;
1168         }*/
1169
1170
1171
1172
1173         if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1174                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1175                         DeAllocateCodecsOMX();
1176                         return 0;
1177         }
1178
1179         omx_running=true;
1180
1181         return 1;
1182 }
1183
1184
1185 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1186 {
1187         OMX_ERRORTYPE error;
1188         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1189         if (error!=OMX_ErrorNone){
1190                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1191                 return 0;
1192         }
1193
1194         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1195                 return 0;
1196         }
1197
1198         return 1;
1199 }
1200
1201
1202 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1203 {
1204         OMX_ERRORTYPE error;
1205         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1206         if (error!=OMX_ErrorNone){
1207                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1208                 return 0;
1209         }
1210
1211         if (!wait) return 1;
1212         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1213                 return 0;
1214         }
1215
1216         return 1;
1217 }
1218
1219
1220 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1221 {
1222         OMX_ERRORTYPE error;
1223         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1224         if (error!=OMX_ErrorNone){
1225                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1226                 return 0;
1227         }
1228
1229         if (!wait) return 1;
1230         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1231                 return 0;
1232         }
1233
1234
1235         return 1;
1236 }
1237
1238
1239
1240
1241 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1242 {
1243         int i=0;
1244         while (i<1000) {
1245                 omx_event_mutex.Lock();
1246                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1247                 while (itty!=omx_events.end()) {
1248
1249                         VPE_OMX_EVENT current=*itty;
1250                         if (current.handle==handle) { //this is ours
1251                                 if (current.event_type==OMX_EventError) {
1252                                         omx_events.erase(itty);
1253                                         omx_event_mutex.Unlock();
1254                                         return 0;
1255
1256                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1257                                         omx_events.erase(itty);
1258                                         omx_event_mutex.Unlock();
1259                                         return 1;
1260                                 }
1261                         }
1262                         itty++;
1263
1264                 }
1265                 omx_event_mutex.Unlock();
1266                 MILLISLEEP(2);
1267                 i++;
1268
1269         }
1270         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1271         return 0;
1272
1273 }
1274
1275
1276
1277
1278
1279 int VideoVPEOGL::PrepareInputBufsOMX()
1280 {
1281         OMX_ERRORTYPE error;
1282         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1283         memset(&port_def_type,0,sizeof(port_def_type));
1284         port_def_type.nSize=sizeof(port_def_type);
1285         port_def_type.nVersion.nVersion=OMX_VERSION;
1286         port_def_type.nPortIndex=omx_codec_input_port;
1287
1288         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1289
1290         if (error!=OMX_ErrorNone){
1291                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1292         }
1293 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1294                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1295                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1296
1297         port_def_type.nBufferCountActual=60;
1298
1299         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1300
1301         if (error!=OMX_ErrorNone){
1302                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1303         }
1304
1305
1306         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1307         if (error!=OMX_ErrorNone){
1308                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1309                 return 0;
1310         }
1311
1312         input_bufs_omx_mutex.Lock();
1313         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1314
1315         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1316                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1317         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1318                 if (error!=OMX_ErrorNone){
1319                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1320                         input_bufs_omx_mutex.Unlock();
1321                         return 0;
1322                 }*/
1323                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1324                 if (error!=OMX_ErrorNone){
1325                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1326                                 input_bufs_omx_mutex.Unlock();
1327                         return 0;
1328                 }
1329                 input_bufs_omx_all.push_back(buf_head);
1330                 input_bufs_omx_free.push_back(buf_head);
1331         }
1332         omx_first_frame=true;
1333
1334         firstsynched=false;
1335         cur_input_buf_omx=NULL;
1336         input_bufs_omx_mutex.Unlock();
1337
1338
1339         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1340         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1341                 return 0;
1342         }
1343         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1344
1345         return 1;
1346 }
1347
1348 int VideoVPEOGL::DestroyInputBufsOMX()
1349 {
1350         OMX_ERRORTYPE error;
1351
1352         cur_input_buf_omx=NULL;
1353         input_bufs_omx_mutex.Lock();
1354         for (int i=0; i< input_bufs_omx_all.size();i++) {
1355         //      free(input_bufs_omx_all[i]->pBuffer);
1356         //      input_bufs_omx_all[i]->pBuffer=NULL;
1357                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1358                 if (error!=OMX_ErrorNone){
1359                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1360                         input_bufs_omx_mutex.Unlock();
1361                         return 0;
1362                 }
1363         }
1364         input_bufs_omx_all.clear();
1365         input_bufs_omx_free.clear();
1366         input_bufs_omx_mutex.Unlock();
1367
1368 }
1369
1370
1371
1372
1373 int VideoVPEOGL::DeAllocateCodecsOMX()
1374 {
1375         OMX_ERRORTYPE error;
1376         omx_running=false;
1377         if (omx_vid_dec) {
1378                 // first flush all buffers
1379
1380                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1381                 if (error!=OMX_ErrorNone){
1382                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1383
1384                 }
1385
1386                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1387                 if (error!=OMX_ErrorNone){
1388                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1389
1390                 }
1391
1392                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1393                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1394                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1395                 }
1396
1397                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1398                 if (error!=OMX_ErrorNone){
1399                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1400
1401                 }
1402
1403                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1404                 if (error!=OMX_ErrorNone){
1405                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1406
1407                 }
1408
1409                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1410                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1411                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1412                 }
1413
1414                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1415                 if (error!=OMX_ErrorNone) {
1416                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1417
1418                 }
1419
1420                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1421                 if (error!=OMX_ErrorNone) {
1422                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1423
1424                 }
1425
1426                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1427                                 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1428                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1429                 }
1430
1431
1432
1433
1434                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1435                 if (error!=OMX_ErrorNone){
1436                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1437
1438                 }
1439
1440
1441                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1442                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1443                 }
1444
1445                 DestroyInputBufsOMX();
1446
1447                 //todo flushing
1448                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1449                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1450                 }
1451                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1452                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1453                 }
1454
1455                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1456                 if (error!=OMX_ErrorNone){
1457                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1458
1459                 }
1460
1461                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1462                 if (error!=OMX_ErrorNone){
1463                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1464
1465                 }
1466
1467                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1468                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1469                 }
1470
1471                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1472                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1473                 }
1474
1475                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1476                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1477                 }
1478                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1479                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1480                 }
1481
1482
1483
1484                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1485                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1486                 }
1487
1488
1489                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1490                 if (error!=OMX_ErrorNone){
1491                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1492
1493                 }
1494                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1495                 if (error!=OMX_ErrorNone){
1496                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1497
1498                 }
1499
1500                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1501                 if (error!=OMX_ErrorNone){
1502                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1503
1504                 }
1505
1506                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1507                 if (error!=OMX_ErrorNone){
1508                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1509
1510                 }
1511
1512
1513
1514
1515
1516                 error=OMX_FreeHandle(omx_vid_dec);
1517                 error=OMX_FreeHandle(omx_vid_sched);
1518                 error=OMX_FreeHandle(omx_vid_rend);
1519                 error=OMX_FreeHandle(omx_clock);
1520                 omx_vid_dec=NULL;
1521                 if (error!=OMX_ErrorNone) {
1522                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1523                 }
1524         }
1525
1526         return 1;
1527 }
1528
1529 #endif
1530
1531
1532 #ifdef VPE_LIBAV_SUPPORT
1533
1534 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1535 {
1536         int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1537         enum PixelFormat ret_pix=PIX_FMT_NONE;
1538         if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1539         while (*fmt!=PIX_FMT_NONE) {
1540                 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1541                         ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1542                 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1543                         ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1544                 }
1545                 fmt++;
1546         }
1547         return ret_pix;
1548 }
1549
1550 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
1551 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
1552 {
1553         if ((y+height)==src->height) {
1554                 //Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface);
1555                 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
1556         }
1557
1558 }
1559
1560 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1561 {
1562         Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1563         return -1;
1564 }
1565
1566 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1567 {
1568         unsigned int want_sizes[4]={0,0,0,0};
1569         AVPicture pict;
1570         bool normal_pixs=false;
1571         int num_blocks=0;
1572         int num_dct_blocks=0;
1573
1574         int s_a[4];
1575         //reget logic from mplayer
1576         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1577                 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1578                 return 0;
1579         }
1580
1581
1582         if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1583                 normal_pixs=true;
1584                 // standard pixel format
1585                 // this is written using much inspiration from libav util.c, so portions from there
1586                 int width,height;
1587
1588                 width=c->width;
1589                 height=c->height;
1590
1591                 avcodec_align_dimensions2(c, &width, &height, s_a);
1592                 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1593                         width+=2*16;
1594                         height+=2*16;
1595                 }
1596                 // Now we have to determine alignment size
1597                 bool unaligned=true;
1598                 while (unaligned) {
1599                         av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1600                         width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1601                         unaligned=false;
1602                         for (int i=0;i<4;i++) {
1603                                 if ((pict.linesize[i]%s_a[i])!=0) {
1604                                         unaligned=true;
1605                                         break;
1606                                 }
1607                         }
1608                 }
1609                 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1610                 for (int i=0;i<4 ;i++) {
1611                         if (i<3 && pict.data[i+1]) {
1612                                 want_sizes[i]=pict.data[i+1]-pict.data[i];
1613                                 want_sizes[i]+=16;
1614                         } else {
1615                                 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1616                                 want_sizes[i]+=16;
1617                                 break;
1618                         }
1619                 }
1620
1621         } else {
1622                 //TODO set linesizes!
1623
1624                 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1625                 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1626
1627                 want_sizes[2]=sizeof(xvmc_pix_fmt);
1628                 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1629                 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1630                 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1631
1632         }
1633
1634         VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1635
1636         //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1637         if (!frame_buf) {
1638                 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1639                 return -1;
1640         }
1641
1642
1643         //populate pict
1644         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1645         int hchr_shift,vchr_shift;
1646         avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1647         const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1648         for (int i=0;i<4;i++) {
1649                 pic->data[i]=(uint8_t*)frame_buf->data[i];
1650                 pic->linesize[i]=pict.linesize[i];
1651                 if (normal_pixs) {
1652
1653                         int edge_width=16;
1654                         int edge_height=16;
1655                         if (i!=0) {
1656                                 edge_width>>=hchr_shift;
1657                                 edge_height>>=vchr_shift;
1658                         }
1659                         pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1660                 }
1661         }
1662
1663         pic->base[0]=(uint8_t*)frame_buf; // our structure
1664         //pic->extended_data=pic->data;
1665         if(c->pkt) pic->pkt_pts=c->pkt->pts;
1666         else pic->pkt_pts=AV_NOPTS_VALUE;
1667         pic->width=c->width;
1668         pic->height=c->height;
1669         pic->format=c->pix_fmt;
1670         pic->sample_aspect_ratio=c->sample_aspect_ratio;
1671         pic->reordered_opaque= c->reordered_opaque;
1672         pic->age=INT_MAX;
1673         if (!normal_pixs) {
1674                 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
1675                 pix_xvmc->xvmc_id=AV_XVMC_ID;
1676                 pix_xvmc->data_blocks=(short*)pic->data[1];
1677                 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
1678                 pix_xvmc->allocated_mv_blocks=num_blocks;
1679                 pix_xvmc->allocated_data_blocks=num_dct_blocks;
1680                 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
1681                 else pix_xvmc->idct=0;
1682                 pix_xvmc->unsigned_intra=1; // let see what happens
1683                 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
1684                 pix_xvmc->start_mv_blocks_num=0;
1685                 pix_xvmc->filled_mv_blocks_num=0;
1686                 pix_xvmc->next_free_data_block_num=0;
1687                 //that is all folks
1688
1689
1690         }
1691
1692         return 0;
1693
1694 }
1695
1696 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1697 {
1698 //      Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
1699         ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
1700         pic->base[0]=NULL;
1701         pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
1702
1703
1704 }
1705
1706 int VideoVPEOGL::AllocateCodecsLibav()
1707 {
1708         libav_hastime=false;
1709         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
1710         mpeg2codec_context_libav=avcodec_alloc_context();
1711         if (mpeg2codec_context_libav==NULL) {
1712                 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
1713                 return 0;
1714         }
1715         if (decoding_mode!=VPE_NO_XVMC) {
1716                 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
1717                 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
1718                 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
1719                 mpeg2codec_context_libav->get_format=get_format_libav;
1720                 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
1721
1722         }
1723         mpeg2codec_context_libav->get_buffer=get_buffer_libav;
1724         mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
1725         mpeg2codec_context_libav->release_buffer=release_buffer_libav;
1726
1727
1728
1729         int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
1730         if (avc_ret<0) {
1731                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed ");
1732                 return 0;
1733         }
1734         memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
1735         incom_packet_libav_size=200000;
1736         incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
1737
1738         dec_frame_libav_mutex.Lock();
1739         for (int i=0;i<3;i++) {
1740                         AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1741                         if (!dec_frame_libav) {
1742                                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
1743                                 return 0;
1744                         }
1745                         dec_frame_libav_all.push_back(dec_frame_libav);
1746                         dec_frame_libav_free.push_back(dec_frame_libav);
1747         }
1748         dec_frame_libav_decoding=NULL;
1749         dec_frame_libav_mutex.Unlock();
1750
1751         ogl_frame_mutex.Lock();
1752         //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1753         for (int i=0;i<5;i++) {
1754                 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1755                 new_frame->type=1; //1 = YUV, 2 RGB
1756                 new_frame->textures[0]=0;
1757                 new_frame->textures[1]=0;
1758                 new_frame->textures[2]=0;
1759                 new_frame->width=new_frame->height=0;
1760                 all_ogl_frames.push_back(new_frame);
1761                 free_ogl_frames.push_back(new_frame);
1762
1763         }
1764         ogl_frame_outside=false;
1765
1766         ogl_frame_mutex.Unlock();
1767
1768         if (decoding_mode==VPE_XVMC_MOCOMP) {
1769                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1770                 osd->BeginPainting(); // get OpenGl context
1771                 moco_shader=new GLMocoShader();
1772                 moco_shader->init();
1773                 osd->EndPainting();
1774         }
1775
1776         libav_running=true;
1777
1778         return 1;
1779
1780 }
1781
1782 int VideoVPEOGL::DeAllocateCodecsLibav()
1783 {
1784         libav_running=false;
1785         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
1786         dec_frame_libav_mutex.Lock();
1787         dec_frame_libav_upload_and_view_pending.clear();
1788         dec_frame_libav_upload_only_pending.clear();
1789         dec_frame_libav_free.clear();
1790         dec_frame_libav_mutex.Unlock();
1791         while (dec_frame_libav_uploading) {
1792                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1793                 MILLISLEEP(20);
1794         }
1795         dec_frame_libav_mutex.Lock();
1796         for (int i=0; i< dec_frame_libav_all.size();i++) {
1797                 av_free(dec_frame_libav_all[i]);
1798         }
1799
1800         dec_frame_libav_all.clear();
1801
1802         av_free(incom_packet_libav.data);
1803         incom_packet_libav.data=NULL;
1804         incom_packet_libav_size=0;
1805
1806         dec_frame_libav_mutex.Unlock();
1807         dec_frame_libav_decoding=NULL;
1808         while (ogl_frame_outside) {
1809                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1810                 MILLISLEEP(20);
1811         }
1812
1813         ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1814         ogl_frame_mutex.Lock();
1815         for (int i=0; i< dec_frame_libav_all.size();i++) {
1816                 VPEOGLFrame * del_frame=all_ogl_frames[i];
1817                 if (del_frame->textures[0]==0) {
1818                         glDeleteTextures(1,&del_frame->textures[0]);
1819                         del_frame->textures[0]=0;
1820                 }
1821                 if (del_frame->textures[1]==0) {
1822                         glDeleteTextures(1,&del_frame->textures[1]);
1823                         del_frame->textures[1]=0;
1824                 }
1825                 if (del_frame->textures[2]==0) {
1826                         glDeleteTextures(1,&del_frame->textures[2]);
1827                         del_frame->textures[2]=0;
1828                 }
1829
1830                 free(all_ogl_frames[i]);
1831         }
1832         all_ogl_frames.clear();
1833         free_ogl_frames.clear();
1834         ready_ogl_frames.clear();
1835         recycle_ref_ogl_frames.clear();
1836         ogl_forward_ref_frame_num=0;
1837         ogl_backward_ref_frame_num=0;
1838         ogl_forward_ref_frame=NULL;
1839         ogl_backward_ref_frame=NULL;
1840
1841         ogl_frame_mutex.Unlock();
1842         ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1843
1844
1845         if (mpeg2codec_context_libav) {
1846                 avcodec_close(mpeg2codec_context_libav);
1847                 av_free(mpeg2codec_context_libav);
1848                 mpeg2codec_context_libav=NULL;
1849
1850         }
1851
1852
1853
1854         vpe_framebuf_mutex.Lock();
1855
1856         for (int i=0;i<all_frame_bufs.size();i++) {
1857                 VPE_FrameBuf* current=all_frame_bufs[i];
1858                 for (int x=0;x<4;x++) {
1859                         if (current->data[x]) {
1860                                 av_free(current->data[x]);
1861                         }
1862                 }
1863                 free(current);
1864         }
1865         all_frame_bufs.clear();
1866         free_frame_bufs.clear();
1867         locked_libav_frame_buf.clear();
1868         locked_uploading_frame_buf.clear();
1869
1870         vpe_framebuf_mutex.Unlock();
1871
1872
1873
1874         if (moco_shader) {
1875                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1876                 osd->BeginPainting(); // get OpenGl context
1877                 moco_shader->deinit();
1878                 delete moco_shader;
1879                 moco_shader=NULL;
1880                 osd->EndPainting();
1881         }
1882
1883
1884
1885
1886
1887         return 1;
1888 }
1889
1890
1891 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
1892 { //for libav
1893         VPE_FrameBuf* current=NULL;
1894         vpe_framebuf_mutex.Lock();
1895         if (free_frame_bufs.size()>0) {
1896                 current=free_frame_bufs.front();
1897                 free_frame_bufs.pop_front();
1898         } else if (all_frame_bufs.size()<6) {
1899                 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
1900                 memset(current,0,sizeof(VPE_FrameBuf));
1901         } else {
1902                 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
1903                 vpe_framebuf_mutex.Unlock();
1904                 return NULL; // We do not have a frame buffer
1905         }
1906         locked_libav_frame_buf.push_back(current);
1907         vpe_framebuf_mutex.Unlock();
1908         //check if we need reallocation
1909         for (int x=0;x<4;x++) {
1910                 if (current->size[x]!=size[x]) {
1911                         current->data[x]=av_realloc(current->data[x],size[x]);
1912                         current->size[x]=size[x];
1913                 }
1914         }
1915         framebuf_framenum++;
1916         current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
1917         return current;
1918
1919 }
1920
1921 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
1922 {
1923         // first find frame_buf memory
1924
1925         //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
1926         VPE_FrameBuf* current=buf;
1927         vpe_framebuf_mutex.Lock();
1928         if (current) locked_uploading_frame_buf.push_back(current); //locked
1929         vpe_framebuf_mutex.Unlock();
1930
1931 }
1932
1933
1934 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
1935 {
1936         // first find frame_buf memory
1937         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
1938         VPE_FrameBuf* current=buf;
1939         vpe_framebuf_mutex.Lock();
1940         if (current) {
1941                 locked_libav_frame_buf.remove(current); //unlocked
1942                 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
1943                 bool inlist=false;
1944                 while (itty!=locked_uploading_frame_buf.end()) {
1945                         if (*itty==current) {
1946                                 inlist=true;
1947                                 break;
1948                         }
1949                         itty++;
1950                 }
1951                 if (!inlist) {
1952                         free_frame_bufs.push_back(current);
1953                 }
1954         }
1955         vpe_framebuf_mutex.Unlock();
1956 }
1957
1958 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
1959 {
1960         // first find frame_buf memory
1961         VPE_FrameBuf* current=buf;
1962         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
1963         vpe_framebuf_mutex.Lock();
1964         if (current) {
1965                 locked_uploading_frame_buf.remove(current); //unlocked
1966                 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
1967                 bool inlist=false;
1968                 while (itty!=locked_libav_frame_buf.end()) {
1969                         if (*itty==current) {
1970                                 inlist=true;
1971                                 break;
1972                         }
1973                         itty++;
1974                 }
1975                 if (!inlist) {
1976                         free_frame_bufs.push_back(current);
1977                 }
1978         }
1979         vpe_framebuf_mutex.Unlock();
1980 }
1981
1982 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
1983 {
1984         dec_frame_libav_mutex.Lock();
1985         libavwidth=s->width;
1986         libavheight=s->height;
1987         libavpixfmt=s->pix_fmt;
1988         Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num);
1989
1990         dec_frame_libav_upload_only_pending.push_back((AVFrame*)data); // we are only uploading
1991         dec_frame_libav_mutex.Unlock();
1992         threadSignal();
1993 }
1994
1995
1996
1997
1998
1999 #endif
2000
2001 int VideoVPEOGL::stop()
2002 {
2003   if (!initted) return 0;
2004
2005 #ifdef VPE_OMX_SUPPORT
2006   //Check if libav mode
2007   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2008   decoding_backend=0;
2009
2010 #endif
2011
2012
2013
2014 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2015   return 1;
2016 }
2017
2018 int VideoVPEOGL::reset()
2019 {
2020   if (!initted) return 0;
2021
2022 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2023   return 1;
2024 }
2025
2026 int VideoVPEOGL::pause()
2027 {
2028   if (!initted) return 0;
2029
2030 //  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
2031   return 1;
2032 }
2033
2034 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
2035 {
2036   if (!initted) return 0;
2037 //  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2038   return 1;
2039 }
2040
2041 int VideoVPEOGL::fastForward()
2042 {
2043   if (!initted) return 0;
2044
2045 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2046   return 1;
2047 }
2048
2049 int VideoVPEOGL::unFastForward()
2050 {
2051   if (!initted) return 0;
2052
2053 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2054
2055  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2056   return 1;
2057 }
2058
2059 int VideoVPEOGL::attachFrameBuffer()
2060 {
2061   if (!initted) return 0;
2062
2063 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2064   return 1;
2065 }
2066
2067 int VideoVPEOGL::blank(void)
2068 {
2069 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2070 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2071   return 1;
2072 }
2073
2074 ULLONG VideoVPEOGL::getCurrentTimestamp()
2075 {
2076 /*  sync_data_t timestamps;
2077   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
2078   {
2079     // FIXME are these the right way around?
2080
2081     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
2082     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
2083
2084     return timestamps.stc;
2085   }
2086   else
2087   {
2088     return 0;
2089   }*/
2090   return 0;
2091 }
2092
2093 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2094 {
2095   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2096   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2097 }
2098
2099 #ifdef DEV
2100 int VideoVPEOGL::test()
2101 {
2102   return 0;
2103
2104 //  ULLONG stc = 0;
2105 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2106 /*
2107  // reset();
2108   return 1;
2109 */
2110 }
2111
2112 int VideoVPEOGL::test2()
2113 {
2114   return 0;
2115 }
2116 #endif
2117
2118 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2119 {
2120   mediapacket = mplist.front();
2121 }
2122
2123 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2124 {
2125   DeliverMediaPacket(mediapacket, buffer, samplepos);
2126   if (*samplepos == mediapacket.length) {
2127     *samplepos = 0;
2128     return 1;
2129   }
2130   else return 0;
2131 }
2132
2133 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2134                 const UCHAR* buffer,
2135                 UINT *samplepos)
2136 {
2137         if (packet.type == MPTYPE_VIDEO_H264)
2138         {
2139                 h264=true;
2140         }
2141         else
2142         {
2143                 h264=false;
2144         }
2145         switch (decoding_backend) {
2146         default: case 0: return 0; // no backend runnigng
2147 #ifdef VPE_OMX_SUPPORT
2148         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2149 #endif
2150 #ifdef VPE_LIBAV_SUPPORT
2151         case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2152 #endif
2153         }
2154 }
2155
2156 #ifdef VPE_OMX_SUPPORT
2157 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2158                 const UCHAR* buffer,
2159                 UINT *samplepos)
2160 {
2161
2162
2163         //Later add fail back code for libav
2164         /*if (!videoon) {
2165                 *samplepos+=packet.length;
2166                 return packet.length;
2167         }*/
2168
2169
2170         if (!omx_running) return 0; // if we are not runnig do not do this
2171
2172
2173         OMX_ERRORTYPE error;
2174
2175 /*      OMX_PARAM_PORTDEFINITIONTYPE port_image;
2176         memset(&port_image,0,sizeof(port_image));
2177         port_image.nSize=sizeof(port_image);
2178         port_image.nVersion.nVersion=OMX_VERSION;
2179         port_image.nPortIndex =omx_codec_output_port;
2180         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2181         if (error!= OMX_ErrorNone){
2182                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2183         }
2184         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2185
2186         /*First Check, if we have an audio sample*/
2187         if (iframemode) {
2188                 //samplepos=0;
2189                 MILLISLEEP(10);
2190                 return 0; //Not in iframe mode!
2191         }
2192
2193         UINT headerstrip=0;
2194         if (packet.disconti) {
2195                 firstsynched=false;
2196                 if (cur_input_buf_omx) {
2197                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2198                         if (error!=OMX_ErrorNone){
2199                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2200                         }
2201                         cur_input_buf_omx=NULL;
2202                 }
2203         }
2204
2205         /*Inspect PES-Header */
2206
2207 //      OMX_STATETYPE temp_state;
2208 //      OMX_GetState(omx_vid_dec,&temp_state);
2209
2210         if (*samplepos==0) {//stripheader
2211                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2212                 *samplepos+=headerstrip;
2213                 if ( packet.synched ) {
2214
2215                         if (cur_input_buf_omx) {
2216                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2217                                 if (error!=OMX_ErrorNone){
2218                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2219                                 }
2220
2221                                 cur_input_buf_omx=NULL;//write out old data
2222                         }
2223                 //      reftime1=packet.presentation_time;
2224                 //      reftime2=reftime1+1;
2225                         firstsynched=true;
2226                 } else {
2227                         if (!firstsynched) {//
2228                                 *samplepos=packet.length;//if we have not processed at least one
2229                                 return packet.length;//synched packet ignore it!
2230                         }
2231                 }
2232         }
2233
2234         if (!cur_input_buf_omx) {
2235                 input_bufs_omx_mutex.Lock();
2236                 if (input_bufs_omx_free.size()==0) {
2237                         input_bufs_omx_mutex.Unlock();
2238                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2239                         return 0; // we do not have a free media sample
2240
2241                 }
2242                 cur_input_buf_omx=input_bufs_omx_free.front();
2243                 cur_input_buf_omx->nFilledLen=0;
2244                 cur_input_buf_omx->nOffset=0;
2245                 cur_input_buf_omx->nTimeStamp=0;
2246                 input_bufs_omx_free.pop_front();
2247                 input_bufs_omx_mutex.Unlock();
2248         }
2249
2250
2251
2252
2253         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2254                 /*if (packet.disconti) {
2255                         ms->SetDiscontinuity(TRUE);
2256                 } else {
2257                         ms->SetDiscontinuity(FALSE);
2258                 }*/
2259                 //if (packet.synched) {
2260
2261                         //lastreftimePTS=packet.pts;
2262                    if (omx_first_frame) { // TODO time
2263                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2264                            omx_first_frame=false;
2265                    } else
2266
2267                 //}
2268                 //else
2269                 //{
2270                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2271
2272
2273                         //  ms->SetSyncPoint(TRUE);
2274                 //}
2275
2276         }
2277         unsigned int haveToCopy=packet.length-*samplepos;
2278
2279         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2280                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2281                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2282                 haveToCopy-=cancopy;
2283                 cur_input_buf_omx->nFilledLen+=cancopy;
2284                 *samplepos+=cancopy;
2285                 // push old buffer out
2286
2287                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2288                 if (error!=OMX_ErrorNone){
2289                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2290                 }
2291                 // get5 new buffer
2292                 input_bufs_omx_mutex.Lock();
2293                 if (input_bufs_omx_free.size()==0) {
2294                         input_bufs_omx_mutex.Unlock();
2295                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2296                         return *samplepos; // we do not have a free media sample
2297                 }
2298                 cur_input_buf_omx=input_bufs_omx_free.front();
2299                 cur_input_buf_omx->nFilledLen=0;
2300                 cur_input_buf_omx->nOffset=0;
2301                 cur_input_buf_omx->nTimeStamp=0;
2302                 input_bufs_omx_free.pop_front();
2303                 input_bufs_omx_mutex.Unlock();
2304
2305                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2306
2307         }
2308         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2309                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2310         cur_input_buf_omx->nFilledLen+=haveToCopy;
2311
2312
2313
2314         *samplepos+=haveToCopy;
2315
2316         return *samplepos;
2317
2318 }
2319
2320 #endif
2321
2322
2323 #ifdef VPE_LIBAV_SUPPORT
2324 int VideoVPEOGL::DecodePacketlibav()
2325 {
2326         unsigned int haveToCopy=incom_packet_libav.size;
2327         if (incom_packet_libav.size==0) return 1; // we are already empty
2328         while (haveToCopy>0) {
2329                 int dec_bytes=0;
2330                 int frame_ready=0;
2331
2332         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2333
2334 #ifdef BENCHMARK_FPS
2335             int cur_time=getTimeMS();
2336 #endif
2337                 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2338                                 &frame_ready, &incom_packet_libav);
2339 #ifdef BENCHMARK_FPS
2340                 time_in_decoder+=getTimeMS()-cur_time;
2341                 if (frame_ready) num_frames++;
2342                 if ((num_frames%100)==0) {
2343                         float fps=1000./(float)(time_in_decoder);
2344                         fps*=((float)num_frames);
2345                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2346                 }
2347 #endif
2348                 if (dec_bytes<0) {
2349                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2350                         return 0;
2351                 }
2352                 haveToCopy-=dec_bytes;
2353                 if (frame_ready) {
2354                 //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2355
2356                         lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2357                         dec_frame_libav_mutex.Lock();
2358                         libavwidth=mpeg2codec_context_libav->width;
2359                         libavheight=mpeg2codec_context_libav->height;
2360                         libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2361                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2362
2363
2364                         dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
2365                         dec_frame_libav_decoding=NULL;
2366                         if (dec_frame_libav_free.size()>0) {
2367                                 dec_frame_libav_decoding=dec_frame_libav_free.front();
2368                                 dec_frame_libav_free.pop_front();
2369                                 dec_frame_libav_mutex.Unlock();
2370                                 threadSignal();
2371                                 libav_hastime=false;
2372                         } else {
2373                                 libav_hastime=false;
2374                                 dec_frame_libav_mutex.Unlock();
2375                                 threadSignal();
2376                                 // No free buffers
2377                                 return 0;
2378                         }
2379
2380
2381                 }
2382
2383         }
2384         incom_packet_libav.size=0;
2385         return 1;
2386
2387 }
2388
2389
2390 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2391                 const UCHAR* buffer,
2392                 UINT *samplepos)
2393 {
2394         //Later add fail back code for libav
2395         /*if (!videoon) {
2396                 *samplepos+=packet.length;
2397                 return packet.length;
2398         }*/
2399
2400         if (!libav_running) return 0; // if we are not runnig do not do this
2401
2402
2403         if (iframemode) {
2404                 //samplepos=0;
2405                 MILLISLEEP(10);
2406                 return 0; //Not in iframe mode!
2407         }
2408
2409         UINT headerstrip=0;
2410         if (packet.disconti) {
2411                 firstsynched=false;
2412                 if (!DecodePacketlibav()) return 0;
2413         }
2414
2415         /*Inspect PES-Header */
2416         if (!dec_frame_libav_decoding) {
2417                 dec_frame_libav_mutex.Lock();
2418                 if (dec_frame_libav_free.size()>0) {
2419                         dec_frame_libav_decoding=dec_frame_libav_free.front();
2420                         dec_frame_libav_free.pop_front();
2421                         dec_frame_libav_mutex.Unlock();
2422                 } else {
2423                         Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
2424                         dec_frame_libav_mutex.Unlock();
2425                         // No free buffers
2426                         return 0;
2427                 }
2428         }
2429
2430
2431
2432         if (*samplepos==0) {//stripheader
2433                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2434                 *samplepos+=headerstrip;
2435                 if ( packet.synched ) {
2436
2437                         if (!DecodePacketlibav()) return 0; // WriteOut old Data
2438
2439                         libav_time=packet.presentation_time;
2440                         libav_hastime=true;
2441                 //      reftime1=packet.presentation_time;
2442                 //      reftime2=reftime1+1;
2443                         firstsynched=true;
2444                 } else {
2445                         if (!firstsynched) {//
2446                                 *samplepos=packet.length;//if we have not processed at least one
2447                                 return packet.length;//synched packet ignore it!
2448                         }
2449                 }
2450         }
2451
2452
2453
2454
2455
2456
2457         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2458                 /*if (packet.disconti) {
2459                         ms->SetDiscontinuity(TRUE);
2460                 } else {
2461                         ms->SetDiscontinuity(FALSE);
2462                 }*
2463                 //if (packet.synched) {
2464
2465                         //lastreftimePTS=packet.pts;
2466                    if (omx_first_frame) { // TODO time
2467                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2468                            omx_first_frame=false;
2469                    } else
2470
2471                 //}
2472                 //else
2473                 //{
2474                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2475
2476
2477                         //  ms->SetSyncPoint(TRUE);
2478                 //}
2479
2480         }*/
2481         unsigned int haveToCopy=packet.length-*samplepos;
2482
2483         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2484                 // if the buffer is to small reallocate
2485                 incom_packet_libav_size+=haveToCopy;
2486                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2487                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2488         }
2489         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2490         incom_packet_libav.size+=haveToCopy;
2491
2492         *samplepos+=haveToCopy;
2493
2494
2495         return *samplepos;
2496
2497
2498 }
2499
2500 #endif
2501
2502
2503
2504
2505
2506
2507 void VideoVPEOGL::ResetTimeOffsets()
2508 {
2509 }
2510
2511 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
2512 {
2513   //write(fdVideo, buffer, length);
2514         if (!iframemode) EnterIframePlayback();
2515 //      WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
2516
2517   lastpacketnum=-1;
2518   return true;
2519 }
2520
2521 int VideoVPEOGL::EnterIframePlayback()
2522 {
2523
2524         return 0;
2525 }
2526