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;
68 offsetvideonotset=true;
69 offsetaudionotset=true;
87 VideoVPEOGL::~VideoVPEOGL()
92 int VideoVPEOGL::init(UCHAR tformat)
94 if (initted) return 0;
97 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
99 if (!setFormat(tformat)) { shutdown(); return 0; }
100 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
101 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
102 if (!setMode(NORMAL)) { shutdown(); return 0; }
103 if (!setSource()) { shutdown(); return 0; }
104 if (!attachFrameBuffer()) { shutdown(); return 0; }
106 setTVsize(ASPECT4X3);
108 /* if (format == PAL) setLetterboxBorder("38");
109 else setLetterboxBorder("31");*/
123 int VideoVPEOGL::initUsingOSDObjects()
125 EGLDisplay i_egl_display;
126 EGLSurface i_egl_surface;
127 EGLContext i_egl_context;
128 EGLConfig i_egl_config;
129 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
130 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
131 const EGLint attr_context[]={
132 EGL_CONTEXT_CLIENT_VERSION,2,
136 egl_display=i_egl_display;
137 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
138 if (egl_context==EGL_NO_CONTEXT) {
139 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
142 // We create a dummy surface here, in order to allow two contexts
143 const EGLint attr_pbuffer[]={
144 EGL_WIDTH, 1, EGL_HEIGHT,1,
147 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
148 if (egl_surface==EGL_NO_SURFACE) {
149 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
156 //egl_surface=i_egl_surface;
157 //egl_context=i_egl_context;
160 #ifdef VPE_OMX_SUPPORT
161 // we are called before the audio
164 if (error!=OMX_ErrorNone) {
165 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
169 //our callbacks move to play?
173 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)
177 #ifdef VPE_LIBAV_SUPPORT
180 if (decoding_mode==VPE_NO_XVMC) {
181 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
183 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
185 if (mpeg2codec_libav==NULL) {
186 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
190 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
191 transcodecodec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_MPEG4);
192 if (transcodecodec_libav==NULL) {
193 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 transcoder failed");
204 #ifdef VPE_OMX_SUPPORT
206 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
207 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
208 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
210 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
212 struct VPE_OMX_EVENT new_event;
213 new_event.handle=handle;
214 new_event.appdata=appdata;
215 new_event.event_type=event_type;
216 new_event.data1=data1;
217 new_event.data2=data2;
218 new_event.event_data=event_data;
220 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
221 video->AddOmxEvent(new_event);
223 /* switch (event_type) {
224 case OMX_EventCmdComplete: {
229 return OMX_ErrorNone;
233 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
235 omx_event_mutex.Lock();
236 omx_events.push_back(new_event);
237 omx_event_mutex.Unlock();
241 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
243 //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
244 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
245 video->ReturnEmptyOMXBuffer(buffer);
246 return OMX_ErrorNone;
250 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
251 input_bufs_omx_mutex.Lock();
252 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
253 input_bufs_omx_free.push_back(buffer);
254 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
255 input_bufs_omx_mutex.Unlock();
258 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
259 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
260 return OMX_ErrorNone;
263 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
265 enum PixelFormat VideoVPEOGL::get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt)
267 enum PixelFormat ret_pix=PIX_FMT_NONE;
269 while (*fmt!=PIX_FMT_NONE) {
270 if (*fmt== PIX_FMT_TRANSCODE ) {
271 ret_pix=PIX_FMT_TRANSCODE;
278 int VideoVPEOGL::reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
280 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!Not Implemented! \n");
285 int VideoVPEOGL::get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
288 //reget logic from mplayer
289 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
290 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!\n");
295 if (c->pix_fmt!=PIX_FMT_TRANSCODE ) {
296 Log::getInstance()->log("Video", Log::DEBUG,"We only support transcode pixel fmt\n");
299 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
300 transcode_pix_fmt *pix_trans=NULL;
301 OMX_BUFFERHEADERTYPE* our_buf=video->GetFreeOMXBufferforlibav(&pix_trans);
302 if (our_buf==NULL|| pix_trans==NULL) {
303 Log::getInstance()->log("Video", Log::DEBUG,"Getting buffer failed\n");
313 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
315 pic->base[0]=(uint8_t*)our_buf; // our buf
316 //pic->extended_data=pic->data;
317 if(c->pkt) pic->pkt_pts=c->pkt->pts;
318 else pic->pkt_pts=AV_NOPTS_VALUE;
320 pic->height=c->height;
321 pic->format=c->pix_fmt;
322 pic->sample_aspect_ratio=c->sample_aspect_ratio;
323 pic->reordered_opaque= c->reordered_opaque;
325 pic->data[0]=(uint8_t*)pix_trans;
326 pix_trans->transcode_id=AV_TRANSCODE_ID;
327 pix_trans->packet.data=(uint8_t*)our_buf->pBuffer;
328 pix_trans->packet.size=our_buf->nAllocLen;
335 OMX_BUFFERHEADERTYPE* VideoVPEOGL::GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans)
337 OMX_BUFFERHEADERTYPE* returned_buf=NULL;
341 while (returned_buf==NULL && time_out<100){
342 input_bufs_omx_mutex.Lock();
343 if (input_bufs_omx_free.size()!=0) {
344 returned_buf=input_bufs_omx_free.front();
345 returned_buf->nFilledLen=0;
346 returned_buf->nOffset=0;
347 returned_buf->nTimeStamp=0;
348 input_bufs_omx_free.pop_front();
349 input_bufs_omx_in_libav.push_back(returned_buf);
350 input_bufs_omx_mutex.Unlock();
351 returned_buf->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
354 input_bufs_omx_mutex.Unlock();
355 Log::getInstance()->log("Video", Log::DEBUG, "GetFreeOMXBuffer_libav no free sample block");
360 *pix_trans=pix_fmt_omx_free.front();
361 pix_fmt_omx_free.pop_front(); // we assume that there is always a twin
366 void VideoVPEOGL::release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
368 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
369 video->ReturnEmptyOMXBuffer_libav((OMX_BUFFERHEADERTYPE*) pic->base[0],(transcode_pix_fmt *)pic->data[0]);
370 pic->data[0]=NULL; //without doing this avcodec is going to cry
373 void VideoVPEOGL::ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt){
374 input_bufs_omx_mutex.Lock();
375 // We only return it, if it was not passed to OMX!
376 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
377 pix_fmt_omx_free.push_back(pix_fmt);
378 list<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_in_libav.begin();
379 while (itty!=input_bufs_omx_in_libav.end()) {
381 input_bufs_omx_in_libav.remove(buffer);
382 input_bufs_omx_free.push_back(buffer);
383 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
387 input_bufs_omx_mutex.Unlock();
395 int VideoVPEOGL::shutdown()
397 if (!initted) return 0;
402 #ifdef VPE_OMX_SUPPORT
403 DeAllocateCodecsOMX();
406 #ifdef VPE_LIBAV_SUPPORT
407 DeAllocateCodecsLibav();
409 eglDestroyContext(egl_display,egl_context);
413 #ifdef VPE_LIBAV_SUPPORT
414 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
416 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
418 glGenTextures(1, &outframe->textures[0]);
419 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
420 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
421 GL_UNSIGNED_BYTE, NULL);
423 glGenTextures(1, &outframe->textures[1]);
424 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
425 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
426 GL_UNSIGNED_BYTE, NULL);
428 glGenTextures(1, &outframe->textures[2]);
429 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
430 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
431 GL_UNSIGNED_BYTE, NULL);
432 outframe->height=height;
433 outframe->width=width;
434 outframe->stride=stride;
439 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
441 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
443 glGenTextures(1, &outframe->textures[0]);
444 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
445 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
446 GL_UNSIGNED_BYTE, NULL);
447 outframe->textures[1]=outframe->textures[2]=0; // no handles here
453 outframe->height=height;
454 outframe->width=width;
455 outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
460 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
461 VPEOGLFrame *return_obj=NULL;
462 ogl_frame_mutex.Lock();
463 if (ready_ogl_frames.size()>0) {
464 return_obj=ready_ogl_frames.front();
465 ready_ogl_frames.pop_front();
466 //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing num: %d",return_obj->pict_num);
467 ogl_frame_outside=true;
469 ogl_frame_mutex.Unlock();
473 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
475 ogl_frame_mutex.Lock();
477 ogl_frame_outside=false;
478 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
479 if (frame->pict_num==ogl_forward_ref_frame_num ||
480 frame->pict_num==ogl_backward_ref_frame_num ) {
481 recycle_ref_ogl_frames.push_back(frame);
483 free_ogl_frames.push_back(frame);
486 ogl_frame_mutex.Unlock();
489 void VideoVPEOGL::recycleOGLRefFrames()
491 // This function recycles frames formerly used as reference frame
492 ogl_frame_mutex.Lock();
493 list<VPEOGLFrame*> keep;
494 list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
495 while (itty!=recycle_ref_ogl_frames.end()) {
496 // Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
497 if ((*itty)->pict_num==ogl_forward_ref_frame_num
498 || (*itty)->pict_num==ogl_backward_ref_frame_num)
500 // ok we have to keep this
501 keep.push_back(*itty);
503 free_ogl_frames.push_back(*itty);
507 recycle_ref_ogl_frames.clear();
508 recycle_ref_ogl_frames=keep;
510 ogl_frame_mutex.Unlock();
516 void VideoVPEOGL::threadMethod()
518 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
519 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
527 #ifdef VPE_LIBAV_SUPPORT
530 dec_frame_libav_mutex.Lock();
531 AVFrame* dec_frame_libav_uploading_int=NULL;
534 if (dec_frame_libav_upload_and_view_pending.size()>0 ) {
536 dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
537 dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
538 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
539 // dec_frame_libav_uploading_framebuf);
540 // if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
541 // ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
544 if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC ) {
545 dec_frame_libav_upload_and_view_pending.pop_front();
546 if (decoding_mode==VPE_NO_XVMC) upload=true;
548 dec_frame_libav_uploading_framebuf=NULL;
549 dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
550 view=false; //do the upload
551 // Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
555 if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
557 dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
558 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
559 // dec_frame_libav_uploading_framebuf);
560 dec_frame_libav_upload_only_pending.pop_front();
563 /* if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
565 dec_frame_libav_uploading=NULL; //do not upload again
574 if (dec_frame_libav_upload_and_view_pending.size()>0
575 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
577 dec_frame_libav_mutex.Unlock();
580 if (dec_frame_libav_uploading_framebuf) {
582 //Code Block for debugging if needed
583 /* Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
584 ogl_frame_mutex.Lock();
585 list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
586 while (itty!=free_ogl_frames.end()) {
587 Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
592 itty=recycle_ref_ogl_frames.begin();
593 while (itty!=recycle_ref_ogl_frames.end()) {
594 Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
598 itty=ready_ogl_frames.begin();
599 while (itty!=ready_ogl_frames.end()) {
600 Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
604 ogl_frame_mutex.Unlock();*/
608 int width,height,pixfmt;
609 //First get a free ogl image
610 VPEOGLFrame* out_frame=NULL;
613 ogl_frame_mutex.Lock();
614 // Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
615 // recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
616 if (all_ogl_frames.size()==0) {
617 ogl_frame_mutex.Unlock(); break;
620 if (free_ogl_frames.size()>0) {
624 out_frame=free_ogl_frames.front();
625 free_ogl_frames.pop_front();
627 ogl_frame_mutex.Unlock();
630 ogl_frame_mutex.Lock();
632 // if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
633 ogl_frame_mutex.Unlock();
637 // Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
638 if (out_frame->textures[0]==0 || out_frame->width!=width ||
639 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
640 if (out_frame->textures[0]!=0) {
641 glDeleteTextures(1,&out_frame->textures[0]);
642 out_frame->textures[0]=0;
644 if (out_frame->textures[1]!=0) {
645 glDeleteTextures(1,&out_frame->textures[1]);
646 out_frame->textures[1]=0;
648 if (out_frame->textures[2]!=0) {
649 glDeleteTextures(1,&out_frame->textures[2]);
650 out_frame->textures[2]=0;
653 if (decoding_mode==VPE_NO_XVMC) {
654 if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
656 if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
657 // the shaders are easier to implement
660 dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
661 dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
665 //up to now only YUV data, this is for reference only, since the pi is too slow.
666 if (decoding_mode==VPE_NO_XVMC) {
667 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
668 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
669 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
670 out_frame->stride,out_frame->height,
671 GL_LUMINANCE,GL_UNSIGNED_BYTE,
672 dec_frame_libav_uploading_framebuf->data[0]);
674 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
675 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
676 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
677 out_frame->stride>>1,out_frame->height>>1,
678 GL_LUMINANCE,GL_UNSIGNED_BYTE,
679 dec_frame_libav_uploading_framebuf->data[1]);
681 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
682 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
683 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
684 out_frame->stride>>1,out_frame->height>>1,
685 GL_LUMINANCE,GL_UNSIGNED_BYTE,
686 dec_frame_libav_uploading_framebuf->data[2]);
689 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
690 if (moco_shader && pix_fmt) {
693 int cur_time=getTimeMS();
695 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
696 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
697 // Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
698 // pix_fmt->p_past_surface,pix_fmt->p_future_surface);
700 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
702 //Now determine the frame, that fits
703 ogl_frame_mutex.Lock();
705 for (int i=0;i<all_ogl_frames.size();i++) {
706 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
708 ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
709 ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
710 ogl_backward_ref_frame=all_ogl_frames[i];
711 ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
716 // if (!found) {// for debugging
717 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
721 ogl_frame_mutex.Unlock();
722 recycleOGLRefFrames(); //needed for recycling of reference frames
724 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
727 if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
732 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
734 //Now determine the frame, that fits
735 ogl_frame_mutex.Lock();
737 for (int i=0;i<all_ogl_frames.size();i++) {
738 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
740 ogl_forward_ref_frame=all_ogl_frames[i];
741 ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
747 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
748 // ((int)pix_fmt->p_past_surface));
752 ogl_frame_mutex.Unlock();
753 recycleOGLRefFrames(); //needed for recycling of reference frames
756 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
758 if (decoding_mode==VPE_XVMC_MOCOMP)
765 out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
767 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
769 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
770 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
773 time_in_decoder_gl+=getTimeMS()-cur_time;
775 if ((num_frames_gl%100)==0) {
776 float fps=1000./(float)(time_in_decoder_gl);
777 fps*=((float)num_frames_gl);
778 Log::getInstance()->log("Video", Log::NOTICE, "Current GL Decoding FPS %g", fps);
782 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
783 // Excute motion compensation
785 //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
801 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
802 VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
803 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
804 /* Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
805 pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
806 Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
808 releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
809 ogl_frame_mutex.Lock();
810 ready_ogl_frames.push_back(out_frame);
811 ogl_frame_mutex.Unlock();
812 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
814 dec_frame_libav_mutex.Lock();
815 dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
816 dec_frame_libav_mutex.Unlock();
820 dec_frame_libav_mutex.Lock();
821 dec_frame_libav_uploading_framebuf=NULL;
823 if (dec_frame_libav_upload_and_view_pending.size()>0
824 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
826 dec_frame_libav_mutex.Unlock();
834 struct timespec target_time;
836 clock_gettime(CLOCK_REALTIME,&target_time);
837 target_time.tv_nsec+=1000000LL*ts;
838 if (target_time.tv_nsec>999999999) {
839 target_time.tv_nsec-=1000000000L;
840 target_time.tv_sec+=1;
842 threadWaitForSignalTimed(&target_time);
843 //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
851 void VideoVPEOGL::threadPostStopCleanup()
853 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
854 #ifdef VPE_LIBAV_SUPPORT
855 dec_frame_libav_uploading_framebuf=NULL;
862 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
866 // Override the aspect ratio usage, temporarily use to set the video chip mode
867 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
869 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
870 if (!setSource()) { shutdown(); return 0; }
871 if (!attachFramebuffer()) { shutdown(); return 0; }
873 // Reopening the fd causes the scart aspect line to go back to 4:3
874 // Set this again to the same as the tv screen size
875 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
877 // mode == LETTERBOX is invalid if the TV is widescreen
878 if (tvsize == ASPECT16X9) setMode(NORMAL);
883 int VideoVPEOGL::setDefaultAspect()
885 return setAspectRatio(tvsize);
890 int VideoVPEOGL::setFormat(UCHAR tformat)
892 if (!initted) return 0;
893 if ((tformat != PAL) && (tformat != NTSC)) return 0;
896 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
912 int VideoVPEOGL::setConnection(UCHAR tconnection)
914 if (!initted) return 0;
915 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
916 connection = tconnection;
918 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
922 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
924 if (!initted) return 0;
925 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
926 aspectRatio = taspectRatio;
928 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
930 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
934 int VideoVPEOGL::setMode(UCHAR tmode)
936 if (!initted) return 0;
938 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
940 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
941 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
944 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
948 int VideoVPEOGL::signalOff()
950 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
954 int VideoVPEOGL::signalOn()
956 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
960 int VideoVPEOGL::setSource()
962 if (!initted) return 0;
964 // What does this do...
965 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
969 int VideoVPEOGL::setPosition(int x, int y)
971 if (!initted) return 0;
973 // vid_pos_regs_t pos_d;
977 /* vid_pos_regs_t pos_d;
979 memset(&pos_d, 0, sizeof(pos_d));
1004 pos_d.y = 100; // Top left X
1005 pos_d.x = 50; // Top left Y
1013 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
1017 int VideoVPEOGL::sync()
1019 if (!initted) return 0;
1021 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
1028 int VideoVPEOGL::play()
1030 if (!initted) return 0;
1032 #ifdef VPE_OMX_SUPPORT
1034 Log::getInstance()->log("Video", Log::DEBUG, "enter play");
1036 if (!omx_h264) doomx=false;
1038 if (!omx_mpeg2) doomx=false;
1041 if (AllocateCodecsOMX()) {
1042 //decoding_backend=VPE_DECODER_OMX;
1044 // Otherwise fall back to libav
1048 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
1051 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
1056 #ifdef VPE_LIBAV_SUPPORT
1057 if (AllocateCodecsLibav()) {
1058 decoding_backend=VPE_DECODER_libav;
1060 // Otherwise fall back to libav
1069 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1071 int VideoVPEOGL::InitTranscoderLibAV() {
1072 transcodecodec_context_libav = avcodec_alloc_context3(transcodecodec_libav);
1073 if (!transcodecodec_context_libav) {
1074 Log::getInstance()->log("Video", Log::DEBUG, "Alloc avcodec context failed!");
1078 transcodecodec_context_libav->slice_flags = SLICE_FLAG_CODED_ORDER;
1080 transcodecodec_context_libav->pix_fmt = PIX_FMT_TRANSCODE;
1081 transcodecodec_context_libav->get_format = get_format_transcode;
1082 transcodecodec_context_libav->get_buffer = get_buffer_transcode;
1083 transcodecodec_context_libav->reget_buffer = reget_buffer_transcode;
1084 transcodecodec_context_libav->release_buffer = release_buffer_transcode;
1085 //transcodecodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
1086 //transcodecodec_context_libav->time_base.den=9000; //pts values 90 KHz Clock /10;
1088 int avc_ret = avcodec_open2(transcodecodec_context_libav, transcodecodec_libav, NULL);
1090 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed \n");
1094 memset(&incom_packet_libav, 0, sizeof(incom_packet_libav));
1095 incom_packet_libav_size = 200000;
1096 incom_packet_libav.data = (uint8_t*) av_malloc(incom_packet_libav_size + FF_INPUT_BUFFER_PADDING_SIZE);
1103 int VideoVPEOGL::DeInitTranscoderLibAV() {
1105 av_free(incom_packet_libav.data);
1106 incom_packet_libav.data=NULL;
1107 incom_packet_libav_size=0;
1109 if (transcodecodec_context_libav) {
1110 avcodec_close(transcodecodec_context_libav);
1111 av_free(transcodecodec_context_libav);
1112 transcodecodec_context_libav=NULL;
1121 #ifdef VPE_OMX_SUPPORT
1122 int VideoVPEOGL::AllocateCodecsOMX()
1124 OMX_ERRORTYPE error;
1125 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1127 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1128 //Clock, move later to audio
1132 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
1135 if (error!=OMX_ErrorNone){
1136 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
1137 DeAllocateCodecsOMX();
1143 /* TODO Clock config to separate method */
1144 OMX_PORT_PARAM_TYPE p_param;
1145 memset(&p_param,0,sizeof(p_param));
1146 p_param.nSize=sizeof(p_param);
1147 p_param.nVersion.nVersion=OMX_VERSION;
1148 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1149 if (error!=OMX_ErrorNone){
1150 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1151 DeAllocateCodecsOMX();
1154 omx_clock_output_port=p_param.nStartPortNumber;
1156 for (unsigned int i=0;i<p_param.nPorts;i++) {
1157 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
1158 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
1159 DeAllocateCodecsOMX();
1167 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1168 memset(&clock_conf,0,sizeof(clock_conf));
1169 clock_conf.nSize=sizeof(clock_conf);
1170 clock_conf.nVersion.nVersion=OMX_VERSION;
1171 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1172 clock_conf.nStartTime=0;
1173 clock_conf.nOffset=0;
1174 clock_conf.nWaitMask=OMX_CLOCKPORT0;
1175 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1176 if (error!=OMX_ErrorNone){
1177 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1178 DeAllocateCodecsOMX();
1183 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1184 memset(&refclock,0,sizeof(refclock));
1185 refclock.nSize=sizeof(refclock);
1186 refclock.nVersion.nVersion=OMX_VERSION;
1188 if (/*AUDIO*/ false) {
1189 refclock.eClock=OMX_TIME_RefClockAudio;
1191 refclock.eClock=OMX_TIME_RefClockVideo;
1193 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1194 if (error!=OMX_ErrorNone){
1195 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1196 DeAllocateCodecsOMX();
1200 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1201 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
1202 DeAllocateCodecsOMX();
1215 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
1217 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1220 if (error!=OMX_ErrorNone){
1221 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1222 DeAllocateCodecsOMX();
1228 memset(&p_param,0,sizeof(p_param));
1229 p_param.nSize=sizeof(p_param);
1230 p_param.nVersion.nVersion=OMX_VERSION;
1231 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1232 if (error!=OMX_ErrorNone){
1233 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1234 DeAllocateCodecsOMX();
1237 omx_codec_input_port=p_param.nStartPortNumber;
1238 omx_codec_output_port=p_param.nStartPortNumber+1;
1240 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1241 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1242 DeAllocateCodecsOMX();
1247 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1248 memset(&conceal,0,sizeof(conceal));
1249 conceal.nSize=sizeof(conceal);
1250 conceal.nVersion.nVersion=OMX_VERSION;
1251 conceal.bStartWithValidFrame=OMX_FALSE;
1253 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1254 if (error!=OMX_ErrorNone){
1255 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1256 DeAllocateCodecsOMX();
1261 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1262 if (error!=OMX_ErrorNone){
1263 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1264 DeAllocateCodecsOMX();
1270 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1271 if (error!=OMX_ErrorNone){
1272 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1273 DeAllocateCodecsOMX();
1276 omx_shed_input_port=p_param.nStartPortNumber;
1277 omx_shed_output_port=p_param.nStartPortNumber+1;
1280 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1281 if (error!=OMX_ErrorNone){
1282 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1283 DeAllocateCodecsOMX();
1286 omx_shed_clock_port=p_param.nStartPortNumber;
1287 Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1290 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1291 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1292 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1293 DeAllocateCodecsOMX();
1298 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1299 if (error!=OMX_ErrorNone){
1300 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1301 DeAllocateCodecsOMX();
1305 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1306 if (error!=OMX_ErrorNone){
1307 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1308 DeAllocateCodecsOMX();
1311 omx_rend_input_port=p_param.nStartPortNumber;
1312 //omx_rend_output_port=p_param.nStartPortNumber+1;
1315 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1317 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1318 DeAllocateCodecsOMX();
1327 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1328 if (error!=OMX_ErrorNone){
1329 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
1330 DeAllocateCodecsOMX();
1334 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1336 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1337 DeAllocateCodecsOMX();
1341 Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
1342 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1343 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1344 DeAllocateCodecsOMX();
1350 Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
1351 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1352 DeAllocateCodecsOMX();
1359 Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
1360 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1361 DeAllocateCodecsOMX();
1366 Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
1369 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1370 if (error!=OMX_ErrorNone){
1371 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1375 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1376 memset(&ft_type,0,sizeof(ft_type));
1377 ft_type.nSize=sizeof(ft_type);
1378 ft_type.nVersion.nVersion=OMX_VERSION;
1380 ft_type.nPortIndex=omx_codec_input_port;
1382 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1384 #ifndef VPE_LIBAV_MPEG2_TRANSCODING
1385 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1387 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
1388 decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
1389 InitTranscoderLibAV();
1393 Demuxer* demux=Demuxer::getInstance();
1395 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1396 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1397 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1398 if (error!=OMX_ErrorNone){
1399 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1400 DeAllocateCodecsOMX();
1405 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1406 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1407 DeAllocateCodecsOMX();
1412 if (!PrepareInputBufsOMX()) {
1413 DeAllocateCodecsOMX();
1418 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1419 if (error!=OMX_ErrorNone){
1420 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1421 DeAllocateCodecsOMX();
1427 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1429 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1430 DeAllocateCodecsOMX();
1434 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1435 DeAllocateCodecsOMX();
1439 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1440 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1441 DeAllocateCodecsOMX();
1445 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1446 if (error!=OMX_ErrorNone){
1447 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1448 DeAllocateCodecsOMX();
1452 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1454 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1455 DeAllocateCodecsOMX();
1459 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1460 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1461 DeAllocateCodecsOMX();
1465 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1466 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1467 DeAllocateCodecsOMX();
1472 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1473 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1474 DeAllocateCodecsOMX();
1478 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1479 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1480 DeAllocateCodecsOMX();
1485 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1486 memset(&dispconf,0,sizeof(dispconf));
1487 dispconf.nSize=sizeof(dispconf);
1488 dispconf.nVersion.nVersion=OMX_VERSION;
1490 dispconf.nPortIndex=omx_rend_input_port;
1492 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1494 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1495 if (error!=OMX_ErrorNone){
1496 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1497 DeAllocateCodecsOMX();
1501 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1502 dispconf.fullscreen=OMX_FALSE;
1503 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1504 if (error!=OMX_ErrorNone){
1505 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1506 DeAllocateCodecsOMX();
1510 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1511 dispconf.dest_rect.x_offset=100;
1512 dispconf.dest_rect.y_offset=100;
1513 dispconf.dest_rect.width=640;
1514 dispconf.dest_rect.height=480;
1515 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1516 if (error!=OMX_ErrorNone){
1517 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1518 DeAllocateCodecsOMX();
1522 if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
1524 playbacktimeoffset=-GetCurrentSystemTime();
1528 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1529 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1530 DeAllocateCodecsOMX();
1535 //OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1536 memset(&clock_conf,0,sizeof(clock_conf));
1537 clock_conf.nSize=sizeof(clock_conf);
1538 clock_conf.nVersion.nVersion=OMX_VERSION;
1539 clock_conf.eState=OMX_TIME_ClockStateRunning;
1540 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1541 if (error!=OMX_ErrorNone){
1542 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1543 DeAllocateCodecsOMX();
1555 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1557 OMX_ERRORTYPE error;
1558 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1559 if (error!=OMX_ErrorNone){
1560 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1564 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1572 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1574 OMX_ERRORTYPE error;
1575 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1576 if (error!=OMX_ErrorNone){
1577 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1581 if (!wait) return 1;
1582 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1590 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1592 OMX_ERRORTYPE error;
1593 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1594 if (error!=OMX_ErrorNone){
1595 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1599 if (!wait) return 1;
1600 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1611 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1615 omx_event_mutex.Lock();
1616 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1617 while (itty!=omx_events.end()) {
1619 VPE_OMX_EVENT current=*itty;
1620 if (current.handle==handle) { //this is ours
1621 if (current.event_type==OMX_EventError) {
1622 omx_events.erase(itty);
1623 omx_event_mutex.Unlock();
1624 Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
1627 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1628 omx_events.erase(itty);
1629 omx_event_mutex.Unlock();
1630 //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1637 omx_event_mutex.Unlock();
1642 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1651 int VideoVPEOGL::PrepareInputBufsOMX()
1653 OMX_ERRORTYPE error;
1654 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1655 memset(&port_def_type,0,sizeof(port_def_type));
1656 port_def_type.nSize=sizeof(port_def_type);
1657 port_def_type.nVersion.nVersion=OMX_VERSION;
1658 port_def_type.nPortIndex=omx_codec_input_port;
1660 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1662 if (error!=OMX_ErrorNone){
1663 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1665 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1666 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1667 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1669 port_def_type.nBufferCountActual=10;
1670 port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1672 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1674 if (error!=OMX_ErrorNone){
1675 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1679 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1680 if (error!=OMX_ErrorNone){
1681 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1685 input_bufs_omx_mutex.Lock();
1686 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1688 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1689 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1690 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1691 if (error!=OMX_ErrorNone){
1692 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1693 input_bufs_omx_mutex.Unlock();
1696 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1697 if (error!=OMX_ErrorNone){
1698 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1699 input_bufs_omx_mutex.Unlock();
1702 input_bufs_omx_all.push_back(buf_head);
1703 input_bufs_omx_free.push_back(buf_head);
1704 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1705 transcode_pix_fmt* new_pix=NULL;
1706 new_pix=(transcode_pix_fmt*)malloc(sizeof(transcode_pix_fmt));
1707 pix_fmt_omx_all.push_back(new_pix);
1708 pix_fmt_omx_free.push_back(new_pix);
1711 omx_first_frame=true;
1714 cur_input_buf_omx=NULL;
1715 input_bufs_omx_mutex.Unlock();
1718 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1719 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1722 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1727 int VideoVPEOGL::DestroyInputBufsOMX()
1729 OMX_ERRORTYPE error;
1731 cur_input_buf_omx=NULL;
1732 input_bufs_omx_mutex.Lock();
1733 for (int i=0; i< input_bufs_omx_all.size();i++) {
1734 // free(input_bufs_omx_all[i]->pBuffer);
1735 // input_bufs_omx_all[i]->pBuffer=NULL;
1736 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1737 if (error!=OMX_ErrorNone){
1738 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1739 input_bufs_omx_mutex.Unlock();
1743 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1744 free(pix_fmt_omx_all[i]);
1747 input_bufs_omx_all.clear();
1748 input_bufs_omx_free.clear();
1749 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1750 input_bufs_omx_in_libav.clear();
1751 pix_fmt_omx_all.clear();
1752 pix_fmt_omx_free.clear();
1754 input_bufs_omx_mutex.Unlock();
1761 int VideoVPEOGL::DeAllocateCodecsOMX()
1763 OMX_ERRORTYPE error;
1765 Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1766 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1767 if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
1768 DeInitTranscoderLibAV();
1771 if (cur_input_buf_omx) {
1772 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1773 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1774 if (error!=OMX_ErrorNone) {
1775 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1778 cur_input_buf_omx=NULL;//write out old data
1782 // first stop the omx elements
1783 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1784 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1785 DeAllocateCodecsOMX();
1789 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1790 Log::getInstance()->log("Video", Log::DEBUG, "vid_clock ChangeComponentState");
1791 DeAllocateCodecsOMX();
1795 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1796 Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
1797 DeAllocateCodecsOMX();
1801 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1802 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1803 DeAllocateCodecsOMX();
1809 // TODO proper deinit sequence
1810 // first flush all buffers
1812 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1813 if (error!=OMX_ErrorNone) {
1814 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1818 if (!CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1819 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1822 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1823 if (error!=OMX_ErrorNone){
1824 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1829 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1830 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1833 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1834 if (error!=OMX_ErrorNone){
1835 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1842 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1843 if (error!=OMX_ErrorNone){
1844 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1848 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1849 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1850 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1853 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1854 if (error!=OMX_ErrorNone){
1855 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1859 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1860 if (error!=OMX_ErrorNone){
1861 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1865 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1866 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1867 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1870 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1871 if (error!=OMX_ErrorNone) {
1872 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1878 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ) {
1879 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1887 DestroyInputBufsOMX();
1890 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1891 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1893 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1894 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1900 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1901 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1906 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1907 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1913 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1914 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1917 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1918 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1921 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1922 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1927 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1928 if (error!=OMX_ErrorNone) {
1929 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1933 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1934 if (error!=OMX_ErrorNone) {
1935 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1940 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1941 if (error!=OMX_ErrorNone) {
1942 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1946 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1947 if (error!=OMX_ErrorNone) {
1948 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1952 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1953 if (error!=OMX_ErrorNone) {
1954 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1958 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1959 if (error!=OMX_ErrorNone) {
1960 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1975 error=OMX_FreeHandle(omx_vid_dec);
1976 error=OMX_FreeHandle(omx_vid_sched);
1977 error=OMX_FreeHandle(omx_vid_rend);
1978 error=OMX_FreeHandle(omx_clock);
1980 if (error!=OMX_ErrorNone) {
1981 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1984 Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
1992 #ifdef VPE_LIBAV_SUPPORT
1994 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1996 int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1997 enum PixelFormat ret_pix=PIX_FMT_NONE;
1998 if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1999 while (*fmt!=PIX_FMT_NONE) {
2000 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
2001 ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
2002 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
2003 ret_pix=PIX_FMT_XVMC_MPEG2_MC;
2010 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
2011 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
2013 if ((y+height)==src->height) {
2014 /* Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
2015 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
2016 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
2017 Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
2019 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
2024 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2026 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
2030 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2032 unsigned int want_sizes[4]={0,0,0,0};
2034 bool normal_pixs=false;
2036 int num_dct_blocks=0;
2039 //reget logic from mplayer
2040 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
2041 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
2046 if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
2048 // standard pixel format
2049 // this is written using much inspiration from libav util.c, so portions from there
2055 avcodec_align_dimensions2(c, &width, &height, s_a);
2056 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
2060 // Now we have to determine alignment size
2061 bool unaligned=true;
2063 av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
2064 width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
2066 for (int i=0;i<4;i++) {
2067 if ((pict.linesize[i]%s_a[i])!=0) {
2073 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
2074 for (int i=0;i<4 ;i++) {
2075 if (i<3 && pict.data[i+1]) {
2076 want_sizes[i]=pict.data[i+1]-pict.data[i];
2079 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
2086 //TODO set linesizes!
2088 num_blocks=((c->width+15)/16)*((c->height+15)/16);
2089 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
2091 want_sizes[2]=sizeof(xvmc_pix_fmt);
2092 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
2093 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
2094 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
2098 VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
2099 frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
2100 frame_buf->ogl_uploaded=false; //not uploaded yet
2101 frame_buf->width=pic->width;
2102 frame_buf->height=pic->height;
2103 frame_buf->stride=pic->linesize[0];
2105 //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
2107 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
2113 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
2114 int hchr_shift,vchr_shift;
2115 avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
2116 const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
2117 for (int i=0;i<4;i++) {
2118 pic->data[i]=(uint8_t*)frame_buf->data[i];
2119 pic->linesize[i]=pict.linesize[i];
2125 edge_width>>=hchr_shift;
2126 edge_height>>=vchr_shift;
2128 pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
2132 pic->base[0]=(uint8_t*)frame_buf; // our structure
2133 //pic->extended_data=pic->data;
2134 if(c->pkt) pic->pkt_pts=c->pkt->pts;
2135 else pic->pkt_pts=AV_NOPTS_VALUE;
2136 pic->width=c->width;
2137 pic->height=c->height;
2138 pic->format=c->pix_fmt;
2139 pic->sample_aspect_ratio=c->sample_aspect_ratio;
2140 pic->reordered_opaque= c->reordered_opaque;
2143 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
2144 pix_xvmc->xvmc_id=AV_XVMC_ID;
2145 pix_xvmc->data_blocks=(short*)pic->data[1];
2146 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
2147 pix_xvmc->allocated_mv_blocks=num_blocks;
2148 pix_xvmc->allocated_data_blocks=num_dct_blocks;
2149 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
2150 else pix_xvmc->idct=0;
2151 pix_xvmc->unsigned_intra=1; // let see what happens
2152 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
2153 pix_xvmc->start_mv_blocks_num=0;
2154 pix_xvmc->filled_mv_blocks_num=0;
2155 pix_xvmc->next_free_data_block_num=0;
2165 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2167 // Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
2168 ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
2170 pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
2175 int VideoVPEOGL::AllocateCodecsLibav()
2177 if (libav_running) DeAllocateCodecsLibav();
2178 libav_hastime=false;
2179 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
2180 mpeg2codec_context_libav=avcodec_alloc_context();
2181 if (mpeg2codec_context_libav==NULL) {
2182 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
2185 if (decoding_mode!=VPE_NO_XVMC) {
2186 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
2187 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
2188 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
2189 mpeg2codec_context_libav->get_format=get_format_libav;
2190 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
2193 mpeg2codec_context_libav->get_buffer=get_buffer_libav;
2194 mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
2195 mpeg2codec_context_libav->release_buffer=release_buffer_libav;
2199 int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
2201 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
2204 memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
2205 incom_packet_libav_size=200000;
2206 incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2208 dec_frame_libav_mutex.Lock();
2209 for (int i=0;i<3;i++) {
2210 AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
2211 if (!dec_frame_libav) {
2212 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
2215 dec_frame_libav_all.push_back(dec_frame_libav);
2216 dec_frame_libav_free.push_back(dec_frame_libav);
2218 dec_frame_libav_decoding=NULL;
2219 dec_frame_libav_mutex.Unlock();
2221 ogl_frame_mutex.Lock();
2222 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
2223 for (int i=0;i<5;i++) {
2224 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
2225 new_frame->type=1; //1 = YUV, 2 RGB
2226 new_frame->textures[0]=0;
2227 new_frame->textures[1]=0;
2228 new_frame->textures[2]=0;
2229 new_frame->width=new_frame->height=0;
2230 all_ogl_frames.push_back(new_frame);
2231 free_ogl_frames.push_back(new_frame);
2234 ogl_frame_outside=false;
2236 ogl_frame_mutex.Unlock();
2238 if (decoding_mode==VPE_XVMC_MOCOMP) {
2239 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2240 osd->BeginPainting(); // get OpenGl context
2241 moco_shader=new GLMocoShader();
2242 moco_shader->init();
2252 int VideoVPEOGL::DeAllocateCodecsLibav()
2254 libav_running=false;
2255 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
2256 dec_frame_libav_mutex.Lock();
2257 dec_frame_libav_upload_and_view_pending.clear();
2258 dec_frame_libav_upload_only_pending.clear();
2259 dec_frame_libav_free.clear();
2260 dec_frame_libav_mutex.Unlock();
2261 while (dec_frame_libav_uploading_framebuf) {
2262 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
2265 dec_frame_libav_mutex.Lock();
2266 for (int i=0; i< dec_frame_libav_all.size();i++) {
2267 av_free(dec_frame_libav_all[i]);
2270 dec_frame_libav_all.clear();
2272 av_free(incom_packet_libav.data);
2273 incom_packet_libav.data=NULL;
2274 incom_packet_libav_size=0;
2276 dec_frame_libav_mutex.Unlock();
2277 dec_frame_libav_decoding=NULL;
2278 while (ogl_frame_outside) {
2279 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
2283 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
2284 ogl_frame_mutex.Lock();
2285 for (int i=0; i< dec_frame_libav_all.size();i++) {
2286 VPEOGLFrame * del_frame=all_ogl_frames[i];
2287 if (del_frame->textures[0]==0) {
2288 glDeleteTextures(1,&del_frame->textures[0]);
2289 del_frame->textures[0]=0;
2291 if (del_frame->textures[1]==0) {
2292 glDeleteTextures(1,&del_frame->textures[1]);
2293 del_frame->textures[1]=0;
2295 if (del_frame->textures[2]==0) {
2296 glDeleteTextures(1,&del_frame->textures[2]);
2297 del_frame->textures[2]=0;
2300 free(all_ogl_frames[i]);
2302 all_ogl_frames.clear();
2303 free_ogl_frames.clear();
2304 ready_ogl_frames.clear();
2305 recycle_ref_ogl_frames.clear();
2306 ogl_forward_ref_frame_num=0;
2307 ogl_backward_ref_frame_num=0;
2308 ogl_forward_ref_frame=NULL;
2309 ogl_backward_ref_frame=NULL;
2311 ogl_frame_mutex.Unlock();
2312 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
2315 if (mpeg2codec_context_libav) {
2316 avcodec_close(mpeg2codec_context_libav);
2317 av_free(mpeg2codec_context_libav);
2318 mpeg2codec_context_libav=NULL;
2324 vpe_framebuf_mutex.Lock();
2326 for (int i=0;i<all_frame_bufs.size();i++) {
2327 VPE_FrameBuf* current=all_frame_bufs[i];
2328 for (int x=0;x<4;x++) {
2329 if (current->data[x]) {
2330 av_free(current->data[x]);
2335 all_frame_bufs.clear();
2336 free_frame_bufs.clear();
2337 locked_libav_frame_buf.clear();
2338 locked_uploading_frame_buf.clear();
2340 vpe_framebuf_mutex.Unlock();
2345 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2346 osd->BeginPainting(); // get OpenGl context
2347 moco_shader->deinit();
2361 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
2363 VPE_FrameBuf* current=NULL;
2364 vpe_framebuf_mutex.Lock();
2365 if (free_frame_bufs.size()>0) {
2366 current=free_frame_bufs.front();
2367 free_frame_bufs.pop_front();
2368 } else if (all_frame_bufs.size()<6) {
2369 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
2370 memset(current,0,sizeof(VPE_FrameBuf));
2372 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
2373 vpe_framebuf_mutex.Unlock();
2374 return NULL; // We do not have a frame buffer
2376 locked_libav_frame_buf.push_back(current);
2377 vpe_framebuf_mutex.Unlock();
2378 //check if we need reallocation
2379 for (int x=0;x<4;x++) {
2380 if (current->size[x]!=size[x]) {
2381 current->data[x]=av_realloc(current->data[x],size[x]);
2382 current->size[x]=size[x];
2385 framebuf_framenum++;
2386 current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
2391 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
2393 // first find frame_buf memory
2395 //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
2396 VPE_FrameBuf* current=buf;
2397 vpe_framebuf_mutex.Lock();
2398 if (current) locked_uploading_frame_buf.push_back(current); //locked
2399 vpe_framebuf_mutex.Unlock();
2404 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
2406 // first find frame_buf memory
2407 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
2408 VPE_FrameBuf* current=buf;
2409 vpe_framebuf_mutex.Lock();
2411 locked_libav_frame_buf.remove(current); //unlocked
2412 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
2414 while (itty!=locked_uploading_frame_buf.end()) {
2415 if (*itty==current) {
2422 free_frame_bufs.push_back(current);
2425 vpe_framebuf_mutex.Unlock();
2428 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
2430 // first find frame_buf memory
2431 VPE_FrameBuf* current=buf;
2432 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
2433 vpe_framebuf_mutex.Lock();
2435 locked_uploading_frame_buf.remove(current); //unlocked
2436 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
2438 while (itty!=locked_libav_frame_buf.end()) {
2439 if (*itty==current) {
2446 free_frame_bufs.push_back(current);
2449 vpe_framebuf_mutex.Unlock();
2452 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
2454 dec_frame_libav_mutex.Lock();
2455 libavwidth=s->width;
2456 libavheight=s->height;
2457 libavpixfmt=s->pix_fmt;
2458 //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
2460 dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
2461 dec_frame_libav_mutex.Unlock();
2471 int VideoVPEOGL::stop()
2473 if (!initted) return 0;
2475 #ifdef VPE_OMX_SUPPORT
2476 //Check if libav mode
2477 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2484 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2488 int VideoVPEOGL::reset()
2490 if (!initted) return 0;
2492 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2496 int VideoVPEOGL::pause()
2498 if (!initted) return 0;
2499 Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2502 //maybe also change omx clock?
2503 pausetimecode=GetCurrentSystemTime();
2509 int VideoVPEOGL::unPause() // FIXME get rid - same as play!! Not here!
2511 if (!initted) return 0;
2512 Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2515 playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
2516 paused=false; // may be also change omx clock
2522 int VideoVPEOGL::fastForward()
2524 if (!initted) return 0;
2526 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2530 int VideoVPEOGL::unFastForward()
2532 if (!initted) return 0;
2534 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2536 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2540 int VideoVPEOGL::attachFrameBuffer()
2542 if (!initted) return 0;
2544 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2548 int VideoVPEOGL::blank(void)
2550 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2551 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2555 ULLONG VideoVPEOGL::getCurrentTimestamp()
2558 return lastreftimePTS;
2563 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2565 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2566 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2571 int VideoVPEOGL::test()
2576 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2583 int VideoVPEOGL::test2()
2591 long long VideoVPEOGL::SetStartOffset(long long curreftime, bool *rsync)
2595 startoffset=curreftime;//offset is set for audio
2597 offsetvideonotset=false;
2599 if (offsetvideonotset) {
2600 offsetvideonotset=false;
2603 if ( (curreftime-lastrefvideotime)>10000000LL
2604 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2605 startoffset+=curreftime-lastrefvideotime;
2606 lastrefaudiotime+=curreftime-lastrefvideotime;
2608 offsetaudionotset=true;
2615 lastrefvideotime=curreftime;
2621 long long VideoVPEOGL::SetStartAudioOffset(long long curreftime, bool *rsync)
2625 startoffset=curreftime;
2627 offsetaudionotset=false;
2629 if (offsetaudionotset) {
2630 offsetaudionotset=false;
2633 if ( (curreftime-lastrefaudiotime)>10000000LL
2634 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2635 startoffset+=curreftime-lastrefaudiotime;
2636 lastrefvideotime+=curreftime-lastrefaudiotime;
2638 offsetvideonotset=true;
2644 lastrefaudiotime=curreftime;
2649 void VideoVPEOGL::ResetTimeOffsets() {
2650 offsetnotset=true; //called from demuxer
2651 offsetvideonotset=true;
2652 offsetaudionotset=true;
2660 long long VideoVPEOGL::GetCurrentSystemTime()
2663 clock_gettime(CLOCK_MONOTONIC, &ts);
2664 return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
2667 void VideoVPEOGL::WaitUntil(long long time)
2669 struct timespec interval;
2670 interval.tv_sec=time/10000000LL;
2671 interval.tv_nsec=(time %10000000LL)*100LL;
2672 while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
2675 void VideoVPEOGL::FrameWaitforDisplay(long long pts)
2677 //ok first calculate the absolute time
2678 long long target_time=pts-playbacktimeoffset;
2679 // we have to wait untile the next frame
2680 long long offset=Demuxer::getInstance()->getFrameRate();
2681 long long current_time=GetCurrentSystemTime();
2682 if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
2683 if (offset==0) offset=25;
2684 offset=10000000LL/offset;
2685 target_time+=offset;
2686 Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
2687 target_time-current_time);
2689 WaitUntil(target_time);
2690 Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out");
2694 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2696 mediapacket = mplist.front();
2699 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2701 DeliverMediaPacket(mediapacket, buffer, samplepos);
2702 if (*samplepos == mediapacket.length) {
2709 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2710 const UCHAR* buffer,
2713 if (packet.type == MPTYPE_VIDEO_H264)
2721 switch (decoding_backend) {
2722 default: case 0: return 0; // no backend runnigng
2723 #ifdef VPE_OMX_SUPPORT
2724 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2725 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2726 case VPE_DECODER_OMX_libav_TRANSCODE: return DeliverMediaPacketOMXTranscode(packet,buffer,samplepos);
2729 #ifdef VPE_LIBAV_SUPPORT
2730 case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2735 #ifdef VPE_OMX_SUPPORT
2736 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2737 const UCHAR* buffer,
2742 //Later add fail back code for libav
2744 *samplepos+=packet.length;
2745 return packet.length;
2749 if (!omx_running) return 0; // if we are not runnig do not do this
2750 if (paused) return 0; //Block if we pause
2752 long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
2753 if (packet.synched &&
2754 (packet.presentation_time<0 || // preroll skip frames
2755 (packet.presentation_time-1000000LL)>(current_media_time))) { // we are late skip
2756 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld", packet.presentation_time,current_media_time);
2757 *samplepos=packet.length;
2758 return packet.length;
2761 OMX_ERRORTYPE error;
2763 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
2764 memset(&port_image,0,sizeof(port_image));
2765 port_image.nSize=sizeof(port_image);
2766 port_image.nVersion.nVersion=OMX_VERSION;
2767 port_image.nPortIndex =omx_codec_output_port;
2768 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2769 if (error!= OMX_ErrorNone){
2770 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2772 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2774 /*First Check, if we have an audio sample*/
2778 return 0; //Not in iframe mode!
2782 if (packet.disconti) {
2784 if (cur_input_buf_omx) {
2785 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2786 if (error!=OMX_ErrorNone){
2787 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2789 cur_input_buf_omx=NULL;
2793 /*Inspect PES-Header */
2795 // OMX_STATETYPE temp_state;
2796 // OMX_GetState(omx_vid_dec,&temp_state);
2798 if (*samplepos==0) {//stripheader
2799 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2800 *samplepos+=headerstrip;
2801 if ( packet.synched ) {
2803 if (cur_input_buf_omx) {
2804 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
2805 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2806 if (error!=OMX_ErrorNone){
2807 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2809 FrameWaitforDisplay(lastreftimeOMX);
2811 cur_input_buf_omx=NULL;//write out old data
2813 // reftime1=packet.presentation_time;
2814 // reftime2=reftime1+1;
2817 if (!firstsynched) {//
2818 *samplepos=packet.length;//if we have not processed at least one
2819 return packet.length;//synched packet ignore it!
2824 if (!cur_input_buf_omx) {
2825 input_bufs_omx_mutex.Lock();
2826 if (input_bufs_omx_free.size()==0) {
2827 input_bufs_omx_mutex.Unlock();
2828 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2829 return 0; // we do not have a free media sample
2832 cur_input_buf_omx=input_bufs_omx_free.front();
2833 cur_input_buf_omx->nFilledLen=0;
2834 cur_input_buf_omx->nOffset=0;
2835 cur_input_buf_omx->nTimeStamp=0;
2836 input_bufs_omx_free.pop_front();
2837 input_bufs_omx_mutex.Unlock();
2843 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2844 /*if (packet.disconti) {
2845 ms->SetDiscontinuity(TRUE);
2847 ms->SetDiscontinuity(FALSE);
2849 if (packet.synched) {
2850 Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
2852 //lastreftimePTS=packet.pts;
2853 if (omx_first_frame) { // TODO time
2854 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2855 Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
2856 omx_first_frame=false;
2858 //cur_input_buf_omx->nFlags=0;
2859 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
2861 lastreftimeOMX=packet.presentation_time;
2862 Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
2863 lastreftimePTS=packet.pts;
2864 cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
2868 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2869 cur_input_buf_omx->nTimeStamp=0;
2872 // ms->SetSyncPoint(TRUE);
2874 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
2879 unsigned int haveToCopy=packet.length-*samplepos;
2881 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2882 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2883 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2884 haveToCopy-=cancopy;
2885 cur_input_buf_omx->nFilledLen+=cancopy;
2886 *samplepos+=cancopy;
2887 // push old buffer out
2889 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2890 if (error!=OMX_ErrorNone){
2891 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2894 input_bufs_omx_mutex.Lock();
2895 if (input_bufs_omx_free.size()==0) {
2896 input_bufs_omx_mutex.Unlock();
2897 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2898 return *samplepos; // we do not have a free media sample
2900 cur_input_buf_omx=input_bufs_omx_free.front();
2901 cur_input_buf_omx->nFilledLen=0;
2902 cur_input_buf_omx->nOffset=0;
2903 cur_input_buf_omx->nTimeStamp=0;
2904 input_bufs_omx_free.pop_front();
2905 input_bufs_omx_mutex.Unlock();
2907 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2910 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2911 buffer+packet.pos_buffer+*samplepos,haveToCopy);
2912 cur_input_buf_omx->nFilledLen+=haveToCopy;
2916 *samplepos+=haveToCopy;
2924 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2928 int VideoVPEOGL::DecodePacketOMXTranscode()
2930 unsigned int haveToCopy=incom_packet_libav.size;
2931 if (incom_packet_libav.size==0) return 1; // we are already empty
2934 while (haveToCopy>0) {
2938 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2940 #ifdef BENCHMARK_FPS
2941 int cur_time=getTimeMS();
2943 dec_bytes=avcodec_decode_video2(transcodecodec_context_libav, &transcode_frame_libav,
2944 &frame_ready, &incom_packet_libav);
2945 #ifdef BENCHMARK_FPS
2946 time_in_decoder+=getTimeMS()-cur_time;
2947 if (frame_ready) num_frames++;
2948 if ((num_frames%100)==0) {
2949 float fps=1000./(float)(time_in_decoder);
2950 fps*=((float)num_frames);
2951 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2955 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2958 haveToCopy-=dec_bytes;
2960 struct transcode_pix_fmt *transcode=(struct transcode_pix_fmt *)transcode_frame_libav.data[0];
2961 //if (!benchmark) fwrite(transcode->packet.data,transcode->packet.size,1,output_file);
2964 //add omx magic, this should be an omx packet
2965 OMX_BUFFERHEADERTYPE* omx_packet=(OMX_BUFFERHEADERTYPE*)transcode_frame_libav.base[0];
2966 omx_packet->nFilledLen=transcode->packet.size;
2968 input_bufs_omx_mutex.Lock();
2969 input_bufs_omx_in_libav.remove(omx_packet); // say that it is passed down to the decoder
2970 input_bufs_omx_mutex.Unlock();
2972 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,omx_packet);
2973 if (error!=OMX_ErrorNone){
2974 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2982 incom_packet_libav.size=0;
2988 UINT VideoVPEOGL::DeliverMediaPacketOMXTranscode(MediaPacket packet,
2989 const UCHAR* buffer,
2992 //Later add fail back code for libav
2994 *samplepos+=packet.length;
2995 return packet.length;
2998 if (!omx_running) return 0; // if we are not runnig do not do this
3004 return 0; //Not in iframe mode!
3008 if (packet.disconti) {
3010 if (!DecodePacketOMXTranscode()) return 0;
3013 /*Inspect PES-Header */
3014 if (*samplepos==0) {//stripheader
3015 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3016 *samplepos+=headerstrip;
3017 if ( packet.synched ) {
3019 if (!DecodePacketOMXTranscode()) return 0; // WriteOut old Data
3022 incom_packet_libav.pts=packet.pts/3600;
3023 incom_packet_libav.dts=packet.dts/3600;
3024 // reftime1=packet.presentation_time;
3025 // reftime2=reftime1+1;
3028 incom_packet_libav.pts=0;
3029 incom_packet_libav.dts=0;
3030 if (!firstsynched) {//
3031 *samplepos=packet.length;//if we have not processed at least one
3032 return packet.length;//synched packet ignore it!
3042 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3043 /*if (packet.disconti) {
3044 ms->SetDiscontinuity(TRUE);
3046 ms->SetDiscontinuity(FALSE);
3048 //if (packet.synched) {
3050 //lastreftimePTS=packet.pts;
3051 if (omx_first_frame) { // TODO time
3052 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3053 omx_first_frame=false;
3059 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3062 // ms->SetSyncPoint(TRUE);
3066 unsigned int haveToCopy=packet.length-*samplepos;
3068 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3069 // if the buffer is to small reallocate
3070 incom_packet_libav_size+=haveToCopy;
3071 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3072 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3074 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3075 incom_packet_libav.size+=haveToCopy;
3077 *samplepos+=haveToCopy;
3088 #ifdef VPE_LIBAV_SUPPORT
3089 int VideoVPEOGL::DecodePacketlibav()
3091 unsigned int haveToCopy=incom_packet_libav.size;
3092 if (incom_packet_libav.size==0) return 1; // we are already empty
3093 while (haveToCopy>0) {
3097 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
3099 #ifdef BENCHMARK_FPS
3100 int cur_time=getTimeMS();
3102 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
3103 &frame_ready, &incom_packet_libav);
3104 #ifdef BENCHMARK_FPS
3105 time_in_decoder+=getTimeMS()-cur_time;
3106 if (frame_ready) num_frames++;
3107 if ((num_frames%100)==0) {
3108 float fps=1000./(float)(time_in_decoder);
3109 fps*=((float)num_frames);
3110 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
3114 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
3117 haveToCopy-=dec_bytes;
3119 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
3121 lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
3122 dec_frame_libav_mutex.Lock();
3123 libavwidth=mpeg2codec_context_libav->width;
3124 libavheight=mpeg2codec_context_libav->height;
3125 libavpixfmt=mpeg2codec_context_libav->pix_fmt;
3126 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
3127 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
3128 // ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
3131 dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
3132 dec_frame_libav_decoding=NULL;
3133 if (dec_frame_libav_free.size()>0) {
3134 dec_frame_libav_decoding=dec_frame_libav_free.front();
3135 dec_frame_libav_free.pop_front();
3136 dec_frame_libav_mutex.Unlock();
3138 libav_hastime=false;
3140 libav_hastime=false;
3141 dec_frame_libav_mutex.Unlock();
3142 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
3152 incom_packet_libav.size=0;
3158 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
3159 const UCHAR* buffer,
3162 //Later add fail back code for libav
3164 *samplepos+=packet.length;
3165 return packet.length;
3168 if (!libav_running) return 0; // if we are not runnig do not do this
3174 return 0; //Not in iframe mode!
3178 if (packet.disconti) {
3180 if (!DecodePacketlibav()) return 0;
3183 /*Inspect PES-Header */
3184 if (!dec_frame_libav_decoding) {
3185 dec_frame_libav_mutex.Lock();
3186 if (dec_frame_libav_free.size()>0) {
3187 dec_frame_libav_decoding=dec_frame_libav_free.front();
3188 dec_frame_libav_free.pop_front();
3189 dec_frame_libav_mutex.Unlock();
3191 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
3192 dec_frame_libav_mutex.Unlock();
3200 if (*samplepos==0) {//stripheader
3201 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3202 *samplepos+=headerstrip;
3203 if ( packet.synched ) {
3205 if (!DecodePacketlibav()) return 0; // WriteOut old Data
3207 libav_time=packet.presentation_time;
3209 // reftime1=packet.presentation_time;
3210 // reftime2=reftime1+1;
3213 if (!firstsynched) {//
3214 *samplepos=packet.length;//if we have not processed at least one
3215 return packet.length;//synched packet ignore it!
3225 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3226 /*if (packet.disconti) {
3227 ms->SetDiscontinuity(TRUE);
3229 ms->SetDiscontinuity(FALSE);
3231 //if (packet.synched) {
3233 //lastreftimePTS=packet.pts;
3234 if (omx_first_frame) { // TODO time
3235 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3236 omx_first_frame=false;
3242 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3245 // ms->SetSyncPoint(TRUE);
3249 unsigned int haveToCopy=packet.length-*samplepos;
3251 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3252 // if the buffer is to small reallocate
3253 incom_packet_libav_size+=haveToCopy;
3254 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3255 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3257 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3258 incom_packet_libav.size+=haveToCopy;
3260 *samplepos+=haveToCopy;
3271 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
3273 //write(fdVideo, buffer, length);
3274 if (!iframemode) EnterIframePlayback();
3275 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
3281 int VideoVPEOGL::EnterIframePlayback()