2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "videovpeogl.h"
23 #include "mtdraspberry.h"
25 #include "osdopengl.h"
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
32 VideoVPEOGL::VideoVPEOGL()
36 #ifdef VPE_OMX_SUPPORT
40 cur_input_buf_omx=NULL;
41 omx_h264=omx_mpeg2=true;
44 #ifdef VPE_LIBAV_SUPPORT
45 mpeg2codec_context_libav=NULL;
47 dec_frame_libav_uploading=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;
63 VideoVPEOGL::~VideoVPEOGL()
68 int VideoVPEOGL::init(UCHAR tformat)
70 if (initted) return 0;
73 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
75 if (!setFormat(tformat)) { shutdown(); return 0; }
76 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
77 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
78 if (!setMode(NORMAL)) { shutdown(); return 0; }
79 if (!setSource()) { shutdown(); return 0; }
80 if (!attachFrameBuffer()) { shutdown(); return 0; }
84 /* if (format == PAL) setLetterboxBorder("38");
85 else setLetterboxBorder("31");*/
99 int VideoVPEOGL::initUsingOSDObjects()
101 EGLDisplay i_egl_display;
102 EGLSurface i_egl_surface;
103 EGLContext i_egl_context;
104 EGLConfig i_egl_config;
105 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
106 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
107 const EGLint attr_context[]={
108 EGL_CONTEXT_CLIENT_VERSION,2,
112 egl_display=i_egl_display;
113 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
114 if (egl_context==EGL_NO_CONTEXT) {
115 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %d",eglGetError());
118 // We create a dummy surface here, in order to allow two contexts
119 const EGLint attr_pbuffer[]={
120 EGL_WIDTH, 1, EGL_HEIGHT,1,
123 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
124 if (egl_surface==EGL_NO_SURFACE) {
125 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %d",eglGetError());
132 //egl_surface=i_egl_surface;
133 //egl_context=i_egl_context;
136 #ifdef VPE_OMX_SUPPORT
137 // we are called before the audio
140 if (error!=OMX_ErrorNone) {
141 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
145 //our callbacks move to play?
149 #ifdef VPE_LIBAV_SUPPORT
152 if (decoding_mode==VPE_NO_XVMC) {
153 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
155 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
157 if (mpeg2codec_libav==NULL) {
158 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
168 #ifdef VPE_OMX_SUPPORT
170 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
171 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
172 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
174 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
176 struct VPE_OMX_EVENT new_event;
177 new_event.handle=handle;
178 new_event.appdata=appdata;
179 new_event.event_type=event_type;
180 new_event.data1=data1;
181 new_event.data2=data2;
182 new_event.event_data=event_data;
184 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
185 video->AddOmxEvent(new_event);
187 /* switch (event_type) {
188 case OMX_EventCmdComplete: {
193 return OMX_ErrorNone;
197 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
199 omx_event_mutex.Lock();
200 omx_events.push_back(new_event);
201 omx_event_mutex.Unlock();
205 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
207 Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
208 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
209 video->ReturnEmptyOMXBuffer(buffer);
210 return OMX_ErrorNone;
214 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
215 input_bufs_omx_mutex.Lock();
216 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
217 input_bufs_omx_free.push_back(buffer);
218 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
219 input_bufs_omx_mutex.Unlock();
222 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
223 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
224 return OMX_ErrorNone;
229 int VideoVPEOGL::shutdown()
231 if (!initted) return 0;
236 #ifdef VPE_OMX_SUPPORT
237 DeAllocateCodecsOMX();
240 #ifdef VPE_LIBAV_SUPPORT
241 DeAllocateCodecsLibav();
243 eglDestroyContext(egl_display,egl_context);
248 int VideoVPEOGL::AllocateYUVOglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
250 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture");
252 glGenTextures(1, &outframe->textures[0]);
253 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
254 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
255 GL_UNSIGNED_BYTE, NULL);
257 glGenTextures(1, &outframe->textures[1]);
258 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
259 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
260 GL_UNSIGNED_BYTE, NULL);
262 glGenTextures(1, &outframe->textures[2]);
263 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
264 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
265 GL_UNSIGNED_BYTE, NULL);
266 outframe->height=height;
267 outframe->width=width;
268 outframe->stride=stride;
273 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
274 VPEOGLFrame *return_obj=NULL;
275 ogl_frame_mutex.Lock();
276 if (ready_ogl_frames.size()>0) {
277 return_obj=ready_ogl_frames.front();
278 ready_ogl_frames.pop_front();
279 ogl_frame_outside=true;
281 ogl_frame_mutex.Unlock();
285 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
287 ogl_frame_mutex.Lock();
289 ogl_frame_outside=false;
290 free_ogl_frames.push_back(frame);
292 ogl_frame_mutex.Unlock();
295 void VideoVPEOGL::threadMethod()
297 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
298 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
303 #ifdef VPE_LIBAV_SUPPORT
304 dec_frame_libav_mutex.Lock();
305 if (dec_frame_libav_upload_pending.size()>0) {
306 dec_frame_libav_uploading=dec_frame_libav_upload_pending.front();
307 dec_frame_libav_upload_pending.pop_front();
308 if (dec_frame_libav_upload_pending.size()>0) sleep=false;
310 dec_frame_libav_mutex.Unlock();
311 if (dec_frame_libav_uploading) {
312 int width,height,pixfmt;
313 //First get a free ogl image
314 VPEOGLFrame* out_frame=NULL;
316 ogl_frame_mutex.Lock();
317 if (all_ogl_frames.size()==0) {
318 ogl_frame_mutex.Unlock(); break;
321 if (free_ogl_frames.size()>0) {
325 out_frame=free_ogl_frames.front();
326 free_ogl_frames.pop_front();
327 } else MILLISLEEP(2);
328 ogl_frame_mutex.Unlock();
332 if (out_frame->textures[0]==0 || out_frame->width!=width ||
333 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
334 if (out_frame->textures[0]!=0) {
335 glDeleteTextures(1,&out_frame->textures[0]);
336 out_frame->textures[0]=0;
338 if (out_frame->textures[1]!=0) {
339 glDeleteTextures(1,&out_frame->textures[1]);
340 out_frame->textures[1]=0;
342 if (out_frame->textures[2]!=0) {
343 glDeleteTextures(1,&out_frame->textures[2]);
344 out_frame->textures[2]=0;
346 if (!AllocateYUVOglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
349 //up to now only YUV data, this is for reference only, since the pi is too slow.
350 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
351 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
353 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
354 out_frame->stride,out_frame->height,
355 GL_LUMINANCE,GL_UNSIGNED_BYTE,
356 dec_frame_libav_uploading->data[0]);
359 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
360 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
361 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
362 out_frame->stride>>1,out_frame->height>>1,
363 GL_LUMINANCE,GL_UNSIGNED_BYTE,
364 dec_frame_libav_uploading->data[1]);
366 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
367 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
368 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
369 out_frame->stride>>1,out_frame->height>>1,
370 GL_LUMINANCE,GL_UNSIGNED_BYTE,
371 dec_frame_libav_uploading->data[2]);
374 releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
377 ogl_frame_mutex.Lock();
378 ready_ogl_frames.push_back(out_frame);
379 ogl_frame_mutex.Unlock();
380 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
384 dec_frame_libav_mutex.Lock();
385 dec_frame_libav_free.push_back(dec_frame_libav_uploading);
386 dec_frame_libav_uploading=NULL;
387 dec_frame_libav_mutex.Unlock();
400 if (sleep) threadWaitForSignal();
406 void VideoVPEOGL::threadPostStopCleanup()
408 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
409 #ifdef VPE_LIBAV_SUPPORT
410 dec_frame_libav_uploading=NULL;
417 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
421 // Override the aspect ratio usage, temporarily use to set the video chip mode
422 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
424 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
425 if (!setSource()) { shutdown(); return 0; }
426 if (!attachFramebuffer()) { shutdown(); return 0; }
428 // Reopening the fd causes the scart aspect line to go back to 4:3
429 // Set this again to the same as the tv screen size
430 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
432 // mode == LETTERBOX is invalid if the TV is widescreen
433 if (tvsize == ASPECT16X9) setMode(NORMAL);
438 int VideoVPEOGL::setDefaultAspect()
440 return setAspectRatio(tvsize);
445 int VideoVPEOGL::setFormat(UCHAR tformat)
447 if (!initted) return 0;
448 if ((tformat != PAL) && (tformat != NTSC)) return 0;
451 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
467 int VideoVPEOGL::setConnection(UCHAR tconnection)
469 if (!initted) return 0;
470 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
471 connection = tconnection;
473 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
477 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
479 if (!initted) return 0;
480 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
481 aspectRatio = taspectRatio;
483 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
485 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
489 int VideoVPEOGL::setMode(UCHAR tmode)
491 if (!initted) return 0;
493 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
495 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
496 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
499 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
503 int VideoVPEOGL::signalOff()
505 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
509 int VideoVPEOGL::signalOn()
511 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
515 int VideoVPEOGL::setSource()
517 if (!initted) return 0;
519 // What does this do...
520 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
524 int VideoVPEOGL::setPosition(int x, int y)
526 if (!initted) return 0;
528 // vid_pos_regs_t pos_d;
532 /* vid_pos_regs_t pos_d;
534 memset(&pos_d, 0, sizeof(pos_d));
559 pos_d.y = 100; // Top left X
560 pos_d.x = 50; // Top left Y
568 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
572 int VideoVPEOGL::sync()
574 if (!initted) return 0;
576 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
583 int VideoVPEOGL::play()
585 if (!initted) return 0;
587 #ifdef VPE_OMX_SUPPORT
590 if (!omx_h264) doomx=false;
592 if (!omx_mpeg2) doomx=false;
595 if (AllocateCodecsOMX()) {
596 decoding_backend=VPE_DECODER_OMX;
598 // Otherwise fall back to libav
602 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
605 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
610 #ifdef VPE_LIBAV_SUPPORT
611 if (AllocateCodecsLibav()) {
612 decoding_backend=VPE_DECODER_libav;
614 // Otherwise fall back to libav
623 #ifdef VPE_OMX_SUPPORT
624 int VideoVPEOGL::AllocateCodecsOMX()
627 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
629 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
630 //Clock, move later to audio
634 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
637 if (error!=OMX_ErrorNone){
638 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
639 DeAllocateCodecsOMX();
645 OMX_PORT_PARAM_TYPE p_param;
646 memset(&p_param,0,sizeof(p_param));
647 p_param.nSize=sizeof(p_param);
648 p_param.nVersion.nVersion=OMX_VERSION;
649 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
650 if (error!=OMX_ErrorNone){
651 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
652 DeAllocateCodecsOMX();
655 omx_clock_output_port=p_param.nStartPortNumber;
657 for (unsigned int i=0;i<p_param.nPorts;i++) {
658 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
659 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
660 DeAllocateCodecsOMX();
666 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
667 memset(&clock_conf,0,sizeof(clock_conf));
668 clock_conf.nSize=sizeof(clock_conf);
669 clock_conf.nVersion.nVersion=OMX_VERSION;
670 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
671 clock_conf.nStartTime=0;
672 clock_conf.nOffset=0;
673 clock_conf.nWaitMask=OMX_CLOCKPORT0;
674 error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
675 if (error!=OMX_ErrorNone){
676 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
677 DeAllocateCodecsOMX();
684 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
686 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
689 if (error!=OMX_ErrorNone){
690 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
691 DeAllocateCodecsOMX();
697 memset(&p_param,0,sizeof(p_param));
698 p_param.nSize=sizeof(p_param);
699 p_param.nVersion.nVersion=OMX_VERSION;
700 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
701 if (error!=OMX_ErrorNone){
702 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
703 DeAllocateCodecsOMX();
706 omx_codec_input_port=p_param.nStartPortNumber;
707 omx_codec_output_port=p_param.nStartPortNumber+1;
709 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
710 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
711 DeAllocateCodecsOMX();
716 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
717 memset(&conceal,0,sizeof(conceal));
718 conceal.nSize=sizeof(conceal);
719 conceal.nVersion.nVersion=OMX_VERSION;
720 conceal.bStartWithValidFrame=OMX_FALSE;
722 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
723 if (error!=OMX_ErrorNone){
724 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
725 DeAllocateCodecsOMX();
730 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
731 if (error!=OMX_ErrorNone){
732 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
733 DeAllocateCodecsOMX();
739 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
740 if (error!=OMX_ErrorNone){
741 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
742 DeAllocateCodecsOMX();
745 omx_shed_input_port=p_param.nStartPortNumber;
746 omx_shed_output_port=p_param.nStartPortNumber+1;
749 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
750 if (error!=OMX_ErrorNone){
751 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
752 DeAllocateCodecsOMX();
755 omx_shed_clock_port=p_param.nStartPortNumber;
758 if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
759 || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
760 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
761 DeAllocateCodecsOMX();
766 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
767 if (error!=OMX_ErrorNone){
768 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
769 DeAllocateCodecsOMX();
773 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
774 if (error!=OMX_ErrorNone){
775 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
776 DeAllocateCodecsOMX();
779 omx_rend_input_port=p_param.nStartPortNumber;
780 //omx_rend_output_port=p_param.nStartPortNumber+1;
783 if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
785 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
786 DeAllocateCodecsOMX();
799 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
800 if (error!=OMX_ErrorNone){
801 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
808 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
809 memset(&ft_type,0,sizeof(ft_type));
810 ft_type.nSize=sizeof(ft_type);
811 ft_type.nVersion.nVersion=OMX_VERSION;
813 ft_type.nPortIndex=omx_codec_input_port;
815 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
817 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
820 Demuxer* demux=Demuxer::getInstance();
822 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
823 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
824 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
825 if (error!=OMX_ErrorNone){
826 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
827 DeAllocateCodecsOMX();
832 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
833 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
834 DeAllocateCodecsOMX();
839 if (!PrepareInputBufsOMX()) {
840 DeAllocateCodecsOMX();
845 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
846 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
847 DeAllocateCodecsOMX();
851 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
852 if (error!=OMX_ErrorNone){
853 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);
854 DeAllocateCodecsOMX();
858 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
860 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
861 DeAllocateCodecsOMX();
865 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
866 DeAllocateCodecsOMX();
870 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
871 if (error!=OMX_ErrorNone){
872 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
873 DeAllocateCodecsOMX();
879 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
881 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
882 DeAllocateCodecsOMX();
886 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
889 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
890 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
891 DeAllocateCodecsOMX();
894 if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
895 ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
896 DeAllocateCodecsOMX();
900 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
901 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
902 DeAllocateCodecsOMX();
906 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
907 if (error!=OMX_ErrorNone){
908 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
909 DeAllocateCodecsOMX();
913 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
915 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
916 DeAllocateCodecsOMX();
920 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
921 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
922 DeAllocateCodecsOMX();
926 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
927 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
928 DeAllocateCodecsOMX();
933 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
934 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
935 DeAllocateCodecsOMX();
939 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
940 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
941 DeAllocateCodecsOMX();
946 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
947 memset(&dispconf,0,sizeof(dispconf));
948 dispconf.nSize=sizeof(dispconf);
949 dispconf.nVersion.nVersion=OMX_VERSION;
951 dispconf.nPortIndex=omx_rend_input_port;
953 dispconf.set=OMX_DISPLAY_SET_LAYER ;
955 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
956 if (error!=OMX_ErrorNone){
957 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
958 DeAllocateCodecsOMX();
962 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
963 dispconf.fullscreen=OMX_FALSE;
964 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
965 if (error!=OMX_ErrorNone){
966 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
967 DeAllocateCodecsOMX();
971 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
972 dispconf.dest_rect.x_offset=100;
973 dispconf.dest_rect.y_offset=100;
974 dispconf.dest_rect.width=640;
975 dispconf.dest_rect.height=480;
976 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
977 if (error!=OMX_ErrorNone){
978 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
979 DeAllocateCodecsOMX();
986 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
987 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
988 DeAllocateCodecsOMX();
998 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1000 OMX_ERRORTYPE error;
1001 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1002 if (error!=OMX_ErrorNone){
1003 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1007 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1015 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1017 OMX_ERRORTYPE error;
1018 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1019 if (error!=OMX_ErrorNone){
1020 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1024 if (!wait) return 1;
1025 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1033 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1035 OMX_ERRORTYPE error;
1036 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1037 if (error!=OMX_ErrorNone){
1038 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1042 if (!wait) return 1;
1043 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1054 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1058 omx_event_mutex.Lock();
1059 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1060 while (itty!=omx_events.end()) {
1062 VPE_OMX_EVENT current=*itty;
1063 if (current.handle==handle) { //this is ours
1064 if (current.event_type==OMX_EventError) {
1065 omx_events.erase(itty);
1066 omx_event_mutex.Unlock();
1069 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1070 omx_events.erase(itty);
1071 omx_event_mutex.Unlock();
1078 omx_event_mutex.Unlock();
1083 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1092 int VideoVPEOGL::PrepareInputBufsOMX()
1094 OMX_ERRORTYPE error;
1095 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1096 memset(&port_def_type,0,sizeof(port_def_type));
1097 port_def_type.nSize=sizeof(port_def_type);
1098 port_def_type.nVersion.nVersion=OMX_VERSION;
1099 port_def_type.nPortIndex=omx_codec_input_port;
1101 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1103 if (error!=OMX_ErrorNone){
1104 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1106 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1107 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1108 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1110 port_def_type.nBufferCountActual=60;
1112 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1114 if (error!=OMX_ErrorNone){
1115 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1119 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1120 if (error!=OMX_ErrorNone){
1121 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1125 input_bufs_omx_mutex.Lock();
1126 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1128 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1129 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1130 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1131 if (error!=OMX_ErrorNone){
1132 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1133 input_bufs_omx_mutex.Unlock();
1136 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1137 if (error!=OMX_ErrorNone){
1138 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1139 input_bufs_omx_mutex.Unlock();
1142 input_bufs_omx_all.push_back(buf_head);
1143 input_bufs_omx_free.push_back(buf_head);
1145 omx_first_frame=true;
1148 cur_input_buf_omx=NULL;
1149 input_bufs_omx_mutex.Unlock();
1152 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1153 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1156 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1161 int VideoVPEOGL::DestroyInputBufsOMX()
1163 OMX_ERRORTYPE error;
1165 cur_input_buf_omx=NULL;
1166 input_bufs_omx_mutex.Lock();
1167 for (int i=0; i< input_bufs_omx_all.size();i++) {
1168 // free(input_bufs_omx_all[i]->pBuffer);
1169 // input_bufs_omx_all[i]->pBuffer=NULL;
1170 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1171 if (error!=OMX_ErrorNone){
1172 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1173 input_bufs_omx_mutex.Unlock();
1177 input_bufs_omx_all.clear();
1178 input_bufs_omx_free.clear();
1179 input_bufs_omx_mutex.Unlock();
1186 int VideoVPEOGL::DeAllocateCodecsOMX()
1188 OMX_ERRORTYPE error;
1191 // first flush all buffers
1193 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1194 if (error!=OMX_ErrorNone){
1195 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1199 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1200 if (error!=OMX_ErrorNone){
1201 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1205 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1206 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1207 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1210 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1211 if (error!=OMX_ErrorNone){
1212 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1216 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1217 if (error!=OMX_ErrorNone){
1218 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1222 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1223 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1224 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1227 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1228 if (error!=OMX_ErrorNone) {
1229 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1233 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1234 if (error!=OMX_ErrorNone) {
1235 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1239 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1240 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1241 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1247 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1248 if (error!=OMX_ErrorNone){
1249 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1254 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1255 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1258 DestroyInputBufsOMX();
1261 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1262 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1264 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1265 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1268 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1269 if (error!=OMX_ErrorNone){
1270 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1274 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1275 if (error!=OMX_ErrorNone){
1276 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1280 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1281 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1284 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1285 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1288 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1289 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1291 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1292 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1297 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1298 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1302 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1303 if (error!=OMX_ErrorNone){
1304 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1307 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1308 if (error!=OMX_ErrorNone){
1309 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1313 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1314 if (error!=OMX_ErrorNone){
1315 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1319 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1320 if (error!=OMX_ErrorNone){
1321 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1329 error=OMX_FreeHandle(omx_vid_dec);
1330 error=OMX_FreeHandle(omx_vid_sched);
1331 error=OMX_FreeHandle(omx_vid_rend);
1332 error=OMX_FreeHandle(omx_clock);
1334 if (error!=OMX_ErrorNone) {
1335 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1345 #ifdef VPE_LIBAV_SUPPORT
1347 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1349 int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1350 enum PixelFormat ret_pix=PIX_FMT_NONE;
1351 if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1352 while (*fmt!=PIX_FMT_NONE) {
1353 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1354 ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1355 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1356 ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1363 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1365 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1369 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1371 unsigned int want_sizes[4]={0,0,0,0};
1373 bool normal_pixs=false;
1375 int num_dct_blocks=0;
1378 //reget logic from mplayer
1379 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1380 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1385 if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1387 // standard pixel format
1388 // this is written using much inspiration from libav util.c, so portions from there
1394 avcodec_align_dimensions2(c, &width, &height, s_a);
1395 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1399 // Now we have to determine alignment size
1400 bool unaligned=true;
1402 av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1403 width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1405 for (int i=0;i<4;i++) {
1406 if ((pict.linesize[i]%s_a[i])!=0) {
1412 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1413 for (int i=0;i<4 ;i++) {
1414 if (i<3 && pict.data[i+1]) {
1415 want_sizes[i]=pict.data[i+1]-pict.data[i];
1418 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1425 //TODO set linesizes!
1427 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1428 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1430 want_sizes[2]=sizeof(xvmc_pix_fmt);
1431 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1432 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1433 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1437 VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1439 //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1441 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1447 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1448 int hchr_shift,vchr_shift;
1449 avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1450 const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1451 for (int i=0;i<4;i++) {
1452 pic->data[i]=(uint8_t*)frame_buf->data[i];
1453 pic->linesize[i]=pict.linesize[i];
1459 edge_width>>=hchr_shift;
1460 edge_height>>=vchr_shift;
1462 pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1466 pic->base[0]=(uint8_t*)frame_buf; // our structure
1467 //pic->extended_data=pic->data;
1468 if(c->pkt) pic->pkt_pts=c->pkt->pts;
1469 else pic->pkt_pts=AV_NOPTS_VALUE;
1470 pic->width=c->width;
1471 pic->height=c->height;
1472 pic->format=c->pix_fmt;
1473 pic->sample_aspect_ratio=c->sample_aspect_ratio;
1474 pic->reordered_opaque= c->reordered_opaque;
1477 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
1478 pix_xvmc->xvmc_id=AV_XVMC_ID;
1479 pix_xvmc->data_blocks=(short*)pic->data[1];
1480 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
1481 pix_xvmc->allocated_mv_blocks=num_blocks;
1482 pix_xvmc->allocated_data_blocks=num_dct_blocks;
1483 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
1484 else pix_xvmc->idct=0;
1485 pix_xvmc->unsigned_intra=0; // let see what happens
1486 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
1487 pix_xvmc->start_mv_blocks_num=0;
1488 pix_xvmc->filled_mv_blocks_num=0;
1489 pix_xvmc->next_free_data_block_num=0;
1499 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1501 // Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
1502 ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
1504 pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
1509 int VideoVPEOGL::AllocateCodecsLibav()
1511 libav_hastime=false;
1512 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
1513 mpeg2codec_context_libav=avcodec_alloc_context();
1514 if (mpeg2codec_context_libav==NULL) {
1515 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
1518 if (decoding_mode!=VPE_NO_XVMC) {
1519 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
1520 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
1521 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
1522 mpeg2codec_context_libav->get_format=get_format_libav;
1525 mpeg2codec_context_libav->get_buffer=get_buffer_libav;
1526 mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
1527 mpeg2codec_context_libav->release_buffer=release_buffer_libav;
1530 int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
1532 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
1535 memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
1536 incom_packet_libav_size=200000;
1537 incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
1539 dec_frame_libav_mutex.Lock();
1540 for (int i=0;i<3;i++) {
1541 AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1542 if (!dec_frame_libav) {
1543 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
1546 dec_frame_libav_all.push_back(dec_frame_libav);
1547 dec_frame_libav_free.push_back(dec_frame_libav);
1549 dec_frame_libav_decoding=NULL;
1550 dec_frame_libav_mutex.Unlock();
1552 ogl_frame_mutex.Lock();
1553 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1554 for (int i=0;i<3;i++) {
1555 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1556 new_frame->type=1; //1 = YUV, 2 RGB
1557 new_frame->textures[0]=0;
1558 new_frame->textures[1]=0;
1559 new_frame->textures[2]=0;
1560 new_frame->width=new_frame->height=0;
1561 all_ogl_frames.push_back(new_frame);
1562 free_ogl_frames.push_back(new_frame);
1565 ogl_frame_outside=false;
1567 ogl_frame_mutex.Unlock();
1575 int VideoVPEOGL::DeAllocateCodecsLibav()
1577 libav_running=false;
1578 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
1579 dec_frame_libav_mutex.Lock();
1580 dec_frame_libav_upload_pending.clear();
1581 dec_frame_libav_free.clear();
1582 dec_frame_libav_mutex.Unlock();
1583 while (dec_frame_libav_uploading) {
1584 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1587 dec_frame_libav_mutex.Lock();
1588 for (int i=0; i< dec_frame_libav_all.size();i++) {
1589 av_free(dec_frame_libav_all[i]);
1592 dec_frame_libav_all.clear();
1594 av_free(incom_packet_libav.data);
1595 incom_packet_libav.data=NULL;
1596 incom_packet_libav_size=0;
1598 dec_frame_libav_mutex.Unlock();
1599 dec_frame_libav_decoding=NULL;
1600 while (ogl_frame_outside) {
1601 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1605 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1606 ogl_frame_mutex.Lock();
1607 for (int i=0; i< dec_frame_libav_all.size();i++) {
1608 VPEOGLFrame * del_frame=all_ogl_frames[i];
1609 if (del_frame->textures[0]==0) {
1610 glDeleteTextures(1,&del_frame->textures[0]);
1611 del_frame->textures[0]=0;
1613 if (del_frame->textures[1]==0) {
1614 glDeleteTextures(1,&del_frame->textures[1]);
1615 del_frame->textures[1]=0;
1617 if (del_frame->textures[2]==0) {
1618 glDeleteTextures(1,&del_frame->textures[2]);
1619 del_frame->textures[2]=0;
1621 free(all_ogl_frames[i]);
1623 all_ogl_frames.clear();
1624 free_ogl_frames.clear();
1625 ready_ogl_frames.clear();
1626 ogl_frame_mutex.Unlock();
1627 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1630 if (mpeg2codec_context_libav) {
1631 avcodec_close(mpeg2codec_context_libav);
1632 av_free(mpeg2codec_context_libav);
1633 mpeg2codec_context_libav=NULL;
1639 vpe_framebuf_mutex.Lock();
1641 for (int i=0;i<all_frame_bufs.size();i++) {
1642 VPE_FrameBuf* current=all_frame_bufs[i];
1643 for (int x=0;x<4;x++) {
1644 if (current->data[x]) {
1645 av_free(current->data[x]);
1650 all_frame_bufs.clear();
1651 free_frame_bufs.clear();
1652 locked_libav_frame_buf.clear();
1653 locked_uploading_frame_buf.clear();
1655 vpe_framebuf_mutex.Unlock();
1662 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
1664 VPE_FrameBuf* current=NULL;
1665 vpe_framebuf_mutex.Lock();
1666 if (free_frame_bufs.size()>0) {
1667 current=free_frame_bufs.front();
1668 free_frame_bufs.pop_front();
1669 } else if (all_frame_bufs.size()<6) {
1670 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
1671 memset(current,0,sizeof(VPE_FrameBuf));
1673 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
1674 vpe_framebuf_mutex.Unlock();
1675 return NULL; // We do not have a frame buffer
1677 locked_libav_frame_buf.push_back(current);
1678 vpe_framebuf_mutex.Unlock();
1679 //check if we need reallocation
1680 for (int x=0;x<4;x++) {
1681 if (current->size[x]!=size[x]) {
1682 current->data[x]=av_realloc(current->data[x],size[x]);
1683 current->size[x]=size[x];
1686 framebuf_framenum++;
1687 current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
1692 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
1694 // first find frame_buf memory
1696 //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
1697 VPE_FrameBuf* current=buf;
1698 vpe_framebuf_mutex.Lock();
1699 if (current) locked_uploading_frame_buf.push_back(current); //locked
1700 vpe_framebuf_mutex.Unlock();
1705 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
1707 // first find frame_buf memory
1708 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
1709 VPE_FrameBuf* current=buf;
1710 vpe_framebuf_mutex.Lock();
1712 locked_libav_frame_buf.remove(current); //unlocked
1713 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
1715 while (itty!=locked_uploading_frame_buf.end()) {
1716 if (*itty==current) {
1723 free_frame_bufs.push_back(current);
1726 vpe_framebuf_mutex.Unlock();
1729 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
1731 // first find frame_buf memory
1732 VPE_FrameBuf* current=buf;
1733 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
1734 vpe_framebuf_mutex.Lock();
1736 locked_uploading_frame_buf.remove(current); //unlocked
1737 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
1739 while (itty!=locked_libav_frame_buf.end()) {
1740 if (*itty==current) {
1747 free_frame_bufs.push_back(current);
1750 vpe_framebuf_mutex.Unlock();
1760 int VideoVPEOGL::stop()
1762 if (!initted) return 0;
1764 #ifdef VPE_OMX_SUPPORT
1765 //Check if libav mode
1766 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1773 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1777 int VideoVPEOGL::reset()
1779 if (!initted) return 0;
1781 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1785 int VideoVPEOGL::pause()
1787 if (!initted) return 0;
1789 // if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1793 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1795 if (!initted) return 0;
1796 // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1800 int VideoVPEOGL::fastForward()
1802 if (!initted) return 0;
1804 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
1808 int VideoVPEOGL::unFastForward()
1810 if (!initted) return 0;
1812 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1814 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1818 int VideoVPEOGL::attachFrameBuffer()
1820 if (!initted) return 0;
1822 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1826 int VideoVPEOGL::blank(void)
1828 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1829 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1833 ULLONG VideoVPEOGL::getCurrentTimestamp()
1835 /* sync_data_t timestamps;
1836 if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
1838 // FIXME are these the right way around?
1840 timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1841 timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1843 return timestamps.stc;
1852 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1854 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1855 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1859 int VideoVPEOGL::test()
1864 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1871 int VideoVPEOGL::test2()
1877 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1879 mediapacket = mplist.front();
1882 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1884 DeliverMediaPacket(mediapacket, buffer, samplepos);
1885 if (*samplepos == mediapacket.length) {
1892 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1893 const UCHAR* buffer,
1896 if (packet.type == MPTYPE_VIDEO_H264)
1904 switch (decoding_backend) {
1905 default: case 0: return 0; // no backend runnigng
1906 #ifdef VPE_OMX_SUPPORT
1907 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1909 #ifdef VPE_LIBAV_SUPPORT
1910 case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
1915 #ifdef VPE_OMX_SUPPORT
1916 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1917 const UCHAR* buffer,
1922 //Later add fail back code for libav
1924 *samplepos+=packet.length;
1925 return packet.length;
1929 if (!omx_running) return 0; // if we are not runnig do not do this
1932 OMX_ERRORTYPE error;
1934 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
1935 memset(&port_image,0,sizeof(port_image));
1936 port_image.nSize=sizeof(port_image);
1937 port_image.nVersion.nVersion=OMX_VERSION;
1938 port_image.nPortIndex =omx_codec_output_port;
1939 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
1940 if (error!= OMX_ErrorNone){
1941 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
1943 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
1945 /*First Check, if we have an audio sample*/
1949 return 0; //Not in iframe mode!
1953 if (packet.disconti) {
1955 if (cur_input_buf_omx) {
1956 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1957 if (error!=OMX_ErrorNone){
1958 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1960 cur_input_buf_omx=NULL;
1964 /*Inspect PES-Header */
1966 // OMX_STATETYPE temp_state;
1967 // OMX_GetState(omx_vid_dec,&temp_state);
1969 if (*samplepos==0) {//stripheader
1970 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1971 *samplepos+=headerstrip;
1972 if ( packet.synched ) {
1974 if (cur_input_buf_omx) {
1975 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1976 if (error!=OMX_ErrorNone){
1977 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1980 cur_input_buf_omx=NULL;//write out old data
1982 // reftime1=packet.presentation_time;
1983 // reftime2=reftime1+1;
1986 if (!firstsynched) {//
1987 *samplepos=packet.length;//if we have not processed at least one
1988 return packet.length;//synched packet ignore it!
1993 if (!cur_input_buf_omx) {
1994 input_bufs_omx_mutex.Lock();
1995 if (input_bufs_omx_free.size()==0) {
1996 input_bufs_omx_mutex.Unlock();
1997 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1998 return 0; // we do not have a free media sample
2001 cur_input_buf_omx=input_bufs_omx_free.front();
2002 cur_input_buf_omx->nFilledLen=0;
2003 cur_input_buf_omx->nOffset=0;
2004 cur_input_buf_omx->nTimeStamp=0;
2005 input_bufs_omx_free.pop_front();
2006 input_bufs_omx_mutex.Unlock();
2012 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2013 /*if (packet.disconti) {
2014 ms->SetDiscontinuity(TRUE);
2016 ms->SetDiscontinuity(FALSE);
2018 //if (packet.synched) {
2020 //lastreftimePTS=packet.pts;
2021 if (omx_first_frame) { // TODO time
2022 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2023 omx_first_frame=false;
2029 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2032 // ms->SetSyncPoint(TRUE);
2036 unsigned int haveToCopy=packet.length-*samplepos;
2038 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2039 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2040 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2041 haveToCopy-=cancopy;
2042 cur_input_buf_omx->nFilledLen+=cancopy;
2043 *samplepos+=cancopy;
2044 // push old buffer out
2046 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2047 if (error!=OMX_ErrorNone){
2048 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2051 input_bufs_omx_mutex.Lock();
2052 if (input_bufs_omx_free.size()==0) {
2053 input_bufs_omx_mutex.Unlock();
2054 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2055 return *samplepos; // we do not have a free media sample
2057 cur_input_buf_omx=input_bufs_omx_free.front();
2058 cur_input_buf_omx->nFilledLen=0;
2059 cur_input_buf_omx->nOffset=0;
2060 cur_input_buf_omx->nTimeStamp=0;
2061 input_bufs_omx_free.pop_front();
2062 input_bufs_omx_mutex.Unlock();
2064 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2067 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2068 buffer+packet.pos_buffer+*samplepos,haveToCopy);
2069 cur_input_buf_omx->nFilledLen+=haveToCopy;
2073 *samplepos+=haveToCopy;
2082 #ifdef VPE_LIBAV_SUPPORT
2083 int VideoVPEOGL::DecodePacketlibav()
2085 unsigned int haveToCopy=incom_packet_libav.size;
2086 if (incom_packet_libav.size==0) return 1; // we are already empty
2087 while (haveToCopy>0) {
2091 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2093 #ifdef BENCHMARK_FPS
2094 int cur_time=getTimeMS();
2096 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2097 &frame_ready, &incom_packet_libav);
2098 #ifdef BENCHMARK_FPS
2099 time_in_decoder+=getTimeMS()-cur_time;
2100 if (frame_ready) num_frames++;
2101 if ((num_frames%100)==0) {
2102 float fps=1000./(float)(time_in_decoder);
2103 fps*=((float)num_frames);
2104 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2108 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2111 haveToCopy-=dec_bytes;
2113 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2115 lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2116 dec_frame_libav_mutex.Lock();
2117 libavwidth=mpeg2codec_context_libav->width;
2118 libavheight=mpeg2codec_context_libav->height;
2119 libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2120 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2123 dec_frame_libav_upload_pending.push_back(dec_frame_libav_decoding);
2124 dec_frame_libav_decoding=NULL;
2125 if (dec_frame_libav_free.size()>0) {
2126 dec_frame_libav_decoding=dec_frame_libav_free.front();
2127 dec_frame_libav_free.pop_front();
2128 dec_frame_libav_mutex.Unlock();
2130 libav_hastime=false;
2132 libav_hastime=false;
2133 dec_frame_libav_mutex.Unlock();
2142 incom_packet_libav.size=0;
2148 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2149 const UCHAR* buffer,
2152 //Later add fail back code for libav
2154 *samplepos+=packet.length;
2155 return packet.length;
2158 if (!libav_running) return 0; // if we are not runnig do not do this
2164 return 0; //Not in iframe mode!
2168 if (packet.disconti) {
2170 if (!DecodePacketlibav()) return 0;
2173 /*Inspect PES-Header */
2174 if (!dec_frame_libav_decoding) {
2175 dec_frame_libav_mutex.Lock();
2176 if (dec_frame_libav_free.size()>0) {
2177 dec_frame_libav_decoding=dec_frame_libav_free.front();
2178 dec_frame_libav_free.pop_front();
2179 dec_frame_libav_mutex.Unlock();
2181 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
2182 dec_frame_libav_mutex.Unlock();
2190 if (*samplepos==0) {//stripheader
2191 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2192 *samplepos+=headerstrip;
2193 if ( packet.synched ) {
2195 if (!DecodePacketlibav()) return 0; // WriteOut old Data
2197 libav_time=packet.presentation_time;
2199 // reftime1=packet.presentation_time;
2200 // reftime2=reftime1+1;
2203 if (!firstsynched) {//
2204 *samplepos=packet.length;//if we have not processed at least one
2205 return packet.length;//synched packet ignore it!
2215 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2216 /*if (packet.disconti) {
2217 ms->SetDiscontinuity(TRUE);
2219 ms->SetDiscontinuity(FALSE);
2221 //if (packet.synched) {
2223 //lastreftimePTS=packet.pts;
2224 if (omx_first_frame) { // TODO time
2225 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2226 omx_first_frame=false;
2232 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2235 // ms->SetSyncPoint(TRUE);
2239 unsigned int haveToCopy=packet.length-*samplepos;
2241 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2242 // if the buffer is to small reallocate
2243 incom_packet_libav_size+=haveToCopy;
2244 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2245 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2247 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2248 incom_packet_libav.size+=haveToCopy;
2250 *samplepos+=haveToCopy;
2265 void VideoVPEOGL::ResetTimeOffsets()
2269 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
2271 //write(fdVideo, buffer, length);
2272 if (!iframemode) EnterIframePlayback();
2273 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
2279 int VideoVPEOGL::EnterIframePlayback()