2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
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.
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.
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.
21 #include "videovpeogl.h"
23 #include "mtdraspberry.h"
25 #include "osdopengl.h"
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
32 VideoVPEOGL::VideoVPEOGL()
36 #ifdef VPE_OMX_SUPPORT
40 cur_input_buf_omx=NULL;
41 omx_h264=omx_mpeg2=true;
44 #ifdef VPE_LIBAV_SUPPORT
45 mpeg2codec_context_libav=NULL;
47 dec_frame_libav_uploading_framebuf=NULL;
48 dec_frame_libav_decoding=NULL;
49 ogl_frame_outside=false;
50 //decoding_mode=VPE_NO_XVMC;
51 decoding_mode=VPE_XVMC_MOCOMP;
52 //decoding_mode=VPE_XVMC_IDCT;
56 ogl_forward_ref_frame_num=0;
57 ogl_backward_ref_frame_num=0;
58 ogl_forward_ref_frame=NULL;
59 ogl_backward_ref_frame=NULL;
62 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
63 transcodecodec_libav=NULL;
64 transcodecodec_context_libav=NULL;
77 VideoVPEOGL::~VideoVPEOGL()
82 int VideoVPEOGL::init(UCHAR tformat)
84 if (initted) return 0;
87 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
89 if (!setFormat(tformat)) { shutdown(); return 0; }
90 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
91 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
92 if (!setMode(NORMAL)) { shutdown(); return 0; }
93 if (!setSource()) { shutdown(); return 0; }
94 if (!attachFrameBuffer()) { shutdown(); return 0; }
98 /* if (format == PAL) setLetterboxBorder("38");
99 else setLetterboxBorder("31");*/
113 int VideoVPEOGL::initUsingOSDObjects()
115 EGLDisplay i_egl_display;
116 EGLSurface i_egl_surface;
117 EGLContext i_egl_context;
118 EGLConfig i_egl_config;
119 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
120 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
121 const EGLint attr_context[]={
122 EGL_CONTEXT_CLIENT_VERSION,2,
126 egl_display=i_egl_display;
127 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
128 if (egl_context==EGL_NO_CONTEXT) {
129 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
132 // We create a dummy surface here, in order to allow two contexts
133 const EGLint attr_pbuffer[]={
134 EGL_WIDTH, 1, EGL_HEIGHT,1,
137 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
138 if (egl_surface==EGL_NO_SURFACE) {
139 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
146 //egl_surface=i_egl_surface;
147 //egl_context=i_egl_context;
150 #ifdef VPE_OMX_SUPPORT
151 // we are called before the audio
154 if (error!=OMX_ErrorNone) {
155 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
159 //our callbacks move to play?
163 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)
167 #ifdef VPE_LIBAV_SUPPORT
170 if (decoding_mode==VPE_NO_XVMC) {
171 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
173 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
175 if (mpeg2codec_libav==NULL) {
176 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
180 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
181 transcodecodec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_MPEG4);
182 if (transcodecodec_libav==NULL) {
183 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 transcoder failed");
194 #ifdef VPE_OMX_SUPPORT
196 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
197 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
198 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
200 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
202 struct VPE_OMX_EVENT new_event;
203 new_event.handle=handle;
204 new_event.appdata=appdata;
205 new_event.event_type=event_type;
206 new_event.data1=data1;
207 new_event.data2=data2;
208 new_event.event_data=event_data;
210 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
211 video->AddOmxEvent(new_event);
213 /* switch (event_type) {
214 case OMX_EventCmdComplete: {
219 return OMX_ErrorNone;
223 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
225 omx_event_mutex.Lock();
226 omx_events.push_back(new_event);
227 omx_event_mutex.Unlock();
231 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
233 //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
234 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
235 video->ReturnEmptyOMXBuffer(buffer);
236 return OMX_ErrorNone;
240 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
241 input_bufs_omx_mutex.Lock();
242 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
243 input_bufs_omx_free.push_back(buffer);
244 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
245 input_bufs_omx_mutex.Unlock();
248 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
249 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
250 return OMX_ErrorNone;
253 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
255 enum PixelFormat VideoVPEOGL::get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt)
257 enum PixelFormat ret_pix=PIX_FMT_NONE;
259 while (*fmt!=PIX_FMT_NONE) {
260 if (*fmt== PIX_FMT_TRANSCODE ) {
261 ret_pix=PIX_FMT_TRANSCODE;
268 int VideoVPEOGL::reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
270 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!Not Implemented! \n");
275 int VideoVPEOGL::get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
278 //reget logic from mplayer
279 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
280 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!\n");
285 if (c->pix_fmt!=PIX_FMT_TRANSCODE ) {
286 Log::getInstance()->log("Video", Log::DEBUG,"We only support transcode pixel fmt\n");
289 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
290 transcode_pix_fmt *pix_trans=NULL;
291 OMX_BUFFERHEADERTYPE* our_buf=video->GetFreeOMXBufferforlibav(&pix_trans);
292 if (our_buf==NULL|| pix_trans==NULL) {
293 Log::getInstance()->log("Video", Log::DEBUG,"Getting buffer failed\n");
303 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
305 pic->base[0]=(uint8_t*)our_buf; // our buf
306 //pic->extended_data=pic->data;
307 if(c->pkt) pic->pkt_pts=c->pkt->pts;
308 else pic->pkt_pts=AV_NOPTS_VALUE;
310 pic->height=c->height;
311 pic->format=c->pix_fmt;
312 pic->sample_aspect_ratio=c->sample_aspect_ratio;
313 pic->reordered_opaque= c->reordered_opaque;
315 pic->data[0]=(uint8_t*)pix_trans;
316 pix_trans->transcode_id=AV_TRANSCODE_ID;
317 pix_trans->packet.data=(uint8_t*)our_buf->pBuffer;
318 pix_trans->packet.size=our_buf->nAllocLen;
325 OMX_BUFFERHEADERTYPE* VideoVPEOGL::GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans)
327 OMX_BUFFERHEADERTYPE* returned_buf=NULL;
331 while (returned_buf==NULL && time_out<100){
332 input_bufs_omx_mutex.Lock();
333 if (input_bufs_omx_free.size()!=0) {
334 returned_buf=input_bufs_omx_free.front();
335 returned_buf->nFilledLen=0;
336 returned_buf->nOffset=0;
337 returned_buf->nTimeStamp=0;
338 input_bufs_omx_free.pop_front();
339 input_bufs_omx_in_libav.push_back(returned_buf);
340 input_bufs_omx_mutex.Unlock();
341 returned_buf->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
344 input_bufs_omx_mutex.Unlock();
345 Log::getInstance()->log("Video", Log::DEBUG, "GetFreeOMXBuffer_libav no free sample block");
350 *pix_trans=pix_fmt_omx_free.front();
351 pix_fmt_omx_free.pop_front(); // we assume that there is always a twin
356 void VideoVPEOGL::release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
358 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
359 video->ReturnEmptyOMXBuffer_libav((OMX_BUFFERHEADERTYPE*) pic->base[0],(transcode_pix_fmt *)pic->data[0]);
360 pic->data[0]=NULL; //without doing this avcodec is going to cry
363 void VideoVPEOGL::ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt){
364 input_bufs_omx_mutex.Lock();
365 // We only return it, if it was not passed to OMX!
366 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
367 pix_fmt_omx_free.push_back(pix_fmt);
368 list<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_in_libav.begin();
369 while (itty!=input_bufs_omx_in_libav.end()) {
371 input_bufs_omx_in_libav.remove(buffer);
372 input_bufs_omx_free.push_back(buffer);
373 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
377 input_bufs_omx_mutex.Unlock();
385 int VideoVPEOGL::shutdown()
387 if (!initted) return 0;
392 #ifdef VPE_OMX_SUPPORT
393 DeAllocateCodecsOMX();
396 #ifdef VPE_LIBAV_SUPPORT
397 DeAllocateCodecsLibav();
399 eglDestroyContext(egl_display,egl_context);
403 #ifdef VPE_LIBAV_SUPPORT
404 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
406 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
408 glGenTextures(1, &outframe->textures[0]);
409 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
410 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
411 GL_UNSIGNED_BYTE, NULL);
413 glGenTextures(1, &outframe->textures[1]);
414 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
415 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
416 GL_UNSIGNED_BYTE, NULL);
418 glGenTextures(1, &outframe->textures[2]);
419 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
420 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
421 GL_UNSIGNED_BYTE, NULL);
422 outframe->height=height;
423 outframe->width=width;
424 outframe->stride=stride;
429 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
431 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
433 glGenTextures(1, &outframe->textures[0]);
434 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
435 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
436 GL_UNSIGNED_BYTE, NULL);
437 outframe->textures[1]=outframe->textures[2]=0; // no handles here
443 outframe->height=height;
444 outframe->width=width;
445 outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
450 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
451 VPEOGLFrame *return_obj=NULL;
452 ogl_frame_mutex.Lock();
453 if (ready_ogl_frames.size()>0) {
454 return_obj=ready_ogl_frames.front();
455 ready_ogl_frames.pop_front();
456 //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing num: %d",return_obj->pict_num);
457 ogl_frame_outside=true;
459 ogl_frame_mutex.Unlock();
463 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
465 ogl_frame_mutex.Lock();
467 ogl_frame_outside=false;
468 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
469 if (frame->pict_num==ogl_forward_ref_frame_num ||
470 frame->pict_num==ogl_backward_ref_frame_num ) {
471 recycle_ref_ogl_frames.push_back(frame);
473 free_ogl_frames.push_back(frame);
476 ogl_frame_mutex.Unlock();
479 void VideoVPEOGL::recycleOGLRefFrames()
481 // This function recycles frames formerly used as reference frame
482 ogl_frame_mutex.Lock();
483 list<VPEOGLFrame*> keep;
484 list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
485 while (itty!=recycle_ref_ogl_frames.end()) {
486 // Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
487 if ((*itty)->pict_num==ogl_forward_ref_frame_num
488 || (*itty)->pict_num==ogl_backward_ref_frame_num)
490 // ok we have to keep this
491 keep.push_back(*itty);
493 free_ogl_frames.push_back(*itty);
497 recycle_ref_ogl_frames.clear();
498 recycle_ref_ogl_frames=keep;
500 ogl_frame_mutex.Unlock();
506 void VideoVPEOGL::threadMethod()
508 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
509 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
517 #ifdef VPE_LIBAV_SUPPORT
520 dec_frame_libav_mutex.Lock();
521 AVFrame* dec_frame_libav_uploading_int=NULL;
524 if (dec_frame_libav_upload_and_view_pending.size()>0 ) {
526 dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
527 dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
528 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
529 // dec_frame_libav_uploading_framebuf);
530 // if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
531 // ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
534 if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC ) {
535 dec_frame_libav_upload_and_view_pending.pop_front();
536 if (decoding_mode==VPE_NO_XVMC) upload=true;
538 dec_frame_libav_uploading_framebuf=NULL;
539 dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
540 view=false; //do the upload
541 // Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
545 if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
547 dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
548 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
549 // dec_frame_libav_uploading_framebuf);
550 dec_frame_libav_upload_only_pending.pop_front();
553 /* if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
555 dec_frame_libav_uploading=NULL; //do not upload again
564 if (dec_frame_libav_upload_and_view_pending.size()>0
565 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
567 dec_frame_libav_mutex.Unlock();
570 if (dec_frame_libav_uploading_framebuf) {
572 //Code Block for debugging if needed
573 /* Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
574 ogl_frame_mutex.Lock();
575 list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
576 while (itty!=free_ogl_frames.end()) {
577 Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
582 itty=recycle_ref_ogl_frames.begin();
583 while (itty!=recycle_ref_ogl_frames.end()) {
584 Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
588 itty=ready_ogl_frames.begin();
589 while (itty!=ready_ogl_frames.end()) {
590 Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
594 ogl_frame_mutex.Unlock();*/
598 int width,height,pixfmt;
599 //First get a free ogl image
600 VPEOGLFrame* out_frame=NULL;
603 ogl_frame_mutex.Lock();
604 // Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
605 // recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
606 if (all_ogl_frames.size()==0) {
607 ogl_frame_mutex.Unlock(); break;
610 if (free_ogl_frames.size()>0) {
614 out_frame=free_ogl_frames.front();
615 free_ogl_frames.pop_front();
617 ogl_frame_mutex.Unlock();
620 ogl_frame_mutex.Lock();
622 // if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
623 ogl_frame_mutex.Unlock();
627 // Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
628 if (out_frame->textures[0]==0 || out_frame->width!=width ||
629 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
630 if (out_frame->textures[0]!=0) {
631 glDeleteTextures(1,&out_frame->textures[0]);
632 out_frame->textures[0]=0;
634 if (out_frame->textures[1]!=0) {
635 glDeleteTextures(1,&out_frame->textures[1]);
636 out_frame->textures[1]=0;
638 if (out_frame->textures[2]!=0) {
639 glDeleteTextures(1,&out_frame->textures[2]);
640 out_frame->textures[2]=0;
643 if (decoding_mode==VPE_NO_XVMC) {
644 if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
646 if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
647 // the shaders are easier to implement
650 dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
651 dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
655 //up to now only YUV data, this is for reference only, since the pi is too slow.
656 if (decoding_mode==VPE_NO_XVMC) {
657 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
658 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
659 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
660 out_frame->stride,out_frame->height,
661 GL_LUMINANCE,GL_UNSIGNED_BYTE,
662 dec_frame_libav_uploading_framebuf->data[0]);
664 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
665 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
666 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
667 out_frame->stride>>1,out_frame->height>>1,
668 GL_LUMINANCE,GL_UNSIGNED_BYTE,
669 dec_frame_libav_uploading_framebuf->data[1]);
671 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
672 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
673 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
674 out_frame->stride>>1,out_frame->height>>1,
675 GL_LUMINANCE,GL_UNSIGNED_BYTE,
676 dec_frame_libav_uploading_framebuf->data[2]);
679 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
680 if (moco_shader && pix_fmt) {
683 int cur_time=getTimeMS();
685 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
686 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
687 // Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
688 // pix_fmt->p_past_surface,pix_fmt->p_future_surface);
690 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
692 //Now determine the frame, that fits
693 ogl_frame_mutex.Lock();
695 for (int i=0;i<all_ogl_frames.size();i++) {
696 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
698 ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
699 ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
700 ogl_backward_ref_frame=all_ogl_frames[i];
701 ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
706 // if (!found) {// for debugging
707 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
711 ogl_frame_mutex.Unlock();
712 recycleOGLRefFrames(); //needed for recycling of reference frames
714 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
717 if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
722 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
724 //Now determine the frame, that fits
725 ogl_frame_mutex.Lock();
727 for (int i=0;i<all_ogl_frames.size();i++) {
728 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
730 ogl_forward_ref_frame=all_ogl_frames[i];
731 ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
737 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
738 // ((int)pix_fmt->p_past_surface));
742 ogl_frame_mutex.Unlock();
743 recycleOGLRefFrames(); //needed for recycling of reference frames
746 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
748 if (decoding_mode==VPE_XVMC_MOCOMP)
755 out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
757 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
759 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
760 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
763 time_in_decoder_gl+=getTimeMS()-cur_time;
765 if ((num_frames_gl%100)==0) {
766 float fps=1000./(float)(time_in_decoder_gl);
767 fps*=((float)num_frames_gl);
768 Log::getInstance()->log("Video", Log::NOTICE, "Current GL Decoding FPS %g", fps);
772 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
773 // Excute motion compensation
775 //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
791 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
792 VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
793 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
794 /* Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
795 pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
796 Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
798 releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
799 ogl_frame_mutex.Lock();
800 ready_ogl_frames.push_back(out_frame);
801 ogl_frame_mutex.Unlock();
802 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
804 dec_frame_libav_mutex.Lock();
805 dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
806 dec_frame_libav_mutex.Unlock();
810 dec_frame_libav_mutex.Lock();
811 dec_frame_libav_uploading_framebuf=NULL;
813 if (dec_frame_libav_upload_and_view_pending.size()>0
814 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
816 dec_frame_libav_mutex.Unlock();
824 struct timespec target_time;
826 clock_gettime(CLOCK_REALTIME,&target_time);
827 target_time.tv_nsec+=1000000LL*ts;
828 if (target_time.tv_nsec>999999999) {
829 target_time.tv_nsec-=1000000000L;
830 target_time.tv_sec+=1;
832 threadWaitForSignalTimed(&target_time);
833 //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
841 void VideoVPEOGL::threadPostStopCleanup()
843 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
844 #ifdef VPE_LIBAV_SUPPORT
845 dec_frame_libav_uploading_framebuf=NULL;
852 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
856 // Override the aspect ratio usage, temporarily use to set the video chip mode
857 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
859 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
860 if (!setSource()) { shutdown(); return 0; }
861 if (!attachFramebuffer()) { shutdown(); return 0; }
863 // Reopening the fd causes the scart aspect line to go back to 4:3
864 // Set this again to the same as the tv screen size
865 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
867 // mode == LETTERBOX is invalid if the TV is widescreen
868 if (tvsize == ASPECT16X9) setMode(NORMAL);
873 int VideoVPEOGL::setDefaultAspect()
875 return setAspectRatio(tvsize);
880 int VideoVPEOGL::setFormat(UCHAR tformat)
882 if (!initted) return 0;
883 if ((tformat != PAL) && (tformat != NTSC)) return 0;
886 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
902 int VideoVPEOGL::setConnection(UCHAR tconnection)
904 if (!initted) return 0;
905 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
906 connection = tconnection;
908 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
912 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
914 if (!initted) return 0;
915 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
916 aspectRatio = taspectRatio;
918 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
920 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
924 int VideoVPEOGL::setMode(UCHAR tmode)
926 if (!initted) return 0;
928 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
930 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
931 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
934 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
938 int VideoVPEOGL::signalOff()
940 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
944 int VideoVPEOGL::signalOn()
946 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
950 int VideoVPEOGL::setSource()
952 if (!initted) return 0;
954 // What does this do...
955 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
959 int VideoVPEOGL::setPosition(int x, int y)
961 if (!initted) return 0;
963 // vid_pos_regs_t pos_d;
967 /* vid_pos_regs_t pos_d;
969 memset(&pos_d, 0, sizeof(pos_d));
994 pos_d.y = 100; // Top left X
995 pos_d.x = 50; // Top left Y
1003 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
1007 int VideoVPEOGL::sync()
1009 if (!initted) return 0;
1011 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
1018 int VideoVPEOGL::play()
1020 if (!initted) return 0;
1022 #ifdef VPE_OMX_SUPPORT
1025 if (!omx_h264) doomx=false;
1027 if (!omx_mpeg2) doomx=false;
1030 if (AllocateCodecsOMX()) {
1031 //decoding_backend=VPE_DECODER_OMX;
1033 // Otherwise fall back to libav
1037 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
1040 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
1045 #ifdef VPE_LIBAV_SUPPORT
1046 if (AllocateCodecsLibav()) {
1047 decoding_backend=VPE_DECODER_libav;
1049 // Otherwise fall back to libav
1058 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1060 int VideoVPEOGL::InitTranscoderLibAV() {
1061 transcodecodec_context_libav = avcodec_alloc_context3(transcodecodec_libav);
1062 if (!transcodecodec_context_libav) {
1063 Log::getInstance()->log("Video", Log::DEBUG, "Alloc avcodec context failed!");
1067 transcodecodec_context_libav->slice_flags = SLICE_FLAG_CODED_ORDER;
1069 transcodecodec_context_libav->pix_fmt = PIX_FMT_TRANSCODE;
1070 transcodecodec_context_libav->get_format = get_format_transcode;
1071 transcodecodec_context_libav->get_buffer = get_buffer_transcode;
1072 transcodecodec_context_libav->reget_buffer = reget_buffer_transcode;
1073 transcodecodec_context_libav->release_buffer = release_buffer_transcode;
1074 //transcodecodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
1075 //transcodecodec_context_libav->time_base.den=9000; //pts values 90 KHz Clock /10;
1077 int avc_ret = avcodec_open2(transcodecodec_context_libav, transcodecodec_libav, NULL);
1079 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed \n");
1083 memset(&incom_packet_libav, 0, sizeof(incom_packet_libav));
1084 incom_packet_libav_size = 200000;
1085 incom_packet_libav.data = (uint8_t*) av_malloc(incom_packet_libav_size + FF_INPUT_BUFFER_PADDING_SIZE);
1092 int VideoVPEOGL::DeInitTranscoderLibAV() {
1094 av_free(incom_packet_libav.data);
1095 incom_packet_libav.data=NULL;
1096 incom_packet_libav_size=0;
1098 if (transcodecodec_context_libav) {
1099 avcodec_close(transcodecodec_context_libav);
1100 av_free(transcodecodec_context_libav);
1101 transcodecodec_context_libav=NULL;
1110 #ifdef VPE_OMX_SUPPORT
1111 int VideoVPEOGL::AllocateCodecsOMX()
1113 OMX_ERRORTYPE error;
1114 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1116 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1117 //Clock, move later to audio
1121 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
1124 if (error!=OMX_ErrorNone){
1125 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
1126 DeAllocateCodecsOMX();
1132 OMX_PORT_PARAM_TYPE p_param;
1133 memset(&p_param,0,sizeof(p_param));
1134 p_param.nSize=sizeof(p_param);
1135 p_param.nVersion.nVersion=OMX_VERSION;
1136 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1137 if (error!=OMX_ErrorNone){
1138 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1139 DeAllocateCodecsOMX();
1142 omx_clock_output_port=p_param.nStartPortNumber;
1144 for (unsigned int i=0;i<p_param.nPorts;i++) {
1145 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
1146 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
1147 DeAllocateCodecsOMX();
1153 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1154 memset(&clock_conf,0,sizeof(clock_conf));
1155 clock_conf.nSize=sizeof(clock_conf);
1156 clock_conf.nVersion.nVersion=OMX_VERSION;
1157 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1158 clock_conf.nStartTime=0;
1159 clock_conf.nOffset=0;
1160 clock_conf.nWaitMask=OMX_CLOCKPORT0;
1161 error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1162 if (error!=OMX_ErrorNone){
1163 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1164 DeAllocateCodecsOMX();
1171 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
1173 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1176 if (error!=OMX_ErrorNone){
1177 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1178 DeAllocateCodecsOMX();
1184 memset(&p_param,0,sizeof(p_param));
1185 p_param.nSize=sizeof(p_param);
1186 p_param.nVersion.nVersion=OMX_VERSION;
1187 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1188 if (error!=OMX_ErrorNone){
1189 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1190 DeAllocateCodecsOMX();
1193 omx_codec_input_port=p_param.nStartPortNumber;
1194 omx_codec_output_port=p_param.nStartPortNumber+1;
1196 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1197 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1198 DeAllocateCodecsOMX();
1203 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1204 memset(&conceal,0,sizeof(conceal));
1205 conceal.nSize=sizeof(conceal);
1206 conceal.nVersion.nVersion=OMX_VERSION;
1207 conceal.bStartWithValidFrame=OMX_FALSE;
1209 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1210 if (error!=OMX_ErrorNone){
1211 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1212 DeAllocateCodecsOMX();
1217 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1218 if (error!=OMX_ErrorNone){
1219 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1220 DeAllocateCodecsOMX();
1226 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1227 if (error!=OMX_ErrorNone){
1228 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1229 DeAllocateCodecsOMX();
1232 omx_shed_input_port=p_param.nStartPortNumber;
1233 omx_shed_output_port=p_param.nStartPortNumber+1;
1236 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1237 if (error!=OMX_ErrorNone){
1238 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1239 DeAllocateCodecsOMX();
1242 omx_shed_clock_port=p_param.nStartPortNumber;
1245 if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
1246 || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
1247 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1248 DeAllocateCodecsOMX();
1253 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1254 if (error!=OMX_ErrorNone){
1255 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1256 DeAllocateCodecsOMX();
1260 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1261 if (error!=OMX_ErrorNone){
1262 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1263 DeAllocateCodecsOMX();
1266 omx_rend_input_port=p_param.nStartPortNumber;
1267 //omx_rend_output_port=p_param.nStartPortNumber+1;
1270 if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1272 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1273 DeAllocateCodecsOMX();
1286 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1287 if (error!=OMX_ErrorNone){
1288 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1295 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1296 memset(&ft_type,0,sizeof(ft_type));
1297 ft_type.nSize=sizeof(ft_type);
1298 ft_type.nVersion.nVersion=OMX_VERSION;
1300 ft_type.nPortIndex=omx_codec_input_port;
1302 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1304 //ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1305 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
1306 decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
1307 InitTranscoderLibAV();
1310 Demuxer* demux=Demuxer::getInstance();
1312 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1313 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1314 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1315 if (error!=OMX_ErrorNone){
1316 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1317 DeAllocateCodecsOMX();
1322 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1323 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1324 DeAllocateCodecsOMX();
1329 if (!PrepareInputBufsOMX()) {
1330 DeAllocateCodecsOMX();
1335 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1336 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
1337 DeAllocateCodecsOMX();
1341 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1342 if (error!=OMX_ErrorNone){
1343 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);
1344 DeAllocateCodecsOMX();
1348 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1350 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1351 DeAllocateCodecsOMX();
1355 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1356 DeAllocateCodecsOMX();
1360 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1361 if (error!=OMX_ErrorNone){
1362 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1363 DeAllocateCodecsOMX();
1369 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1371 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1372 DeAllocateCodecsOMX();
1376 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1379 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1380 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1381 DeAllocateCodecsOMX();
1384 if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
1385 ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
1386 DeAllocateCodecsOMX();
1390 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1391 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1392 DeAllocateCodecsOMX();
1396 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1397 if (error!=OMX_ErrorNone){
1398 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1399 DeAllocateCodecsOMX();
1403 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1405 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1406 DeAllocateCodecsOMX();
1410 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1411 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1412 DeAllocateCodecsOMX();
1416 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1417 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1418 DeAllocateCodecsOMX();
1423 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1424 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1425 DeAllocateCodecsOMX();
1429 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1430 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1431 DeAllocateCodecsOMX();
1436 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1437 memset(&dispconf,0,sizeof(dispconf));
1438 dispconf.nSize=sizeof(dispconf);
1439 dispconf.nVersion.nVersion=OMX_VERSION;
1441 dispconf.nPortIndex=omx_rend_input_port;
1443 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1445 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1446 if (error!=OMX_ErrorNone){
1447 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1448 DeAllocateCodecsOMX();
1452 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1453 dispconf.fullscreen=OMX_FALSE;
1454 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1455 if (error!=OMX_ErrorNone){
1456 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1457 DeAllocateCodecsOMX();
1461 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1462 dispconf.dest_rect.x_offset=100;
1463 dispconf.dest_rect.y_offset=100;
1464 dispconf.dest_rect.width=640;
1465 dispconf.dest_rect.height=480;
1466 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1467 if (error!=OMX_ErrorNone){
1468 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1469 DeAllocateCodecsOMX();
1476 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1477 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1478 DeAllocateCodecsOMX();
1482 if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
1489 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1491 OMX_ERRORTYPE error;
1492 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1493 if (error!=OMX_ErrorNone){
1494 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1498 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1506 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1508 OMX_ERRORTYPE error;
1509 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1510 if (error!=OMX_ErrorNone){
1511 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1515 if (!wait) return 1;
1516 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1524 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1526 OMX_ERRORTYPE error;
1527 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1528 if (error!=OMX_ErrorNone){
1529 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1533 if (!wait) return 1;
1534 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1545 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1549 omx_event_mutex.Lock();
1550 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1551 while (itty!=omx_events.end()) {
1553 VPE_OMX_EVENT current=*itty;
1554 if (current.handle==handle) { //this is ours
1555 if (current.event_type==OMX_EventError) {
1556 omx_events.erase(itty);
1557 omx_event_mutex.Unlock();
1560 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1561 omx_events.erase(itty);
1562 omx_event_mutex.Unlock();
1569 omx_event_mutex.Unlock();
1574 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1583 int VideoVPEOGL::PrepareInputBufsOMX()
1585 OMX_ERRORTYPE error;
1586 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1587 memset(&port_def_type,0,sizeof(port_def_type));
1588 port_def_type.nSize=sizeof(port_def_type);
1589 port_def_type.nVersion.nVersion=OMX_VERSION;
1590 port_def_type.nPortIndex=omx_codec_input_port;
1592 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1594 if (error!=OMX_ErrorNone){
1595 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1597 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1598 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1599 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1601 port_def_type.nBufferCountActual=60;
1602 port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1604 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1606 if (error!=OMX_ErrorNone){
1607 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1611 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1612 if (error!=OMX_ErrorNone){
1613 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1617 input_bufs_omx_mutex.Lock();
1618 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1620 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1621 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1622 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1623 if (error!=OMX_ErrorNone){
1624 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1625 input_bufs_omx_mutex.Unlock();
1628 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1629 if (error!=OMX_ErrorNone){
1630 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1631 input_bufs_omx_mutex.Unlock();
1634 input_bufs_omx_all.push_back(buf_head);
1635 input_bufs_omx_free.push_back(buf_head);
1636 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1637 transcode_pix_fmt* new_pix=NULL;
1638 new_pix=(transcode_pix_fmt*)malloc(sizeof(transcode_pix_fmt));
1639 pix_fmt_omx_all.push_back(new_pix);
1640 pix_fmt_omx_free.push_back(new_pix);
1643 omx_first_frame=true;
1646 cur_input_buf_omx=NULL;
1647 input_bufs_omx_mutex.Unlock();
1650 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1651 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1654 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1659 int VideoVPEOGL::DestroyInputBufsOMX()
1661 OMX_ERRORTYPE error;
1663 cur_input_buf_omx=NULL;
1664 input_bufs_omx_mutex.Lock();
1665 for (int i=0; i< input_bufs_omx_all.size();i++) {
1666 // free(input_bufs_omx_all[i]->pBuffer);
1667 // input_bufs_omx_all[i]->pBuffer=NULL;
1668 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1669 if (error!=OMX_ErrorNone){
1670 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1671 input_bufs_omx_mutex.Unlock();
1675 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1676 free(pix_fmt_omx_all[i]);
1679 input_bufs_omx_all.clear();
1680 input_bufs_omx_free.clear();
1681 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1682 input_bufs_omx_in_libav.clear();
1683 pix_fmt_omx_all.clear();
1684 pix_fmt_omx_free.clear();
1686 input_bufs_omx_mutex.Unlock();
1693 int VideoVPEOGL::DeAllocateCodecsOMX()
1695 OMX_ERRORTYPE error;
1697 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1698 if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
1699 DeInitTranscoderLibAV();
1703 // first flush all buffers
1705 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1706 if (error!=OMX_ErrorNone){
1707 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1711 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1712 if (error!=OMX_ErrorNone){
1713 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1717 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1718 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1719 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1722 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1723 if (error!=OMX_ErrorNone){
1724 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1728 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1729 if (error!=OMX_ErrorNone){
1730 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1734 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1735 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1736 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1739 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1740 if (error!=OMX_ErrorNone) {
1741 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1745 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1746 if (error!=OMX_ErrorNone) {
1747 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1751 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1752 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1753 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1759 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1760 if (error!=OMX_ErrorNone){
1761 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1766 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1767 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1770 DestroyInputBufsOMX();
1773 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1774 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1776 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1777 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1780 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1781 if (error!=OMX_ErrorNone){
1782 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1786 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1787 if (error!=OMX_ErrorNone){
1788 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1792 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1793 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1796 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1797 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1800 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1801 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1803 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1804 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1809 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1810 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1814 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1815 if (error!=OMX_ErrorNone){
1816 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1819 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1820 if (error!=OMX_ErrorNone){
1821 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1825 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1826 if (error!=OMX_ErrorNone){
1827 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1831 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1832 if (error!=OMX_ErrorNone){
1833 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1841 error=OMX_FreeHandle(omx_vid_dec);
1842 error=OMX_FreeHandle(omx_vid_sched);
1843 error=OMX_FreeHandle(omx_vid_rend);
1844 error=OMX_FreeHandle(omx_clock);
1846 if (error!=OMX_ErrorNone) {
1847 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1857 #ifdef VPE_LIBAV_SUPPORT
1859 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1861 int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1862 enum PixelFormat ret_pix=PIX_FMT_NONE;
1863 if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1864 while (*fmt!=PIX_FMT_NONE) {
1865 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1866 ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1867 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1868 ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1875 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
1876 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
1878 if ((y+height)==src->height) {
1879 /* Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
1880 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
1881 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
1882 Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
1884 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
1889 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1891 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1895 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1897 unsigned int want_sizes[4]={0,0,0,0};
1899 bool normal_pixs=false;
1901 int num_dct_blocks=0;
1904 //reget logic from mplayer
1905 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1906 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1911 if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1913 // standard pixel format
1914 // this is written using much inspiration from libav util.c, so portions from there
1920 avcodec_align_dimensions2(c, &width, &height, s_a);
1921 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1925 // Now we have to determine alignment size
1926 bool unaligned=true;
1928 av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1929 width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1931 for (int i=0;i<4;i++) {
1932 if ((pict.linesize[i]%s_a[i])!=0) {
1938 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1939 for (int i=0;i<4 ;i++) {
1940 if (i<3 && pict.data[i+1]) {
1941 want_sizes[i]=pict.data[i+1]-pict.data[i];
1944 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1951 //TODO set linesizes!
1953 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1954 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1956 want_sizes[2]=sizeof(xvmc_pix_fmt);
1957 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1958 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1959 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1963 VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1964 frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
1965 frame_buf->ogl_uploaded=false; //not uploaded yet
1966 frame_buf->width=pic->width;
1967 frame_buf->height=pic->height;
1968 frame_buf->stride=pic->linesize[0];
1970 //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1972 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1978 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1979 int hchr_shift,vchr_shift;
1980 avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1981 const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1982 for (int i=0;i<4;i++) {
1983 pic->data[i]=(uint8_t*)frame_buf->data[i];
1984 pic->linesize[i]=pict.linesize[i];
1990 edge_width>>=hchr_shift;
1991 edge_height>>=vchr_shift;
1993 pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1997 pic->base[0]=(uint8_t*)frame_buf; // our structure
1998 //pic->extended_data=pic->data;
1999 if(c->pkt) pic->pkt_pts=c->pkt->pts;
2000 else pic->pkt_pts=AV_NOPTS_VALUE;
2001 pic->width=c->width;
2002 pic->height=c->height;
2003 pic->format=c->pix_fmt;
2004 pic->sample_aspect_ratio=c->sample_aspect_ratio;
2005 pic->reordered_opaque= c->reordered_opaque;
2008 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
2009 pix_xvmc->xvmc_id=AV_XVMC_ID;
2010 pix_xvmc->data_blocks=(short*)pic->data[1];
2011 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
2012 pix_xvmc->allocated_mv_blocks=num_blocks;
2013 pix_xvmc->allocated_data_blocks=num_dct_blocks;
2014 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
2015 else pix_xvmc->idct=0;
2016 pix_xvmc->unsigned_intra=1; // let see what happens
2017 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
2018 pix_xvmc->start_mv_blocks_num=0;
2019 pix_xvmc->filled_mv_blocks_num=0;
2020 pix_xvmc->next_free_data_block_num=0;
2030 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2032 // Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
2033 ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
2035 pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
2040 int VideoVPEOGL::AllocateCodecsLibav()
2042 if (libav_running) DeAllocateCodecsLibav();
2043 libav_hastime=false;
2044 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
2045 mpeg2codec_context_libav=avcodec_alloc_context();
2046 if (mpeg2codec_context_libav==NULL) {
2047 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
2050 if (decoding_mode!=VPE_NO_XVMC) {
2051 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
2052 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
2053 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
2054 mpeg2codec_context_libav->get_format=get_format_libav;
2055 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
2058 mpeg2codec_context_libav->get_buffer=get_buffer_libav;
2059 mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
2060 mpeg2codec_context_libav->release_buffer=release_buffer_libav;
2064 int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
2066 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
2069 memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
2070 incom_packet_libav_size=200000;
2071 incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2073 dec_frame_libav_mutex.Lock();
2074 for (int i=0;i<3;i++) {
2075 AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
2076 if (!dec_frame_libav) {
2077 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
2080 dec_frame_libav_all.push_back(dec_frame_libav);
2081 dec_frame_libav_free.push_back(dec_frame_libav);
2083 dec_frame_libav_decoding=NULL;
2084 dec_frame_libav_mutex.Unlock();
2086 ogl_frame_mutex.Lock();
2087 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
2088 for (int i=0;i<5;i++) {
2089 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
2090 new_frame->type=1; //1 = YUV, 2 RGB
2091 new_frame->textures[0]=0;
2092 new_frame->textures[1]=0;
2093 new_frame->textures[2]=0;
2094 new_frame->width=new_frame->height=0;
2095 all_ogl_frames.push_back(new_frame);
2096 free_ogl_frames.push_back(new_frame);
2099 ogl_frame_outside=false;
2101 ogl_frame_mutex.Unlock();
2103 if (decoding_mode==VPE_XVMC_MOCOMP) {
2104 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2105 osd->BeginPainting(); // get OpenGl context
2106 moco_shader=new GLMocoShader();
2107 moco_shader->init();
2117 int VideoVPEOGL::DeAllocateCodecsLibav()
2119 libav_running=false;
2120 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
2121 dec_frame_libav_mutex.Lock();
2122 dec_frame_libav_upload_and_view_pending.clear();
2123 dec_frame_libav_upload_only_pending.clear();
2124 dec_frame_libav_free.clear();
2125 dec_frame_libav_mutex.Unlock();
2126 while (dec_frame_libav_uploading_framebuf) {
2127 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
2130 dec_frame_libav_mutex.Lock();
2131 for (int i=0; i< dec_frame_libav_all.size();i++) {
2132 av_free(dec_frame_libav_all[i]);
2135 dec_frame_libav_all.clear();
2137 av_free(incom_packet_libav.data);
2138 incom_packet_libav.data=NULL;
2139 incom_packet_libav_size=0;
2141 dec_frame_libav_mutex.Unlock();
2142 dec_frame_libav_decoding=NULL;
2143 while (ogl_frame_outside) {
2144 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
2148 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
2149 ogl_frame_mutex.Lock();
2150 for (int i=0; i< dec_frame_libav_all.size();i++) {
2151 VPEOGLFrame * del_frame=all_ogl_frames[i];
2152 if (del_frame->textures[0]==0) {
2153 glDeleteTextures(1,&del_frame->textures[0]);
2154 del_frame->textures[0]=0;
2156 if (del_frame->textures[1]==0) {
2157 glDeleteTextures(1,&del_frame->textures[1]);
2158 del_frame->textures[1]=0;
2160 if (del_frame->textures[2]==0) {
2161 glDeleteTextures(1,&del_frame->textures[2]);
2162 del_frame->textures[2]=0;
2165 free(all_ogl_frames[i]);
2167 all_ogl_frames.clear();
2168 free_ogl_frames.clear();
2169 ready_ogl_frames.clear();
2170 recycle_ref_ogl_frames.clear();
2171 ogl_forward_ref_frame_num=0;
2172 ogl_backward_ref_frame_num=0;
2173 ogl_forward_ref_frame=NULL;
2174 ogl_backward_ref_frame=NULL;
2176 ogl_frame_mutex.Unlock();
2177 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
2180 if (mpeg2codec_context_libav) {
2181 avcodec_close(mpeg2codec_context_libav);
2182 av_free(mpeg2codec_context_libav);
2183 mpeg2codec_context_libav=NULL;
2189 vpe_framebuf_mutex.Lock();
2191 for (int i=0;i<all_frame_bufs.size();i++) {
2192 VPE_FrameBuf* current=all_frame_bufs[i];
2193 for (int x=0;x<4;x++) {
2194 if (current->data[x]) {
2195 av_free(current->data[x]);
2200 all_frame_bufs.clear();
2201 free_frame_bufs.clear();
2202 locked_libav_frame_buf.clear();
2203 locked_uploading_frame_buf.clear();
2205 vpe_framebuf_mutex.Unlock();
2210 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2211 osd->BeginPainting(); // get OpenGl context
2212 moco_shader->deinit();
2226 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
2228 VPE_FrameBuf* current=NULL;
2229 vpe_framebuf_mutex.Lock();
2230 if (free_frame_bufs.size()>0) {
2231 current=free_frame_bufs.front();
2232 free_frame_bufs.pop_front();
2233 } else if (all_frame_bufs.size()<6) {
2234 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
2235 memset(current,0,sizeof(VPE_FrameBuf));
2237 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
2238 vpe_framebuf_mutex.Unlock();
2239 return NULL; // We do not have a frame buffer
2241 locked_libav_frame_buf.push_back(current);
2242 vpe_framebuf_mutex.Unlock();
2243 //check if we need reallocation
2244 for (int x=0;x<4;x++) {
2245 if (current->size[x]!=size[x]) {
2246 current->data[x]=av_realloc(current->data[x],size[x]);
2247 current->size[x]=size[x];
2250 framebuf_framenum++;
2251 current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
2256 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
2258 // first find frame_buf memory
2260 //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
2261 VPE_FrameBuf* current=buf;
2262 vpe_framebuf_mutex.Lock();
2263 if (current) locked_uploading_frame_buf.push_back(current); //locked
2264 vpe_framebuf_mutex.Unlock();
2269 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
2271 // first find frame_buf memory
2272 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
2273 VPE_FrameBuf* current=buf;
2274 vpe_framebuf_mutex.Lock();
2276 locked_libav_frame_buf.remove(current); //unlocked
2277 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
2279 while (itty!=locked_uploading_frame_buf.end()) {
2280 if (*itty==current) {
2287 free_frame_bufs.push_back(current);
2290 vpe_framebuf_mutex.Unlock();
2293 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
2295 // first find frame_buf memory
2296 VPE_FrameBuf* current=buf;
2297 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
2298 vpe_framebuf_mutex.Lock();
2300 locked_uploading_frame_buf.remove(current); //unlocked
2301 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
2303 while (itty!=locked_libav_frame_buf.end()) {
2304 if (*itty==current) {
2311 free_frame_bufs.push_back(current);
2314 vpe_framebuf_mutex.Unlock();
2317 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
2319 dec_frame_libav_mutex.Lock();
2320 libavwidth=s->width;
2321 libavheight=s->height;
2322 libavpixfmt=s->pix_fmt;
2323 //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
2325 dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
2326 dec_frame_libav_mutex.Unlock();
2336 int VideoVPEOGL::stop()
2338 if (!initted) return 0;
2340 #ifdef VPE_OMX_SUPPORT
2341 //Check if libav mode
2342 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2349 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2353 int VideoVPEOGL::reset()
2355 if (!initted) return 0;
2357 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2361 int VideoVPEOGL::pause()
2363 if (!initted) return 0;
2365 // if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
2369 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
2371 if (!initted) return 0;
2372 // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2376 int VideoVPEOGL::fastForward()
2378 if (!initted) return 0;
2380 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2384 int VideoVPEOGL::unFastForward()
2386 if (!initted) return 0;
2388 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2390 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2394 int VideoVPEOGL::attachFrameBuffer()
2396 if (!initted) return 0;
2398 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2402 int VideoVPEOGL::blank(void)
2404 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2405 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2409 ULLONG VideoVPEOGL::getCurrentTimestamp()
2411 /* sync_data_t timestamps;
2412 if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
2414 // FIXME are these the right way around?
2416 timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
2417 timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
2419 return timestamps.stc;
2428 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2430 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2431 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2435 int VideoVPEOGL::test()
2440 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2447 int VideoVPEOGL::test2()
2453 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2455 mediapacket = mplist.front();
2458 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2460 DeliverMediaPacket(mediapacket, buffer, samplepos);
2461 if (*samplepos == mediapacket.length) {
2468 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2469 const UCHAR* buffer,
2472 if (packet.type == MPTYPE_VIDEO_H264)
2480 switch (decoding_backend) {
2481 default: case 0: return 0; // no backend runnigng
2482 #ifdef VPE_OMX_SUPPORT
2483 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2484 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2485 case VPE_DECODER_OMX_libav_TRANSCODE: return DeliverMediaPacketOMXTranscode(packet,buffer,samplepos);
2488 #ifdef VPE_LIBAV_SUPPORT
2489 case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2494 #ifdef VPE_OMX_SUPPORT
2495 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2496 const UCHAR* buffer,
2501 //Later add fail back code for libav
2503 *samplepos+=packet.length;
2504 return packet.length;
2508 if (!omx_running) return 0; // if we are not runnig do not do this
2511 OMX_ERRORTYPE error;
2513 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
2514 memset(&port_image,0,sizeof(port_image));
2515 port_image.nSize=sizeof(port_image);
2516 port_image.nVersion.nVersion=OMX_VERSION;
2517 port_image.nPortIndex =omx_codec_output_port;
2518 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2519 if (error!= OMX_ErrorNone){
2520 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2522 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2524 /*First Check, if we have an audio sample*/
2528 return 0; //Not in iframe mode!
2532 if (packet.disconti) {
2534 if (cur_input_buf_omx) {
2535 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2536 if (error!=OMX_ErrorNone){
2537 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2539 cur_input_buf_omx=NULL;
2543 /*Inspect PES-Header */
2545 // OMX_STATETYPE temp_state;
2546 // OMX_GetState(omx_vid_dec,&temp_state);
2548 if (*samplepos==0) {//stripheader
2549 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2550 *samplepos+=headerstrip;
2551 if ( packet.synched ) {
2553 if (cur_input_buf_omx) {
2554 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2555 if (error!=OMX_ErrorNone){
2556 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2559 cur_input_buf_omx=NULL;//write out old data
2561 // reftime1=packet.presentation_time;
2562 // reftime2=reftime1+1;
2565 if (!firstsynched) {//
2566 *samplepos=packet.length;//if we have not processed at least one
2567 return packet.length;//synched packet ignore it!
2572 if (!cur_input_buf_omx) {
2573 input_bufs_omx_mutex.Lock();
2574 if (input_bufs_omx_free.size()==0) {
2575 input_bufs_omx_mutex.Unlock();
2576 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2577 return 0; // we do not have a free media sample
2580 cur_input_buf_omx=input_bufs_omx_free.front();
2581 cur_input_buf_omx->nFilledLen=0;
2582 cur_input_buf_omx->nOffset=0;
2583 cur_input_buf_omx->nTimeStamp=0;
2584 input_bufs_omx_free.pop_front();
2585 input_bufs_omx_mutex.Unlock();
2591 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2592 /*if (packet.disconti) {
2593 ms->SetDiscontinuity(TRUE);
2595 ms->SetDiscontinuity(FALSE);
2597 //if (packet.synched) {
2599 //lastreftimePTS=packet.pts;
2600 if (omx_first_frame) { // TODO time
2601 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2602 omx_first_frame=false;
2608 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2611 // ms->SetSyncPoint(TRUE);
2615 unsigned int haveToCopy=packet.length-*samplepos;
2617 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2618 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2619 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2620 haveToCopy-=cancopy;
2621 cur_input_buf_omx->nFilledLen+=cancopy;
2622 *samplepos+=cancopy;
2623 // push old buffer out
2625 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2626 if (error!=OMX_ErrorNone){
2627 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2630 input_bufs_omx_mutex.Lock();
2631 if (input_bufs_omx_free.size()==0) {
2632 input_bufs_omx_mutex.Unlock();
2633 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2634 return *samplepos; // we do not have a free media sample
2636 cur_input_buf_omx=input_bufs_omx_free.front();
2637 cur_input_buf_omx->nFilledLen=0;
2638 cur_input_buf_omx->nOffset=0;
2639 cur_input_buf_omx->nTimeStamp=0;
2640 input_bufs_omx_free.pop_front();
2641 input_bufs_omx_mutex.Unlock();
2643 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2646 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2647 buffer+packet.pos_buffer+*samplepos,haveToCopy);
2648 cur_input_buf_omx->nFilledLen+=haveToCopy;
2652 *samplepos+=haveToCopy;
2660 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2664 int VideoVPEOGL::DecodePacketOMXTranscode()
2666 unsigned int haveToCopy=incom_packet_libav.size;
2667 if (incom_packet_libav.size==0) return 1; // we are already empty
2670 while (haveToCopy>0) {
2674 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2676 #ifdef BENCHMARK_FPS
2677 int cur_time=getTimeMS();
2679 dec_bytes=avcodec_decode_video2(transcodecodec_context_libav, &transcode_frame_libav,
2680 &frame_ready, &incom_packet_libav);
2681 #ifdef BENCHMARK_FPS
2682 time_in_decoder+=getTimeMS()-cur_time;
2683 if (frame_ready) num_frames++;
2684 if ((num_frames%100)==0) {
2685 float fps=1000./(float)(time_in_decoder);
2686 fps*=((float)num_frames);
2687 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2691 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2694 haveToCopy-=dec_bytes;
2696 struct transcode_pix_fmt *transcode=(struct transcode_pix_fmt *)transcode_frame_libav.data[0];
2697 //if (!benchmark) fwrite(transcode->packet.data,transcode->packet.size,1,output_file);
2700 //add omx magic, this should be an omx packet
2701 OMX_BUFFERHEADERTYPE* omx_packet=(OMX_BUFFERHEADERTYPE*)transcode_frame_libav.base[0];
2702 omx_packet->nFilledLen=transcode->packet.size;
2704 input_bufs_omx_mutex.Lock();
2705 input_bufs_omx_in_libav.remove(omx_packet); // say that it is passed down to the decoder
2706 input_bufs_omx_mutex.Unlock();
2708 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,omx_packet);
2709 if (error!=OMX_ErrorNone){
2710 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2718 incom_packet_libav.size=0;
2724 UINT VideoVPEOGL::DeliverMediaPacketOMXTranscode(MediaPacket packet,
2725 const UCHAR* buffer,
2728 //Later add fail back code for libav
2730 *samplepos+=packet.length;
2731 return packet.length;
2734 if (!omx_running) return 0; // if we are not runnig do not do this
2740 return 0; //Not in iframe mode!
2744 if (packet.disconti) {
2746 if (!DecodePacketOMXTranscode()) return 0;
2749 /*Inspect PES-Header */
2750 if (*samplepos==0) {//stripheader
2751 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2752 *samplepos+=headerstrip;
2753 if ( packet.synched ) {
2755 if (!DecodePacketOMXTranscode()) return 0; // WriteOut old Data
2758 incom_packet_libav.pts=packet.pts/3600;
2759 incom_packet_libav.dts=packet.dts/3600;
2760 // reftime1=packet.presentation_time;
2761 // reftime2=reftime1+1;
2764 incom_packet_libav.pts=0;
2765 incom_packet_libav.dts=0;
2766 if (!firstsynched) {//
2767 *samplepos=packet.length;//if we have not processed at least one
2768 return packet.length;//synched packet ignore it!
2778 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2779 /*if (packet.disconti) {
2780 ms->SetDiscontinuity(TRUE);
2782 ms->SetDiscontinuity(FALSE);
2784 //if (packet.synched) {
2786 //lastreftimePTS=packet.pts;
2787 if (omx_first_frame) { // TODO time
2788 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2789 omx_first_frame=false;
2795 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2798 // ms->SetSyncPoint(TRUE);
2802 unsigned int haveToCopy=packet.length-*samplepos;
2804 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2805 // if the buffer is to small reallocate
2806 incom_packet_libav_size+=haveToCopy;
2807 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2808 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2810 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2811 incom_packet_libav.size+=haveToCopy;
2813 *samplepos+=haveToCopy;
2824 #ifdef VPE_LIBAV_SUPPORT
2825 int VideoVPEOGL::DecodePacketlibav()
2827 unsigned int haveToCopy=incom_packet_libav.size;
2828 if (incom_packet_libav.size==0) return 1; // we are already empty
2829 while (haveToCopy>0) {
2833 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2835 #ifdef BENCHMARK_FPS
2836 int cur_time=getTimeMS();
2838 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2839 &frame_ready, &incom_packet_libav);
2840 #ifdef BENCHMARK_FPS
2841 time_in_decoder+=getTimeMS()-cur_time;
2842 if (frame_ready) num_frames++;
2843 if ((num_frames%100)==0) {
2844 float fps=1000./(float)(time_in_decoder);
2845 fps*=((float)num_frames);
2846 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2850 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2853 haveToCopy-=dec_bytes;
2855 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2857 lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2858 dec_frame_libav_mutex.Lock();
2859 libavwidth=mpeg2codec_context_libav->width;
2860 libavheight=mpeg2codec_context_libav->height;
2861 libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2862 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2863 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
2864 // ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
2867 dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
2868 dec_frame_libav_decoding=NULL;
2869 if (dec_frame_libav_free.size()>0) {
2870 dec_frame_libav_decoding=dec_frame_libav_free.front();
2871 dec_frame_libav_free.pop_front();
2872 dec_frame_libav_mutex.Unlock();
2874 libav_hastime=false;
2876 libav_hastime=false;
2877 dec_frame_libav_mutex.Unlock();
2878 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
2888 incom_packet_libav.size=0;
2894 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2895 const UCHAR* buffer,
2898 //Later add fail back code for libav
2900 *samplepos+=packet.length;
2901 return packet.length;
2904 if (!libav_running) return 0; // if we are not runnig do not do this
2910 return 0; //Not in iframe mode!
2914 if (packet.disconti) {
2916 if (!DecodePacketlibav()) return 0;
2919 /*Inspect PES-Header */
2920 if (!dec_frame_libav_decoding) {
2921 dec_frame_libav_mutex.Lock();
2922 if (dec_frame_libav_free.size()>0) {
2923 dec_frame_libav_decoding=dec_frame_libav_free.front();
2924 dec_frame_libav_free.pop_front();
2925 dec_frame_libav_mutex.Unlock();
2927 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
2928 dec_frame_libav_mutex.Unlock();
2936 if (*samplepos==0) {//stripheader
2937 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2938 *samplepos+=headerstrip;
2939 if ( packet.synched ) {
2941 if (!DecodePacketlibav()) return 0; // WriteOut old Data
2943 libav_time=packet.presentation_time;
2945 // reftime1=packet.presentation_time;
2946 // reftime2=reftime1+1;
2949 if (!firstsynched) {//
2950 *samplepos=packet.length;//if we have not processed at least one
2951 return packet.length;//synched packet ignore it!
2961 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2962 /*if (packet.disconti) {
2963 ms->SetDiscontinuity(TRUE);
2965 ms->SetDiscontinuity(FALSE);
2967 //if (packet.synched) {
2969 //lastreftimePTS=packet.pts;
2970 if (omx_first_frame) { // TODO time
2971 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2972 omx_first_frame=false;
2978 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2981 // ms->SetSyncPoint(TRUE);
2985 unsigned int haveToCopy=packet.length-*samplepos;
2987 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2988 // if the buffer is to small reallocate
2989 incom_packet_libav_size+=haveToCopy;
2990 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2991 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2993 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2994 incom_packet_libav.size+=haveToCopy;
2996 *samplepos+=haveToCopy;
3011 void VideoVPEOGL::ResetTimeOffsets()
3015 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
3017 //write(fdVideo, buffer, length);
3018 if (!iframemode) EnterIframePlayback();
3019 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
3025 int VideoVPEOGL::EnterIframePlayback()