2 Copyright 2004-2005 Chris Tallon, 2009-12 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, see <https://www.gnu.org/licenses/>.
29 #include "woptionpane.h"
30 #include "osdopenvg.h"
37 //A lot of parts of this file are heavily inspired by xbmc omx implementations
39 VideoOMX::VideoOMX() {
44 cur_input_buf_omx = NULL;
45 omx_h264 = omx_mpeg2 = true;
48 omx_vid_stalled = false;
51 offsetvideonotset = true;
52 offsetaudionotset = true;
60 mpeg2_supported=false;
65 deinterlace=2; //advanced
70 strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
71 strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
72 strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
73 strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
74 strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
75 strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
83 int VideoOMX::init(UCHAR tformat)
85 if (initted) return 0;
88 // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
89 // Seems safe to call it more than once.
92 int ret=vc_gencmd_send("codec_enabled MPG2");
94 Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_send failed %x",ret);
97 ret=vc_gencmd_read_response(buffer,sizeof(buffer));
99 Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_read_response failed %x",ret);
101 if (STRCASECMP(buffer,"MPG2=enabled")==0) {
102 mpeg2_supported=true;
103 } else if (STRCASECMP(buffer,"MPG2=disabled")==0) {
104 mpeg2_supported=false;
106 Log::getInstance()->log("Video", Log::DEBUG, "Undefined mpg codec answer %s",buffer);
111 if (!setFormat(tformat)) { shutdown(); return 0; }
112 if (!setConnection(HDMI)) { shutdown(); return 0; }
113 if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; }
114 if (!setMode(NORMAL)) { shutdown(); return 0; }
115 if (!setSource()) { shutdown(); return 0; }
116 if (!attachFrameBuffer()) { shutdown(); return 0; }
118 setTVsize(ASPECT16X9);
124 if (error != OMX_ErrorNone) {
125 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x",
144 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
145 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
146 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
148 //Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
150 struct VPE_OMX_EVENT new_event;
151 new_event.handle=handle;
152 new_event.appdata=appdata;
153 new_event.event_type=event_type;
154 new_event.data1=data1;
155 new_event.data2=data2;
156 new_event.event_data=event_data;
158 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
159 video->AddOmxEvent(new_event);
161 /* switch (event_type) {
162 case OMX_EventCmdComplete: {
167 return OMX_ErrorNone;
171 void VideoOMX::signalOmx()
174 * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
175 * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
176 * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
177 * in what the Signal class used to do here and I'll sort it out later.
178 * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
179 * exact sychronisation and remove the wait spin loops? Unknown.
181 * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
182 * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
184 * Callers of signalOmx:
186 * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
187 * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
188 * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
190 * Surprise: WaitForEvent isn't a long running loop while video is playing.
193 omx_event_ready_signal_mutex.lock();
194 omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
195 omx_event_ready_signal_mutex.unlock();
198 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
200 omx_event_mutex.lock();
201 omx_events.push_back(new_event);
202 omx_event_mutex.unlock();
207 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
209 // Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
210 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
211 /* long long temp =buffer->nTimeStamp.nLowPart
212 | ((long long) buffer->nTimeStamp.nHighPart << 32);
213 Log::getInstance()->log("Video", Log::NOTICE, "EBD Video %lld %x",temp,buffer->nFlags);*/
214 video->ReturnEmptyOMXBuffer(buffer);
215 return OMX_ErrorNone;
219 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
220 input_bufs_omx_mutex.lock();
221 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d",input_bufs_omx_free.size(),input_bufs_omx_all.size());
222 input_bufs_omx_free.push_back(buffer);
223 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
224 input_bufs_omx_mutex.unlock();
229 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
230 //Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
231 return OMX_ErrorNone;
236 int VideoOMX::shutdown()
238 if (!initted) return 0;
240 Log::getInstance()->log("Video", Log::NOTICE, "Shutdown video module");
242 DeAllocateCodecsOMX();
244 //vc_tv_show_info(0); // back to console
247 struct fb_var_screeninfo screeninfo;
248 fd_fbset=open("/dev/fb0",O_RDONLY);
250 Log::getInstance()->log("Video", Log::CRIT, "Could not open frame buffer device %d", fd_fbset);
253 if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)){
255 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOGET_VSCREENINFO frame buffer device");
258 screeninfo.bits_per_pixel=8;
259 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
260 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
262 screeninfo.bits_per_pixel=16;
263 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
264 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
272 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
274 Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
275 char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
278 if (STRCASECMP(name, "None") == 0) {
280 }/* else if (STRCASECMP(name, "LineDouble") == 0) {
282 }*/ else if (STRCASECMP(name, "Advanced") == 0) {
284 } /*else if (STRCASECMP(name, "Crazy") == 0) {
285 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
286 }*/ else if (STRCASECMP(name, "Fast") == 0) {
289 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
297 bool VideoOMX::handleOptionChanges(Option* option)
299 if (Video::handleOptionChanges(option))
301 switch (option->id) {
303 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
305 } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
308 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
311 } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
314 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Fast")
318 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
327 bool VideoOMX::saveOptionstoServer()
330 switch (deinterlace) {
332 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
335 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
338 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
341 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
344 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
351 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
352 UINT numChoices, UINT defaultChoice, UINT startInt,
353 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
355 bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
357 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
363 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
364 option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/3,2,0,deinterlaceopts,NULL,false,this);
365 options->push_back(option);
366 pane->addOptionLine(option);
374 int VideoOMX::setTVsize(UCHAR ttvsize)
376 if (tvsize!=ttvsize) pendingmodechange=true;
381 UCHAR VideoOMX::getTVsize() {
383 return ASPECT16X9; // in order that aspect ratio changes are reported
387 void VideoOMX::executePendingModeChanges()
389 if (pendingmodechange) {
390 Log::getInstance()->log("Video", Log::NOTICE, "Execute pending mode change");
391 Osd::getInstance()->shutdown();
393 Osd::getInstance()->restore();
394 Osd::getInstance()->init();
395 BoxStack::getInstance()->redrawAllBoxes();
400 int VideoOMX::setDefaultAspect()
402 return setAspectRatio(tvsize,parx,pary);
407 int VideoOMX::setFormat(UCHAR tformat)
409 if (!initted) return 0;
410 if ((tformat != PAL) && (tformat != NTSC)
411 && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
421 // selectVideoMode(0);
426 void VideoOMX::selectVideoMode(int interlaced)
428 TV_GET_STATE_RESP_T tvstate;
429 vc_tv_get_state(&tvstate);
431 if ((tvstate.state & VC_HDMI_UNPLUGGED)) {
433 Log::getInstance()->log("Video", Log::NOTICE, "HDMI unplugged");
436 Log::getInstance()->log("Video", Log::NOTICE, "HDMI plugged");
437 if (connection==COMPOSITERGB) {
439 Log::getInstance()->log("Video", Log::NOTICE, "SDTV set");
442 Log::getInstance()->log("Video", Log::NOTICE, "HDMI set");
448 TV_SUPPORTED_MODE_T all_supp_modes[200];
449 HDMI_RES_GROUP_T pref_group;
450 TV_SUPPORTED_MODE_T *mymode=NULL;
451 TV_SUPPORTED_MODE_T *mymode_second_best=NULL;
452 // bool got_optimum=false;
454 HDMI_RES_GROUP_T group=HDMI_RES_GROUP_CEA;
455 int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
457 &pref_group,&pref_mode);
458 if (all_my_modes<=0) {
459 group=HDMI_RES_GROUP_DMT;
460 all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
462 &pref_group,&pref_mode);
463 Log::getInstance()->log("Video", Log::NOTICE, "No CEA fall back to DMT modes ");
470 if (format==PAL)target_fps=50;
471 else if (format==NTSC) target_fps=60;
473 //Now first determine native resolution
474 int native_width=1920;
475 int native_height=1080;
476 for (int i=0;i<all_my_modes;i++) {
477 if (all_supp_modes[i].native) {
478 mymode=all_supp_modes+i;
479 Log::getInstance()->log("Video", Log::NOTICE, "Found native mode %dx%d %d Hz i: %d",
480 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
481 native_width=mymode->width;
482 native_height=mymode->height;
486 //Now find the mode which matches best
487 for (int i=0;i<all_my_modes;i++) {
488 TV_SUPPORTED_MODE_T *curmode=all_supp_modes+i;
489 if (curmode->width==native_width &&
490 curmode->height==native_height &&
491 curmode->frame_rate==target_fps) {
492 if(curmode->scan_mode==interlaced) {
495 Log::getInstance()->log("Video", Log::NOTICE, "Found optimum mode %dx%d %d Hz i: %d",
496 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
498 mymode_second_best=curmode;
499 Log::getInstance()->log("Video", Log::NOTICE, "Found close to optimum mode %dx%d %d Hz i: %d",
500 mymode_second_best->width,mymode_second_best->height,
501 mymode_second_best->frame_rate,mymode_second_best->scan_mode);
506 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
509 Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode");
510 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode->code);
511 } else if (mymode_second_best) {
512 Log::getInstance()->log("Video", Log::NOTICE, "Switch to close to optimum mode");
513 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode_second_best->code);
515 Log::getInstance()->log("Video", Log::NOTICE, "Switch to prefered mode");
516 vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
517 static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE));
520 outputinterlaced=interlaced;
523 Log::getInstance()->log("Video", Log::NOTICE, "Analog tv case");
524 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off();
525 SDTV_MODE_T setmode=SDTV_MODE_PAL;
526 SDTV_OPTIONS_T options;
531 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 16:9");
532 options.aspect=SDTV_ASPECT_16_9; break;
534 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 4:3");
535 options.aspect=SDTV_ASPECT_4_3; break;
537 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 14:9");
538 options.aspect=SDTV_ASPECT_14_9; break;
541 if (format==PAL) setmode=SDTV_MODE_PAL;
542 else if (format==NTSC) setmode=SDTV_MODE_NTSC;
543 else if (format==PAL_M)setmode=SDTV_MODE_PAL_M;
544 else if (format==NTSC_J) setmode=SDTV_MODE_NTSC_J;
545 vc_tv_sdtv_power_on(setmode,&options);
549 // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
550 // If this was just to reinit CEC then funcitons should be made to do that
554 pendingmodechange=false;
559 int VideoOMX::setConnection(UCHAR tconnection)
561 if (!initted) return 0;
562 if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0;
563 if (connection!=tconnection) pendingmodechange=true;
564 connection = tconnection;
566 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
570 int VideoOMX::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
572 if (!initted) return 0;
573 //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
574 aspectRatio = taspectRatio;
578 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i: PAR %d %d", aspectRatio,parx,pary);
581 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
585 int VideoOMX::setMode(UCHAR tmode)
587 if (!initted) return 0;
588 if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode;
593 bool VideoOMX::setVideoDisplay(VideoDisplay display)
595 if (!initted) return false;
596 switch (display.mode)
598 case None: return true; //??
605 xpos = ((float) display.x) / ((float) screenWidth);
606 ypos = ((float) display.y) / ((float) screenHeight);
613 xpos = ((float) display.x) / ((float) screenWidth);
614 ypos = ((float) display.y) / ((float) screenHeight);
621 xpos = ((float) display.x) / ((float) screenWidth);
622 ypos = ((float) display.y) / ((float) screenHeight);
623 width = ((float) display.width) / ((float) screenWidth);
624 height = ((float) display.height) / ((float) screenHeight);
632 void VideoOMX::updateMode()
638 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
639 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
641 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
642 memset(&dispconf, 0, sizeof(dispconf));
643 dispconf.nSize = sizeof(dispconf);
644 dispconf.nVersion.nVersion = OMX_VERSION;
645 dispconf.nPortIndex = omx_rend_input_port;
647 dispconf.set = OMX_DISPLAY_SET_LAYER;
648 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
650 if (error != OMX_ErrorNone) {
651 Log::getInstance()->log("Video", Log::DEBUG,
652 "Set OMX_IndexConfigDisplayRegion1 failed %x", error);
653 pthread_setcancelstate(oldcancelstate, NULL);
654 pthread_setcanceltype(oldcanceltype, NULL);
655 clock_mutex.unlock();
660 dispconf.pixel_x =parx;
661 dispconf.pixel_y=pary;
662 dispconf.set = OMX_DISPLAY_SET_PIXEL;
663 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
665 if (error != OMX_ErrorNone) {
666 Log::getInstance()->log("Video", Log::DEBUG,
667 "Set OMX_IndexConfigDisplayRegion5 failed %x", error);
668 pthread_setcancelstate(oldcancelstate, NULL);
669 pthread_setcanceltype(oldcanceltype, NULL);
670 clock_mutex.unlock();
676 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
679 dispconf.fullscreen = OMX_TRUE;
681 dispconf.fullscreen = OMX_FALSE;
683 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
685 if (error != OMX_ErrorNone) {
686 Log::getInstance()->log("Video", Log::DEBUG,
687 "Set OMX_IndexConfigDisplayRegion2 failed %x", error);
688 pthread_setcancelstate(oldcancelstate, NULL);
689 pthread_setcanceltype(oldcanceltype, NULL);
690 clock_mutex.unlock();
694 dispconf.set = OMX_DISPLAY_SET_MODE;
696 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
697 : OMX_DISPLAY_MODE_LETTERBOX;
699 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
701 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
703 if (error != OMX_ErrorNone) {
704 Log::getInstance()->log("Video", Log::DEBUG,
705 "Set OMX_IndexConfigDisplayRegion3 failed %x", error);
706 pthread_setcancelstate(oldcancelstate, NULL);
707 pthread_setcanceltype(oldcanceltype, NULL);
708 clock_mutex.unlock();
713 unsigned int display_width, display_height;
714 display_width = display_height = 0;
715 if (graphics_get_display_size(0, &display_width, &display_height)
717 Log::getInstance()->log("OSD", Log::WARN,
718 "Getting display size failed! (BCM API) ");
719 pthread_setcancelstate(oldcancelstate, NULL);
720 pthread_setcanceltype(oldcanceltype, NULL);
721 clock_mutex.unlock();
724 //UnSetFullscreen with window
725 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
726 dispconf.dest_rect.x_offset
727 = (int) (xpos * ((float) display_width));
728 dispconf.dest_rect.y_offset = (int) (ypos
729 * ((float) display_height));
730 dispconf.dest_rect.width = (int) (width * ((float) display_width));
731 dispconf.dest_rect.height = (int) (height * ((float) display_height));
732 Log::getInstance()->log("Video", Log::DEBUG,
733 "Set dest_rect as %d %d %d %d", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset,
734 dispconf.dest_rect.width , dispconf.dest_rect.height);
736 error = OMX_SetParameter(omx_vid_rend,
737 OMX_IndexConfigDisplayRegion, &dispconf);
738 if (error != OMX_ErrorNone) {
739 Log::getInstance()->log("Video", Log::DEBUG,
740 "Set OMX_IndexConfigDisplayRegion failed %x", error);
741 pthread_setcancelstate(oldcancelstate, NULL);
742 pthread_setcanceltype(oldcanceltype, NULL);
743 clock_mutex.unlock();
747 pthread_setcancelstate(oldcancelstate, NULL);
748 pthread_setcanceltype(oldcanceltype, NULL);
751 clock_mutex.unlock();
754 int VideoOMX::signalOff()
757 Log::getInstance()->log("Video", Log::NOTICE, "signalOff");
758 Osd::getInstance()->stopUpdate(); // turn off drawing thread
759 InputMan::getInstance()->shutdown();
761 InputMan::getInstance()->init(); // FIXME
766 int VideoOMX::signalOn()
769 Osd::getInstance()->shutdown();
770 Log::getInstance()->log("Video", Log::NOTICE, "signalOn");
772 Osd::getInstance()->restore();
773 Osd::getInstance()->init();
774 BoxStack::getInstance()->redrawAllBoxes();
781 int VideoOMX::setSource()
783 if (!initted) return 0;
785 // What does this do...
786 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
790 int VideoOMX::setPosition(int x, int y) {
793 xpos = ((float) x*2.f) / ((float) screenWidth);
794 ypos = ((float) y*2.f) / ((float) screenHeight);
802 if (!initted) return 0;
804 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
808 void VideoOMX::interlaceSwitch4Demux() {
810 Demuxer *demux=Demuxer::getInstance();
812 if (hdmi) { // only switch if hdmi and HD or interlaced SD material
816 int set_interlaced=0;
817 if (demux->getHorizontalSize()>720 && demux->getInterlaced()) {
820 Log::getInstance()->log("Video", Log::NOTICE, "switch interlacing %d %d %d",demux->getInterlaced(),outputinterlaced,set_interlaced);
821 if (outputinterlaced!=set_interlaced) {
822 selectVideoMode(set_interlaced);
823 Osd::getInstance()->shutdown();
824 Osd::getInstance()->restore();
825 Osd::getInstance()->init();
826 BoxStack::getInstance()->redrawAllBoxes();
838 int VideoOMX::play() {
842 Log::getInstance()->log("Video", Log::DEBUG, "enter play");
844 interlaceSwitch4Demux();
846 if (AllocateCodecsOMX()) {
848 // Otherwise fall back to libav
852 Log::getInstance()->log("Video", Log::NOTICE,
853 "Allocate Codecs OMX failed assume h264 unsupported");
856 Log::getInstance()->log("Video", Log::NOTICE,
857 "Allocate Codecs OMX failed assume mpeg2 unsupported");
866 int VideoOMX::initClock()
870 if (clock_references==0)
873 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
874 omx_event_mutex.lock();
876 omx_event_mutex.unlock();
878 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
880 if (error!=OMX_ErrorNone) {
881 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
882 clock_mutex.unlock();
883 DeAllocateCodecsOMX();
887 /* TODO Clock config to separate method */
888 OMX_PORT_PARAM_TYPE p_param;
889 memset(&p_param,0,sizeof(p_param));
890 p_param.nSize=sizeof(p_param);
891 p_param.nVersion.nVersion=OMX_VERSION;
892 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
893 if (error!=OMX_ErrorNone) {
894 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
895 clock_mutex.unlock();
896 DeAllocateCodecsOMX();
899 omx_clock_output_port=p_param.nStartPortNumber;
901 for (unsigned int i=0;i<p_param.nPorts;i++) {
902 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
903 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
904 clock_mutex.unlock();
905 DeAllocateCodecsOMX();
914 Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
916 clock_mutex.unlock();
920 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
924 *p_omx_clock_output_port=0;
931 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
932 memset(&refclock,0,sizeof(refclock));
933 refclock.nSize=sizeof(refclock);
934 refclock.nVersion.nVersion=OMX_VERSION;
936 refclock.eClock=OMX_TIME_RefClockAudio;
938 //refclock.eClock=OMX_TIME_RefClockVideo;
939 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
940 if (error!=OMX_ErrorNone){
941 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
942 clock_mutex.unlock();
943 DeAllocateCodecsOMX();
947 OMX_PORT_PARAM_TYPE p_param;
948 memset(&p_param,0,sizeof(p_param));
949 p_param.nSize=sizeof(p_param);
950 p_param.nVersion.nVersion=OMX_VERSION;
951 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
952 if (error!=OMX_ErrorNone){
953 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
954 clock_mutex.unlock();
955 DeAllocateCodecsOMX();
959 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
960 memset(&clock_conf,0,sizeof(clock_conf));
961 clock_conf.nSize=sizeof(clock_conf);
962 clock_conf.nVersion.nVersion=OMX_VERSION;
963 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
964 clock_conf.nStartTime=intToOMXTicks(0);
965 clock_conf.nOffset=intToOMXTicks(0);
966 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
967 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
968 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
969 if (error!=OMX_ErrorNone) {
970 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
974 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
975 *p_omx_clock=omx_clock;
976 clock_mutex.unlock();
980 int VideoOMX::getClockVideoandInit()
989 if (clock_references==1) { // only if no audio is attached to this clock!
990 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
991 memset(&refclock,0,sizeof(refclock));
992 refclock.nSize=sizeof(refclock);
993 refclock.nVersion.nVersion=OMX_VERSION;
995 //refclock.eClock=OMX_TIME_RefClockAudio;
997 refclock.eClock=OMX_TIME_RefClockVideo;
998 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
999 if (error!=OMX_ErrorNone) {
1000 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1001 clock_mutex.unlock();
1002 DeAllocateCodecsOMX();
1007 OMX_PORT_PARAM_TYPE p_param;
1008 memset(&p_param,0,sizeof(p_param));
1009 p_param.nSize=sizeof(p_param);
1010 p_param.nVersion.nVersion=OMX_VERSION;
1011 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1012 if (error!=OMX_ErrorNone){
1013 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1014 clock_mutex.unlock();
1015 DeAllocateCodecsOMX();
1020 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1021 memset(&clock_conf,0,sizeof(clock_conf));
1022 clock_conf.nSize=sizeof(clock_conf);
1023 clock_conf.nVersion.nVersion=OMX_VERSION;
1024 clock_conf.eState=OMX_TIME_ClockStateStopped;
1025 clock_conf.nStartTime=intToOMXTicks(0);
1026 clock_conf.nOffset=intToOMXTicks(0);
1027 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1028 if (error!=OMX_ErrorNone) {
1029 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1033 memset(&clock_conf,0,sizeof(clock_conf));
1034 clock_conf.nSize=sizeof(clock_conf);
1035 clock_conf.nVersion.nVersion=OMX_VERSION;
1036 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1037 clock_conf.nStartTime=intToOMXTicks(0);
1038 clock_conf.nOffset=intToOMXTicks(0);
1039 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1040 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1041 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1042 if (error!=OMX_ErrorNone) {
1043 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1046 omx_clock_output_port=p_param.nStartPortNumber;
1047 clock_mutex.unlock();
1052 void VideoOMX::clockUnpause()
1054 OMX_ERRORTYPE error;
1055 Log::getInstance()->log("Video", Log::NOTICE, "enter Clockunpause");
1057 if (clock_references>0 && clockpaused) {
1058 OMX_TIME_CONFIG_SCALETYPE scale_type;
1059 memset(&scale_type,0,sizeof(scale_type));
1060 scale_type.nSize=sizeof(scale_type);
1061 scale_type.nVersion.nVersion=OMX_VERSION;
1062 scale_type.xScale=1<<16;
1063 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1064 if (error!=OMX_ErrorNone) {
1065 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause OMX_IndexConfigTimeScale failed %x", error);
1067 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockUnpause");
1070 clock_mutex.unlock();
1074 void VideoOMX::clockPause()
1076 OMX_ERRORTYPE error;
1077 Log::getInstance()->log("Video", Log::NOTICE, "enter ClockPause");
1079 if (clock_references>0 && !clockpaused) {
1080 OMX_TIME_CONFIG_SCALETYPE scale_type;
1081 memset(&scale_type,0,sizeof(scale_type));
1082 scale_type.nSize=sizeof(scale_type);
1083 scale_type.nVersion.nVersion=OMX_VERSION;
1084 scale_type.xScale=0;
1085 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1086 if (error!=OMX_ErrorNone) {
1087 Log::getInstance()->log("Video", Log::DEBUG, "ClockPause OMX_IndexConfigTimeScale failed %x", error);
1089 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockPause");
1092 clock_mutex.unlock();
1097 int VideoOMX::AllocateCodecsOMX()
1099 OMX_ERRORTYPE error;
1100 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1102 Demuxer* demux=Demuxer::getInstance();
1107 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1108 //Clock, move later to audio including events
1110 Log::getInstance()->log("Video", Log::NOTICE, "Deinter VideoType %d x %d i: %d", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1111 if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) {
1115 Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
1120 if (!getClockVideoandInit()){
1121 return 0;// get the clock and init it if necessary
1126 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
1133 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1135 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1138 if (error!=OMX_ErrorNone){
1139 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1140 clock_mutex.unlock();
1141 DeAllocateCodecsOMX();
1146 Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
1147 OMX_PORT_PARAM_TYPE p_param;
1148 memset(&p_param,0,sizeof(p_param));
1149 p_param.nSize=sizeof(p_param);
1150 p_param.nVersion.nVersion=OMX_VERSION;
1151 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1152 if (error!=OMX_ErrorNone){
1153 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1154 clock_mutex.unlock();
1155 DeAllocateCodecsOMX();
1158 omx_codec_input_port=p_param.nStartPortNumber;
1159 omx_codec_output_port=p_param.nStartPortNumber+1;
1161 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1162 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1163 clock_mutex.unlock();
1164 DeAllocateCodecsOMX();
1168 Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
1170 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1171 memset(&conceal,0,sizeof(conceal));
1172 conceal.nSize=sizeof(conceal);
1173 conceal.nVersion.nVersion=OMX_VERSION;
1174 conceal.bStartWithValidFrame=OMX_FALSE;
1176 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1177 if (error!=OMX_ErrorNone){
1178 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1179 clock_mutex.unlock();
1180 DeAllocateCodecsOMX();
1185 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1187 if (error != OMX_ErrorNone) {
1188 Log::getInstance()->log("Video", Log::DEBUG,
1189 "Init OMX video deinterlacer failed %x", error);
1190 clock_mutex.unlock();
1191 DeAllocateCodecsOMX();
1195 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1197 if (error != OMX_ErrorNone) {
1198 Log::getInstance()->log("Video", Log::DEBUG,
1199 "Init OMX video deinterlacer OMX_GetParameter failed %x",
1201 clock_mutex.unlock();
1202 DeAllocateCodecsOMX();
1205 omx_deint_input_port = p_param.nStartPortNumber;
1206 omx_deint_output_port = p_param.nStartPortNumber + 1;
1208 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1209 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1210 Log::getInstance()->log("Video", Log::DEBUG,
1211 "Disable Ports OMX video deint failed");
1212 clock_mutex.unlock();
1213 DeAllocateCodecsOMX();
1220 error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1221 if (error!=OMX_ErrorNone){
1222 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1223 clock_mutex.unlock();
1224 DeAllocateCodecsOMX();
1230 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1231 if (error!=OMX_ErrorNone){
1232 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1233 clock_mutex.unlock();
1234 DeAllocateCodecsOMX();
1237 omx_shed_input_port=p_param.nStartPortNumber;
1238 omx_shed_output_port=p_param.nStartPortNumber+1;
1241 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1242 if (error!=OMX_ErrorNone){
1243 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1244 clock_mutex.unlock();
1245 DeAllocateCodecsOMX();
1248 omx_shed_clock_port=p_param.nStartPortNumber;
1249 Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1252 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1253 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1254 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1255 clock_mutex.unlock();
1256 DeAllocateCodecsOMX();
1261 error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1262 if (error!=OMX_ErrorNone){
1263 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1264 clock_mutex.unlock();
1265 DeAllocateCodecsOMX();
1269 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1270 if (error!=OMX_ErrorNone){
1271 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1272 clock_mutex.unlock();
1273 DeAllocateCodecsOMX();
1276 omx_rend_input_port=p_param.nStartPortNumber;
1277 //omx_rend_output_port=p_param.nStartPortNumber+1;
1280 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1282 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1283 clock_mutex.unlock();
1284 DeAllocateCodecsOMX();
1292 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1293 if (error!=OMX_ErrorNone){
1294 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);
1295 clock_mutex.unlock();
1296 DeAllocateCodecsOMX();
1300 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1302 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1303 clock_mutex.unlock();
1304 DeAllocateCodecsOMX();
1310 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1311 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1312 clock_mutex.unlock();
1313 DeAllocateCodecsOMX();
1320 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1321 clock_mutex.unlock();
1322 DeAllocateCodecsOMX();
1330 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1331 clock_mutex.unlock();
1332 DeAllocateCodecsOMX();
1338 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1339 if (error!=OMX_ErrorNone){
1340 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1344 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1345 memset(&ft_type,0,sizeof(ft_type));
1346 ft_type.nSize=sizeof(ft_type);
1347 ft_type.nVersion.nVersion=OMX_VERSION;
1349 ft_type.nPortIndex=omx_codec_input_port;
1351 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1353 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1358 ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1359 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1360 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1361 if (error!=OMX_ErrorNone){
1362 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1363 clock_mutex.unlock();
1364 DeAllocateCodecsOMX();
1369 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1370 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1371 clock_mutex.unlock();
1372 DeAllocateCodecsOMX();
1376 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1377 memset(&stall_conf,0,sizeof(stall_conf));
1378 stall_conf.nSize=sizeof(stall_conf);
1379 stall_conf.nVersion.nVersion=OMX_VERSION;
1380 stall_conf.nPortIndex=omx_codec_output_port;
1381 stall_conf.nDelay=1500*1000;
1382 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1383 if (error!=OMX_ErrorNone){
1384 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigBufferStall failed %x", error);
1385 clock_mutex.unlock();
1386 DeAllocateCodecsOMX();
1389 omx_vid_stalled = false;
1391 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1392 memset(&req_callback,0,sizeof(req_callback));
1393 req_callback.nSize=sizeof(req_callback);
1394 req_callback.nVersion.nVersion=OMX_VERSION;
1395 req_callback.nPortIndex=omx_codec_output_port;
1396 req_callback.nIndex=OMX_IndexConfigBufferStall;
1397 req_callback.bEnable=OMX_TRUE;
1398 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1399 if (error!=OMX_ErrorNone){
1400 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigRequestCallback failed %x", error);
1401 clock_mutex.unlock();
1402 DeAllocateCodecsOMX();
1408 if (!PrepareInputBufsOMX()) {
1409 clock_mutex.unlock();
1410 DeAllocateCodecsOMX();
1415 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1416 if (error!=OMX_ErrorNone){
1417 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1418 clock_mutex.unlock();
1419 DeAllocateCodecsOMX();
1425 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1427 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1428 clock_mutex.unlock();
1429 DeAllocateCodecsOMX();
1433 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1434 clock_mutex.unlock();
1435 DeAllocateCodecsOMX();
1441 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1442 if (error!=OMX_ErrorNone){
1443 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
1444 clock_mutex.unlock();
1445 DeAllocateCodecsOMX();
1451 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1453 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
1454 clock_mutex.unlock();
1455 DeAllocateCodecsOMX();
1459 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1460 clock_mutex.unlock();
1461 DeAllocateCodecsOMX();
1465 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1466 Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
1467 clock_mutex.unlock();
1468 DeAllocateCodecsOMX();
1472 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1473 memset(&imagefilter,0,sizeof(imagefilter));
1474 imagefilter.nSize=sizeof(imagefilter);
1475 imagefilter.nVersion.nVersion=OMX_VERSION;
1477 imagefilter.nPortIndex=omx_deint_output_port;
1478 imagefilter.nNumParams=4;
1479 imagefilter.nParams[0]=3;//???
1480 imagefilter.nParams[1]=0;//default frame interval
1481 imagefilter.nParams[2]=0;// frame rate
1482 if (demux->getHorizontalSize() <= 720){
1483 imagefilter.nParams[3] = 1;//use qpus
1487 imagefilter.nParams[3] = 0;//use qpus
1490 switch (deinterlace) {
1492 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1494 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1496 imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1498 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1502 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1503 if (error!=OMX_ErrorNone){
1504 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
1505 clock_mutex.unlock();
1506 DeAllocateCodecsOMX();
1511 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1512 if (error!=OMX_ErrorNone){
1513 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
1514 clock_mutex.unlock();
1515 DeAllocateCodecsOMX();
1519 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1521 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
1522 clock_mutex.unlock();
1523 DeAllocateCodecsOMX();
1527 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1528 clock_mutex.unlock();
1529 DeAllocateCodecsOMX();
1535 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1536 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1537 clock_mutex.unlock();
1538 DeAllocateCodecsOMX();
1542 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1543 if (error!=OMX_ErrorNone){
1544 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1545 clock_mutex.unlock();
1546 DeAllocateCodecsOMX();
1550 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1552 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1553 clock_mutex.unlock();
1554 DeAllocateCodecsOMX();
1558 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1559 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1560 clock_mutex.unlock();
1561 DeAllocateCodecsOMX();
1565 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1566 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1567 clock_mutex.unlock();
1568 DeAllocateCodecsOMX();
1573 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1574 Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
1575 clock_mutex.unlock();
1576 DeAllocateCodecsOMX();
1579 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1580 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1583 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1584 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1585 clock_mutex.unlock();
1586 DeAllocateCodecsOMX();
1590 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1591 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1592 clock_mutex.unlock();
1593 DeAllocateCodecsOMX();
1598 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1599 memset(&dispconf,0,sizeof(dispconf));
1600 dispconf.nSize=sizeof(dispconf);
1601 dispconf.nVersion.nVersion=OMX_VERSION;
1603 dispconf.nPortIndex=omx_rend_input_port;
1605 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1607 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1608 if (error!=OMX_ErrorNone){
1609 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1610 clock_mutex.unlock();
1611 DeAllocateCodecsOMX();
1615 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1616 dispconf.fullscreen=OMX_FALSE;
1617 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1618 if (error!=OMX_ErrorNone){
1619 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1620 clock_mutex.unlock();
1621 DeAllocateCodecsOMX();
1625 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1626 dispconf.dest_rect.x_offset=100;
1627 dispconf.dest_rect.y_offset=100;
1628 dispconf.dest_rect.width=640;
1629 dispconf.dest_rect.height=480;
1630 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1631 if (error!=OMX_ErrorNone){
1632 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1633 clock_mutex.unlock();
1634 DeAllocateCodecsOMX();
1639 //playbacktimeoffset=-GetCurrentSystemTime();
1643 clock_mutex.unlock();
1647 setClockExecutingandRunning();
1656 int VideoOMX::idleClock()
1658 //OMX_ERRORTYPE error;
1659 OMX_STATETYPE temp_state;
1661 OMX_GetState(omx_clock,&temp_state);
1663 if (temp_state!=OMX_StateIdle) {
1664 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1665 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1666 clock_mutex.unlock();
1670 clock_mutex.unlock();
1674 int VideoOMX::setClockExecutingandRunning()
1676 OMX_ERRORTYPE error;
1677 OMX_STATETYPE temp_state;
1679 OMX_GetState(omx_clock,&temp_state);
1681 if (temp_state!=OMX_StateExecuting) {
1682 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1683 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1684 clock_mutex.unlock();
1685 DeAllocateCodecsOMX();
1690 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1691 memset(&clock_conf,0,sizeof(clock_conf));
1692 clock_conf.nSize=sizeof(clock_conf);
1693 clock_conf.nVersion.nVersion=OMX_VERSION;
1694 clock_conf.eState=OMX_TIME_ClockStateRunning;
1695 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1696 if (error!=OMX_ErrorNone) {
1697 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1698 clock_mutex.unlock();
1699 DeAllocateCodecsOMX();
1702 clock_mutex.unlock();
1708 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1710 OMX_ERRORTYPE error;
1711 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1712 if (error!=OMX_ErrorNone){
1713 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1718 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1727 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1729 OMX_ERRORTYPE error;
1732 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1733 memset(&pdt,0,sizeof(pdt));
1734 pdt.nSize=sizeof(pdt);
1735 pdt.nVersion.nVersion=OMX_VERSION;
1736 pdt.nPortIndex=port;
1737 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1738 if (error==OMX_ErrorNone) {
1739 if(pdt.bEnabled==OMX_TRUE) {
1740 skip=true; //already disabled;
1746 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1747 if (error!=OMX_ErrorNone){
1748 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1752 if (!wait) return 1;
1753 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1762 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1764 OMX_ERRORTYPE error;
1767 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1768 memset(&pdt,0,sizeof(pdt));
1769 pdt.nSize=sizeof(pdt);
1770 pdt.nVersion.nVersion=OMX_VERSION;
1771 pdt.nPortIndex=port;
1772 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1773 if (error==OMX_ErrorNone) {
1774 if(pdt.bEnabled==OMX_FALSE) {
1775 skip=true; //already disabled;
1782 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1783 if (error!=OMX_ErrorNone){
1784 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1788 if (!wait) return 1;
1789 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1797 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1800 int iend=(wait/5+1);
1802 omx_event_mutex.lock();
1803 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1804 while (itty!=omx_events.end()) {
1806 VPE_OMX_EVENT current=*itty;
1807 if (current.handle==handle) { //this is ours
1808 if (current.event_type==OMX_EventError) {
1809 omx_events.erase(itty);
1810 omx_event_mutex.unlock();
1811 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1814 } else if (current.event_type==event) {
1815 omx_events.erase(itty);
1816 omx_event_mutex.unlock();
1817 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1824 omx_event_mutex.unlock();
1826 //Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent");
1827 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1828 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1834 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1839 int VideoOMX::clearEvents()
1841 omx_event_mutex.lock();
1843 omx_event_mutex.unlock();
1848 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1850 omx_event_mutex.lock();
1851 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1852 while (itty!=omx_events.end()) {
1853 VPE_OMX_EVENT current=*itty;
1854 if (current.handle==handle) { //this is ours
1855 itty=omx_events.erase(itty);
1861 omx_event_mutex.unlock();
1865 void VideoOMX::checkForStalledBuffers()
1867 //Log::getInstance()->log("Video", Log::DEBUG, "Check stalled");
1869 omx_event_mutex.lock();
1870 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1871 while (itty!=omx_events.end()) {
1872 VPE_OMX_EVENT current=*itty;
1873 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1874 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1875 OMX_ERRORTYPE error;
1876 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1877 memset(&stall_conf,0,sizeof(stall_conf));
1878 stall_conf.nSize=sizeof(stall_conf);
1879 stall_conf.nVersion.nVersion=OMX_VERSION;
1880 stall_conf.nPortIndex=omx_codec_output_port;
1881 stall_conf.nDelay=200000;
1883 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1884 if (error!=OMX_ErrorNone){
1885 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX_IndexConfigBufferStall failed %x", error);
1886 clock_mutex.unlock();
1887 omx_event_mutex.unlock();
1890 if (stall_conf.bStalled==OMX_TRUE) {
1891 omx_vid_stalled=true;
1892 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder stalled! %d", stall_conf.nDelay);
1894 omx_vid_stalled=false;
1895 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder unstalled! %d",stall_conf.nDelay);
1897 omx_events.erase(itty);
1902 omx_event_mutex.unlock();
1903 clock_mutex.unlock();
1909 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1912 while (i<200/*1000*/) {
1913 omx_event_mutex.lock();
1914 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1915 while (itty!=omx_events.end()) {
1917 VPE_OMX_EVENT current=*itty;
1918 if (current.handle==handle) { //this is ours
1919 if (current.event_type==OMX_EventError) {
1920 omx_events.erase(itty);
1921 omx_event_mutex.unlock();
1922 Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1);
1925 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1926 omx_events.erase(itty);
1927 omx_event_mutex.unlock();
1928 //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1935 omx_event_mutex.unlock();
1937 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1938 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1944 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1951 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1953 OMX_ERRORTYPE error;
1954 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1955 memset(&port_def_type,0,sizeof(port_def_type));
1956 port_def_type.nSize=sizeof(port_def_type);
1957 port_def_type.nVersion.nVersion=OMX_VERSION;
1958 port_def_type.nPortIndex=omx_codec_input_port;
1960 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1962 if (error!=OMX_ErrorNone){
1963 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1965 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1966 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1967 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1969 port_def_type.nBufferCountActual=100;
1970 port_def_type.nBufferSize=max(port_def_type.nBufferSize,150000); // for transcoder important
1972 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1974 if (error!=OMX_ErrorNone){
1975 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1979 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1980 if (error!=OMX_ErrorNone){
1981 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1985 input_bufs_omx_mutex.lock();
1986 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1988 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1989 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1990 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1991 if (error!=OMX_ErrorNone){
1992 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1993 input_bufs_omx_mutex.unlock();
1996 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1997 if (error!=OMX_ErrorNone){
1998 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1999 input_bufs_omx_mutex.unlock();
2002 input_bufs_omx_all.push_back(buf_head);
2003 input_bufs_omx_free.push_back(buf_head);
2005 omx_first_frame=true;
2008 cur_input_buf_omx=NULL;
2009 input_bufs_omx_mutex.unlock();
2012 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
2013 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
2016 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
2021 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2023 OMX_ERRORTYPE error;
2025 cur_input_buf_omx=NULL;
2026 input_bufs_omx_mutex.lock();
2027 for (UINT i=0; i< input_bufs_omx_all.size();i++) {
2028 // free(input_bufs_omx_all[i]->pBuffer);
2029 // input_bufs_omx_all[i]->pBuffer=NULL;
2030 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
2031 if (error!=OMX_ErrorNone){
2032 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
2033 input_bufs_omx_mutex.unlock();
2038 input_bufs_omx_all.clear();
2039 input_bufs_omx_free.clear();
2040 input_bufs_omx_mutex.unlock();
2047 int VideoOMX::FlushRenderingPipe()
2049 OMX_ERRORTYPE error;
2053 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2054 omx_codec_output_port, NULL);
2055 if (error != OMX_ErrorNone) {
2056 Log::getInstance()->log("Video", Log::DEBUG,
2057 "OMX_Flush codec out 1 failed %x", error);
2061 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2062 omx_shed_input_port, NULL);
2063 if (error != OMX_ErrorNone) {
2064 Log::getInstance()->log("Video", Log::DEBUG,
2065 "OMX_Flush shed in 2 failed %x", error);
2069 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2070 omx_codec_output_port)) {
2071 Log::getInstance()->log("Video", Log::DEBUG,
2072 "flush cmd codec 3 failed");
2075 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2076 omx_shed_input_port)) {
2077 Log::getInstance()->log("Video", Log::DEBUG,
2078 "flush cmd shed 4 failed");
2081 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2082 omx_codec_output_port, NULL);
2083 if (error != OMX_ErrorNone) {
2084 Log::getInstance()->log("Video", Log::DEBUG,
2085 "OMX_Flush codec out 5 failed %x", error);
2089 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2090 omx_deint_input_port, NULL);
2091 if (error != OMX_ErrorNone) {
2092 Log::getInstance()->log("Video", Log::DEBUG,
2093 "OMX_Flush deint in 6 failed %x", error);
2097 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2098 omx_codec_output_port)) {
2099 Log::getInstance()->log("Video", Log::DEBUG,
2100 "flush cmd codec 7 failed");
2103 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2104 omx_deint_input_port)) {
2105 Log::getInstance()->log("Video", Log::DEBUG,
2106 "flush cmd deint 8 failed");
2110 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2111 omx_deint_output_port, NULL);
2112 if (error != OMX_ErrorNone) {
2113 Log::getInstance()->log("Video", Log::DEBUG,
2114 "OMX_Flush deint out 9 failed %x", error);
2118 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2119 omx_shed_input_port, NULL);
2120 if (error != OMX_ErrorNone) {
2121 Log::getInstance()->log("Video", Log::DEBUG,
2122 "OMX_Flush shed in 10 failed %x", error);
2126 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2127 omx_deint_output_port)) {
2128 Log::getInstance()->log("Video", Log::DEBUG,
2129 "flush cmd deint 11 failed");
2132 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2133 omx_shed_input_port)) {
2134 Log::getInstance()->log("Video", Log::DEBUG,
2135 "flush cmd shed 12 failed");
2143 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2144 omx_rend_input_port, NULL);
2145 if (error != OMX_ErrorNone) {
2146 Log::getInstance()->log("Video", Log::DEBUG,
2147 "OMX_Flush rend in failed %x", error);
2151 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2152 omx_shed_output_port, NULL);
2153 if (error != OMX_ErrorNone) {
2154 Log::getInstance()->log("Video", Log::DEBUG,
2155 "OMX_Flush shed out failed %x", error);
2161 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2162 omx_rend_input_port)) {
2163 Log::getInstance()->log("Video", Log::DEBUG,
2164 "flush cmd shed rend failed");
2167 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2168 omx_shed_output_port)) {
2169 Log::getInstance()->log("Video", Log::DEBUG,
2170 "flush cmd shed rend failed");
2177 int VideoOMX::DeAllocateCodecsOMX()
2179 OMX_ERRORTYPE error;
2181 Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
2183 if (cur_input_buf_omx) {
2184 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2185 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2186 if (error!=OMX_ErrorNone) {
2187 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2190 cur_input_buf_omx=NULL;//write out old data
2195 // first stop the omx elements
2196 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2197 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
2200 clock_mutex.unlock();
2206 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2207 Log::getInstance()->log("Video", Log::DEBUG,
2208 "vid_deint ChangeComponentState");
2214 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2215 Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
2219 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2220 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
2226 // TODO proper deinit sequence
2227 // first flush all buffers
2228 FlushRenderingPipe();
2234 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2235 if (error!=OMX_ErrorNone){
2236 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
2240 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2241 if (error!=OMX_ErrorNone){
2242 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
2246 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2247 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2248 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
2254 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2255 omx_codec_input_port, NULL);
2256 if (error != OMX_ErrorNone) {
2257 Log::getInstance()->log("Video", Log::DEBUG,
2258 "OMX_Flush codec out failed %x", error);
2265 DestroyInputBufsOMX();
2268 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2269 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
2271 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2272 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
2278 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2279 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
2284 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2285 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
2289 if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2290 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
2295 if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2296 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
2302 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2303 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
2306 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2307 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
2310 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2311 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
2317 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2318 if (error!=OMX_ErrorNone) {
2319 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2324 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2325 if (error!=OMX_ErrorNone) {
2326 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2330 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2331 if (error!=OMX_ErrorNone) {
2332 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2336 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2337 if (error!=OMX_ErrorNone) {
2338 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2343 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2344 if (error!=OMX_ErrorNone) {
2345 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2349 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2350 if (error!=OMX_ErrorNone) {
2351 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2356 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2357 if (error!=OMX_ErrorNone) {
2358 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2362 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2363 if (error!=OMX_ErrorNone) {
2364 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2371 error=OMX_FreeHandle(omx_vid_dec);
2372 error=OMX_FreeHandle(omx_vid_sched);
2373 error=OMX_FreeHandle(omx_vid_rend);
2374 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2376 clock_mutex.unlock();
2378 if (error!=OMX_ErrorNone) {
2379 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2381 } else clock_mutex.unlock();
2382 Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2388 void VideoOMX::destroyClock()
2391 if (clock_references>0) {
2393 if (clock_references==0) {
2394 OMX_ERRORTYPE error;
2395 Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2396 error=OMX_FreeHandle(omx_clock);
2397 if (error!=OMX_ErrorNone) {
2398 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2403 clock_mutex.unlock();
2407 int VideoOMX::stop()
2409 if (!initted) return 0;
2412 //Check if libav mode
2413 DeAllocateCodecsOMX();
2418 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2422 int VideoOMX::reset()
2424 if (!initted) return 0;
2427 DeAllocateCodecsOMX();
2428 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2432 int VideoOMX::pause()
2434 if (!initted) return 0;
2435 Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2437 // ignore it audio handles this
2441 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2443 if (!initted) return 0;
2444 Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2447 //ignore it audio handles this
2452 int VideoOMX::fastForward()
2454 if (!initted) return 0;
2456 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2460 int VideoOMX::unFastForward()
2462 if (!initted) return 0;
2464 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2466 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2470 int VideoOMX::attachFrameBuffer()
2472 if (!initted) return 0;
2474 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2478 int VideoOMX::blank(void)
2480 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2481 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2485 ULLONG VideoOMX::getCurrentTimestamp() {
2488 long long ncur_clock_time = cur_clock_time;
2492 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2493 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2495 OMX_ERRORTYPE error;
2496 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2497 memset(&clock_conf, 0, sizeof(clock_conf));
2498 clock_conf.nSize = sizeof(clock_conf);
2499 clock_conf.nVersion.nVersion = OMX_VERSION;
2500 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2502 if (error != OMX_ErrorNone) {
2503 Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error);
2506 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2508 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2509 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2510 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2511 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2512 cur_time_stamp.nPortIndex = omx_clock_output_port;
2513 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2515 if (error != OMX_ErrorNone) {
2516 Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error);
2518 long long temp = cur_time_stamp.nTimestamp.nLowPart
2519 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2520 ncur_clock_time = cur_clock_time = temp * 10LL;
2523 clock_mutex.unlock();
2524 pthread_setcancelstate(oldcancelstate, NULL);
2525 pthread_setcanceltype(oldcanceltype, NULL);
2528 //ncur_clock_time -= startoffset;
2529 ncur_clock_time -= lastreftimeOMX;
2530 long long result = lastreftimePTS;
2531 if (lastreftimePTS==0) return 0; // invalid time
2532 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2534 result = (1LL << 33) - result;
2535 //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2543 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2545 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2546 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2551 int VideoOMX::test()
2556 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2563 int VideoOMX::test2()
2571 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2575 startoffset=curreftime;//offset is set for audio
2577 offsetvideonotset=false;
2579 if (offsetvideonotset) {
2580 offsetvideonotset=false;
2583 if ( (curreftime-lastrefvideotime)>10000000LL
2584 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2585 startoffset+=curreftime-lastrefvideotime;
2586 lastrefaudiotime+=curreftime-lastrefvideotime;
2588 offsetaudionotset=true;
2595 lastrefvideotime=curreftime;
2601 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2605 startoffset=curreftime;
2607 offsetaudionotset=false;
2609 if (offsetaudionotset) {
2610 offsetaudionotset=false;
2613 if ( (curreftime-lastrefaudiotime)>10000000LL
2614 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2615 startoffset+=curreftime-lastrefaudiotime;
2616 lastrefvideotime+=curreftime-lastrefaudiotime;
2618 offsetvideonotset=true;
2624 lastrefaudiotime=curreftime;
2629 void VideoOMX::ResetTimeOffsets() {
2630 offsetnotset=true; //called from demuxer
2631 offsetvideonotset=true;
2632 offsetaudionotset=true;
2641 void VideoOMX::FirstFrameFix()
2645 Demuxer* demux=Demuxer::getInstance();
2646 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2647 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2649 if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2650 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2651 OMX_ERRORTYPE error;
2652 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2653 memset(&port_def_type,0,sizeof(port_def_type));
2654 port_def_type.nSize=sizeof(port_def_type);
2655 port_def_type.nVersion.nVersion=OMX_VERSION;
2656 port_def_type.nPortIndex=omx_codec_output_port;
2658 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2659 if (error != OMX_ErrorNone) {
2660 Log::getInstance()->log("Video", Log::DEBUG,
2661 "OMX_IndexParamPortDefinition fix failed %x", error);
2662 clock_mutex.unlock();
2667 Log::getInstance()->log("Video", Log::DEBUG,
2668 "Deinit first frame fix %d %d %d %d %d %d %d %d",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2669 port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2670 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2671 port_def_type.format.video.bFlagErrorConcealment );
2672 Log::getInstance()->log("Video", Log::DEBUG,
2673 "Deinit first frame fix2 %d %d",
2674 port_def_type.format.video.eCompressionFormat ,
2675 port_def_type.format.video.eColorFormat );
2678 // we cause the video_decode to determine the interlacing properties
2679 OMX_CONFIG_INTERLACETYPE il;
2680 memset(&il,0,sizeof(il));
2681 il.nSize=sizeof(il);
2682 il.nVersion.nVersion=OMX_VERSION;
2683 il.nPortIndex=omx_codec_output_port;
2684 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2685 if (error != OMX_ErrorNone) {
2686 Log::getInstance()->log("Video", Log::DEBUG,
2687 "OMX_IndexConfigCommonInterlace fix failed %x", error);
2691 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2692 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2695 DisablePort(omx_vid_deint,omx_deint_input_port,true);
2696 // This is a dirty hack
2697 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2700 port_def_type.nPortIndex=omx_deint_output_port;
2701 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2703 if (error != OMX_ErrorNone) {
2704 Log::getInstance()->log("Video", Log::DEBUG,
2705 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2706 clock_mutex.unlock();
2707 pthread_setcancelstate(oldcancelstate, NULL);
2708 pthread_setcanceltype(oldcanceltype, NULL);
2714 port_def_type.nPortIndex=omx_deint_input_port;
2715 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2717 if (error != OMX_ErrorNone) {
2718 Log::getInstance()->log("Video", Log::DEBUG,
2719 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2720 clock_mutex.unlock();
2721 pthread_setcancelstate(oldcancelstate, NULL);
2722 pthread_setcanceltype(oldcanceltype, NULL);
2725 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2727 Log::getInstance()->log("Video", Log::DEBUG,
2729 EnablePort(omx_vid_deint,omx_deint_input_port,true);
2730 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2731 port_def_type.nPortIndex=omx_deint_output_port;
2732 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2734 if (error != OMX_ErrorNone) {
2735 Log::getInstance()->log("Video", Log::DEBUG,
2736 "Get OMX_IndexParamPortDefinition2 failed %x", error);
2737 clock_mutex.unlock();
2738 pthread_setcancelstate(oldcancelstate, NULL);
2739 pthread_setcanceltype(oldcanceltype, NULL);
2742 Log::getInstance()->log("Video", Log::DEBUG,
2743 "Deinit first frame fix3 %d %d %d %d %d %d %d ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2744 port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2745 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2746 port_def_type.format.image.bFlagErrorConcealment );
2747 Log::getInstance()->log("Video", Log::DEBUG,
2748 "Deinit first frame fix4 %d %d",
2749 port_def_type.format.image.eCompressionFormat ,
2750 port_def_type.format.image.eColorFormat );
2751 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2754 port_def_type.nPortIndex=omx_shed_input_port;
2755 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2757 if (error != OMX_ErrorNone) {
2758 Log::getInstance()->log("Video", Log::DEBUG,
2759 "Set OMX_IndexParamPortDefinition3 failed %x", error);
2760 clock_mutex.unlock();
2761 pthread_setcancelstate(oldcancelstate, NULL);
2762 pthread_setcanceltype(oldcanceltype, NULL);
2765 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2769 EnablePort(omx_vid_deint,omx_deint_output_port,true);
2771 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2772 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2774 clock_mutex.unlock();
2775 pthread_setcancelstate(oldcancelstate, NULL);
2776 pthread_setcanceltype(oldcanceltype, NULL);
2783 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2786 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2787 if (error != OMX_ErrorNone) {
2788 Log::getInstance()->log("Video", Log::DEBUG,
2789 "OMX_EmptyThisBuffer failed %x", error);
2791 if (first_frame) FirstFrameFix();
2795 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2797 // protect the call to empty this buffer
2800 /* long long temp =buffer->nTimeStamp.nLowPart
2801 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2803 //pthread_testcancel();
2804 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2805 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2808 /* OMX_ERRORTYPE error;
2809 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2810 memset(×tamp, 0, sizeof(timestamp));
2811 timestamp.nSize = sizeof(timestamp);
2812 timestamp.nVersion.nVersion = OMX_VERSION;
2813 timestamp.nPortIndex =omx_clock_output_port;
2815 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2818 if (error != OMX_ErrorNone) {
2819 Log::getInstance()->log("Audio", Log::DEBUG,
2820 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
2821 omx_rend_input_port);
2823 long long temp2 =timestamp.nTimestamp.nLowPart
2824 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2827 Log::getInstance()->log("Video", Log::NOTICE, "OMXETB %x %lld %lld %x",handle,temp,temp2,buffer->nFlags);*/
2828 OMX_ERRORTYPE ret_val;
2829 ret_val=OMX_EmptyThisBuffer(handle,buffer);
2830 clock_mutex.unlock();
2831 pthread_setcancelstate(oldcancelstate, NULL);
2832 pthread_setcanceltype(oldcanceltype, NULL);
2833 //pthread_testcancel();
2837 bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length)
2839 const UCHAR* curbuf=buffer;
2840 const UCHAR* curbufend=buffer+length;
2841 unsigned int detector=0xFFFFFFFF;
2842 bool gotaud=false; // have seen access unit delimiter
2844 while (curbuf!=curbufend) {
2848 if (detector==0x00000109) {
2850 detector=0xFFFFFFFF;
2851 } else if (gotaud &&detector==0x00000001) {
2853 if (curbuf!=curbufend) {
2854 unsigned char picttype=(*curbuf)& 0x1F;
2855 return picttype==0x07;
2859 if (detector==0x00000100) {
2861 if (curbuf==curbufend) return false;
2863 if (curbuf==curbufend) return false;
2864 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2871 return false; // no frame found
2876 bool VideoOMX::DrainTargetBufferFull()
2878 //Check, if we have OMX output buffers
2880 input_bufs_omx_mutex.lock();
2881 full=(input_bufs_omx_free.size()==0);
2882 input_bufs_omx_mutex.unlock();
2883 checkForStalledBuffers(); // check if the decoder has a problem
2884 if (full && omx_vid_stalled && !omx_first_frame) {
2885 omx_vid_stalled=false;
2886 Log::getInstance()->log("Video", Log::DEBUG, "Decoder is stalled, do a reset!");
2890 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2891 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2894 FlushRenderingPipe();
2895 omx_first_frame=true;
2896 clock_mutex.unlock();
2898 pthread_setcancelstate(oldcancelstate, NULL);
2899 pthread_setcanceltype(oldcanceltype, NULL);
2905 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, UINT /* samplepos */)
2908 mediapackets.clear();
2909 std::list<MediaPacket>::const_iterator begin=mplist.begin();
2910 std::list<MediaPacket>::const_iterator itty=mplist.begin();
2911 advance(itty,min(mplist.size(),10));
2912 mediapackets.insert(mediapackets.begin(),begin,itty);//front
2916 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2919 while (consumed < mediapackets.size()) {
2920 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2921 if (*samplepos == mediapackets[consumed].length) {
2925 } else return consumed;
2930 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2931 const UCHAR* buffer,
2934 if (packet.type == MPTYPE_VIDEO_H264)
2944 //Later add fail back code for libav
2946 *samplepos+=packet.length;
2947 return packet.length;
2951 if (!omx_running) return 0; // if we are not runnig do not do this
2953 if (isClockPaused()) return 0; //Block if we pause
2955 // Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 1");
2956 //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
2959 /*First Check, if we have an video sample*/
2963 return 0; //Not in iframe mode!
2967 if (packet.disconti) {
2969 if (cur_input_buf_omx) {
2970 PutBufferToPres(cur_input_buf_omx);
2971 cur_input_buf_omx=NULL;
2974 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2");
2975 /*Inspect PES-Header */
2977 // OMX_STATETYPE temp_state;
2978 // OMX_GetState(omx_vid_dec,&temp_state);
2980 if (*samplepos==0) {//stripheader
2981 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2982 // if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2983 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2984 *samplepos+=headerstrip;
2985 if (headerstrip>=packet.length) {
2986 *samplepos=packet.length;// Packet is obviously damaged
2987 return packet.length;//skip it!
2989 if ( packet.synched ) {
2990 if (!firstsynched) {
2991 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2a");
2992 // check if this is an I frame, the decoder does not like non I frames at startup!
2993 if (!detectIFrame(buffer,packet.length)) {
2994 *samplepos=packet.length;//if we have not processed at least one
2995 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 3");
2996 return packet.length;//synched packet ignore it!
2999 if (cur_input_buf_omx) {
3000 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4a");
3001 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3002 PutBufferToPres(cur_input_buf_omx);
3003 cur_input_buf_omx=NULL;//write out old data
3005 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4b");
3010 if (!firstsynched) {//
3011 *samplepos=packet.length;//if we have not processed at least one
3012 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 5");
3013 return packet.length;//synched packet ignore it!
3017 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 6");
3018 if (!cur_input_buf_omx) {
3019 input_bufs_omx_mutex.lock();
3020 if (input_bufs_omx_free.size()==0) {
3021 input_bufs_omx_mutex.unlock();
3022 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3023 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 7");
3024 return 0; // we do not have a free media sample
3027 cur_input_buf_omx=input_bufs_omx_free.front();
3028 cur_input_buf_omx->nFilledLen=0;
3029 cur_input_buf_omx->nOffset=0;
3030 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3031 input_bufs_omx_free.pop_front();
3032 input_bufs_omx_mutex.unlock();
3038 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3039 if (packet.synched) {
3040 // Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
3042 //lastreftimePTS=packet.pts;
3043 if (omx_first_frame) { // TODO time
3044 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3045 Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
3046 omx_first_frame=false;
3048 cur_input_buf_omx->nFlags=0;
3049 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3051 lastreftimeOMX=packet.presentation_time;
3052 // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
3053 lastreftimePTS=packet.pts;
3054 cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3058 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3059 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3060 //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
3062 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3067 unsigned int haveToCopy=packet.length-*samplepos;
3068 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 8");
3070 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3071 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3072 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3073 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3074 haveToCopy-=cancopy;
3075 cur_input_buf_omx->nFilledLen+=cancopy;
3076 *samplepos+=cancopy;
3077 // push old buffer out
3078 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 9");
3080 PutBufferToPres(cur_input_buf_omx);
3081 cur_input_buf_omx=NULL;
3083 input_bufs_omx_mutex.lock();
3084 if (input_bufs_omx_free.size()==0) {
3085 input_bufs_omx_mutex.unlock();
3086 // Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
3087 return *samplepos; // we do not have a free media sample
3089 cur_input_buf_omx=input_bufs_omx_free.front();
3090 cur_input_buf_omx->nFilledLen=0;
3091 cur_input_buf_omx->nOffset=0;
3092 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3093 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3094 input_bufs_omx_free.pop_front();
3095 input_bufs_omx_mutex.unlock();
3096 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 10");
3099 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3100 buffer+packet.pos_buffer+*samplepos,haveToCopy);
3101 cur_input_buf_omx->nFilledLen+=haveToCopy;
3103 // Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 11");
3105 *samplepos+=haveToCopy;
3114 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
3115 if (!omx_running) return false;
3117 EnterIframePlayback();
3119 //int haveToCopy = length;
3121 if (!cur_input_buf_omx) {
3122 input_bufs_omx_mutex.lock();
3123 if (input_bufs_omx_free.size() == 0) {
3124 input_bufs_omx_mutex.unlock();
3125 // Log::getInstance()->log("Video", Log::DEBUG,
3126 // "Deliver MediaPacket no free sample");
3127 return false; // we do not have a free media sample
3130 cur_input_buf_omx = input_bufs_omx_free.front();
3131 cur_input_buf_omx->nFilledLen = 0;
3132 cur_input_buf_omx->nOffset = 0;
3133 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3134 input_bufs_omx_free.pop_front();
3135 input_bufs_omx_mutex.unlock();
3139 unsigned int pattern, packet_length;
3140 unsigned int headerstrip = 0;
3145 //Now we strip the pes header
3146 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3147 while ((read_pos + 7) <= length) {
3148 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3149 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3153 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3154 packet_length = ((buffer[read_pos + 4] << 8)
3155 | (buffer[read_pos + 5])) + 6;
3156 if (read_pos + packet_length > length)
3159 if ((headerstrip < packet_length)
3160 && (cur_input_buf_omx->nFilledLen + packet_length
3161 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3163 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3166 cur_input_buf_omx->nFlags
3167 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3170 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3171 PutBufferToPres(cur_input_buf_omx);
3172 cur_input_buf_omx = NULL;
3174 if (!cur_input_buf_omx) {
3176 while (count < 100 && omx_running && iframemode) {
3179 input_bufs_omx_mutex.lock();
3180 if (input_bufs_omx_free.size() == 0) {
3181 input_bufs_omx_mutex.unlock();
3182 // Log::getInstance()->log("Video", Log::DEBUG,
3183 // "Ifrane no free sample");
3185 if (!omx_running) return false;
3188 cur_input_buf_omx = input_bufs_omx_free.front();
3189 cur_input_buf_omx->nFilledLen = 0;
3190 cur_input_buf_omx->nOffset = 0;
3191 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3192 cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3193 input_bufs_omx_free.pop_front();
3194 input_bufs_omx_mutex.unlock();
3197 if (!cur_input_buf_omx)
3202 if (packet_length > headerstrip) {
3204 cur_input_buf_omx->pBuffer
3205 + cur_input_buf_omx->nFilledLen,
3206 buffer + read_pos + headerstrip,
3207 packet_length - headerstrip);
3208 cur_input_buf_omx->nFilledLen += packet_length
3211 read_pos += packet_length;
3213 pattern = (buffer[read_pos] << 16)
3214 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3220 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3223 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3226 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3228 PutBufferToPres(cur_input_buf_omx);
3229 cur_input_buf_omx = NULL;
3232 MILLISLEEP(40); //Block a bit
3236 int VideoOMX::EnterIframePlayback()
3238 Log::getInstance()->log("Video", Log::DEBUG,
3239 "EnterIframePlayback");
3240 if (cur_input_buf_omx) {
3241 PutBufferToPres(cur_input_buf_omx);
3242 cur_input_buf_omx = NULL;
3244 Log::getInstance()->log("Video", Log::DEBUG,
3245 "EnterIframePlayback 2");
3246 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3247 DeAllocateCodecsOMX();
3248 AllocateCodecsOMX();
3249 Log::getInstance()->log("Video", Log::DEBUG,
3250 "leave IframePlayback");