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.
23 #include "mtdraspberry.h"
26 #include "woptionpane.h"
27 #include "osdopenvg.h"
33 //A lot of parts of this file are heavily inspired by xbmc omx implementations
35 VideoOMX::VideoOMX() {
40 cur_input_buf_omx = NULL;
41 omx_h264 = omx_mpeg2 = true;
45 offsetvideonotset = true;
46 offsetaudionotset = true;
56 deinterlace=2; //advanced
65 int VideoOMX::init(UCHAR tformat)
67 if (initted) return 0;
70 if (!setFormat(tformat)) { shutdown(); return 0; }
71 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
72 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
73 if (!setMode(NORMAL)) { shutdown(); return 0; }
74 if (!setSource()) { shutdown(); return 0; }
75 if (!attachFrameBuffer()) { shutdown(); return 0; }
90 int VideoOMX::initUsingOSDObjects()
93 // we are called before the audio
96 if (error!=OMX_ErrorNone) {
97 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
105 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
106 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
107 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
109 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
111 struct VPE_OMX_EVENT new_event;
112 new_event.handle=handle;
113 new_event.appdata=appdata;
114 new_event.event_type=event_type;
115 new_event.data1=data1;
116 new_event.data2=data2;
117 new_event.event_data=event_data;
119 VideoOMX *video=(VideoOMX *)getInstance();
120 video->AddOmxEvent(new_event);
122 /* switch (event_type) {
123 case OMX_EventCmdComplete: {
128 return OMX_ErrorNone;
132 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
134 omx_event_mutex.Lock();
135 omx_events.push_back(new_event);
136 omx_event_mutex.Unlock();
140 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
142 //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
143 VideoOMX *video=(VideoOMX *)getInstance();
144 video->ReturnEmptyOMXBuffer(buffer);
145 return OMX_ErrorNone;
149 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
150 input_bufs_omx_mutex.Lock();
151 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
152 input_bufs_omx_free.push_back(buffer);
153 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
154 input_bufs_omx_mutex.Unlock();
157 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
158 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
159 return OMX_ErrorNone;
164 int VideoOMX::shutdown()
166 if (!initted) return 0;
169 DeAllocateCodecsOMX();
171 vc_tv_show_info(0); // back to console
177 bool VideoOMX::loadOptionsfromServer(VDR* vdr)
179 Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
180 char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
183 if (STRCASECMP(name, "None") == 0) {
185 }/* else if (STRCASECMP(name, "LineDouble") == 0) {
187 }*/ else if (STRCASECMP(name, "Advanced") == 0) {
189 } /*else if (STRCASECMP(name, "Crazy") == 0) {
190 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
192 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
199 bool VideoOMX::handleOptionChanges(Option* option)
201 if (Video::handleOptionChanges(option))
203 switch (option->id) {
205 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
207 } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
210 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
213 } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
217 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
226 bool VideoOMX::saveOptionstoServer()
229 switch (deinterlace) {
231 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
234 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
237 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
240 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
247 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
248 UINT numChoices, UINT defaultChoice, UINT startInt,
249 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
251 bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
253 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
259 static const char* deinterlaceopts[]={"None",/*"LineDouble",*/"Advanced"/*,"Crazy"*/};
260 option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/2,1,0,deinterlaceopts,NULL,false,this);
261 options->push_back(option);
262 pane->addOptionLine(option);
270 int VideoOMX::setTVsize(UCHAR ttvsize)
274 // Override the aspect ratio usage, temporarily use to set the video chip mode
275 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
277 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
278 if (!setSource()) { shutdown(); return 0; }
279 if (!attachFramebuffer()) { shutdown(); return 0; }
281 // Reopening the fd causes the scart aspect line to go back to 4:3
282 // Set this again to the same as the tv screen size
283 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
285 // mode == LETTERBOX is invalid if the TV is widescreen
286 if (tvsize == ASPECT16X9) setMode(NORMAL);
291 int VideoOMX::setDefaultAspect()
293 return setAspectRatio(tvsize);
298 int VideoOMX::setFormat(UCHAR tformat)
300 if (!initted) return 0;
301 if ((tformat != PAL) && (tformat != NTSC)) return 0;
311 // selectVideoMode(0);
316 //void VideoOMX::selectVideoMode(int interlaced)
318 // if (/*hdmi*/ true) {
319 // TV_SUPPORTED_MODE_T all_supp_modes[TV_MAX_SUPPORTED_MODES];
320 // HDMI_RES_GROUP_T pref_group;
321 // TV_SUPPORTED_MODE_T *mymode=NULL;
322 // TV_SUPPORTED_MODE_T *mymode_second_best=NULL;
323 // bool got_optimum=false;
324 // uint32_t pref_mode;
325 // int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
326 // all_supp_modes,TV_MAX_SUPPORTED_MODES,
327 // &pref_group,&pref_mode);
328 // int target_fps=50;
329 // if (format==PAL)target_fps=50;
330 // else if (format==NTSC) target_fps=60;
331 // if (all_my_modes<=0) {
332 // Log::getInstance()->log("Video", Log::NOTICE, "No CEA modes found abort");
336 // //Now first determine native resolution
337 // int native_width=1920;
338 // int native_height=1080;
339 // for (int i=0;i<all_my_modes;i++) {
340 // if (all_supp_modes[i].native) {
341 // mymode=all_supp_modes+i;
342 // Log::getInstance()->log("Video", Log::NOTICE, "Found native mode %dx%d %d Hz i: %d",
343 // mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
347 // //Now find the mode which matches best
348 // for (int i=0;i<all_my_modes;i++) {
349 // TV_SUPPORTED_MODE_T *curmode=all_supp_modes+i;
350 // if (curmode->width==native_width &&
351 // curmode->height==native_height &&
352 // curmode->frame_rate==target_fps) {
353 // if(curmode->scan_mode==interlaced) {
356 // Log::getInstance()->log("Video", Log::NOTICE, "Found optimum mode %dx%d %d Hz i: %d",
357 // mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
359 // mymode_second_best=curmode;
360 // Log::getInstance()->log("Video", Log::NOTICE, "Found close to optimum mode %dx%d %d Hz i: %d",
361 // mymode_second_best->width,mymode_second_best->height,
362 // mymode_second_best->frame_rate,mymode_second_best->scan_mode);
368 // Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode");
369 // vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,HDMI_RES_GROUP_CEA,mymode->code);
370 // } else if (mymode_second_best) {
371 // Log::getInstance()->log("Video", Log::NOTICE, "Switch to close to optimum mode");
372 // vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,HDMI_RES_GROUP_CEA,mymode_second_best->code);
374 // Log::getInstance()->log("Video", Log::NOTICE, "Switch to prefered mode");
375 // vc_tv_hdmi_power_on_best(1920,1080,target_fps,interlaced?HDMI_INTERLACED:HDMI_NONINTERLACED,
376 // (EDID_MODE_MATCH_FLAG_T)(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE));
386 int VideoOMX::setConnection(UCHAR tconnection)
388 if (!initted) return 0;
389 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
390 connection = tconnection;
392 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
396 int VideoOMX::setAspectRatio(UCHAR taspectRatio)
398 if (!initted) return 0;
399 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
400 aspectRatio = taspectRatio;
402 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
404 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
408 int VideoOMX::setMode(UCHAR tmode)
410 if (!initted) return 0;
417 void VideoOMX::updateMode()
422 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
423 memset(&dispconf, 0, sizeof(dispconf));
424 dispconf.nSize = sizeof(dispconf);
425 dispconf.nVersion.nVersion = OMX_VERSION;
426 dispconf.nPortIndex = omx_rend_input_port;
428 dispconf.set = OMX_DISPLAY_SET_LAYER;
429 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
431 if (error != OMX_ErrorNone) {
432 Log::getInstance()->log("Video", Log::DEBUG,
433 "Set OMX_IndexConfigDisplayRegion1 failed %x", error);
434 clock_mutex.Unlock();
437 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
438 if (mode != QUARTER && mode != EIGHTH) {
440 dispconf.fullscreen = OMX_TRUE;
442 dispconf.fullscreen = OMX_FALSE;
444 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
446 if (error != OMX_ErrorNone) {
447 Log::getInstance()->log("Video", Log::DEBUG,
448 "Set OMX_IndexConfigDisplayRegion2 failed %x", error);
449 clock_mutex.Unlock();
453 dispconf.set = OMX_DISPLAY_SET_MODE;
454 if (mode != QUARTER && mode != EIGHTH) {
455 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
456 : OMX_DISPLAY_MODE_LETTERBOX;
458 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
460 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
462 if (error != OMX_ErrorNone) {
463 Log::getInstance()->log("Video", Log::DEBUG,
464 "Set OMX_IndexConfigDisplayRegion3 failed %x", error);
465 clock_mutex.Unlock();
469 if (mode == QUARTER || mode == EIGHTH) {
470 unsigned int display_width, display_height;
471 display_width = display_height = 0;
472 if (graphics_get_display_size(0, &display_width, &display_height)
474 Log::getInstance()->log("OSD", Log::WARN,
475 "Getting display size failed! (BCM API) ");
476 clock_mutex.Unlock();
479 //UnSetFullscreen with window
480 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
481 dispconf.dest_rect.x_offset
482 = (int) (xpos * ((float) display_width));
483 dispconf.dest_rect.y_offset = (int) (ypos
484 * ((float) display_height));
485 if (mode == QUARTER) {
486 dispconf.dest_rect.width = display_width >> 1;
487 dispconf.dest_rect.height = display_height >> 1;
488 } else if (mode == EIGHTH) {
489 dispconf.dest_rect.width = display_width >> 2;
490 dispconf.dest_rect.height = display_height >> 2;
492 error = OMX_SetParameter(omx_vid_rend,
493 OMX_IndexConfigDisplayRegion, &dispconf);
494 if (error != OMX_ErrorNone) {
495 Log::getInstance()->log("Video", Log::DEBUG,
496 "Set OMX_IndexConfigDisplayRegion failed %x", error);
497 clock_mutex.Unlock();
503 clock_mutex.Unlock();
506 int VideoOMX::signalOff()
508 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
512 int VideoOMX::signalOn()
514 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
518 int VideoOMX::setSource()
520 if (!initted) return 0;
522 // What does this do...
523 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
527 int VideoOMX::setPosition(int x, int y) {
530 xpos = ((float) x*2.f) / ((float) screenWidth);
531 ypos = ((float) y*2.f) / ((float) screenHeight);
539 if (!initted) return 0;
541 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
546 int VideoOMX::play() {
550 Log::getInstance()->log("Video", Log::DEBUG, "enter play");
552 if (AllocateCodecsOMX()) {
554 // Otherwise fall back to libav
558 Log::getInstance()->log("Video", Log::NOTICE,
559 "Allocate Codecs OMX failed assume h264 unsupported");
562 Log::getInstance()->log("Video", Log::NOTICE,
563 "Allocate Codecs OMX failed assume mpeg2 unsupported");
572 int VideoOMX::initClock()
576 if (clock_references==0)
579 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
582 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
584 if (error!=OMX_ErrorNone) {
585 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
586 clock_mutex.Unlock();
587 DeAllocateCodecsOMX();
591 /* TODO Clock config to separate method */
592 OMX_PORT_PARAM_TYPE p_param;
593 memset(&p_param,0,sizeof(p_param));
594 p_param.nSize=sizeof(p_param);
595 p_param.nVersion.nVersion=OMX_VERSION;
596 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
597 if (error!=OMX_ErrorNone) {
598 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
599 clock_mutex.Unlock();
600 DeAllocateCodecsOMX();
603 omx_clock_output_port=p_param.nStartPortNumber;
605 for (unsigned int i=0;i<p_param.nPorts;i++) {
606 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
607 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
608 clock_mutex.Unlock();
609 DeAllocateCodecsOMX();
618 Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
620 clock_mutex.Unlock();
624 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
628 *p_omx_clock_output_port=0;
635 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
636 memset(&refclock,0,sizeof(refclock));
637 refclock.nSize=sizeof(refclock);
638 refclock.nVersion.nVersion=OMX_VERSION;
640 refclock.eClock=OMX_TIME_RefClockAudio;
642 //refclock.eClock=OMX_TIME_RefClockVideo;
643 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
644 if (error!=OMX_ErrorNone){
645 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
646 clock_mutex.Unlock();
647 DeAllocateCodecsOMX();
651 OMX_PORT_PARAM_TYPE p_param;
652 memset(&p_param,0,sizeof(p_param));
653 p_param.nSize=sizeof(p_param);
654 p_param.nVersion.nVersion=OMX_VERSION;
655 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
656 if (error!=OMX_ErrorNone){
657 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
658 clock_mutex.Unlock();
659 DeAllocateCodecsOMX();
663 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
664 memset(&clock_conf,0,sizeof(clock_conf));
665 clock_conf.nSize=sizeof(clock_conf);
666 clock_conf.nVersion.nVersion=OMX_VERSION;
667 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
668 clock_conf.nStartTime=0;
669 clock_conf.nOffset=0;
670 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
671 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
672 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
673 if (error!=OMX_ErrorNone) {
674 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
678 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
679 *p_omx_clock=omx_clock;
680 clock_mutex.Unlock();
684 int VideoOMX::getClockVideoandInit()
693 if (clock_references==1) { // only if no audio is attached to this clock!
694 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
695 memset(&refclock,0,sizeof(refclock));
696 refclock.nSize=sizeof(refclock);
697 refclock.nVersion.nVersion=OMX_VERSION;
699 //refclock.eClock=OMX_TIME_RefClockAudio;
701 refclock.eClock=OMX_TIME_RefClockVideo;
702 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
703 if (error!=OMX_ErrorNone) {
704 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
705 clock_mutex.Unlock();
706 DeAllocateCodecsOMX();
711 OMX_PORT_PARAM_TYPE p_param;
712 memset(&p_param,0,sizeof(p_param));
713 p_param.nSize=sizeof(p_param);
714 p_param.nVersion.nVersion=OMX_VERSION;
715 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
716 if (error!=OMX_ErrorNone){
717 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
718 clock_mutex.Unlock();
719 DeAllocateCodecsOMX();
724 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
725 memset(&clock_conf,0,sizeof(clock_conf));
726 clock_conf.nSize=sizeof(clock_conf);
727 clock_conf.nVersion.nVersion=OMX_VERSION;
728 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
729 clock_conf.nStartTime=0;
730 clock_conf.nOffset=0;
731 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
732 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
733 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
734 if (error!=OMX_ErrorNone) {
735 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
738 omx_clock_output_port=p_param.nStartPortNumber;
739 clock_mutex.Unlock();
744 void VideoOMX::clockUnpause()
748 if (clock_references>0) {
749 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
750 memset(&clock_conf,0,sizeof(clock_conf));
751 clock_conf.nSize=sizeof(clock_conf);
752 clock_conf.nVersion.nVersion=OMX_VERSION;
753 clock_conf.eState=OMX_TIME_ClockStateRunning;
754 clock_conf.nStartTime=0;
755 clock_conf.nOffset=0;
756 clock_conf.nWaitMask=OMX_CLOCKPORT1;
757 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
758 if (error!=OMX_ErrorNone) {
759 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
762 clock_mutex.Unlock();
766 void VideoOMX::clockPause()
770 if (clock_references>0) {
771 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
772 memset(&clock_conf,0,sizeof(clock_conf));
773 clock_conf.nSize=sizeof(clock_conf);
774 clock_conf.nVersion.nVersion=OMX_VERSION;
775 clock_conf.eState=OMX_TIME_ClockStateStopped;
776 clock_conf.nStartTime=0;
777 clock_conf.nOffset=0;
778 clock_conf.nWaitMask=OMX_CLOCKPORT1;
779 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
780 if (error!=OMX_ErrorNone) {
781 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
784 clock_mutex.Unlock();
789 int VideoOMX::AllocateCodecsOMX()
792 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
794 Demuxer* demux=Demuxer::getInstance();
797 deint_first_frame=false;
799 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
800 //Clock, move later to audio including events
802 if (deinterlace!=0 && (demux->getHorizontalSize()<=720 /*|| demux->getHorizontalSize()==1920*/)) { //only deinterlace SD material
804 deint_first_frame=true;
806 Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
811 if (!getClockVideoandInit()){
812 return 0;// get the clock and init it if necessary
817 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
825 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
827 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
830 if (error!=OMX_ErrorNone){
831 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
832 clock_mutex.Unlock();
833 DeAllocateCodecsOMX();
838 Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
839 OMX_PORT_PARAM_TYPE p_param;
840 memset(&p_param,0,sizeof(p_param));
841 p_param.nSize=sizeof(p_param);
842 p_param.nVersion.nVersion=OMX_VERSION;
843 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
844 if (error!=OMX_ErrorNone){
845 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
846 clock_mutex.Unlock();
847 DeAllocateCodecsOMX();
850 omx_codec_input_port=p_param.nStartPortNumber;
851 omx_codec_output_port=p_param.nStartPortNumber+1;
853 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
854 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
855 clock_mutex.Unlock();
856 DeAllocateCodecsOMX();
860 Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
862 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
863 memset(&conceal,0,sizeof(conceal));
864 conceal.nSize=sizeof(conceal);
865 conceal.nVersion.nVersion=OMX_VERSION;
866 conceal.bStartWithValidFrame=OMX_FALSE;
868 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
869 if (error!=OMX_ErrorNone){
870 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
871 clock_mutex.Unlock();
872 DeAllocateCodecsOMX();
877 error = OMX_GetHandle(&omx_vid_deint, VPE_OMX_VIDEO_DEINTERLACE, NULL,
879 if (error != OMX_ErrorNone) {
880 Log::getInstance()->log("Video", Log::DEBUG,
881 "Init OMX video deinterlacer failed %x", error);
882 clock_mutex.Unlock();
883 DeAllocateCodecsOMX();
887 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
889 if (error != OMX_ErrorNone) {
890 Log::getInstance()->log("Video", Log::DEBUG,
891 "Init OMX video deinterlacer OMX_GetParameter failed %x",
893 clock_mutex.Unlock();
894 DeAllocateCodecsOMX();
897 omx_deint_input_port = p_param.nStartPortNumber;
898 omx_deint_output_port = p_param.nStartPortNumber + 1;
900 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
901 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
902 Log::getInstance()->log("Video", Log::DEBUG,
903 "Disable Ports OMX video deint failed");
904 clock_mutex.Unlock();
905 DeAllocateCodecsOMX();
912 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
913 if (error!=OMX_ErrorNone){
914 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
915 clock_mutex.Unlock();
916 DeAllocateCodecsOMX();
922 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
923 if (error!=OMX_ErrorNone){
924 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
925 clock_mutex.Unlock();
926 DeAllocateCodecsOMX();
929 omx_shed_input_port=p_param.nStartPortNumber;
930 omx_shed_output_port=p_param.nStartPortNumber+1;
933 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
934 if (error!=OMX_ErrorNone){
935 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
936 clock_mutex.Unlock();
937 DeAllocateCodecsOMX();
940 omx_shed_clock_port=p_param.nStartPortNumber;
941 Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
944 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
945 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
946 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
947 clock_mutex.Unlock();
948 DeAllocateCodecsOMX();
953 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
954 if (error!=OMX_ErrorNone){
955 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
956 clock_mutex.Unlock();
957 DeAllocateCodecsOMX();
961 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
962 if (error!=OMX_ErrorNone){
963 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
964 clock_mutex.Unlock();
965 DeAllocateCodecsOMX();
968 omx_rend_input_port=p_param.nStartPortNumber;
969 //omx_rend_output_port=p_param.nStartPortNumber+1;
972 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
974 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
975 clock_mutex.Unlock();
976 DeAllocateCodecsOMX();
984 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
985 if (error!=OMX_ErrorNone){
986 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);
987 clock_mutex.Unlock();
988 DeAllocateCodecsOMX();
992 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
994 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
995 clock_mutex.Unlock();
996 DeAllocateCodecsOMX();
1001 Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
1002 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1003 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1004 clock_mutex.Unlock();
1005 DeAllocateCodecsOMX();
1011 Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
1012 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1013 clock_mutex.Unlock();
1014 DeAllocateCodecsOMX();
1021 Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
1022 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1023 clock_mutex.Unlock();
1024 DeAllocateCodecsOMX();
1030 Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
1033 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1034 if (error!=OMX_ErrorNone){
1035 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1039 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1040 memset(&ft_type,0,sizeof(ft_type));
1041 ft_type.nSize=sizeof(ft_type);
1042 ft_type.nVersion.nVersion=OMX_VERSION;
1044 ft_type.nPortIndex=omx_codec_input_port;
1046 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1048 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1053 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1054 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1055 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1056 if (error!=OMX_ErrorNone){
1057 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1058 clock_mutex.Unlock();
1059 DeAllocateCodecsOMX();
1064 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1065 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1066 clock_mutex.Unlock();
1067 DeAllocateCodecsOMX();
1072 if (!PrepareInputBufsOMX()) {
1073 clock_mutex.Unlock();
1074 DeAllocateCodecsOMX();
1079 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1080 if (error!=OMX_ErrorNone){
1081 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1082 clock_mutex.Unlock();
1083 DeAllocateCodecsOMX();
1089 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1091 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1092 clock_mutex.Unlock();
1093 DeAllocateCodecsOMX();
1097 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1098 clock_mutex.Unlock();
1099 DeAllocateCodecsOMX();
1105 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1106 if (error!=OMX_ErrorNone){
1107 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
1108 clock_mutex.Unlock();
1109 DeAllocateCodecsOMX();
1115 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1117 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
1118 clock_mutex.Unlock();
1119 DeAllocateCodecsOMX();
1123 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1124 clock_mutex.Unlock();
1125 DeAllocateCodecsOMX();
1129 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1130 Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
1131 clock_mutex.Unlock();
1132 DeAllocateCodecsOMX();
1136 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1137 memset(&imagefilter,0,sizeof(imagefilter));
1138 imagefilter.nSize=sizeof(imagefilter);
1139 imagefilter.nVersion.nVersion=OMX_VERSION;
1141 imagefilter.nPortIndex=omx_deint_output_port;
1142 imagefilter.nNumParams=1;
1143 imagefilter.nParams[0]=3;//???
1144 switch (deinterlace) {
1146 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1148 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1150 imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1154 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1155 if (error!=OMX_ErrorNone){
1156 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
1157 clock_mutex.Unlock();
1158 DeAllocateCodecsOMX();
1163 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1164 if (error!=OMX_ErrorNone){
1165 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
1166 clock_mutex.Unlock();
1167 DeAllocateCodecsOMX();
1171 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1173 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
1174 clock_mutex.Unlock();
1175 DeAllocateCodecsOMX();
1179 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1180 clock_mutex.Unlock();
1181 DeAllocateCodecsOMX();
1187 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1188 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1189 clock_mutex.Unlock();
1190 DeAllocateCodecsOMX();
1194 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1195 if (error!=OMX_ErrorNone){
1196 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1197 clock_mutex.Unlock();
1198 DeAllocateCodecsOMX();
1202 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1204 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1205 clock_mutex.Unlock();
1206 DeAllocateCodecsOMX();
1210 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1211 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1212 clock_mutex.Unlock();
1213 DeAllocateCodecsOMX();
1217 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1218 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1219 clock_mutex.Unlock();
1220 DeAllocateCodecsOMX();
1225 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1226 Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
1227 clock_mutex.Unlock();
1228 DeAllocateCodecsOMX();
1231 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1232 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1235 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1236 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1237 clock_mutex.Unlock();
1238 DeAllocateCodecsOMX();
1242 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1243 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1244 clock_mutex.Unlock();
1245 DeAllocateCodecsOMX();
1250 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1251 memset(&dispconf,0,sizeof(dispconf));
1252 dispconf.nSize=sizeof(dispconf);
1253 dispconf.nVersion.nVersion=OMX_VERSION;
1255 dispconf.nPortIndex=omx_rend_input_port;
1257 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1259 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1260 if (error!=OMX_ErrorNone){
1261 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1262 clock_mutex.Unlock();
1263 DeAllocateCodecsOMX();
1267 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1268 dispconf.fullscreen=OMX_FALSE;
1269 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1270 if (error!=OMX_ErrorNone){
1271 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1272 clock_mutex.Unlock();
1273 DeAllocateCodecsOMX();
1277 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1278 dispconf.dest_rect.x_offset=100;
1279 dispconf.dest_rect.y_offset=100;
1280 dispconf.dest_rect.width=640;
1281 dispconf.dest_rect.height=480;
1282 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1283 if (error!=OMX_ErrorNone){
1284 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1285 clock_mutex.Unlock();
1286 DeAllocateCodecsOMX();
1291 playbacktimeoffset=-GetCurrentSystemTime();
1295 clock_mutex.Unlock();
1299 setClockExecutingandRunning();
1308 int VideoOMX::idleClock()
1310 OMX_ERRORTYPE error;
1311 OMX_STATETYPE temp_state;
1313 OMX_GetState(omx_clock,&temp_state);
1315 if (temp_state!=OMX_StateIdle) {
1316 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1317 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1318 clock_mutex.Unlock();
1322 clock_mutex.Unlock();
1326 int VideoOMX::setClockExecutingandRunning()
1328 OMX_ERRORTYPE error;
1329 OMX_STATETYPE temp_state;
1331 OMX_GetState(omx_clock,&temp_state);
1333 if (temp_state!=OMX_StateExecuting) {
1334 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1335 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1336 clock_mutex.Unlock();
1337 DeAllocateCodecsOMX();
1342 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1343 memset(&clock_conf,0,sizeof(clock_conf));
1344 clock_conf.nSize=sizeof(clock_conf);
1345 clock_conf.nVersion.nVersion=OMX_VERSION;
1346 clock_conf.eState=OMX_TIME_ClockStateRunning;
1347 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1348 if (error!=OMX_ErrorNone) {
1349 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1350 clock_mutex.Unlock();
1351 DeAllocateCodecsOMX();
1354 clock_mutex.Unlock();
1360 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1362 OMX_ERRORTYPE error;
1363 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1364 if (error!=OMX_ErrorNone){
1365 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1369 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1377 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1379 OMX_ERRORTYPE error;
1380 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1381 if (error!=OMX_ErrorNone){
1382 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1386 if (!wait) return 1;
1387 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1395 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1397 OMX_ERRORTYPE error;
1398 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1399 if (error!=OMX_ErrorNone){
1400 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1404 if (!wait) return 1;
1405 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1413 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex
1417 omx_event_mutex.Lock();
1418 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1419 while (itty!=omx_events.end()) {
1421 VPE_OMX_EVENT current=*itty;
1422 if (current.handle==handle) { //this is ours
1423 if (current.event_type==OMX_EventError) {
1424 omx_events.erase(itty);
1425 omx_event_mutex.Unlock();
1426 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1429 } else if (current.event_type==event) {
1430 omx_events.erase(itty);
1431 omx_event_mutex.Unlock();
1432 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1439 omx_event_mutex.Unlock();
1444 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1450 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1454 omx_event_mutex.Lock();
1455 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1456 while (itty!=omx_events.end()) {
1458 VPE_OMX_EVENT current=*itty;
1459 if (current.handle==handle) { //this is ours
1460 if (current.event_type==OMX_EventError) {
1461 omx_events.erase(itty);
1462 omx_event_mutex.Unlock();
1463 Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
1466 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1467 omx_events.erase(itty);
1468 omx_event_mutex.Unlock();
1469 //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1476 omx_event_mutex.Unlock();
1481 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1490 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1492 OMX_ERRORTYPE error;
1493 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1494 memset(&port_def_type,0,sizeof(port_def_type));
1495 port_def_type.nSize=sizeof(port_def_type);
1496 port_def_type.nVersion.nVersion=OMX_VERSION;
1497 port_def_type.nPortIndex=omx_codec_input_port;
1499 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1501 if (error!=OMX_ErrorNone){
1502 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1504 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1505 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1506 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1508 port_def_type.nBufferCountActual=100;
1509 port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1511 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1513 if (error!=OMX_ErrorNone){
1514 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1518 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1519 if (error!=OMX_ErrorNone){
1520 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1524 input_bufs_omx_mutex.Lock();
1525 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1527 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1528 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1529 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1530 if (error!=OMX_ErrorNone){
1531 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1532 input_bufs_omx_mutex.Unlock();
1535 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1536 if (error!=OMX_ErrorNone){
1537 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1538 input_bufs_omx_mutex.Unlock();
1541 input_bufs_omx_all.push_back(buf_head);
1542 input_bufs_omx_free.push_back(buf_head);
1544 omx_first_frame=true;
1547 cur_input_buf_omx=NULL;
1548 input_bufs_omx_mutex.Unlock();
1551 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1552 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1555 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1560 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
1562 OMX_ERRORTYPE error;
1564 cur_input_buf_omx=NULL;
1565 input_bufs_omx_mutex.Lock();
1566 for (int i=0; i< input_bufs_omx_all.size();i++) {
1567 // free(input_bufs_omx_all[i]->pBuffer);
1568 // input_bufs_omx_all[i]->pBuffer=NULL;
1569 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1570 if (error!=OMX_ErrorNone){
1571 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1572 input_bufs_omx_mutex.Unlock();
1577 input_bufs_omx_all.clear();
1578 input_bufs_omx_free.clear();
1579 input_bufs_omx_present.clear();
1580 input_time_present.clear();
1581 input_time_pts.clear();
1582 input_is_last.clear();
1583 input_bufs_omx_mutex.Unlock();
1590 int VideoOMX::DeAllocateCodecsOMX()
1592 OMX_ERRORTYPE error;
1594 Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1598 if (cur_input_buf_omx) {
1599 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1600 OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1601 if (error!=OMX_ErrorNone) {
1602 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1605 cur_input_buf_omx=NULL;//write out old data
1609 // first stop the omx elements
1610 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1611 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1614 clock_mutex.Unlock();
1620 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
1621 Log::getInstance()->log("Video", Log::DEBUG,
1622 "vid_deint ChangeComponentState");
1628 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1629 Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
1633 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1634 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1640 // TODO proper deinit sequence
1641 // first flush all buffers
1645 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1646 omx_codec_output_port, NULL);
1647 if (error != OMX_ErrorNone) {
1648 Log::getInstance()->log("Video", Log::DEBUG,
1649 "OMX_Flush codec out failed %x", error);
1653 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1654 omx_shed_input_port, NULL);
1655 if (error != OMX_ErrorNone) {
1656 Log::getInstance()->log("Video", Log::DEBUG,
1657 "OMX_Flush shed in failed %x", error);
1661 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1662 omx_codec_output_port)) {
1663 Log::getInstance()->log("Video", Log::DEBUG,
1664 "flush cmd codec failed");
1667 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1668 omx_shed_input_port)) {
1669 Log::getInstance()->log("Video", Log::DEBUG,
1670 "flush cmd shed failed");
1673 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1674 omx_codec_output_port, NULL);
1675 if (error != OMX_ErrorNone) {
1676 Log::getInstance()->log("Video", Log::DEBUG,
1677 "OMX_Flush codec out failed %x", error);
1681 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1682 omx_deint_input_port, NULL);
1683 if (error != OMX_ErrorNone) {
1684 Log::getInstance()->log("Video", Log::DEBUG,
1685 "OMX_Flush deint in failed %x", error);
1689 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
1690 omx_codec_output_port)) {
1691 Log::getInstance()->log("Video", Log::DEBUG,
1692 "flush cmd codec failed");
1695 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1696 omx_deint_input_port)) {
1697 Log::getInstance()->log("Video", Log::DEBUG,
1698 "flush cmd deint failed");
1702 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
1703 omx_deint_output_port, NULL);
1704 if (error != OMX_ErrorNone) {
1705 Log::getInstance()->log("Video", Log::DEBUG,
1706 "OMX_Flush deint out failed %x", error);
1710 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1711 omx_shed_input_port, NULL);
1712 if (error != OMX_ErrorNone) {
1713 Log::getInstance()->log("Video", Log::DEBUG,
1714 "OMX_Flush shed in failed %x", error);
1718 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
1719 omx_deint_output_port)) {
1720 Log::getInstance()->log("Video", Log::DEBUG,
1721 "flush cmd deint failed");
1724 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1725 omx_shed_input_port)) {
1726 Log::getInstance()->log("Video", Log::DEBUG,
1727 "flush cmd shed failed");
1737 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
1738 omx_rend_input_port, NULL);
1739 if (error != OMX_ErrorNone) {
1740 Log::getInstance()->log("Video", Log::DEBUG,
1741 "OMX_Flush rend in failed %x", error);
1745 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
1746 omx_shed_output_port, NULL);
1747 if (error != OMX_ErrorNone) {
1748 Log::getInstance()->log("Video", Log::DEBUG,
1749 "OMX_Flush shed out failed %x", error);
1755 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
1756 omx_rend_input_port)) {
1757 Log::getInstance()->log("Video", Log::DEBUG,
1758 "flush cmd shed rend failed");
1761 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
1762 omx_shed_output_port)) {
1763 Log::getInstance()->log("Video", Log::DEBUG,
1764 "flush cmd shed rend failed");
1771 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1772 if (error!=OMX_ErrorNone){
1773 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1777 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1778 if (error!=OMX_ErrorNone){
1779 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1783 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1784 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1785 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1791 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
1792 omx_codec_input_port, NULL);
1793 if (error != OMX_ErrorNone) {
1794 Log::getInstance()->log("Video", Log::DEBUG,
1795 "OMX_Flush codec out failed %x", error);
1802 DestroyInputBufsOMX();
1805 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1806 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1808 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1809 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1815 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1816 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1821 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1822 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1826 if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
1827 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
1832 if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
1833 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
1839 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1840 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1843 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1844 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1847 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1848 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1854 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1855 if (error!=OMX_ErrorNone) {
1856 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1861 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,NULL);
1862 if (error!=OMX_ErrorNone) {
1863 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1867 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,NULL);
1868 if (error!=OMX_ErrorNone) {
1869 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1873 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1874 if (error!=OMX_ErrorNone) {
1875 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1880 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1881 if (error!=OMX_ErrorNone) {
1882 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1886 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1887 if (error!=OMX_ErrorNone) {
1888 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1893 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1894 if (error!=OMX_ErrorNone) {
1895 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1899 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1900 if (error!=OMX_ErrorNone) {
1901 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1908 error=OMX_FreeHandle(omx_vid_dec);
1909 error=OMX_FreeHandle(omx_vid_sched);
1910 error=OMX_FreeHandle(omx_vid_rend);
1911 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
1913 clock_mutex.Unlock();
1915 if (error!=OMX_ErrorNone) {
1916 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1918 } else clock_mutex.Unlock();
1919 Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
1925 void VideoOMX::destroyClock()
1928 if (clock_references>0) {
1930 if (clock_references==0) {
1931 OMX_ERRORTYPE error;
1932 Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
1933 error=OMX_FreeHandle(omx_clock);
1934 if (error!=OMX_ErrorNone) {
1935 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1940 clock_mutex.Unlock();
1944 int VideoOMX::stop()
1946 if (!initted) return 0;
1949 //Check if libav mode
1950 DeAllocateCodecsOMX();
1955 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1959 int VideoOMX::reset()
1961 if (!initted) return 0;
1964 DeAllocateCodecsOMX();
1965 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1969 int VideoOMX::pause()
1971 if (!initted) return 0;
1972 Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
1975 //maybe also change omx clock?
1976 pausetimecode=GetCurrentSystemTime();
1982 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
1984 if (!initted) return 0;
1985 Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
1988 playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
1989 paused=false; // may be also change omx clock
1995 int VideoOMX::fastForward()
1997 if (!initted) return 0;
1999 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2003 int VideoOMX::unFastForward()
2005 if (!initted) return 0;
2007 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2009 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2013 int VideoOMX::attachFrameBuffer()
2015 if (!initted) return 0;
2017 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2021 int VideoOMX::blank(void)
2023 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2024 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2028 ULLONG VideoOMX::getCurrentTimestamp()
2030 if (iframemode) return 0;
2036 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2038 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2039 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2044 int VideoOMX::test()
2049 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2056 int VideoOMX::test2()
2064 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2068 startoffset=curreftime;//offset is set for audio
2070 offsetvideonotset=false;
2072 if (offsetvideonotset) {
2073 offsetvideonotset=false;
2076 if ( (curreftime-lastrefvideotime)>10000000LL
2077 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2078 startoffset+=curreftime-lastrefvideotime;
2079 lastrefaudiotime+=curreftime-lastrefvideotime;
2081 offsetaudionotset=true;
2088 lastrefvideotime=curreftime;
2094 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2098 startoffset=curreftime;
2100 offsetaudionotset=false;
2102 if (offsetaudionotset) {
2103 offsetaudionotset=false;
2106 if ( (curreftime-lastrefaudiotime)>10000000LL
2107 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2108 startoffset+=curreftime-lastrefaudiotime;
2109 lastrefvideotime+=curreftime-lastrefaudiotime;
2111 offsetvideonotset=true;
2117 lastrefaudiotime=curreftime;
2122 void VideoOMX::ResetTimeOffsets() {
2123 offsetnotset=true; //called from demuxer
2124 offsetvideonotset=true;
2125 offsetaudionotset=true;
2134 long long VideoOMX::GetCurrentSystemTime()
2137 clock_gettime(CLOCK_MONOTONIC, &ts);
2138 return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
2141 void VideoOMX::WaitUntil(long long time)
2143 struct timespec interval;
2144 interval.tv_sec=time/10000000LL;
2145 interval.tv_nsec=(time %10000000LL)*100LL;
2146 while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {
2147 //Log::getInstance()->log("Video", Log::DEBUG, "Wait until multi");
2152 bool VideoOMX::FrameSkip(long long pts)
2154 //ok first calculate the absolute time
2156 long long target_time=pts-playbacktimeoffset;
2157 // we have to wait untile the next frame
2158 long long offset=Demuxer::getInstance()->getFrameRate();
2159 if (offset==0) offset=25;
2160 offset=-2*10000000LL/offset;
2161 target_time+=offset;
2162 long long current_time=GetCurrentSystemTime();
2164 if ((target_time-current_time)<-400000LL) {
2165 skip=true; // we are too slow
2167 /* Log::getInstance()->log("Video", Log::DEBUG,
2168 "Skipping frames1 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
2169 Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
2170 target_time-current_time);*/
2175 if ((target_time - current_time) < 0000LL) { //skip a bit more
2176 skip = true; // we are too slow
2178 /* Log::getInstance()->log("Video", Log::DEBUG,"Skipping frames2 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
2179 Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
2180 target_time-current_time);*/
2190 void VideoOMX::FrameWaitforDisplay(long long pts)
2192 //ok first calculate the absolute time
2193 long long target_time=pts-playbacktimeoffset;
2194 // we have to wait untile the next frame
2195 long long offset=Demuxer::getInstance()->getFrameRate();
2196 long long current_time=GetCurrentSystemTime();
2197 if (offset==0) offset=25;
2198 offset=-3*10000000LL/offset;
2199 target_time+=offset;
2200 //Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld tg: %lld sys: %lld off: %lld diff %lld po: %lld",pts,target_time,current_time,offset,
2201 // target_time-current_time,playbacktimeoffset);
2202 if ((target_time-current_time)>1000000LL) target_time=current_time+1000000LL; // something is wrong do not wait too long
2203 //Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld tg: %lld sys: %lld off: %lld diff %lld po: %lld",pts,target_time,current_time,offset,
2204 // target_time-current_time,playbacktimeoffset);
2206 WaitUntil(target_time);
2207 //Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
2210 void VideoOMX::AdjustAudioPTS(long long pts)
2212 long long newplaybacktimeoffset=pts-GetCurrentSystemTime();
2213 if ((newplaybacktimeoffset-1000000LL)>playbacktimeoffset
2214 || (newplaybacktimeoffset+1000000LL)<playbacktimeoffset) {
2215 Log::getInstance()->log("Video", Log::DEBUG, "Adjust Playbackoffsettime o: %lld n: %lld",
2216 playbacktimeoffset,newplaybacktimeoffset);
2217 playbacktimeoffset=newplaybacktimeoffset;
2222 void VideoOMX::threadPostStopCleanup()
2226 Log::getInstance()->log("Video", Log::DEBUG,
2231 void VideoOMX::threadMethod()
2233 Log::getInstance()->log("Video", Log::DEBUG,
2237 OMX_BUFFERHEADERTYPE* pict=NULL;
2241 input_bufs_omx_mutex.Lock();
2242 if (input_bufs_omx_present.size()>0) {
2243 cur_pts=input_time_pts.front();
2244 pict=input_bufs_omx_present.front();
2245 time=input_time_present.front();
2246 islast=input_is_last.front();
2247 input_bufs_omx_present.pop_front();
2248 input_time_present.pop_front();
2249 input_time_pts.pop_front();
2250 input_is_last.pop_front();
2252 input_bufs_omx_mutex.Unlock();
2256 //Log::getInstance()->log("Video", Log::DEBUG,
2258 if (time!=0 && FrameSkip(time) && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) {
2260 input_bufs_omx_mutex.Lock();
2261 input_bufs_omx_free.push_back(pict);
2262 input_bufs_omx_mutex.Unlock();
2263 //Log::getInstance()->log("Video", Log::DEBUG, "threadMethod Frameskip");
2266 // Log::getInstance()->log("Video", Log::DEBUG,
2267 // "prot empty this buffer in");
2268 if (islast) FrameWaitforDisplay(time);
2269 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, pict);
2270 if (error != OMX_ErrorNone) {
2271 Log::getInstance()->log("Video", Log::DEBUG,
2272 "OMX_EmptyThisBuffer failed %x", error);
2274 //Log::getInstance()->log("Video", Log::DEBUG,
2275 // "time %lld",time);
2276 if (deint_first_frame && dodeint) DeinterlaceFix();
2285 Log::getInstance()->log("Video", Log::DEBUG,
2289 void VideoOMX::DeinterlaceFix()
2292 Demuxer* demux=Demuxer::getInstance();
2294 OMX_ERRORTYPE error;
2295 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2296 memset(&port_def_type,0,sizeof(port_def_type));
2297 port_def_type.nSize=sizeof(port_def_type);
2298 port_def_type.nVersion.nVersion=OMX_VERSION;
2299 port_def_type.nPortIndex=omx_codec_output_port;
2301 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2302 if (error != OMX_ErrorNone) {
2303 Log::getInstance()->log("Video", Log::DEBUG,
2304 "OMX_IndexParamPortDefinition fix failed %x", error);
2305 clock_mutex.Unlock();
2309 if (port_def_type.format.video.nFrameWidth == demux->getHorizontalSize()
2310 && port_def_type.format.video.nFrameHeight == demux->getVerticalSize()){
2311 Log::getInstance()->log("Video", Log::DEBUG,
2312 "Deinit first frame fix");
2313 deint_first_frame=false;
2315 WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2316 DisablePort(omx_vid_dec,omx_codec_output_port,false);
2317 DisablePort(omx_vid_sched,omx_shed_input_port,false);
2318 DisablePort(omx_vid_deint,omx_deint_output_port,false);
2319 DisablePort(omx_vid_deint,omx_deint_input_port,false);
2321 port_def_type.nPortIndex=omx_deint_input_port;
2322 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2324 if (error != OMX_ErrorNone) {
2325 Log::getInstance()->log("Video", Log::DEBUG,
2326 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2327 clock_mutex.Unlock();
2331 port_def_type.nPortIndex=omx_deint_output_port;
2332 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2334 if (error != OMX_ErrorNone) {
2335 Log::getInstance()->log("Video", Log::DEBUG,
2336 "Set OMX_IndexParamPortDefinition2 failed %x", error);
2337 clock_mutex.Unlock();
2342 EnablePort(omx_vid_dec,omx_codec_output_port,false);
2343 EnablePort(omx_vid_deint,omx_deint_input_port,false);
2344 EnablePort(omx_vid_deint,omx_deint_output_port,false);
2345 EnablePort(omx_vid_sched,omx_shed_input_port,false);
2347 clock_mutex.Unlock();
2353 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time, long long pts,bool islast)
2355 input_bufs_omx_mutex.Lock();
2356 input_bufs_omx_present.push_back(buffer);
2357 input_time_present.push_back(time);
2358 input_time_pts.push_back(pts);
2359 input_is_last.push_back(islast);
2360 input_bufs_omx_mutex.Unlock();
2364 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2366 // protect the call to empty this buffer
2369 pthread_testcancel();
2370 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2371 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2373 OMX_ERRORTYPE ret_val;
2374 ret_val=OMX_EmptyThisBuffer(handle,buffer);
2375 clock_mutex.Unlock();
2376 pthread_setcancelstate(oldcancelstate, NULL);
2377 pthread_setcanceltype(oldcanceltype, NULL);
2378 pthread_testcancel();
2382 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2385 mediapackets.clear();
2386 list<MediaPacket>::const_iterator begin=mplist.begin();
2387 list<MediaPacket>::const_iterator itty=mplist.begin();
2388 advance(itty,min(mplist.size(),10));
2389 mediapackets.insert(mediapackets.begin(),begin,itty);//front
2393 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2396 while (consumed<mediapackets.size()) {
2397 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2398 if (*samplepos == mediapackets[consumed].length) {
2402 } else return consumed;
2407 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2408 const UCHAR* buffer,
2411 if (packet.type == MPTYPE_VIDEO_H264)
2421 //Later add fail back code for libav
2423 *samplepos+=packet.length;
2424 return packet.length;
2428 if (!omx_running) return 0; // if we are not runnig do not do this
2429 if (paused) return 0; //Block if we pause
2431 if (packet.synched && FrameSkip(packet.presentation_time)) {
2432 *samplepos=packet.length;
2433 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Frameskip");
2434 *samplepos=packet.length;
2435 return packet.length;
2437 //long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
2438 /* if (packet.synched &&
2439 (packet.presentation_time<0 /*|| // preroll skip frames
2440 (packet.presentation_time+5000000LL)<(current_media_time)*)) { // we are late skip
2441 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
2442 *samplepos=packet.length;
2443 return packet.length;
2446 OMX_ERRORTYPE error;
2448 /*First Check, if we have an video sample*/
2452 return 0; //Not in iframe mode!
2456 if (packet.disconti) {
2458 if (cur_input_buf_omx) {
2459 PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,lastreftimePTS, true);
2460 cur_input_buf_omx=NULL;
2464 /*Inspect PES-Header */
2466 // OMX_STATETYPE temp_state;
2467 // OMX_GetState(omx_vid_dec,&temp_state);
2469 if (*samplepos==0) {//stripheader
2470 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2471 // if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2472 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2473 *samplepos+=headerstrip;
2474 if ( packet.synched ) {
2475 if (cur_input_buf_omx) {
2476 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
2477 PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,lastreftimePTS,true);
2478 cur_input_buf_omx=NULL;//write out old data
2484 if (!firstsynched) {//
2485 *samplepos=packet.length;//if we have not processed at least one
2486 return packet.length;//synched packet ignore it!
2491 if (!cur_input_buf_omx) {
2492 input_bufs_omx_mutex.Lock();
2493 if (input_bufs_omx_free.size()==0) {
2494 input_bufs_omx_mutex.Unlock();
2495 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2496 return 0; // we do not have a free media sample
2499 cur_input_buf_omx=input_bufs_omx_free.front();
2500 cur_input_buf_omx->nFilledLen=0;
2501 cur_input_buf_omx->nOffset=0;
2502 cur_input_buf_omx->nTimeStamp=0;
2503 input_bufs_omx_free.pop_front();
2504 input_bufs_omx_mutex.Unlock();
2510 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2511 if (packet.synched) {
2512 // Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
2514 //lastreftimePTS=packet.pts;
2515 if (omx_first_frame) { // TODO time
2516 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2517 Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
2518 omx_first_frame=false;
2520 //cur_input_buf_omx->nFlags=0;
2521 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
2523 lastreftimeOMX=packet.presentation_time;
2524 // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
2525 lastreftimePTS=packet.pts;
2526 cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
2530 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2531 cur_input_buf_omx->nTimeStamp=0;
2532 //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
2533 // ms->SetSyncPoint(TRUE);
2535 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
2540 unsigned int haveToCopy=packet.length-*samplepos;
2542 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2543 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
2544 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2545 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2546 haveToCopy-=cancopy;
2547 cur_input_buf_omx->nFilledLen+=cancopy;
2548 *samplepos+=cancopy;
2549 // push old buffer out
2551 PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,lastreftimePTS,false);
2552 cur_input_buf_omx=NULL;
2554 input_bufs_omx_mutex.Lock();
2555 if (input_bufs_omx_free.size()==0) {
2556 input_bufs_omx_mutex.Unlock();
2557 // Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
2558 return *samplepos; // we do not have a free media sample
2560 cur_input_buf_omx=input_bufs_omx_free.front();
2561 cur_input_buf_omx->nFilledLen=0;
2562 cur_input_buf_omx->nOffset=0;
2563 cur_input_buf_omx->nTimeStamp=0;
2564 input_bufs_omx_free.pop_front();
2565 input_bufs_omx_mutex.Unlock();
2567 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2570 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2571 buffer+packet.pos_buffer+*samplepos,haveToCopy);
2572 cur_input_buf_omx->nFilledLen+=haveToCopy;
2576 *samplepos+=haveToCopy;
2585 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
2586 if (!omx_running) return false;
2588 EnterIframePlayback();
2590 int haveToCopy = length;
2592 if (!cur_input_buf_omx) {
2593 input_bufs_omx_mutex.Lock();
2594 if (input_bufs_omx_free.size() == 0) {
2595 input_bufs_omx_mutex.Unlock();
2596 // Log::getInstance()->log("Video", Log::DEBUG,
2597 // "Deliver MediaPacket no free sample");
2598 return false; // we do not have a free media sample
2601 cur_input_buf_omx = input_bufs_omx_free.front();
2602 cur_input_buf_omx->nFilledLen = 0;
2603 cur_input_buf_omx->nOffset = 0;
2604 cur_input_buf_omx->nTimeStamp = 0;
2605 input_bufs_omx_free.pop_front();
2606 input_bufs_omx_mutex.Unlock();
2610 unsigned int pattern, packet_length;
2611 unsigned int headerstrip = 0;
2616 //Now we strip the pes header
2617 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
2618 while (read_pos + 7 <= length) {
2619 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
2620 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
2624 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
2625 packet_length = ((buffer[read_pos + 4] << 8)
2626 | (buffer[read_pos + 5])) + 6;
2627 if (read_pos + packet_length > length)
2630 if ((headerstrip < packet_length)
2631 && (cur_input_buf_omx->nFilledLen + packet_length
2632 - headerstrip) > cur_input_buf_omx->nAllocLen) {
2634 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2637 cur_input_buf_omx->nFlags
2638 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2641 cur_input_buf_omx->nTimeStamp = 0;
2642 PutBufferToPres(cur_input_buf_omx, 0,0,false);
2643 cur_input_buf_omx = NULL;
2645 if (!cur_input_buf_omx) {
2647 while (count < 100 && omx_running && iframemode) {
2650 input_bufs_omx_mutex.Lock();
2651 if (input_bufs_omx_free.size() == 0) {
2652 input_bufs_omx_mutex.Unlock();
2653 // Log::getInstance()->log("Video", Log::DEBUG,
2654 // "Ifrane no free sample");
2656 if (!omx_running) return false;
2659 cur_input_buf_omx = input_bufs_omx_free.front();
2660 cur_input_buf_omx->nFilledLen = 0;
2661 cur_input_buf_omx->nOffset = 0;
2662 cur_input_buf_omx->nTimeStamp = 0;
2663 input_bufs_omx_free.pop_front();
2664 input_bufs_omx_mutex.Unlock();
2667 if (!cur_input_buf_omx)
2672 if (packet_length > headerstrip) {
2674 cur_input_buf_omx->pBuffer
2675 + cur_input_buf_omx->nFilledLen,
2676 buffer + read_pos + headerstrip,
2677 packet_length - headerstrip);
2678 cur_input_buf_omx->nFilledLen += packet_length
2681 read_pos += packet_length;
2683 pattern = (buffer[read_pos] << 16)
2684 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
2690 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
2693 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
2696 cur_input_buf_omx->nTimeStamp = 0;
2698 PutBufferToPres(cur_input_buf_omx, 0,0,false);
2699 cur_input_buf_omx = NULL;
2702 MILLISLEEP(40); //Block a bit
2706 int VideoOMX::EnterIframePlayback()
2708 if (cur_input_buf_omx) {
2709 PutBufferToPres(cur_input_buf_omx, lastreftimeOMX, lastreftimePTS,true);
2710 cur_input_buf_omx = NULL;
2712 input_bufs_omx_mutex.Lock();
2713 while (input_bufs_omx_present.size()) {
2714 input_bufs_omx_free.push_back(input_bufs_omx_present.front());
2715 input_bufs_omx_present.pop_front();
2717 input_time_present.clear();
2718 input_time_pts.clear();
2719 input_is_last.clear();
2720 input_bufs_omx_mutex.Unlock();