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()
35 #ifdef VPE_OMX_SUPPORT
39 cur_input_buf_omx=NULL;
40 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 (!setFormat(tformat)) { shutdown(); return 0; }
98 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
99 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
100 if (!setMode(NORMAL)) { shutdown(); return 0; }
101 if (!setSource()) { shutdown(); return 0; }
102 if (!attachFrameBuffer()) { shutdown(); return 0; }
104 setTVsize(ASPECT4X3);
117 int VideoVPEOGL::initUsingOSDObjects()
119 EGLDisplay i_egl_display;
120 EGLSurface i_egl_surface;
121 EGLContext i_egl_context;
122 EGLConfig i_egl_config;
123 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
124 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
125 const EGLint attr_context[]={
126 EGL_CONTEXT_CLIENT_VERSION,2,
130 egl_display=i_egl_display;
131 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
132 if (egl_context==EGL_NO_CONTEXT) {
133 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
136 // We create a dummy surface here, in order to allow two contexts
137 const EGLint attr_pbuffer[]={
138 EGL_WIDTH, 1, EGL_HEIGHT,1,
141 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
142 if (egl_surface==EGL_NO_SURFACE) {
143 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
150 //egl_surface=i_egl_surface;
151 //egl_context=i_egl_context;
154 #ifdef VPE_OMX_SUPPORT
155 // we are called before the audio
158 if (error!=OMX_ErrorNone) {
159 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
163 //our callbacks move to play?
167 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)
171 #ifdef VPE_LIBAV_SUPPORT
174 if (decoding_mode==VPE_NO_XVMC) {
175 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
177 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
179 if (mpeg2codec_libav==NULL) {
180 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
184 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
185 transcodecodec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_MPEG4);
186 if (transcodecodec_libav==NULL) {
187 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 transcoder failed");
198 #ifdef VPE_OMX_SUPPORT
200 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
201 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
202 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
204 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
206 struct VPE_OMX_EVENT new_event;
207 new_event.handle=handle;
208 new_event.appdata=appdata;
209 new_event.event_type=event_type;
210 new_event.data1=data1;
211 new_event.data2=data2;
212 new_event.event_data=event_data;
214 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
215 video->AddOmxEvent(new_event);
217 /* switch (event_type) {
218 case OMX_EventCmdComplete: {
223 return OMX_ErrorNone;
227 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
229 omx_event_mutex.Lock();
230 omx_events.push_back(new_event);
231 omx_event_mutex.Unlock();
235 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
237 //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
238 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
239 video->ReturnEmptyOMXBuffer(buffer);
240 return OMX_ErrorNone;
244 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
245 input_bufs_omx_mutex.Lock();
246 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
247 input_bufs_omx_free.push_back(buffer);
248 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
249 input_bufs_omx_mutex.Unlock();
252 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
253 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
254 return OMX_ErrorNone;
257 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
259 enum PixelFormat VideoVPEOGL::get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt)
261 enum PixelFormat ret_pix=PIX_FMT_NONE;
263 while (*fmt!=PIX_FMT_NONE) {
264 if (*fmt== PIX_FMT_TRANSCODE ) {
265 ret_pix=PIX_FMT_TRANSCODE;
272 int VideoVPEOGL::reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
274 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!Not Implemented! \n");
279 int VideoVPEOGL::get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
282 //reget logic from mplayer
283 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
284 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!\n");
289 if (c->pix_fmt!=PIX_FMT_TRANSCODE ) {
290 Log::getInstance()->log("Video", Log::DEBUG,"We only support transcode pixel fmt\n");
293 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
294 transcode_pix_fmt *pix_trans=NULL;
295 OMX_BUFFERHEADERTYPE* our_buf=video->GetFreeOMXBufferforlibav(&pix_trans);
296 if (our_buf==NULL|| pix_trans==NULL) {
297 Log::getInstance()->log("Video", Log::DEBUG,"Getting buffer failed\n");
307 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
309 pic->base[0]=(uint8_t*)our_buf; // our buf
310 //pic->extended_data=pic->data;
311 if(c->pkt) pic->pkt_pts=c->pkt->pts;
312 else pic->pkt_pts=AV_NOPTS_VALUE;
314 pic->height=c->height;
315 pic->format=c->pix_fmt;
316 pic->sample_aspect_ratio=c->sample_aspect_ratio;
317 pic->reordered_opaque= c->reordered_opaque;
319 pic->data[0]=(uint8_t*)pix_trans;
320 pix_trans->transcode_id=AV_TRANSCODE_ID;
321 pix_trans->packet.data=(uint8_t*)our_buf->pBuffer;
322 pix_trans->packet.size=our_buf->nAllocLen;
329 OMX_BUFFERHEADERTYPE* VideoVPEOGL::GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans)
331 OMX_BUFFERHEADERTYPE* returned_buf=NULL;
335 while (returned_buf==NULL && time_out<100){
336 input_bufs_omx_mutex.Lock();
337 if (input_bufs_omx_free.size()!=0) {
338 returned_buf=input_bufs_omx_free.front();
339 returned_buf->nFilledLen=0;
340 returned_buf->nOffset=0;
341 returned_buf->nTimeStamp=0;
342 input_bufs_omx_free.pop_front();
343 input_bufs_omx_in_libav.push_back(returned_buf);
344 input_bufs_omx_mutex.Unlock();
345 returned_buf->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
348 input_bufs_omx_mutex.Unlock();
349 Log::getInstance()->log("Video", Log::DEBUG, "GetFreeOMXBuffer_libav no free sample block");
354 *pix_trans=pix_fmt_omx_free.front();
355 pix_fmt_omx_free.pop_front(); // we assume that there is always a twin
360 void VideoVPEOGL::release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
362 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
363 video->ReturnEmptyOMXBuffer_libav((OMX_BUFFERHEADERTYPE*) pic->base[0],(transcode_pix_fmt *)pic->data[0]);
364 pic->data[0]=NULL; //without doing this avcodec is going to cry
367 void VideoVPEOGL::ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt){
368 input_bufs_omx_mutex.Lock();
369 // We only return it, if it was not passed to OMX!
370 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
371 pix_fmt_omx_free.push_back(pix_fmt);
372 list<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_in_libav.begin();
373 while (itty!=input_bufs_omx_in_libav.end()) {
375 input_bufs_omx_in_libav.remove(buffer);
376 input_bufs_omx_free.push_back(buffer);
377 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
381 input_bufs_omx_mutex.Unlock();
389 int VideoVPEOGL::shutdown()
391 if (!initted) return 0;
396 #ifdef VPE_OMX_SUPPORT
397 DeAllocateCodecsOMX();
400 #ifdef VPE_LIBAV_SUPPORT
401 DeAllocateCodecsLibav();
403 eglDestroyContext(egl_display,egl_context);
407 #ifdef VPE_LIBAV_SUPPORT
408 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
410 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
412 glGenTextures(1, &outframe->textures[0]);
413 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
414 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
415 GL_UNSIGNED_BYTE, NULL);
417 glGenTextures(1, &outframe->textures[1]);
418 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
419 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
420 GL_UNSIGNED_BYTE, NULL);
422 glGenTextures(1, &outframe->textures[2]);
423 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
424 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
425 GL_UNSIGNED_BYTE, NULL);
426 outframe->height=height;
427 outframe->width=width;
428 outframe->stride=stride;
433 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
435 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
437 glGenTextures(1, &outframe->textures[0]);
438 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
439 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
440 GL_UNSIGNED_BYTE, NULL);
441 outframe->textures[1]=outframe->textures[2]=0; // no handles here
447 outframe->height=height;
448 outframe->width=width;
449 outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
454 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
455 VPEOGLFrame *return_obj=NULL;
456 ogl_frame_mutex.Lock();
457 if (ready_ogl_frames.size()>0) {
458 return_obj=ready_ogl_frames.front();
459 ready_ogl_frames.pop_front();
460 //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing num: %d",return_obj->pict_num);
461 ogl_frame_outside=true;
463 ogl_frame_mutex.Unlock();
467 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
469 ogl_frame_mutex.Lock();
471 ogl_frame_outside=false;
472 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
473 if (frame->pict_num==ogl_forward_ref_frame_num ||
474 frame->pict_num==ogl_backward_ref_frame_num ) {
475 recycle_ref_ogl_frames.push_back(frame);
477 free_ogl_frames.push_back(frame);
480 ogl_frame_mutex.Unlock();
483 void VideoVPEOGL::recycleOGLRefFrames()
485 // This function recycles frames formerly used as reference frame
486 ogl_frame_mutex.Lock();
487 list<VPEOGLFrame*> keep;
488 list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
489 while (itty!=recycle_ref_ogl_frames.end()) {
490 // Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
491 if ((*itty)->pict_num==ogl_forward_ref_frame_num
492 || (*itty)->pict_num==ogl_backward_ref_frame_num)
494 // ok we have to keep this
495 keep.push_back(*itty);
497 free_ogl_frames.push_back(*itty);
501 recycle_ref_ogl_frames.clear();
502 recycle_ref_ogl_frames=keep;
504 ogl_frame_mutex.Unlock();
510 void VideoVPEOGL::threadMethod()
512 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
513 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
521 #ifdef VPE_LIBAV_SUPPORT
524 dec_frame_libav_mutex.Lock();
525 AVFrame* dec_frame_libav_uploading_int=NULL;
528 if (dec_frame_libav_upload_and_view_pending.size()>0 ) {
530 dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
531 dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
532 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
533 // dec_frame_libav_uploading_framebuf);
534 // if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
535 // ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
538 if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC ) {
539 dec_frame_libav_upload_and_view_pending.pop_front();
540 if (decoding_mode==VPE_NO_XVMC) upload=true;
542 dec_frame_libav_uploading_framebuf=NULL;
543 dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
544 view=false; //do the upload
545 // Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
549 if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
551 dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
552 //Log::getInstance()->log("Video", Log::WARN, "threadMethod u %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
553 // dec_frame_libav_uploading_framebuf);
554 dec_frame_libav_upload_only_pending.pop_front();
557 /* if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
559 dec_frame_libav_uploading=NULL; //do not upload again
568 if (dec_frame_libav_upload_and_view_pending.size()>0
569 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
571 dec_frame_libav_mutex.Unlock();
574 if (dec_frame_libav_uploading_framebuf) {
576 //Code Block for debugging if needed
577 /* Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
578 ogl_frame_mutex.Lock();
579 list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
580 while (itty!=free_ogl_frames.end()) {
581 Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
586 itty=recycle_ref_ogl_frames.begin();
587 while (itty!=recycle_ref_ogl_frames.end()) {
588 Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
592 itty=ready_ogl_frames.begin();
593 while (itty!=ready_ogl_frames.end()) {
594 Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
598 ogl_frame_mutex.Unlock();*/
602 int width,height,pixfmt;
603 //First get a free ogl image
604 VPEOGLFrame* out_frame=NULL;
607 ogl_frame_mutex.Lock();
608 // Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
609 // recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
610 if (all_ogl_frames.size()==0) {
611 ogl_frame_mutex.Unlock(); break;
614 if (free_ogl_frames.size()>0) {
618 out_frame=free_ogl_frames.front();
619 free_ogl_frames.pop_front();
621 ogl_frame_mutex.Unlock();
624 ogl_frame_mutex.Lock();
626 // if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
627 ogl_frame_mutex.Unlock();
631 // Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
632 if (out_frame->textures[0]==0 || out_frame->width!=width ||
633 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
634 if (out_frame->textures[0]!=0) {
635 glDeleteTextures(1,&out_frame->textures[0]);
636 out_frame->textures[0]=0;
638 if (out_frame->textures[1]!=0) {
639 glDeleteTextures(1,&out_frame->textures[1]);
640 out_frame->textures[1]=0;
642 if (out_frame->textures[2]!=0) {
643 glDeleteTextures(1,&out_frame->textures[2]);
644 out_frame->textures[2]=0;
647 if (decoding_mode==VPE_NO_XVMC) {
648 if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
650 if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
651 // the shaders are easier to implement
654 dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
655 dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
659 //up to now only YUV data, this is for reference only, since the pi is too slow.
660 if (decoding_mode==VPE_NO_XVMC) {
661 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
662 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
663 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
664 out_frame->stride,out_frame->height,
665 GL_LUMINANCE,GL_UNSIGNED_BYTE,
666 dec_frame_libav_uploading_framebuf->data[0]);
668 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
669 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
670 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
671 out_frame->stride>>1,out_frame->height>>1,
672 GL_LUMINANCE,GL_UNSIGNED_BYTE,
673 dec_frame_libav_uploading_framebuf->data[1]);
675 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
676 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
677 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
678 out_frame->stride>>1,out_frame->height>>1,
679 GL_LUMINANCE,GL_UNSIGNED_BYTE,
680 dec_frame_libav_uploading_framebuf->data[2]);
683 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
684 if (moco_shader && pix_fmt) {
687 int cur_time=getTimeMS();
689 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
690 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
691 // Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
692 // pix_fmt->p_past_surface,pix_fmt->p_future_surface);
694 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
696 //Now determine the frame, that fits
697 ogl_frame_mutex.Lock();
699 for (int i=0;i<all_ogl_frames.size();i++) {
700 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
702 ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
703 ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
704 ogl_backward_ref_frame=all_ogl_frames[i];
705 ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
710 // if (!found) {// for debugging
711 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
715 ogl_frame_mutex.Unlock();
716 recycleOGLRefFrames(); //needed for recycling of reference frames
718 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
721 if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
726 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
728 //Now determine the frame, that fits
729 ogl_frame_mutex.Lock();
731 for (int i=0;i<all_ogl_frames.size();i++) {
732 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
734 ogl_forward_ref_frame=all_ogl_frames[i];
735 ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
741 // Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
742 // ((int)pix_fmt->p_past_surface));
746 ogl_frame_mutex.Unlock();
747 recycleOGLRefFrames(); //needed for recycling of reference frames
750 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
752 if (decoding_mode==VPE_XVMC_MOCOMP)
759 out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
761 // Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
763 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
764 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
767 time_in_decoder_gl+=getTimeMS()-cur_time;
769 if ((num_frames_gl%100)==0) {
770 float fps=1000./(float)(time_in_decoder_gl);
771 fps*=((float)num_frames_gl);
772 Log::getInstance()->log("Video", Log::NOTICE, "Current GL Decoding FPS %g", fps);
776 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
777 // Excute motion compensation
779 //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
795 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
796 VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
797 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
798 /* Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
799 pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
800 Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
802 releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
803 ogl_frame_mutex.Lock();
804 ready_ogl_frames.push_back(out_frame);
805 ogl_frame_mutex.Unlock();
806 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
808 dec_frame_libav_mutex.Lock();
809 dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
810 dec_frame_libav_mutex.Unlock();
814 dec_frame_libav_mutex.Lock();
815 dec_frame_libav_uploading_framebuf=NULL;
817 if (dec_frame_libav_upload_and_view_pending.size()>0
818 ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
820 dec_frame_libav_mutex.Unlock();
828 struct timespec target_time;
830 clock_gettime(CLOCK_REALTIME,&target_time);
831 target_time.tv_nsec+=1000000LL*ts;
832 if (target_time.tv_nsec>999999999) {
833 target_time.tv_nsec-=1000000000L;
834 target_time.tv_sec+=1;
836 threadWaitForSignalTimed(&target_time);
837 //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
845 void VideoVPEOGL::threadPostStopCleanup()
847 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
848 #ifdef VPE_LIBAV_SUPPORT
849 dec_frame_libav_uploading_framebuf=NULL;
856 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
860 // Override the aspect ratio usage, temporarily use to set the video chip mode
861 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
863 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
864 if (!setSource()) { shutdown(); return 0; }
865 if (!attachFramebuffer()) { shutdown(); return 0; }
867 // Reopening the fd causes the scart aspect line to go back to 4:3
868 // Set this again to the same as the tv screen size
869 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
871 // mode == LETTERBOX is invalid if the TV is widescreen
872 if (tvsize == ASPECT16X9) setMode(NORMAL);
877 int VideoVPEOGL::setDefaultAspect()
879 return setAspectRatio(tvsize);
884 int VideoVPEOGL::setFormat(UCHAR tformat)
886 if (!initted) return 0;
887 if ((tformat != PAL) && (tformat != NTSC)) return 0;
890 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
906 int VideoVPEOGL::setConnection(UCHAR tconnection)
908 if (!initted) return 0;
909 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
910 connection = tconnection;
912 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
916 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
918 if (!initted) return 0;
919 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
920 aspectRatio = taspectRatio;
922 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
924 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
928 int VideoVPEOGL::setMode(UCHAR tmode)
930 if (!initted) return 0;
932 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
934 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
935 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
938 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
942 int VideoVPEOGL::signalOff()
944 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
948 int VideoVPEOGL::signalOn()
950 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
954 int VideoVPEOGL::setSource()
956 if (!initted) return 0;
958 // What does this do...
959 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
963 int VideoVPEOGL::setPosition(int x, int y)
965 if (!initted) return 0;
967 // vid_pos_regs_t pos_d;
971 /* vid_pos_regs_t pos_d;
973 memset(&pos_d, 0, sizeof(pos_d));
998 pos_d.y = 100; // Top left X
999 pos_d.x = 50; // Top left Y
1007 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
1011 int VideoVPEOGL::sync()
1013 if (!initted) return 0;
1015 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
1022 int VideoVPEOGL::play()
1024 if (!initted) return 0;
1027 #ifdef VPE_OMX_SUPPORT
1029 Log::getInstance()->log("Video", Log::DEBUG, "enter play");
1031 if (!omx_h264) doomx=false;
1033 if (!omx_mpeg2) doomx=false;
1036 if (AllocateCodecsOMX()) {
1037 //decoding_backend=VPE_DECODER_OMX;
1039 // Otherwise fall back to libav
1043 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
1046 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
1051 #ifdef VPE_LIBAV_SUPPORT
1052 if (AllocateCodecsLibav()) {
1053 decoding_backend=VPE_DECODER_libav;
1055 // Otherwise fall back to libav
1064 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1066 int VideoVPEOGL::InitTranscoderLibAV() {
1067 transcodecodec_context_libav = avcodec_alloc_context3(transcodecodec_libav);
1068 if (!transcodecodec_context_libav) {
1069 Log::getInstance()->log("Video", Log::DEBUG, "Alloc avcodec context failed!");
1073 transcodecodec_context_libav->slice_flags = SLICE_FLAG_CODED_ORDER;
1075 transcodecodec_context_libav->pix_fmt = PIX_FMT_TRANSCODE;
1076 transcodecodec_context_libav->get_format = get_format_transcode;
1077 transcodecodec_context_libav->get_buffer = get_buffer_transcode;
1078 transcodecodec_context_libav->reget_buffer = reget_buffer_transcode;
1079 transcodecodec_context_libav->release_buffer = release_buffer_transcode;
1080 //transcodecodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
1081 //transcodecodec_context_libav->time_base.den=9000; //pts values 90 KHz Clock /10;
1083 int avc_ret = avcodec_open2(transcodecodec_context_libav, transcodecodec_libav, NULL);
1085 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed \n");
1089 memset(&incom_packet_libav, 0, sizeof(incom_packet_libav));
1090 incom_packet_libav_size = 200000;
1091 incom_packet_libav.data = (uint8_t*) av_malloc(incom_packet_libav_size + FF_INPUT_BUFFER_PADDING_SIZE);
1098 int VideoVPEOGL::DeInitTranscoderLibAV() {
1100 av_free(incom_packet_libav.data);
1101 incom_packet_libav.data=NULL;
1102 incom_packet_libav_size=0;
1104 if (transcodecodec_context_libav) {
1105 avcodec_close(transcodecodec_context_libav);
1106 av_free(transcodecodec_context_libav);
1107 transcodecodec_context_libav=NULL;
1116 #ifdef VPE_OMX_SUPPORT
1118 int VideoVPEOGL::initClock()
1120 OMX_ERRORTYPE error;
1122 if (clock_references==0)
1125 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1128 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
1130 if (error!=OMX_ErrorNone) {
1131 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
1132 clock_mutex.Unlock();
1133 DeAllocateCodecsOMX();
1137 /* TODO Clock config to separate method */
1138 OMX_PORT_PARAM_TYPE p_param;
1139 memset(&p_param,0,sizeof(p_param));
1140 p_param.nSize=sizeof(p_param);
1141 p_param.nVersion.nVersion=OMX_VERSION;
1142 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1143 if (error!=OMX_ErrorNone) {
1144 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1145 clock_mutex.Unlock();
1146 DeAllocateCodecsOMX();
1149 omx_clock_output_port=p_param.nStartPortNumber;
1151 for (unsigned int i=0;i<p_param.nPorts;i++) {
1152 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
1153 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
1154 clock_mutex.Unlock();
1155 DeAllocateCodecsOMX();
1164 Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
1166 clock_mutex.Unlock();
1170 int VideoVPEOGL::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
1172 OMX_ERRORTYPE error;
1174 *p_omx_clock_output_port=0;
1181 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1182 memset(&refclock,0,sizeof(refclock));
1183 refclock.nSize=sizeof(refclock);
1184 refclock.nVersion.nVersion=OMX_VERSION;
1186 refclock.eClock=OMX_TIME_RefClockAudio;
1188 //refclock.eClock=OMX_TIME_RefClockVideo;
1189 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1190 if (error!=OMX_ErrorNone){
1191 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1192 clock_mutex.Unlock();
1193 DeAllocateCodecsOMX();
1197 OMX_PORT_PARAM_TYPE p_param;
1198 memset(&p_param,0,sizeof(p_param));
1199 p_param.nSize=sizeof(p_param);
1200 p_param.nVersion.nVersion=OMX_VERSION;
1201 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1202 if (error!=OMX_ErrorNone){
1203 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1204 clock_mutex.Unlock();
1205 DeAllocateCodecsOMX();
1209 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1210 memset(&clock_conf,0,sizeof(clock_conf));
1211 clock_conf.nSize=sizeof(clock_conf);
1212 clock_conf.nVersion.nVersion=OMX_VERSION;
1213 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1214 clock_conf.nStartTime=0;
1215 clock_conf.nOffset=0;
1216 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
1217 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1218 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1219 if (error!=OMX_ErrorNone) {
1220 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1224 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
1225 *p_omx_clock=omx_clock;
1226 clock_mutex.Unlock();
1230 int VideoVPEOGL::getClockVideoandInit()
1232 OMX_ERRORTYPE error;
1239 if (clock_references==1) { // only if no audio is attached to this clock!
1240 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1241 memset(&refclock,0,sizeof(refclock));
1242 refclock.nSize=sizeof(refclock);
1243 refclock.nVersion.nVersion=OMX_VERSION;
1245 //refclock.eClock=OMX_TIME_RefClockAudio;
1247 refclock.eClock=OMX_TIME_RefClockVideo;
1248 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1249 if (error!=OMX_ErrorNone) {
1250 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1251 clock_mutex.Unlock();
1252 DeAllocateCodecsOMX();
1257 OMX_PORT_PARAM_TYPE p_param;
1258 memset(&p_param,0,sizeof(p_param));
1259 p_param.nSize=sizeof(p_param);
1260 p_param.nVersion.nVersion=OMX_VERSION;
1261 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1262 if (error!=OMX_ErrorNone){
1263 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1264 clock_mutex.Unlock();
1265 DeAllocateCodecsOMX();
1270 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1271 memset(&clock_conf,0,sizeof(clock_conf));
1272 clock_conf.nSize=sizeof(clock_conf);
1273 clock_conf.nVersion.nVersion=OMX_VERSION;
1274 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1275 clock_conf.nStartTime=0;
1276 clock_conf.nOffset=0;
1277 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1278 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1279 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1280 if (error!=OMX_ErrorNone) {
1281 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1284 omx_clock_output_port=p_param.nStartPortNumber;
1285 clock_mutex.Unlock();
1290 void VideoVPEOGL::clockUnpause()
1292 OMX_ERRORTYPE error;
1294 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1295 memset(&clock_conf,0,sizeof(clock_conf));
1296 clock_conf.nSize=sizeof(clock_conf);
1297 clock_conf.nVersion.nVersion=OMX_VERSION;
1298 clock_conf.eState=OMX_TIME_ClockStateRunning;
1299 clock_conf.nStartTime=0;
1300 clock_conf.nOffset=0;
1301 clock_conf.nWaitMask=OMX_CLOCKPORT1;
1302 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1303 if (error!=OMX_ErrorNone) {
1304 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
1307 clock_mutex.Unlock();
1311 void VideoVPEOGL::clockPause()
1313 OMX_ERRORTYPE error;
1315 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1316 memset(&clock_conf,0,sizeof(clock_conf));
1317 clock_conf.nSize=sizeof(clock_conf);
1318 clock_conf.nVersion.nVersion=OMX_VERSION;
1319 clock_conf.eState=OMX_TIME_ClockStateStopped;
1320 clock_conf.nStartTime=0;
1321 clock_conf.nOffset=0;
1322 clock_conf.nWaitMask=OMX_CLOCKPORT1;
1323 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1324 if (error!=OMX_ErrorNone) {
1325 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
1327 clock_mutex.Unlock();
1332 int VideoVPEOGL::AllocateCodecsOMX()
1334 OMX_ERRORTYPE error;
1335 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1337 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1338 //Clock, move later to audio including events
1340 Log::getInstance()->log("Video", Log::DEBUG, "Nmark1 ");
1341 if (!getClockVideoandInit()){
1342 return 0;// get the clock and init it if necessary
1344 Log::getInstance()->log("Video", Log::DEBUG, "Nmark2 ");
1347 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
1355 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
1357 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1360 if (error!=OMX_ErrorNone){
1361 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1362 clock_mutex.Unlock();
1363 DeAllocateCodecsOMX();
1368 Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
1369 OMX_PORT_PARAM_TYPE p_param;
1370 memset(&p_param,0,sizeof(p_param));
1371 p_param.nSize=sizeof(p_param);
1372 p_param.nVersion.nVersion=OMX_VERSION;
1373 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1374 if (error!=OMX_ErrorNone){
1375 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1376 clock_mutex.Unlock();
1377 DeAllocateCodecsOMX();
1380 omx_codec_input_port=p_param.nStartPortNumber;
1381 omx_codec_output_port=p_param.nStartPortNumber+1;
1383 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1384 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1385 clock_mutex.Unlock();
1386 DeAllocateCodecsOMX();
1390 Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
1392 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1393 memset(&conceal,0,sizeof(conceal));
1394 conceal.nSize=sizeof(conceal);
1395 conceal.nVersion.nVersion=OMX_VERSION;
1396 conceal.bStartWithValidFrame=OMX_FALSE;
1398 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1399 if (error!=OMX_ErrorNone){
1400 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1401 clock_mutex.Unlock();
1402 DeAllocateCodecsOMX();
1407 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1408 if (error!=OMX_ErrorNone){
1409 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1410 clock_mutex.Unlock();
1411 DeAllocateCodecsOMX();
1417 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1418 if (error!=OMX_ErrorNone){
1419 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1420 clock_mutex.Unlock();
1421 DeAllocateCodecsOMX();
1424 omx_shed_input_port=p_param.nStartPortNumber;
1425 omx_shed_output_port=p_param.nStartPortNumber+1;
1428 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1429 if (error!=OMX_ErrorNone){
1430 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1431 clock_mutex.Unlock();
1432 DeAllocateCodecsOMX();
1435 omx_shed_clock_port=p_param.nStartPortNumber;
1436 Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1439 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1440 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1441 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1442 clock_mutex.Unlock();
1443 DeAllocateCodecsOMX();
1448 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1449 if (error!=OMX_ErrorNone){
1450 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1451 clock_mutex.Unlock();
1452 DeAllocateCodecsOMX();
1456 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1457 if (error!=OMX_ErrorNone){
1458 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1459 clock_mutex.Unlock();
1460 DeAllocateCodecsOMX();
1463 omx_rend_input_port=p_param.nStartPortNumber;
1464 //omx_rend_output_port=p_param.nStartPortNumber+1;
1467 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1469 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1470 clock_mutex.Unlock();
1471 DeAllocateCodecsOMX();
1479 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1480 if (error!=OMX_ErrorNone){
1481 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
1482 clock_mutex.Unlock();
1483 DeAllocateCodecsOMX();
1487 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1489 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1490 clock_mutex.Unlock();
1491 DeAllocateCodecsOMX();
1496 Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
1497 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1498 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1499 clock_mutex.Unlock();
1500 DeAllocateCodecsOMX();
1506 Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
1507 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1508 clock_mutex.Unlock();
1509 DeAllocateCodecsOMX();
1516 Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
1517 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1518 clock_mutex.Unlock();
1519 DeAllocateCodecsOMX();
1522 clock_mutex.Unlock();
1525 Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
1528 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1529 if (error!=OMX_ErrorNone){
1530 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1534 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1535 memset(&ft_type,0,sizeof(ft_type));
1536 ft_type.nSize=sizeof(ft_type);
1537 ft_type.nVersion.nVersion=OMX_VERSION;
1539 ft_type.nPortIndex=omx_codec_input_port;
1541 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1543 #ifndef VPE_LIBAV_MPEG2_TRANSCODING
1544 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1546 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
1547 decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
1548 InitTranscoderLibAV();
1552 Demuxer* demux=Demuxer::getInstance();
1554 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1555 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1556 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1557 if (error!=OMX_ErrorNone){
1558 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1559 clock_mutex.Unlock();
1560 DeAllocateCodecsOMX();
1565 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1566 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1567 clock_mutex.Unlock();
1568 DeAllocateCodecsOMX();
1573 if (!PrepareInputBufsOMX()) {
1574 clock_mutex.Unlock();
1575 DeAllocateCodecsOMX();
1580 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1581 if (error!=OMX_ErrorNone){
1582 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1583 clock_mutex.Unlock();
1584 DeAllocateCodecsOMX();
1590 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1592 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1593 clock_mutex.Unlock();
1594 DeAllocateCodecsOMX();
1598 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1599 clock_mutex.Unlock();
1600 DeAllocateCodecsOMX();
1604 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1605 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1606 clock_mutex.Unlock();
1607 DeAllocateCodecsOMX();
1611 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1612 if (error!=OMX_ErrorNone){
1613 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1614 clock_mutex.Unlock();
1615 DeAllocateCodecsOMX();
1619 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1621 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1622 clock_mutex.Unlock();
1623 DeAllocateCodecsOMX();
1627 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1628 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1629 clock_mutex.Unlock();
1630 DeAllocateCodecsOMX();
1634 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1635 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1636 clock_mutex.Unlock();
1637 DeAllocateCodecsOMX();
1642 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1643 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1644 clock_mutex.Unlock();
1645 DeAllocateCodecsOMX();
1649 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1650 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1651 clock_mutex.Unlock();
1652 DeAllocateCodecsOMX();
1657 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1658 memset(&dispconf,0,sizeof(dispconf));
1659 dispconf.nSize=sizeof(dispconf);
1660 dispconf.nVersion.nVersion=OMX_VERSION;
1662 dispconf.nPortIndex=omx_rend_input_port;
1664 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1666 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1667 if (error!=OMX_ErrorNone){
1668 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1669 clock_mutex.Unlock();
1670 DeAllocateCodecsOMX();
1674 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1675 dispconf.fullscreen=OMX_FALSE;
1676 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1677 if (error!=OMX_ErrorNone){
1678 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1679 clock_mutex.Unlock();
1680 DeAllocateCodecsOMX();
1684 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1685 dispconf.dest_rect.x_offset=100;
1686 dispconf.dest_rect.y_offset=100;
1687 dispconf.dest_rect.width=640;
1688 dispconf.dest_rect.height=480;
1689 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1690 if (error!=OMX_ErrorNone){
1691 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1692 clock_mutex.Unlock();
1693 DeAllocateCodecsOMX();
1697 if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
1699 playbacktimeoffset=-GetCurrentSystemTime();
1703 clock_mutex.Unlock();
1705 setClockExecutingandRunning();
1714 int VideoVPEOGL::idleClock()
1716 OMX_ERRORTYPE error;
1717 OMX_STATETYPE temp_state;
1719 OMX_GetState(omx_clock,&temp_state);
1721 if (temp_state!=OMX_StateIdle) {
1722 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1723 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1724 clock_mutex.Unlock();
1728 clock_mutex.Unlock();
1732 int VideoVPEOGL::setClockExecutingandRunning()
1734 OMX_ERRORTYPE error;
1735 OMX_STATETYPE temp_state;
1737 OMX_GetState(omx_clock,&temp_state);
1739 if (temp_state!=OMX_StateExecuting) {
1740 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1741 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1742 clock_mutex.Unlock();
1743 DeAllocateCodecsOMX();
1748 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1749 memset(&clock_conf,0,sizeof(clock_conf));
1750 clock_conf.nSize=sizeof(clock_conf);
1751 clock_conf.nVersion.nVersion=OMX_VERSION;
1752 clock_conf.eState=OMX_TIME_ClockStateRunning;
1753 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1754 if (error!=OMX_ErrorNone) {
1755 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1756 clock_mutex.Unlock();
1757 DeAllocateCodecsOMX();
1760 clock_mutex.Unlock();
1766 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1768 OMX_ERRORTYPE error;
1769 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1770 if (error!=OMX_ErrorNone){
1771 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1775 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1783 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1785 OMX_ERRORTYPE error;
1786 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1787 if (error!=OMX_ErrorNone){
1788 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1792 if (!wait) return 1;
1793 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1801 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1803 OMX_ERRORTYPE error;
1804 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1805 if (error!=OMX_ErrorNone){
1806 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1810 if (!wait) return 1;
1811 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1822 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1826 omx_event_mutex.Lock();
1827 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1828 while (itty!=omx_events.end()) {
1830 VPE_OMX_EVENT current=*itty;
1831 if (current.handle==handle) { //this is ours
1832 if (current.event_type==OMX_EventError) {
1833 omx_events.erase(itty);
1834 omx_event_mutex.Unlock();
1835 Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
1838 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1839 omx_events.erase(itty);
1840 omx_event_mutex.Unlock();
1841 //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1848 omx_event_mutex.Unlock();
1853 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1862 int VideoVPEOGL::PrepareInputBufsOMX() //needs to be called with locked mutex
1864 OMX_ERRORTYPE error;
1865 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1866 memset(&port_def_type,0,sizeof(port_def_type));
1867 port_def_type.nSize=sizeof(port_def_type);
1868 port_def_type.nVersion.nVersion=OMX_VERSION;
1869 port_def_type.nPortIndex=omx_codec_input_port;
1871 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1873 if (error!=OMX_ErrorNone){
1874 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1876 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1877 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1878 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1880 port_def_type.nBufferCountActual=60;
1881 port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1883 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1885 if (error!=OMX_ErrorNone){
1886 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1890 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1891 if (error!=OMX_ErrorNone){
1892 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1896 input_bufs_omx_mutex.Lock();
1897 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1899 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1900 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1901 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1902 if (error!=OMX_ErrorNone){
1903 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1904 input_bufs_omx_mutex.Unlock();
1907 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1908 if (error!=OMX_ErrorNone){
1909 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1910 input_bufs_omx_mutex.Unlock();
1913 input_bufs_omx_all.push_back(buf_head);
1914 input_bufs_omx_free.push_back(buf_head);
1915 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1916 transcode_pix_fmt* new_pix=NULL;
1917 new_pix=(transcode_pix_fmt*)malloc(sizeof(transcode_pix_fmt));
1918 pix_fmt_omx_all.push_back(new_pix);
1919 pix_fmt_omx_free.push_back(new_pix);
1922 omx_first_frame=true;
1925 cur_input_buf_omx=NULL;
1926 input_bufs_omx_mutex.Unlock();
1929 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1930 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1933 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1938 int VideoVPEOGL::DestroyInputBufsOMX() //need s to be called with locked mutex
1940 OMX_ERRORTYPE error;
1942 cur_input_buf_omx=NULL;
1943 input_bufs_omx_mutex.Lock();
1944 for (int i=0; i< input_bufs_omx_all.size();i++) {
1945 // free(input_bufs_omx_all[i]->pBuffer);
1946 // input_bufs_omx_all[i]->pBuffer=NULL;
1947 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1948 if (error!=OMX_ErrorNone){
1949 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1950 input_bufs_omx_mutex.Unlock();
1954 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1955 free(pix_fmt_omx_all[i]);
1958 input_bufs_omx_all.clear();
1959 input_bufs_omx_free.clear();
1960 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1961 input_bufs_omx_in_libav.clear();
1962 pix_fmt_omx_all.clear();
1963 pix_fmt_omx_free.clear();
1965 input_bufs_omx_mutex.Unlock();
1972 int VideoVPEOGL::DeAllocateCodecsOMX()
1974 OMX_ERRORTYPE error;
1976 Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1977 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1978 if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
1979 DeInitTranscoderLibAV();
1983 if (cur_input_buf_omx) {
1984 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1985 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1986 if (error!=OMX_ErrorNone) {
1987 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1990 cur_input_buf_omx=NULL;//write out old data
1994 // first stop the omx elements
1995 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1996 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1999 clock_mutex.Unlock();
2005 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2006 Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
2010 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2011 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
2017 // TODO proper deinit sequence
2018 // first flush all buffers
2020 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
2021 if (error!=OMX_ErrorNone) {
2022 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
2026 if (!CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
2027 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
2030 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
2031 if (error!=OMX_ErrorNone){
2032 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
2038 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
2039 if (error!=OMX_ErrorNone){
2040 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
2044 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
2045 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
2046 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
2050 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2051 if (error!=OMX_ErrorNone){
2052 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
2056 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2057 if (error!=OMX_ErrorNone){
2058 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
2062 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2063 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2064 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
2067 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
2068 if (error!=OMX_ErrorNone) {
2069 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
2075 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ) {
2076 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
2084 DestroyInputBufsOMX();
2087 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2088 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
2090 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2091 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
2097 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2098 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
2103 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2104 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
2110 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2111 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
2114 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2115 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
2118 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2119 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
2125 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
2126 if (error!=OMX_ErrorNone) {
2127 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2131 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
2132 if (error!=OMX_ErrorNone) {
2133 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2138 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
2139 if (error!=OMX_ErrorNone) {
2140 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2144 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
2145 if (error!=OMX_ErrorNone) {
2146 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2151 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
2152 if (error!=OMX_ErrorNone) {
2153 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2157 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
2158 if (error!=OMX_ErrorNone) {
2159 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2166 error=OMX_FreeHandle(omx_vid_dec);
2167 error=OMX_FreeHandle(omx_vid_sched);
2168 error=OMX_FreeHandle(omx_vid_rend);
2170 clock_mutex.Unlock();
2172 if (error!=OMX_ErrorNone) {
2173 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2175 } else clock_mutex.Unlock();
2176 Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2182 void VideoVPEOGL::destroyClock()
2185 if (clock_references>0) {
2187 if (clock_references==0) {
2188 OMX_ERRORTYPE error;
2189 Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2190 error=OMX_FreeHandle(omx_clock);
2191 if (error!=OMX_ErrorNone) {
2192 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2197 clock_mutex.Unlock();
2204 #ifdef VPE_LIBAV_SUPPORT
2206 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
2208 int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
2209 enum PixelFormat ret_pix=PIX_FMT_NONE;
2210 if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
2211 while (*fmt!=PIX_FMT_NONE) {
2212 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
2213 ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
2214 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
2215 ret_pix=PIX_FMT_XVMC_MPEG2_MC;
2222 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
2223 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
2225 if ((y+height)==src->height) {
2226 /* Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
2227 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
2228 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
2229 Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
2231 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
2236 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2238 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
2242 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2244 unsigned int want_sizes[4]={0,0,0,0};
2246 bool normal_pixs=false;
2248 int num_dct_blocks=0;
2251 //reget logic from mplayer
2252 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
2253 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
2258 if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
2260 // standard pixel format
2261 // this is written using much inspiration from libav util.c, so portions from there
2267 avcodec_align_dimensions2(c, &width, &height, s_a);
2268 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
2272 // Now we have to determine alignment size
2273 bool unaligned=true;
2275 av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
2276 width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
2278 for (int i=0;i<4;i++) {
2279 if ((pict.linesize[i]%s_a[i])!=0) {
2285 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
2286 for (int i=0;i<4 ;i++) {
2287 if (i<3 && pict.data[i+1]) {
2288 want_sizes[i]=pict.data[i+1]-pict.data[i];
2291 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
2298 //TODO set linesizes!
2300 num_blocks=((c->width+15)/16)*((c->height+15)/16);
2301 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
2303 want_sizes[2]=sizeof(xvmc_pix_fmt);
2304 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
2305 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
2306 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
2310 VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
2311 frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
2312 frame_buf->ogl_uploaded=false; //not uploaded yet
2313 frame_buf->width=pic->width;
2314 frame_buf->height=pic->height;
2315 frame_buf->stride=pic->linesize[0];
2317 //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
2319 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
2325 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
2326 int hchr_shift,vchr_shift;
2327 avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
2328 const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
2329 for (int i=0;i<4;i++) {
2330 pic->data[i]=(uint8_t*)frame_buf->data[i];
2331 pic->linesize[i]=pict.linesize[i];
2337 edge_width>>=hchr_shift;
2338 edge_height>>=vchr_shift;
2340 pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
2344 pic->base[0]=(uint8_t*)frame_buf; // our structure
2345 //pic->extended_data=pic->data;
2346 if(c->pkt) pic->pkt_pts=c->pkt->pts;
2347 else pic->pkt_pts=AV_NOPTS_VALUE;
2348 pic->width=c->width;
2349 pic->height=c->height;
2350 pic->format=c->pix_fmt;
2351 pic->sample_aspect_ratio=c->sample_aspect_ratio;
2352 pic->reordered_opaque= c->reordered_opaque;
2355 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
2356 pix_xvmc->xvmc_id=AV_XVMC_ID;
2357 pix_xvmc->data_blocks=(short*)pic->data[1];
2358 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
2359 pix_xvmc->allocated_mv_blocks=num_blocks;
2360 pix_xvmc->allocated_data_blocks=num_dct_blocks;
2361 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
2362 else pix_xvmc->idct=0;
2363 pix_xvmc->unsigned_intra=1; // let see what happens
2364 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
2365 pix_xvmc->start_mv_blocks_num=0;
2366 pix_xvmc->filled_mv_blocks_num=0;
2367 pix_xvmc->next_free_data_block_num=0;
2377 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2379 // Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
2380 ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
2382 pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
2387 int VideoVPEOGL::AllocateCodecsLibav()
2389 if (libav_running) DeAllocateCodecsLibav();
2390 libav_hastime=false;
2391 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
2392 mpeg2codec_context_libav=avcodec_alloc_context();
2393 if (mpeg2codec_context_libav==NULL) {
2394 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
2397 if (decoding_mode!=VPE_NO_XVMC) {
2398 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
2399 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
2400 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
2401 mpeg2codec_context_libav->get_format=get_format_libav;
2402 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
2405 mpeg2codec_context_libav->get_buffer=get_buffer_libav;
2406 mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
2407 mpeg2codec_context_libav->release_buffer=release_buffer_libav;
2411 int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
2413 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
2416 memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
2417 incom_packet_libav_size=200000;
2418 incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2420 dec_frame_libav_mutex.Lock();
2421 for (int i=0;i<3;i++) {
2422 AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
2423 if (!dec_frame_libav) {
2424 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
2427 dec_frame_libav_all.push_back(dec_frame_libav);
2428 dec_frame_libav_free.push_back(dec_frame_libav);
2430 dec_frame_libav_decoding=NULL;
2431 dec_frame_libav_mutex.Unlock();
2433 ogl_frame_mutex.Lock();
2434 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
2435 for (int i=0;i<5;i++) {
2436 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
2437 new_frame->type=1; //1 = YUV, 2 RGB
2438 new_frame->textures[0]=0;
2439 new_frame->textures[1]=0;
2440 new_frame->textures[2]=0;
2441 new_frame->width=new_frame->height=0;
2442 all_ogl_frames.push_back(new_frame);
2443 free_ogl_frames.push_back(new_frame);
2446 ogl_frame_outside=false;
2448 ogl_frame_mutex.Unlock();
2450 if (decoding_mode==VPE_XVMC_MOCOMP) {
2451 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2452 osd->BeginPainting(); // get OpenGl context
2453 moco_shader=new GLMocoShader();
2454 moco_shader->init();
2464 int VideoVPEOGL::DeAllocateCodecsLibav()
2466 libav_running=false;
2467 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
2468 dec_frame_libav_mutex.Lock();
2469 dec_frame_libav_upload_and_view_pending.clear();
2470 dec_frame_libav_upload_only_pending.clear();
2471 dec_frame_libav_free.clear();
2472 dec_frame_libav_mutex.Unlock();
2473 while (dec_frame_libav_uploading_framebuf) {
2474 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
2477 dec_frame_libav_mutex.Lock();
2478 for (int i=0; i< dec_frame_libav_all.size();i++) {
2479 av_free(dec_frame_libav_all[i]);
2482 dec_frame_libav_all.clear();
2484 av_free(incom_packet_libav.data);
2485 incom_packet_libav.data=NULL;
2486 incom_packet_libav_size=0;
2488 dec_frame_libav_mutex.Unlock();
2489 dec_frame_libav_decoding=NULL;
2490 while (ogl_frame_outside) {
2491 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
2495 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
2496 ogl_frame_mutex.Lock();
2497 for (int i=0; i< dec_frame_libav_all.size();i++) {
2498 VPEOGLFrame * del_frame=all_ogl_frames[i];
2499 if (del_frame->textures[0]==0) {
2500 glDeleteTextures(1,&del_frame->textures[0]);
2501 del_frame->textures[0]=0;
2503 if (del_frame->textures[1]==0) {
2504 glDeleteTextures(1,&del_frame->textures[1]);
2505 del_frame->textures[1]=0;
2507 if (del_frame->textures[2]==0) {
2508 glDeleteTextures(1,&del_frame->textures[2]);
2509 del_frame->textures[2]=0;
2512 free(all_ogl_frames[i]);
2514 all_ogl_frames.clear();
2515 free_ogl_frames.clear();
2516 ready_ogl_frames.clear();
2517 recycle_ref_ogl_frames.clear();
2518 ogl_forward_ref_frame_num=0;
2519 ogl_backward_ref_frame_num=0;
2520 ogl_forward_ref_frame=NULL;
2521 ogl_backward_ref_frame=NULL;
2523 ogl_frame_mutex.Unlock();
2524 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
2527 if (mpeg2codec_context_libav) {
2528 avcodec_close(mpeg2codec_context_libav);
2529 av_free(mpeg2codec_context_libav);
2530 mpeg2codec_context_libav=NULL;
2536 vpe_framebuf_mutex.Lock();
2538 for (int i=0;i<all_frame_bufs.size();i++) {
2539 VPE_FrameBuf* current=all_frame_bufs[i];
2540 for (int x=0;x<4;x++) {
2541 if (current->data[x]) {
2542 av_free(current->data[x]);
2547 all_frame_bufs.clear();
2548 free_frame_bufs.clear();
2549 locked_libav_frame_buf.clear();
2550 locked_uploading_frame_buf.clear();
2552 vpe_framebuf_mutex.Unlock();
2557 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2558 osd->BeginPainting(); // get OpenGl context
2559 moco_shader->deinit();
2573 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
2575 VPE_FrameBuf* current=NULL;
2576 vpe_framebuf_mutex.Lock();
2577 if (free_frame_bufs.size()>0) {
2578 current=free_frame_bufs.front();
2579 free_frame_bufs.pop_front();
2580 } else if (all_frame_bufs.size()<6) {
2581 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
2582 memset(current,0,sizeof(VPE_FrameBuf));
2584 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
2585 vpe_framebuf_mutex.Unlock();
2586 return NULL; // We do not have a frame buffer
2588 locked_libav_frame_buf.push_back(current);
2589 vpe_framebuf_mutex.Unlock();
2590 //check if we need reallocation
2591 for (int x=0;x<4;x++) {
2592 if (current->size[x]!=size[x]) {
2593 current->data[x]=av_realloc(current->data[x],size[x]);
2594 current->size[x]=size[x];
2597 framebuf_framenum++;
2598 current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
2603 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
2605 // first find frame_buf memory
2607 //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
2608 VPE_FrameBuf* current=buf;
2609 vpe_framebuf_mutex.Lock();
2610 if (current) locked_uploading_frame_buf.push_back(current); //locked
2611 vpe_framebuf_mutex.Unlock();
2616 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
2618 // first find frame_buf memory
2619 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
2620 VPE_FrameBuf* current=buf;
2621 vpe_framebuf_mutex.Lock();
2623 locked_libav_frame_buf.remove(current); //unlocked
2624 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
2626 while (itty!=locked_uploading_frame_buf.end()) {
2627 if (*itty==current) {
2634 free_frame_bufs.push_back(current);
2637 vpe_framebuf_mutex.Unlock();
2640 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
2642 // first find frame_buf memory
2643 VPE_FrameBuf* current=buf;
2644 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
2645 vpe_framebuf_mutex.Lock();
2647 locked_uploading_frame_buf.remove(current); //unlocked
2648 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
2650 while (itty!=locked_libav_frame_buf.end()) {
2651 if (*itty==current) {
2658 free_frame_bufs.push_back(current);
2661 vpe_framebuf_mutex.Unlock();
2664 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
2666 dec_frame_libav_mutex.Lock();
2667 libavwidth=s->width;
2668 libavheight=s->height;
2669 libavpixfmt=s->pix_fmt;
2670 //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
2672 dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
2673 dec_frame_libav_mutex.Unlock();
2683 int VideoVPEOGL::stop()
2685 if (!initted) return 0;
2688 #ifdef VPE_OMX_SUPPORT
2689 //Check if libav mode
2690 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2697 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2701 int VideoVPEOGL::reset()
2703 if (!initted) return 0;
2706 DeAllocateCodecsOMX();
2707 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2711 int VideoVPEOGL::pause()
2713 if (!initted) return 0;
2714 Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2717 //maybe also change omx clock?
2718 pausetimecode=GetCurrentSystemTime();
2724 int VideoVPEOGL::unPause() // FIXME get rid - same as play!! Not here!
2726 if (!initted) return 0;
2727 Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2730 playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
2731 paused=false; // may be also change omx clock
2737 int VideoVPEOGL::fastForward()
2739 if (!initted) return 0;
2741 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2745 int VideoVPEOGL::unFastForward()
2747 if (!initted) return 0;
2749 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2751 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2755 int VideoVPEOGL::attachFrameBuffer()
2757 if (!initted) return 0;
2759 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2763 int VideoVPEOGL::blank(void)
2765 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2766 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2770 ULLONG VideoVPEOGL::getCurrentTimestamp()
2772 if (iframemode) return 0;
2773 return lastreftimePTS;
2778 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2780 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2781 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2786 int VideoVPEOGL::test()
2791 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2798 int VideoVPEOGL::test2()
2806 long long VideoVPEOGL::SetStartOffset(long long curreftime, bool *rsync)
2810 startoffset=curreftime;//offset is set for audio
2812 offsetvideonotset=false;
2814 if (offsetvideonotset) {
2815 offsetvideonotset=false;
2818 if ( (curreftime-lastrefvideotime)>10000000LL
2819 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2820 startoffset+=curreftime-lastrefvideotime;
2821 lastrefaudiotime+=curreftime-lastrefvideotime;
2823 offsetaudionotset=true;
2830 lastrefvideotime=curreftime;
2836 long long VideoVPEOGL::SetStartAudioOffset(long long curreftime, bool *rsync)
2840 startoffset=curreftime;
2842 offsetaudionotset=false;
2844 if (offsetaudionotset) {
2845 offsetaudionotset=false;
2848 if ( (curreftime-lastrefaudiotime)>10000000LL
2849 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2850 startoffset+=curreftime-lastrefaudiotime;
2851 lastrefvideotime+=curreftime-lastrefaudiotime;
2853 offsetvideonotset=true;
2859 lastrefaudiotime=curreftime;
2864 void VideoVPEOGL::ResetTimeOffsets() {
2865 offsetnotset=true; //called from demuxer
2866 offsetvideonotset=true;
2867 offsetaudionotset=true;
2875 long long VideoVPEOGL::GetCurrentSystemTime()
2878 clock_gettime(CLOCK_MONOTONIC, &ts);
2879 return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
2882 void VideoVPEOGL::WaitUntil(long long time)
2884 struct timespec interval;
2885 interval.tv_sec=time/10000000LL;
2886 interval.tv_nsec=(time %10000000LL)*100LL;
2887 while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
2890 void VideoVPEOGL::FrameWaitforDisplay(long long pts)
2892 //ok first calculate the absolute time
2893 long long target_time=pts-playbacktimeoffset;
2894 // we have to wait untile the next frame
2895 long long offset=Demuxer::getInstance()->getFrameRate();
2896 long long current_time=GetCurrentSystemTime();
2897 if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
2898 if (offset==0) offset=25;
2899 offset=10000000LL/offset;
2900 target_time+=offset;
2901 Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
2902 target_time-current_time);
2904 WaitUntil(target_time);
2905 Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
2908 void VideoVPEOGL::AdjustAudioPTS(long long pts)
2910 long long newplaybacktimeoffset=pts-GetCurrentSystemTime();
2911 /* if ((newplaybacktimeoffset-1000000LL)>playbacktimeoffset
2912 || (newplaybacktimeoffset+1000000LL)<playbacktimeoffset) {
2913 Log::getInstance()->log("Video", Log::DEBUG, "Adjust Playbackoffsettime o: %lld n: %lld",
2914 playbacktimeoffset,newplaybacktimeoffset);*/
2915 playbacktimeoffset=newplaybacktimeoffset;
2921 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2923 mediapacket = mplist.front();
2926 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2928 DeliverMediaPacket(mediapacket, buffer, samplepos);
2929 if (*samplepos == mediapacket.length) {
2936 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2937 const UCHAR* buffer,
2940 if (packet.type == MPTYPE_VIDEO_H264)
2948 switch (decoding_backend) {
2949 default: case 0: return 0; // no backend runnigng
2950 #ifdef VPE_OMX_SUPPORT
2951 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2952 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2953 case VPE_DECODER_OMX_libav_TRANSCODE: return DeliverMediaPacketOMXTranscode(packet,buffer,samplepos);
2956 #ifdef VPE_LIBAV_SUPPORT
2957 case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2962 #ifdef VPE_OMX_SUPPORT
2963 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2964 const UCHAR* buffer,
2969 //Later add fail back code for libav
2971 *samplepos+=packet.length;
2972 return packet.length;
2976 if (!omx_running) return 0; // if we are not runnig do not do this
2977 if (paused) return 0; //Block if we pause
2979 long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
2980 if (packet.synched &&
2981 (packet.presentation_time<0 /*|| // preroll skip frames
2982 (packet.presentation_time+5000000LL)<(current_media_time)*/)) { // we are late skip
2983 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
2984 *samplepos=packet.length;
2985 return packet.length;
2988 OMX_ERRORTYPE error;
2990 /*First Check, if we have an video sample*/
2994 return 0; //Not in iframe mode!
2998 if (packet.disconti) {
3000 if (cur_input_buf_omx) {
3001 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3002 if (error!=OMX_ErrorNone){
3003 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3005 FrameWaitforDisplay(lastreftimeOMX);
3006 cur_input_buf_omx=NULL;
3010 /*Inspect PES-Header */
3012 // OMX_STATETYPE temp_state;
3013 // OMX_GetState(omx_vid_dec,&temp_state);
3015 if (*samplepos==0) {//stripheader
3016 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3017 if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
3018 buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
3019 *samplepos+=headerstrip;
3020 if ( packet.synched ) {
3021 if (cur_input_buf_omx) {
3022 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3023 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3024 if (error!=OMX_ErrorNone){
3025 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3027 cur_input_buf_omx=NULL;//write out old data
3028 FrameWaitforDisplay(lastreftimeOMX);
3034 if (!firstsynched) {//
3035 *samplepos=packet.length;//if we have not processed at least one
3036 return packet.length;//synched packet ignore it!
3041 if (!cur_input_buf_omx) {
3042 input_bufs_omx_mutex.Lock();
3043 if (input_bufs_omx_free.size()==0) {
3044 input_bufs_omx_mutex.Unlock();
3045 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3046 return 0; // we do not have a free media sample
3049 cur_input_buf_omx=input_bufs_omx_free.front();
3050 cur_input_buf_omx->nFilledLen=0;
3051 cur_input_buf_omx->nOffset=0;
3052 cur_input_buf_omx->nTimeStamp=0;
3053 input_bufs_omx_free.pop_front();
3054 input_bufs_omx_mutex.Unlock();
3060 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3061 if (packet.synched) {
3062 Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
3064 //lastreftimePTS=packet.pts;
3065 if (omx_first_frame) { // TODO time
3066 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3067 Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
3068 omx_first_frame=false;
3070 //cur_input_buf_omx->nFlags=0;
3071 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3073 lastreftimeOMX=packet.presentation_time;
3074 Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
3075 lastreftimePTS=packet.pts;
3076 cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
3080 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3081 cur_input_buf_omx->nTimeStamp=0;
3084 // ms->SetSyncPoint(TRUE);
3086 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3091 unsigned int haveToCopy=packet.length-*samplepos;
3093 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3094 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3095 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3096 haveToCopy-=cancopy;
3097 cur_input_buf_omx->nFilledLen+=cancopy;
3098 *samplepos+=cancopy;
3099 // push old buffer out
3101 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
3102 if (error!=OMX_ErrorNone){
3103 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3106 input_bufs_omx_mutex.Lock();
3107 if (input_bufs_omx_free.size()==0) {
3108 input_bufs_omx_mutex.Unlock();
3109 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3110 return *samplepos; // we do not have a free media sample
3112 cur_input_buf_omx=input_bufs_omx_free.front();
3113 cur_input_buf_omx->nFilledLen=0;
3114 cur_input_buf_omx->nOffset=0;
3115 cur_input_buf_omx->nTimeStamp=0;
3116 input_bufs_omx_free.pop_front();
3117 input_bufs_omx_mutex.Unlock();
3119 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3122 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3123 buffer+packet.pos_buffer+*samplepos,haveToCopy);
3124 cur_input_buf_omx->nFilledLen+=haveToCopy;
3128 *samplepos+=haveToCopy;
3136 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
3140 int VideoVPEOGL::DecodePacketOMXTranscode()
3142 unsigned int haveToCopy=incom_packet_libav.size;
3143 if (incom_packet_libav.size==0) return 1; // we are already empty
3146 while (haveToCopy>0) {
3150 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
3152 #ifdef BENCHMARK_FPS
3153 int cur_time=getTimeMS();
3155 dec_bytes=avcodec_decode_video2(transcodecodec_context_libav, &transcode_frame_libav,
3156 &frame_ready, &incom_packet_libav);
3157 #ifdef BENCHMARK_FPS
3158 time_in_decoder+=getTimeMS()-cur_time;
3159 if (frame_ready) num_frames++;
3160 if ((num_frames%100)==0) {
3161 float fps=1000./(float)(time_in_decoder);
3162 fps*=((float)num_frames);
3163 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
3167 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
3170 haveToCopy-=dec_bytes;
3172 struct transcode_pix_fmt *transcode=(struct transcode_pix_fmt *)transcode_frame_libav.data[0];
3173 //if (!benchmark) fwrite(transcode->packet.data,transcode->packet.size,1,output_file);
3176 //add omx magic, this should be an omx packet
3177 OMX_BUFFERHEADERTYPE* omx_packet=(OMX_BUFFERHEADERTYPE*)transcode_frame_libav.base[0];
3178 omx_packet->nFilledLen=transcode->packet.size;
3180 input_bufs_omx_mutex.Lock();
3181 input_bufs_omx_in_libav.remove(omx_packet); // say that it is passed down to the decoder
3182 input_bufs_omx_mutex.Unlock();
3184 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,omx_packet);
3185 if (error!=OMX_ErrorNone){
3186 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
3194 incom_packet_libav.size=0;
3200 UINT VideoVPEOGL::DeliverMediaPacketOMXTranscode(MediaPacket packet,
3201 const UCHAR* buffer,
3204 //Later add fail back code for libav
3206 *samplepos+=packet.length;
3207 return packet.length;
3210 if (!omx_running) return 0; // if we are not runnig do not do this
3216 return 0; //Not in iframe mode!
3220 if (packet.disconti) {
3222 if (!DecodePacketOMXTranscode()) return 0;
3225 /*Inspect PES-Header */
3226 if (*samplepos==0) {//stripheader
3227 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3228 *samplepos+=headerstrip;
3229 if ( packet.synched ) {
3231 if (!DecodePacketOMXTranscode()) return 0; // WriteOut old Data
3234 incom_packet_libav.pts=packet.pts/3600;
3235 incom_packet_libav.dts=packet.dts/3600;
3236 // reftime1=packet.presentation_time;
3237 // reftime2=reftime1+1;
3240 incom_packet_libav.pts=0;
3241 incom_packet_libav.dts=0;
3242 if (!firstsynched) {//
3243 *samplepos=packet.length;//if we have not processed at least one
3244 return packet.length;//synched packet ignore it!
3254 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3255 /*if (packet.disconti) {
3256 ms->SetDiscontinuity(TRUE);
3258 ms->SetDiscontinuity(FALSE);
3260 //if (packet.synched) {
3262 //lastreftimePTS=packet.pts;
3263 if (omx_first_frame) { // TODO time
3264 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3265 omx_first_frame=false;
3271 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3274 // ms->SetSyncPoint(TRUE);
3278 unsigned int haveToCopy=packet.length-*samplepos;
3280 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3281 // if the buffer is to small reallocate
3282 incom_packet_libav_size+=haveToCopy;
3283 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3284 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3286 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3287 incom_packet_libav.size+=haveToCopy;
3289 *samplepos+=haveToCopy;
3300 #ifdef VPE_LIBAV_SUPPORT
3301 int VideoVPEOGL::DecodePacketlibav()
3303 unsigned int haveToCopy=incom_packet_libav.size;
3304 if (incom_packet_libav.size==0) return 1; // we are already empty
3305 while (haveToCopy>0) {
3309 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
3311 #ifdef BENCHMARK_FPS
3312 int cur_time=getTimeMS();
3314 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
3315 &frame_ready, &incom_packet_libav);
3316 #ifdef BENCHMARK_FPS
3317 time_in_decoder+=getTimeMS()-cur_time;
3318 if (frame_ready) num_frames++;
3319 if ((num_frames%100)==0) {
3320 float fps=1000./(float)(time_in_decoder);
3321 fps*=((float)num_frames);
3322 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
3326 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
3329 haveToCopy-=dec_bytes;
3331 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
3333 lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
3334 dec_frame_libav_mutex.Lock();
3335 libavwidth=mpeg2codec_context_libav->width;
3336 libavheight=mpeg2codec_context_libav->height;
3337 libavpixfmt=mpeg2codec_context_libav->pix_fmt;
3338 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
3339 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
3340 // ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
3343 dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
3344 dec_frame_libav_decoding=NULL;
3345 if (dec_frame_libav_free.size()>0) {
3346 dec_frame_libav_decoding=dec_frame_libav_free.front();
3347 dec_frame_libav_free.pop_front();
3348 dec_frame_libav_mutex.Unlock();
3350 libav_hastime=false;
3352 libav_hastime=false;
3353 dec_frame_libav_mutex.Unlock();
3354 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
3364 incom_packet_libav.size=0;
3370 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
3371 const UCHAR* buffer,
3374 //Later add fail back code for libav
3376 *samplepos+=packet.length;
3377 return packet.length;
3380 if (!libav_running) return 0; // if we are not runnig do not do this
3386 return 0; //Not in iframe mode!
3390 if (packet.disconti) {
3392 if (!DecodePacketlibav()) return 0;
3395 /*Inspect PES-Header */
3396 if (!dec_frame_libav_decoding) {
3397 dec_frame_libav_mutex.Lock();
3398 if (dec_frame_libav_free.size()>0) {
3399 dec_frame_libav_decoding=dec_frame_libav_free.front();
3400 dec_frame_libav_free.pop_front();
3401 dec_frame_libav_mutex.Unlock();
3403 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
3404 dec_frame_libav_mutex.Unlock();
3412 if (*samplepos==0) {//stripheader
3413 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
3414 *samplepos+=headerstrip;
3415 if ( packet.synched ) {
3417 if (!DecodePacketlibav()) return 0; // WriteOut old Data
3419 libav_time=packet.presentation_time;
3421 // reftime1=packet.presentation_time;
3422 // reftime2=reftime1+1;
3425 if (!firstsynched) {//
3426 *samplepos=packet.length;//if we have not processed at least one
3427 return packet.length;//synched packet ignore it!
3437 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3438 /*if (packet.disconti) {
3439 ms->SetDiscontinuity(TRUE);
3441 ms->SetDiscontinuity(FALSE);
3443 //if (packet.synched) {
3445 //lastreftimePTS=packet.pts;
3446 if (omx_first_frame) { // TODO time
3447 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3448 omx_first_frame=false;
3454 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3457 // ms->SetSyncPoint(TRUE);
3461 unsigned int haveToCopy=packet.length-*samplepos;
3463 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
3464 // if the buffer is to small reallocate
3465 incom_packet_libav_size+=haveToCopy;
3466 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
3467 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
3469 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
3470 incom_packet_libav.size+=haveToCopy;
3472 *samplepos+=haveToCopy;
3483 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length) {
3484 if (!omx_running) return false;
3486 EnterIframePlayback();
3488 int haveToCopy = length;
3490 if (!cur_input_buf_omx) {
3491 input_bufs_omx_mutex.Lock();
3492 if (input_bufs_omx_free.size() == 0) {
3493 input_bufs_omx_mutex.Unlock();
3494 Log::getInstance()->log("Video", Log::DEBUG,
3495 "Deliver MediaPacket no free sample");
3496 return false; // we do not have a free media sample
3499 cur_input_buf_omx = input_bufs_omx_free.front();
3500 cur_input_buf_omx->nFilledLen = 0;
3501 cur_input_buf_omx->nOffset = 0;
3502 cur_input_buf_omx->nTimeStamp = 0;
3503 input_bufs_omx_free.pop_front();
3504 input_bufs_omx_mutex.Unlock();
3508 unsigned int pattern, packet_length;
3509 unsigned int headerstrip = 0;
3514 //Now we strip the pes header
3515 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3516 while (read_pos + 7 <= length) {
3517 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3518 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3522 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3523 packet_length = ((buffer[read_pos + 4] << 8)
3524 | (buffer[read_pos + 5])) + 6;
3525 if (read_pos + packet_length > length)
3528 if ((headerstrip < packet_length)
3529 && (cur_input_buf_omx->nFilledLen + packet_length
3530 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3532 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3535 cur_input_buf_omx->nFlags
3536 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3539 cur_input_buf_omx->nTimeStamp = 0;
3540 OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
3542 if (error != OMX_ErrorNone) {
3543 Log::getInstance()->log("Video", Log::DEBUG,
3544 "OMX_EmptyThisBuffer failed %x", error);
3546 cur_input_buf_omx = NULL;
3548 if (!cur_input_buf_omx) {
3550 while (count < 100 && omx_running && iframemode) {
3553 input_bufs_omx_mutex.Lock();
3554 if (input_bufs_omx_free.size() == 0) {
3555 input_bufs_omx_mutex.Unlock();
3556 Log::getInstance()->log("Video", Log::DEBUG,
3557 "Ifrane no free sample");
3559 if (!omx_running) return false;
3562 cur_input_buf_omx = input_bufs_omx_free.front();
3563 cur_input_buf_omx->nFilledLen = 0;
3564 cur_input_buf_omx->nOffset = 0;
3565 cur_input_buf_omx->nTimeStamp = 0;
3566 input_bufs_omx_free.pop_front();
3567 input_bufs_omx_mutex.Unlock();
3570 if (!cur_input_buf_omx)
3575 if (packet_length > headerstrip) {
3577 cur_input_buf_omx->pBuffer
3578 + cur_input_buf_omx->nFilledLen,
3579 buffer + read_pos + headerstrip,
3580 packet_length - headerstrip);
3581 cur_input_buf_omx->nFilledLen += packet_length
3584 read_pos += packet_length;
3586 pattern = (buffer[read_pos] << 16)
3587 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3593 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3596 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3599 cur_input_buf_omx->nTimeStamp = 0;
3600 OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
3601 if (error != OMX_ErrorNone) {
3602 Log::getInstance()->log("Video", Log::DEBUG,
3603 "OMX_EmptyThisBuffer failed %x", error);
3605 cur_input_buf_omx = NULL;
3608 MILLISLEEP(40); //Block a bit
3612 int VideoVPEOGL::EnterIframePlayback()
3615 if (cur_input_buf_omx) {
3616 OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
3618 if (error != OMX_ErrorNone) {
3619 Log::getInstance()->log("Video", Log::DEBUG,
3620 "OMX_EmptyThisBuffer failed %x", error);
3623 cur_input_buf_omx = NULL;
3625 clock_mutex.Unlock();