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"
36 //A lot of parts of this file are heavily inspired by xbmc omx implementations
38 VideoOMX::VideoOMX() {
43 cur_input_buf_omx = NULL;
44 omx_h264 = omx_mpeg2 = true;
47 omx_vid_stalled = false;
50 offsetvideonotset = true;
51 offsetaudionotset = true;
59 mpeg2_supported=false;
64 deinterlace=2; //advanced
69 strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
70 strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
71 strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
72 strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
73 strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
74 strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
82 int VideoOMX::init(UCHAR tformat)
84 if (initted) return 0;
87 // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
88 // Seems safe to call it more than once.
91 int ret=vc_gencmd_send("codec_enabled MPG2");
93 Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_send failed %x",ret);
96 ret=vc_gencmd_read_response(buffer,sizeof(buffer));
98 Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_read_response failed %x",ret);
100 if (STRCASECMP(buffer,"MPG2=enabled")==0) {
101 mpeg2_supported=true;
102 } else if (STRCASECMP(buffer,"MPG2=disabled")==0) {
103 mpeg2_supported=false;
105 Log::getInstance()->log("Video", Log::DEBUG, "Undefined mpg codec answer %s",buffer);
110 if (!setFormat(tformat)) { shutdown(); return 0; }
111 if (!setConnection(HDMI)) { shutdown(); return 0; }
112 if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; }
113 if (!setMode(NORMAL)) { shutdown(); return 0; }
114 if (!setSource()) { shutdown(); return 0; }
115 if (!attachFrameBuffer()) { shutdown(); return 0; }
117 setTVsize(ASPECT16X9);
123 if (error != OMX_ErrorNone) {
124 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x",
143 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
144 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
145 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
147 //Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
149 struct VPE_OMX_EVENT new_event;
150 new_event.handle=handle;
151 new_event.appdata=appdata;
152 new_event.event_type=event_type;
153 new_event.data1=data1;
154 new_event.data2=data2;
155 new_event.event_data=event_data;
157 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
158 video->AddOmxEvent(new_event);
160 /* switch (event_type) {
161 case OMX_EventCmdComplete: {
166 return OMX_ErrorNone;
170 void VideoOMX::signalOmx()
173 * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
174 * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
175 * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
176 * in what the Signal class used to do here and I'll sort it out later.
177 * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
178 * exact sychronisation and remove the wait spin loops? Unknown.
180 * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
181 * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
183 * Callers of signalOmx:
185 * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
186 * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
187 * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
189 * Surprise: WaitForEvent isn't a long running loop while video is playing.
192 omx_event_ready_signal_mutex.lock();
193 omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
194 omx_event_ready_signal_mutex.unlock();
197 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
199 omx_event_mutex.lock();
200 omx_events.push_back(new_event);
201 omx_event_mutex.unlock();
206 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
208 // Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
209 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
210 /* long long temp =buffer->nTimeStamp.nLowPart
211 | ((long long) buffer->nTimeStamp.nHighPart << 32);
212 Log::getInstance()->log("Video", Log::NOTICE, "EBD Video %lld %x",temp,buffer->nFlags);*/
213 video->ReturnEmptyOMXBuffer(buffer);
214 return OMX_ErrorNone;
218 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
219 input_bufs_omx_mutex.lock();
220 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d",input_bufs_omx_free.size(),input_bufs_omx_all.size());
221 input_bufs_omx_free.push_back(buffer);
222 //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
223 input_bufs_omx_mutex.unlock();
228 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
229 //Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
230 return OMX_ErrorNone;
235 int VideoOMX::shutdown()
237 if (!initted) return 0;
239 Log::getInstance()->log("Video", Log::NOTICE, "Shutdown video module");
241 DeAllocateCodecsOMX();
243 //vc_tv_show_info(0); // back to console
246 struct fb_var_screeninfo screeninfo;
247 fd_fbset=open("/dev/fb0",O_RDONLY);
249 Log::getInstance()->log("Video", Log::CRIT, "Could not open frame buffer device %d", fd_fbset);
252 if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)){
254 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOGET_VSCREENINFO frame buffer device");
257 screeninfo.bits_per_pixel=8;
258 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
259 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
261 screeninfo.bits_per_pixel=16;
262 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
263 Log::getInstance()->log("Video", Log::CRIT, "Could not FBIOPUT_VSCREENINFO frame buffer device");
271 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
273 Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
274 char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
277 if (STRCASECMP(name, "None") == 0) {
279 }/* else if (STRCASECMP(name, "LineDouble") == 0) {
281 }*/ else if (STRCASECMP(name, "Advanced") == 0) {
283 } /*else if (STRCASECMP(name, "Crazy") == 0) {
284 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
285 }*/ else if (STRCASECMP(name, "Fast") == 0) {
288 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
296 bool VideoOMX::handleOptionChanges(Option* option)
298 if (Video::handleOptionChanges(option))
300 switch (option->id) {
302 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
304 } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
307 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
310 } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
313 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Fast")
317 Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
326 bool VideoOMX::saveOptionstoServer()
329 switch (deinterlace) {
331 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
334 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
337 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
340 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
343 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
350 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
351 UINT numChoices, UINT defaultChoice, UINT startInt,
352 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
354 bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
356 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
362 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
363 option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/3,2,0,deinterlaceopts,NULL,false,this);
364 options->push_back(option);
365 pane->addOptionLine(option);
373 int VideoOMX::setTVsize(UCHAR ttvsize)
375 if (tvsize!=ttvsize) pendingmodechange=true;
380 UCHAR VideoOMX::getTVsize() {
382 return ASPECT16X9; // in order that aspect ratio changes are reported
386 void VideoOMX::executePendingModeChanges()
388 if (pendingmodechange) {
389 Log::getInstance()->log("Video", Log::NOTICE, "Execute pending mode change");
390 Osd::getInstance()->shutdown();
392 Osd::getInstance()->restore();
393 Osd::getInstance()->init();
394 BoxStack::getInstance()->redrawAllBoxes();
399 int VideoOMX::setDefaultAspect()
401 return setAspectRatio(tvsize,parx,pary);
406 int VideoOMX::setFormat(UCHAR tformat)
408 if (!initted) return 0;
409 if ((tformat != PAL) && (tformat != NTSC)
410 && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
420 // selectVideoMode(0);
425 void VideoOMX::selectVideoMode(int interlaced)
427 TV_GET_STATE_RESP_T tvstate;
428 vc_tv_get_state(&tvstate);
430 if ((tvstate.state & VC_HDMI_UNPLUGGED)) {
432 Log::getInstance()->log("Video", Log::NOTICE, "HDMI unplugged");
435 Log::getInstance()->log("Video", Log::NOTICE, "HDMI plugged");
436 if (connection==COMPOSITERGB) {
438 Log::getInstance()->log("Video", Log::NOTICE, "SDTV set");
441 Log::getInstance()->log("Video", Log::NOTICE, "HDMI set");
447 TV_SUPPORTED_MODE_T all_supp_modes[200];
448 HDMI_RES_GROUP_T pref_group;
449 TV_SUPPORTED_MODE_T *mymode=NULL;
450 TV_SUPPORTED_MODE_T *mymode_second_best=NULL;
451 // bool got_optimum=false;
453 HDMI_RES_GROUP_T group=HDMI_RES_GROUP_CEA;
454 int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
456 &pref_group,&pref_mode);
457 if (all_my_modes<=0) {
458 group=HDMI_RES_GROUP_DMT;
459 all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
461 &pref_group,&pref_mode);
462 Log::getInstance()->log("Video", Log::NOTICE, "No CEA fall back to DMT modes ");
469 if (format==PAL)target_fps=50;
470 else if (format==NTSC) target_fps=60;
472 //Now first determine native resolution
473 int native_width=1920;
474 int native_height=1080;
475 for (int i=0;i<all_my_modes;i++) {
476 if (all_supp_modes[i].native) {
477 mymode=all_supp_modes+i;
478 Log::getInstance()->log("Video", Log::NOTICE, "Found native mode %dx%d %d Hz i: %d",
479 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
480 native_width=mymode->width;
481 native_height=mymode->height;
485 //Now find the mode which matches best
486 for (int i=0;i<all_my_modes;i++) {
487 TV_SUPPORTED_MODE_T *curmode=all_supp_modes+i;
488 if (curmode->width==native_width &&
489 curmode->height==native_height &&
490 curmode->frame_rate==target_fps) {
491 if(curmode->scan_mode==interlaced) {
494 Log::getInstance()->log("Video", Log::NOTICE, "Found optimum mode %dx%d %d Hz i: %d",
495 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
497 mymode_second_best=curmode;
498 Log::getInstance()->log("Video", Log::NOTICE, "Found close to optimum mode %dx%d %d Hz i: %d",
499 mymode_second_best->width,mymode_second_best->height,
500 mymode_second_best->frame_rate,mymode_second_best->scan_mode);
505 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
508 Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode");
509 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode->code);
510 } else if (mymode_second_best) {
511 Log::getInstance()->log("Video", Log::NOTICE, "Switch to close to optimum mode");
512 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode_second_best->code);
514 Log::getInstance()->log("Video", Log::NOTICE, "Switch to prefered mode");
515 vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
516 static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE));
519 outputinterlaced=interlaced;
522 Log::getInstance()->log("Video", Log::NOTICE, "Analog tv case");
523 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off();
524 SDTV_MODE_T setmode=SDTV_MODE_PAL;
525 SDTV_OPTIONS_T options;
530 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 16:9");
531 options.aspect=SDTV_ASPECT_16_9; break;
533 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 4:3");
534 options.aspect=SDTV_ASPECT_4_3; break;
536 Log::getInstance()->log("Video", Log::NOTICE, "SDTV aspect 14:9");
537 options.aspect=SDTV_ASPECT_14_9; break;
540 if (format==PAL) setmode=SDTV_MODE_PAL;
541 else if (format==NTSC) setmode=SDTV_MODE_NTSC;
542 else if (format==PAL_M)setmode=SDTV_MODE_PAL_M;
543 else if (format==NTSC_J) setmode=SDTV_MODE_NTSC_J;
544 vc_tv_sdtv_power_on(setmode,&options);
548 // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
549 // If this was just to reinit CEC then funcitons should be made to do that
553 pendingmodechange=false;
558 int VideoOMX::setConnection(UCHAR tconnection)
560 if (!initted) return 0;
561 if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0;
562 if (connection!=tconnection) pendingmodechange=true;
563 connection = tconnection;
565 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
569 int VideoOMX::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
571 if (!initted) return 0;
572 //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
573 aspectRatio = taspectRatio;
577 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i: PAR %d %d", aspectRatio,parx,pary);
580 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
584 int VideoOMX::setMode(UCHAR tmode)
586 if (!initted) return 0;
587 if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode;
592 bool VideoOMX::setVideoDisplay(VideoDisplay display)
594 if (!initted) return false;
595 switch (display.mode)
597 case None: return true; //??
604 xpos = ((float) display.x) / ((float) screenWidth);
605 ypos = ((float) display.y) / ((float) screenHeight);
612 xpos = ((float) display.x) / ((float) screenWidth);
613 ypos = ((float) display.y) / ((float) screenHeight);
620 xpos = ((float) display.x) / ((float) screenWidth);
621 ypos = ((float) display.y) / ((float) screenHeight);
622 width = ((float) display.width) / ((float) screenWidth);
623 height = ((float) display.height) / ((float) screenHeight);
631 void VideoOMX::updateMode()
637 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
638 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
640 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
641 memset(&dispconf, 0, sizeof(dispconf));
642 dispconf.nSize = sizeof(dispconf);
643 dispconf.nVersion.nVersion = OMX_VERSION;
644 dispconf.nPortIndex = omx_rend_input_port;
646 dispconf.set = OMX_DISPLAY_SET_LAYER;
647 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
649 if (error != OMX_ErrorNone) {
650 Log::getInstance()->log("Video", Log::DEBUG,
651 "Set OMX_IndexConfigDisplayRegion1 failed %x", error);
652 pthread_setcancelstate(oldcancelstate, NULL);
653 pthread_setcanceltype(oldcanceltype, NULL);
654 clock_mutex.unlock();
659 dispconf.pixel_x =parx;
660 dispconf.pixel_y=pary;
661 dispconf.set = OMX_DISPLAY_SET_PIXEL;
662 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
664 if (error != OMX_ErrorNone) {
665 Log::getInstance()->log("Video", Log::DEBUG,
666 "Set OMX_IndexConfigDisplayRegion5 failed %x", error);
667 pthread_setcancelstate(oldcancelstate, NULL);
668 pthread_setcanceltype(oldcanceltype, NULL);
669 clock_mutex.unlock();
675 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
678 dispconf.fullscreen = OMX_TRUE;
680 dispconf.fullscreen = OMX_FALSE;
682 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
684 if (error != OMX_ErrorNone) {
685 Log::getInstance()->log("Video", Log::DEBUG,
686 "Set OMX_IndexConfigDisplayRegion2 failed %x", error);
687 pthread_setcancelstate(oldcancelstate, NULL);
688 pthread_setcanceltype(oldcanceltype, NULL);
689 clock_mutex.unlock();
693 dispconf.set = OMX_DISPLAY_SET_MODE;
695 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
696 : OMX_DISPLAY_MODE_LETTERBOX;
698 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
700 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
702 if (error != OMX_ErrorNone) {
703 Log::getInstance()->log("Video", Log::DEBUG,
704 "Set OMX_IndexConfigDisplayRegion3 failed %x", error);
705 pthread_setcancelstate(oldcancelstate, NULL);
706 pthread_setcanceltype(oldcanceltype, NULL);
707 clock_mutex.unlock();
712 unsigned int display_width, display_height;
713 display_width = display_height = 0;
714 if (graphics_get_display_size(0, &display_width, &display_height)
716 Log::getInstance()->log("OSD", Log::WARN,
717 "Getting display size failed! (BCM API) ");
718 pthread_setcancelstate(oldcancelstate, NULL);
719 pthread_setcanceltype(oldcanceltype, NULL);
720 clock_mutex.unlock();
723 //UnSetFullscreen with window
724 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
725 dispconf.dest_rect.x_offset
726 = (int) (xpos * ((float) display_width));
727 dispconf.dest_rect.y_offset = (int) (ypos
728 * ((float) display_height));
729 dispconf.dest_rect.width = (int) (width * ((float) display_width));
730 dispconf.dest_rect.height = (int) (height * ((float) display_height));
731 Log::getInstance()->log("Video", Log::DEBUG,
732 "Set dest_rect as %d %d %d %d", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset,
733 dispconf.dest_rect.width , dispconf.dest_rect.height);
735 error = OMX_SetParameter(omx_vid_rend,
736 OMX_IndexConfigDisplayRegion, &dispconf);
737 if (error != OMX_ErrorNone) {
738 Log::getInstance()->log("Video", Log::DEBUG,
739 "Set OMX_IndexConfigDisplayRegion failed %x", error);
740 pthread_setcancelstate(oldcancelstate, NULL);
741 pthread_setcanceltype(oldcanceltype, NULL);
742 clock_mutex.unlock();
746 pthread_setcancelstate(oldcancelstate, NULL);
747 pthread_setcanceltype(oldcanceltype, NULL);
750 clock_mutex.unlock();
753 int VideoOMX::signalOff()
756 Log::getInstance()->log("Video", Log::NOTICE, "signalOff");
757 Osd::getInstance()->stopUpdate(); // turn off drawing thread
758 InputMan::getInstance()->shutdown();
760 InputMan::getInstance()->init(); // FIXME
765 int VideoOMX::signalOn()
768 Osd::getInstance()->shutdown();
769 Log::getInstance()->log("Video", Log::NOTICE, "signalOn");
771 Osd::getInstance()->restore();
772 Osd::getInstance()->init();
773 BoxStack::getInstance()->redrawAllBoxes();
780 int VideoOMX::setSource()
782 if (!initted) return 0;
784 // What does this do...
785 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
789 int VideoOMX::setPosition(int x, int y) {
792 xpos = ((float) x*2.f) / ((float) screenWidth);
793 ypos = ((float) y*2.f) / ((float) screenHeight);
801 if (!initted) return 0;
803 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
807 void VideoOMX::interlaceSwitch4Demux() {
809 Demuxer *demux=Demuxer::getInstance();
811 if (hdmi) { // only switch if hdmi and HD or interlaced SD material
815 int set_interlaced=0;
816 if (demux->getHorizontalSize()>720 && demux->getInterlaced()) {
819 Log::getInstance()->log("Video", Log::NOTICE, "switch interlacing %d %d %d",demux->getInterlaced(),outputinterlaced,set_interlaced);
820 if (outputinterlaced!=set_interlaced) {
821 selectVideoMode(set_interlaced);
822 Osd::getInstance()->shutdown();
823 Osd::getInstance()->restore();
824 Osd::getInstance()->init();
825 BoxStack::getInstance()->redrawAllBoxes();
837 int VideoOMX::play() {
841 Log::getInstance()->log("Video", Log::DEBUG, "enter play");
843 interlaceSwitch4Demux();
845 if (AllocateCodecsOMX()) {
847 // Otherwise fall back to libav
851 Log::getInstance()->log("Video", Log::NOTICE,
852 "Allocate Codecs OMX failed assume h264 unsupported");
855 Log::getInstance()->log("Video", Log::NOTICE,
856 "Allocate Codecs OMX failed assume mpeg2 unsupported");
865 int VideoOMX::initClock()
869 if (clock_references==0)
872 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
873 omx_event_mutex.lock();
875 omx_event_mutex.unlock();
877 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
879 if (error!=OMX_ErrorNone) {
880 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
881 clock_mutex.unlock();
882 DeAllocateCodecsOMX();
886 /* TODO Clock config to separate method */
887 OMX_PORT_PARAM_TYPE p_param;
888 memset(&p_param,0,sizeof(p_param));
889 p_param.nSize=sizeof(p_param);
890 p_param.nVersion.nVersion=OMX_VERSION;
891 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
892 if (error!=OMX_ErrorNone) {
893 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
894 clock_mutex.unlock();
895 DeAllocateCodecsOMX();
898 omx_clock_output_port=p_param.nStartPortNumber;
900 for (unsigned int i=0;i<p_param.nPorts;i++) {
901 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
902 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
903 clock_mutex.unlock();
904 DeAllocateCodecsOMX();
913 Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
915 clock_mutex.unlock();
919 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
923 *p_omx_clock_output_port=0;
930 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
931 memset(&refclock,0,sizeof(refclock));
932 refclock.nSize=sizeof(refclock);
933 refclock.nVersion.nVersion=OMX_VERSION;
935 refclock.eClock=OMX_TIME_RefClockAudio;
937 //refclock.eClock=OMX_TIME_RefClockVideo;
938 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
939 if (error!=OMX_ErrorNone){
940 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
941 clock_mutex.unlock();
942 DeAllocateCodecsOMX();
946 OMX_PORT_PARAM_TYPE p_param;
947 memset(&p_param,0,sizeof(p_param));
948 p_param.nSize=sizeof(p_param);
949 p_param.nVersion.nVersion=OMX_VERSION;
950 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
951 if (error!=OMX_ErrorNone){
952 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
953 clock_mutex.unlock();
954 DeAllocateCodecsOMX();
958 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
959 memset(&clock_conf,0,sizeof(clock_conf));
960 clock_conf.nSize=sizeof(clock_conf);
961 clock_conf.nVersion.nVersion=OMX_VERSION;
962 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
963 clock_conf.nStartTime=intToOMXTicks(0);
964 clock_conf.nOffset=intToOMXTicks(0);
965 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
966 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
967 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
968 if (error!=OMX_ErrorNone) {
969 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
973 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
974 *p_omx_clock=omx_clock;
975 clock_mutex.unlock();
979 int VideoOMX::getClockVideoandInit()
988 if (clock_references==1) { // only if no audio is attached to this clock!
989 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
990 memset(&refclock,0,sizeof(refclock));
991 refclock.nSize=sizeof(refclock);
992 refclock.nVersion.nVersion=OMX_VERSION;
994 //refclock.eClock=OMX_TIME_RefClockAudio;
996 refclock.eClock=OMX_TIME_RefClockVideo;
997 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
998 if (error!=OMX_ErrorNone) {
999 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
1000 clock_mutex.unlock();
1001 DeAllocateCodecsOMX();
1006 OMX_PORT_PARAM_TYPE p_param;
1007 memset(&p_param,0,sizeof(p_param));
1008 p_param.nSize=sizeof(p_param);
1009 p_param.nVersion.nVersion=OMX_VERSION;
1010 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1011 if (error!=OMX_ErrorNone){
1012 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1013 clock_mutex.unlock();
1014 DeAllocateCodecsOMX();
1019 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1020 memset(&clock_conf,0,sizeof(clock_conf));
1021 clock_conf.nSize=sizeof(clock_conf);
1022 clock_conf.nVersion.nVersion=OMX_VERSION;
1023 clock_conf.eState=OMX_TIME_ClockStateStopped;
1024 clock_conf.nStartTime=intToOMXTicks(0);
1025 clock_conf.nOffset=intToOMXTicks(0);
1026 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1027 if (error!=OMX_ErrorNone) {
1028 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1032 memset(&clock_conf,0,sizeof(clock_conf));
1033 clock_conf.nSize=sizeof(clock_conf);
1034 clock_conf.nVersion.nVersion=OMX_VERSION;
1035 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1036 clock_conf.nStartTime=intToOMXTicks(0);
1037 clock_conf.nOffset=intToOMXTicks(0);
1038 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1039 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1040 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1041 if (error!=OMX_ErrorNone) {
1042 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
1045 omx_clock_output_port=p_param.nStartPortNumber;
1046 clock_mutex.unlock();
1051 void VideoOMX::clockUnpause()
1053 OMX_ERRORTYPE error;
1054 Log::getInstance()->log("Video", Log::NOTICE, "enter Clockunpause");
1056 if (clock_references>0 && clockpaused) {
1057 OMX_TIME_CONFIG_SCALETYPE scale_type;
1058 memset(&scale_type,0,sizeof(scale_type));
1059 scale_type.nSize=sizeof(scale_type);
1060 scale_type.nVersion.nVersion=OMX_VERSION;
1061 scale_type.xScale=1<<16;
1062 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1063 if (error!=OMX_ErrorNone) {
1064 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause OMX_IndexConfigTimeScale failed %x", error);
1066 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockUnpause");
1069 clock_mutex.unlock();
1073 void VideoOMX::clockPause()
1075 OMX_ERRORTYPE error;
1076 Log::getInstance()->log("Video", Log::NOTICE, "enter ClockPause");
1078 if (clock_references>0 && !clockpaused) {
1079 OMX_TIME_CONFIG_SCALETYPE scale_type;
1080 memset(&scale_type,0,sizeof(scale_type));
1081 scale_type.nSize=sizeof(scale_type);
1082 scale_type.nVersion.nVersion=OMX_VERSION;
1083 scale_type.xScale=0;
1084 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1085 if (error!=OMX_ErrorNone) {
1086 Log::getInstance()->log("Video", Log::DEBUG, "ClockPause OMX_IndexConfigTimeScale failed %x", error);
1088 Log::getInstance()->log("Video", Log::NOTICE, "set playback speed ClockPause");
1091 clock_mutex.unlock();
1096 int VideoOMX::AllocateCodecsOMX()
1098 OMX_ERRORTYPE error;
1099 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1101 Demuxer* demux=Demuxer::getInstance();
1106 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1107 //Clock, move later to audio including events
1109 Log::getInstance()->log("Video", Log::NOTICE, "Deinter VideoType %d x %d i: %d", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1110 if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) {
1114 Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
1119 if (!getClockVideoandInit()){
1120 return 0;// get the clock and init it if necessary
1125 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
1132 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1134 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1137 if (error!=OMX_ErrorNone){
1138 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1139 clock_mutex.unlock();
1140 DeAllocateCodecsOMX();
1145 Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
1146 OMX_PORT_PARAM_TYPE p_param;
1147 memset(&p_param,0,sizeof(p_param));
1148 p_param.nSize=sizeof(p_param);
1149 p_param.nVersion.nVersion=OMX_VERSION;
1150 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1151 if (error!=OMX_ErrorNone){
1152 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1153 clock_mutex.unlock();
1154 DeAllocateCodecsOMX();
1157 omx_codec_input_port=p_param.nStartPortNumber;
1158 omx_codec_output_port=p_param.nStartPortNumber+1;
1160 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1161 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1162 clock_mutex.unlock();
1163 DeAllocateCodecsOMX();
1167 Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
1169 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1170 memset(&conceal,0,sizeof(conceal));
1171 conceal.nSize=sizeof(conceal);
1172 conceal.nVersion.nVersion=OMX_VERSION;
1173 conceal.bStartWithValidFrame=OMX_FALSE;
1175 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1176 if (error!=OMX_ErrorNone){
1177 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1178 clock_mutex.unlock();
1179 DeAllocateCodecsOMX();
1184 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1186 if (error != OMX_ErrorNone) {
1187 Log::getInstance()->log("Video", Log::DEBUG,
1188 "Init OMX video deinterlacer failed %x", error);
1189 clock_mutex.unlock();
1190 DeAllocateCodecsOMX();
1194 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1196 if (error != OMX_ErrorNone) {
1197 Log::getInstance()->log("Video", Log::DEBUG,
1198 "Init OMX video deinterlacer OMX_GetParameter failed %x",
1200 clock_mutex.unlock();
1201 DeAllocateCodecsOMX();
1204 omx_deint_input_port = p_param.nStartPortNumber;
1205 omx_deint_output_port = p_param.nStartPortNumber + 1;
1207 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1208 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1209 Log::getInstance()->log("Video", Log::DEBUG,
1210 "Disable Ports OMX video deint failed");
1211 clock_mutex.unlock();
1212 DeAllocateCodecsOMX();
1219 error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1220 if (error!=OMX_ErrorNone){
1221 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1222 clock_mutex.unlock();
1223 DeAllocateCodecsOMX();
1229 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1230 if (error!=OMX_ErrorNone){
1231 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1232 clock_mutex.unlock();
1233 DeAllocateCodecsOMX();
1236 omx_shed_input_port=p_param.nStartPortNumber;
1237 omx_shed_output_port=p_param.nStartPortNumber+1;
1240 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1241 if (error!=OMX_ErrorNone){
1242 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1243 clock_mutex.unlock();
1244 DeAllocateCodecsOMX();
1247 omx_shed_clock_port=p_param.nStartPortNumber;
1248 Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1251 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1252 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1253 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1254 clock_mutex.unlock();
1255 DeAllocateCodecsOMX();
1260 error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1261 if (error!=OMX_ErrorNone){
1262 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1263 clock_mutex.unlock();
1264 DeAllocateCodecsOMX();
1268 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1269 if (error!=OMX_ErrorNone){
1270 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1271 clock_mutex.unlock();
1272 DeAllocateCodecsOMX();
1275 omx_rend_input_port=p_param.nStartPortNumber;
1276 //omx_rend_output_port=p_param.nStartPortNumber+1;
1279 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1281 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1282 clock_mutex.unlock();
1283 DeAllocateCodecsOMX();
1291 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1292 if (error!=OMX_ErrorNone){
1293 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);
1294 clock_mutex.unlock();
1295 DeAllocateCodecsOMX();
1299 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1301 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1302 clock_mutex.unlock();
1303 DeAllocateCodecsOMX();
1309 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1310 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1311 clock_mutex.unlock();
1312 DeAllocateCodecsOMX();
1319 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1320 clock_mutex.unlock();
1321 DeAllocateCodecsOMX();
1329 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1330 clock_mutex.unlock();
1331 DeAllocateCodecsOMX();
1337 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1338 if (error!=OMX_ErrorNone){
1339 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1343 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1344 memset(&ft_type,0,sizeof(ft_type));
1345 ft_type.nSize=sizeof(ft_type);
1346 ft_type.nVersion.nVersion=OMX_VERSION;
1348 ft_type.nPortIndex=omx_codec_input_port;
1350 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1352 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1357 ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1358 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1359 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1360 if (error!=OMX_ErrorNone){
1361 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1362 clock_mutex.unlock();
1363 DeAllocateCodecsOMX();
1368 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1369 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1370 clock_mutex.unlock();
1371 DeAllocateCodecsOMX();
1375 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1376 memset(&stall_conf,0,sizeof(stall_conf));
1377 stall_conf.nSize=sizeof(stall_conf);
1378 stall_conf.nVersion.nVersion=OMX_VERSION;
1379 stall_conf.nPortIndex=omx_codec_output_port;
1380 stall_conf.nDelay=1500*1000;
1381 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1382 if (error!=OMX_ErrorNone){
1383 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigBufferStall failed %x", error);
1384 clock_mutex.unlock();
1385 DeAllocateCodecsOMX();
1388 omx_vid_stalled = false;
1390 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1391 memset(&req_callback,0,sizeof(req_callback));
1392 req_callback.nSize=sizeof(req_callback);
1393 req_callback.nVersion.nVersion=OMX_VERSION;
1394 req_callback.nPortIndex=omx_codec_output_port;
1395 req_callback.nIndex=OMX_IndexConfigBufferStall;
1396 req_callback.bEnable=OMX_TRUE;
1397 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1398 if (error!=OMX_ErrorNone){
1399 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigRequestCallback failed %x", error);
1400 clock_mutex.unlock();
1401 DeAllocateCodecsOMX();
1407 if (!PrepareInputBufsOMX()) {
1408 clock_mutex.unlock();
1409 DeAllocateCodecsOMX();
1414 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1415 if (error!=OMX_ErrorNone){
1416 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1417 clock_mutex.unlock();
1418 DeAllocateCodecsOMX();
1424 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1426 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1427 clock_mutex.unlock();
1428 DeAllocateCodecsOMX();
1432 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1433 clock_mutex.unlock();
1434 DeAllocateCodecsOMX();
1440 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1441 if (error!=OMX_ErrorNone){
1442 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
1443 clock_mutex.unlock();
1444 DeAllocateCodecsOMX();
1450 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1452 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
1453 clock_mutex.unlock();
1454 DeAllocateCodecsOMX();
1458 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1459 clock_mutex.unlock();
1460 DeAllocateCodecsOMX();
1464 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1465 Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
1466 clock_mutex.unlock();
1467 DeAllocateCodecsOMX();
1471 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1472 memset(&imagefilter,0,sizeof(imagefilter));
1473 imagefilter.nSize=sizeof(imagefilter);
1474 imagefilter.nVersion.nVersion=OMX_VERSION;
1476 imagefilter.nPortIndex=omx_deint_output_port;
1477 imagefilter.nNumParams=4;
1478 imagefilter.nParams[0]=3;//???
1479 imagefilter.nParams[1]=0;//default frame interval
1480 imagefilter.nParams[2]=0;// frame rate
1481 if (demux->getHorizontalSize() <= 720){
1482 imagefilter.nParams[3] = 1;//use qpus
1486 imagefilter.nParams[3] = 0;//use qpus
1489 switch (deinterlace) {
1491 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1493 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1495 imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1497 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1501 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1502 if (error!=OMX_ErrorNone){
1503 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
1504 clock_mutex.unlock();
1505 DeAllocateCodecsOMX();
1510 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1511 if (error!=OMX_ErrorNone){
1512 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
1513 clock_mutex.unlock();
1514 DeAllocateCodecsOMX();
1518 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1520 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
1521 clock_mutex.unlock();
1522 DeAllocateCodecsOMX();
1526 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1527 clock_mutex.unlock();
1528 DeAllocateCodecsOMX();
1534 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1535 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1536 clock_mutex.unlock();
1537 DeAllocateCodecsOMX();
1541 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1542 if (error!=OMX_ErrorNone){
1543 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
1544 clock_mutex.unlock();
1545 DeAllocateCodecsOMX();
1549 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1551 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
1552 clock_mutex.unlock();
1553 DeAllocateCodecsOMX();
1557 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1558 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1559 clock_mutex.unlock();
1560 DeAllocateCodecsOMX();
1564 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1565 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1566 clock_mutex.unlock();
1567 DeAllocateCodecsOMX();
1572 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1573 Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
1574 clock_mutex.unlock();
1575 DeAllocateCodecsOMX();
1578 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1579 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1582 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1583 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1584 clock_mutex.unlock();
1585 DeAllocateCodecsOMX();
1589 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1590 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1591 clock_mutex.unlock();
1592 DeAllocateCodecsOMX();
1597 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1598 memset(&dispconf,0,sizeof(dispconf));
1599 dispconf.nSize=sizeof(dispconf);
1600 dispconf.nVersion.nVersion=OMX_VERSION;
1602 dispconf.nPortIndex=omx_rend_input_port;
1604 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1606 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1607 if (error!=OMX_ErrorNone){
1608 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1609 clock_mutex.unlock();
1610 DeAllocateCodecsOMX();
1614 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1615 dispconf.fullscreen=OMX_FALSE;
1616 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1617 if (error!=OMX_ErrorNone){
1618 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1619 clock_mutex.unlock();
1620 DeAllocateCodecsOMX();
1624 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1625 dispconf.dest_rect.x_offset=100;
1626 dispconf.dest_rect.y_offset=100;
1627 dispconf.dest_rect.width=640;
1628 dispconf.dest_rect.height=480;
1629 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1630 if (error!=OMX_ErrorNone){
1631 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1632 clock_mutex.unlock();
1633 DeAllocateCodecsOMX();
1638 //playbacktimeoffset=-GetCurrentSystemTime();
1642 clock_mutex.unlock();
1646 setClockExecutingandRunning();
1655 int VideoOMX::idleClock()
1657 //OMX_ERRORTYPE error;
1658 OMX_STATETYPE temp_state;
1660 OMX_GetState(omx_clock,&temp_state);
1662 if (temp_state!=OMX_StateIdle) {
1663 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1664 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
1665 clock_mutex.unlock();
1669 clock_mutex.unlock();
1673 int VideoOMX::setClockExecutingandRunning()
1675 OMX_ERRORTYPE error;
1676 OMX_STATETYPE temp_state;
1678 OMX_GetState(omx_clock,&temp_state);
1680 if (temp_state!=OMX_StateExecuting) {
1681 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1682 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
1683 clock_mutex.unlock();
1684 DeAllocateCodecsOMX();
1689 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1690 memset(&clock_conf,0,sizeof(clock_conf));
1691 clock_conf.nSize=sizeof(clock_conf);
1692 clock_conf.nVersion.nVersion=OMX_VERSION;
1693 clock_conf.eState=OMX_TIME_ClockStateRunning;
1694 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1695 if (error!=OMX_ErrorNone) {
1696 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1697 clock_mutex.unlock();
1698 DeAllocateCodecsOMX();
1701 clock_mutex.unlock();
1707 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1709 OMX_ERRORTYPE error;
1710 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1711 if (error!=OMX_ErrorNone){
1712 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1717 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1726 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1728 OMX_ERRORTYPE error;
1731 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1732 memset(&pdt,0,sizeof(pdt));
1733 pdt.nSize=sizeof(pdt);
1734 pdt.nVersion.nVersion=OMX_VERSION;
1735 pdt.nPortIndex=port;
1736 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1737 if (error==OMX_ErrorNone) {
1738 if(pdt.bEnabled==OMX_TRUE) {
1739 skip=true; //already disabled;
1745 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1746 if (error!=OMX_ErrorNone){
1747 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1751 if (!wait) return 1;
1752 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1761 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1763 OMX_ERRORTYPE error;
1766 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1767 memset(&pdt,0,sizeof(pdt));
1768 pdt.nSize=sizeof(pdt);
1769 pdt.nVersion.nVersion=OMX_VERSION;
1770 pdt.nPortIndex=port;
1771 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1772 if (error==OMX_ErrorNone) {
1773 if(pdt.bEnabled==OMX_FALSE) {
1774 skip=true; //already disabled;
1781 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1782 if (error!=OMX_ErrorNone){
1783 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1787 if (!wait) return 1;
1788 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1796 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1799 int iend=(wait/5+1);
1801 omx_event_mutex.lock();
1802 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1803 while (itty!=omx_events.end()) {
1805 VPE_OMX_EVENT current=*itty;
1806 if (current.handle==handle) { //this is ours
1807 if (current.event_type==OMX_EventError) {
1808 omx_events.erase(itty);
1809 omx_event_mutex.unlock();
1810 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
1813 } else if (current.event_type==event) {
1814 omx_events.erase(itty);
1815 omx_event_mutex.unlock();
1816 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
1823 omx_event_mutex.unlock();
1825 //Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent");
1826 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1827 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1833 Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
1838 int VideoOMX::clearEvents()
1840 omx_event_mutex.lock();
1842 omx_event_mutex.unlock();
1847 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1849 omx_event_mutex.lock();
1850 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1851 while (itty!=omx_events.end()) {
1852 VPE_OMX_EVENT current=*itty;
1853 if (current.handle==handle) { //this is ours
1854 itty=omx_events.erase(itty);
1860 omx_event_mutex.unlock();
1864 void VideoOMX::checkForStalledBuffers()
1866 //Log::getInstance()->log("Video", Log::DEBUG, "Check stalled");
1868 omx_event_mutex.lock();
1869 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1870 while (itty!=omx_events.end()) {
1871 VPE_OMX_EVENT current=*itty;
1872 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1873 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1874 OMX_ERRORTYPE error;
1875 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1876 memset(&stall_conf,0,sizeof(stall_conf));
1877 stall_conf.nSize=sizeof(stall_conf);
1878 stall_conf.nVersion.nVersion=OMX_VERSION;
1879 stall_conf.nPortIndex=omx_codec_output_port;
1880 stall_conf.nDelay=200000;
1882 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1883 if (error!=OMX_ErrorNone){
1884 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX_IndexConfigBufferStall failed %x", error);
1885 clock_mutex.unlock();
1886 omx_event_mutex.unlock();
1889 if (stall_conf.bStalled==OMX_TRUE) {
1890 omx_vid_stalled=true;
1891 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder stalled! %d", stall_conf.nDelay);
1893 omx_vid_stalled=false;
1894 Log::getInstance()->log("Video", Log::DEBUG, "Video decoder unstalled! %d",stall_conf.nDelay);
1896 omx_events.erase(itty);
1901 omx_event_mutex.unlock();
1902 clock_mutex.unlock();
1908 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1911 while (i<200/*1000*/) {
1912 omx_event_mutex.lock();
1913 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1914 while (itty!=omx_events.end()) {
1916 VPE_OMX_EVENT current=*itty;
1917 if (current.handle==handle) { //this is ours
1918 if (current.event_type==OMX_EventError) {
1919 omx_events.erase(itty);
1920 omx_event_mutex.unlock();
1921 Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1);
1924 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1925 omx_events.erase(itty);
1926 omx_event_mutex.unlock();
1927 //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1934 omx_event_mutex.unlock();
1936 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1937 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1943 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1950 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1952 OMX_ERRORTYPE error;
1953 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1954 memset(&port_def_type,0,sizeof(port_def_type));
1955 port_def_type.nSize=sizeof(port_def_type);
1956 port_def_type.nVersion.nVersion=OMX_VERSION;
1957 port_def_type.nPortIndex=omx_codec_input_port;
1959 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1961 if (error!=OMX_ErrorNone){
1962 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1964 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1965 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1966 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1968 port_def_type.nBufferCountActual=100;
1969 port_def_type.nBufferSize=max(port_def_type.nBufferSize,150000); // for transcoder important
1971 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1973 if (error!=OMX_ErrorNone){
1974 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1978 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1979 if (error!=OMX_ErrorNone){
1980 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1984 input_bufs_omx_mutex.lock();
1985 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1987 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1988 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1989 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1990 if (error!=OMX_ErrorNone){
1991 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1992 input_bufs_omx_mutex.unlock();
1995 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1996 if (error!=OMX_ErrorNone){
1997 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1998 input_bufs_omx_mutex.unlock();
2001 input_bufs_omx_all.push_back(buf_head);
2002 input_bufs_omx_free.push_back(buf_head);
2004 omx_first_frame=true;
2007 cur_input_buf_omx=NULL;
2008 input_bufs_omx_mutex.unlock();
2011 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
2012 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
2015 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
2020 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2022 OMX_ERRORTYPE error;
2024 cur_input_buf_omx=NULL;
2025 input_bufs_omx_mutex.lock();
2026 for (UINT i=0; i< input_bufs_omx_all.size();i++) {
2027 // free(input_bufs_omx_all[i]->pBuffer);
2028 // input_bufs_omx_all[i]->pBuffer=NULL;
2029 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
2030 if (error!=OMX_ErrorNone){
2031 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
2032 input_bufs_omx_mutex.unlock();
2037 input_bufs_omx_all.clear();
2038 input_bufs_omx_free.clear();
2039 input_bufs_omx_mutex.unlock();
2046 int VideoOMX::FlushRenderingPipe()
2048 OMX_ERRORTYPE error;
2052 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2053 omx_codec_output_port, NULL);
2054 if (error != OMX_ErrorNone) {
2055 Log::getInstance()->log("Video", Log::DEBUG,
2056 "OMX_Flush codec out 1 failed %x", error);
2060 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2061 omx_shed_input_port, NULL);
2062 if (error != OMX_ErrorNone) {
2063 Log::getInstance()->log("Video", Log::DEBUG,
2064 "OMX_Flush shed in 2 failed %x", error);
2068 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2069 omx_codec_output_port)) {
2070 Log::getInstance()->log("Video", Log::DEBUG,
2071 "flush cmd codec 3 failed");
2074 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2075 omx_shed_input_port)) {
2076 Log::getInstance()->log("Video", Log::DEBUG,
2077 "flush cmd shed 4 failed");
2080 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2081 omx_codec_output_port, NULL);
2082 if (error != OMX_ErrorNone) {
2083 Log::getInstance()->log("Video", Log::DEBUG,
2084 "OMX_Flush codec out 5 failed %x", error);
2088 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2089 omx_deint_input_port, NULL);
2090 if (error != OMX_ErrorNone) {
2091 Log::getInstance()->log("Video", Log::DEBUG,
2092 "OMX_Flush deint in 6 failed %x", error);
2096 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2097 omx_codec_output_port)) {
2098 Log::getInstance()->log("Video", Log::DEBUG,
2099 "flush cmd codec 7 failed");
2102 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2103 omx_deint_input_port)) {
2104 Log::getInstance()->log("Video", Log::DEBUG,
2105 "flush cmd deint 8 failed");
2109 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2110 omx_deint_output_port, NULL);
2111 if (error != OMX_ErrorNone) {
2112 Log::getInstance()->log("Video", Log::DEBUG,
2113 "OMX_Flush deint out 9 failed %x", error);
2117 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2118 omx_shed_input_port, NULL);
2119 if (error != OMX_ErrorNone) {
2120 Log::getInstance()->log("Video", Log::DEBUG,
2121 "OMX_Flush shed in 10 failed %x", error);
2125 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2126 omx_deint_output_port)) {
2127 Log::getInstance()->log("Video", Log::DEBUG,
2128 "flush cmd deint 11 failed");
2131 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2132 omx_shed_input_port)) {
2133 Log::getInstance()->log("Video", Log::DEBUG,
2134 "flush cmd shed 12 failed");
2142 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2143 omx_rend_input_port, NULL);
2144 if (error != OMX_ErrorNone) {
2145 Log::getInstance()->log("Video", Log::DEBUG,
2146 "OMX_Flush rend in failed %x", error);
2150 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2151 omx_shed_output_port, NULL);
2152 if (error != OMX_ErrorNone) {
2153 Log::getInstance()->log("Video", Log::DEBUG,
2154 "OMX_Flush shed out failed %x", error);
2160 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2161 omx_rend_input_port)) {
2162 Log::getInstance()->log("Video", Log::DEBUG,
2163 "flush cmd shed rend failed");
2166 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2167 omx_shed_output_port)) {
2168 Log::getInstance()->log("Video", Log::DEBUG,
2169 "flush cmd shed rend failed");
2176 int VideoOMX::DeAllocateCodecsOMX()
2178 OMX_ERRORTYPE error;
2180 Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
2182 if (cur_input_buf_omx) {
2183 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2184 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2185 if (error!=OMX_ErrorNone) {
2186 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2189 cur_input_buf_omx=NULL;//write out old data
2194 // first stop the omx elements
2195 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2196 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
2199 clock_mutex.unlock();
2205 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2206 Log::getInstance()->log("Video", Log::DEBUG,
2207 "vid_deint ChangeComponentState");
2213 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2214 Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
2218 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2219 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
2225 // TODO proper deinit sequence
2226 // first flush all buffers
2227 FlushRenderingPipe();
2233 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2234 if (error!=OMX_ErrorNone){
2235 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
2239 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2240 if (error!=OMX_ErrorNone){
2241 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
2245 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2246 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2247 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
2253 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2254 omx_codec_input_port, NULL);
2255 if (error != OMX_ErrorNone) {
2256 Log::getInstance()->log("Video", Log::DEBUG,
2257 "OMX_Flush codec out failed %x", error);
2264 DestroyInputBufsOMX();
2267 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2268 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
2270 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2271 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
2277 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2278 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
2283 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2284 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
2288 if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2289 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
2294 if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2295 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
2301 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2302 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
2305 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2306 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
2309 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2310 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
2316 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2317 if (error!=OMX_ErrorNone) {
2318 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2323 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2324 if (error!=OMX_ErrorNone) {
2325 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2329 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2330 if (error!=OMX_ErrorNone) {
2331 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2335 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2336 if (error!=OMX_ErrorNone) {
2337 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2342 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2343 if (error!=OMX_ErrorNone) {
2344 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2348 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2349 if (error!=OMX_ErrorNone) {
2350 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2355 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2356 if (error!=OMX_ErrorNone) {
2357 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2361 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2362 if (error!=OMX_ErrorNone) {
2363 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
2370 error=OMX_FreeHandle(omx_vid_dec);
2371 error=OMX_FreeHandle(omx_vid_sched);
2372 error=OMX_FreeHandle(omx_vid_rend);
2373 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2375 clock_mutex.unlock();
2377 if (error!=OMX_ErrorNone) {
2378 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2380 } else clock_mutex.unlock();
2381 Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
2387 void VideoOMX::destroyClock()
2390 if (clock_references>0) {
2392 if (clock_references==0) {
2393 OMX_ERRORTYPE error;
2394 Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
2395 error=OMX_FreeHandle(omx_clock);
2396 if (error!=OMX_ErrorNone) {
2397 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
2402 clock_mutex.unlock();
2406 int VideoOMX::stop()
2408 if (!initted) return 0;
2411 //Check if libav mode
2412 DeAllocateCodecsOMX();
2417 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2421 int VideoOMX::reset()
2423 if (!initted) return 0;
2426 DeAllocateCodecsOMX();
2427 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2431 int VideoOMX::pause()
2433 if (!initted) return 0;
2434 Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
2436 // ignore it audio handles this
2440 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2442 if (!initted) return 0;
2443 Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
2446 //ignore it audio handles this
2451 int VideoOMX::fastForward()
2453 if (!initted) return 0;
2455 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2459 int VideoOMX::unFastForward()
2461 if (!initted) return 0;
2463 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2465 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2469 int VideoOMX::attachFrameBuffer()
2471 if (!initted) return 0;
2473 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2477 int VideoOMX::blank(void)
2479 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2480 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2484 ULLONG VideoOMX::getCurrentTimestamp() {
2487 long long ncur_clock_time = cur_clock_time;
2491 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2492 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2494 OMX_ERRORTYPE error;
2495 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2496 memset(&clock_conf, 0, sizeof(clock_conf));
2497 clock_conf.nSize = sizeof(clock_conf);
2498 clock_conf.nVersion.nVersion = OMX_VERSION;
2499 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2501 if (error != OMX_ErrorNone) {
2502 Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error);
2505 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2507 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2508 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2509 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2510 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2511 cur_time_stamp.nPortIndex = omx_clock_output_port;
2512 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2514 if (error != OMX_ErrorNone) {
2515 Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error);
2517 long long temp = cur_time_stamp.nTimestamp.nLowPart
2518 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2519 ncur_clock_time = cur_clock_time = temp * 10LL;
2522 clock_mutex.unlock();
2523 pthread_setcancelstate(oldcancelstate, NULL);
2524 pthread_setcanceltype(oldcanceltype, NULL);
2527 //ncur_clock_time -= startoffset;
2528 ncur_clock_time -= lastreftimeOMX;
2529 long long result = lastreftimePTS;
2530 if (lastreftimePTS==0) return 0; // invalid time
2531 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2533 result = (1LL << 33) - result;
2534 //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2542 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2544 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2545 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2550 int VideoOMX::test()
2555 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2562 int VideoOMX::test2()
2570 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2574 startoffset=curreftime;//offset is set for audio
2576 offsetvideonotset=false;
2578 if (offsetvideonotset) {
2579 offsetvideonotset=false;
2582 if ( (curreftime-lastrefvideotime)>10000000LL
2583 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2584 startoffset+=curreftime-lastrefvideotime;
2585 lastrefaudiotime+=curreftime-lastrefvideotime;
2587 offsetaudionotset=true;
2594 lastrefvideotime=curreftime;
2600 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2604 startoffset=curreftime;
2606 offsetaudionotset=false;
2608 if (offsetaudionotset) {
2609 offsetaudionotset=false;
2612 if ( (curreftime-lastrefaudiotime)>10000000LL
2613 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2614 startoffset+=curreftime-lastrefaudiotime;
2615 lastrefvideotime+=curreftime-lastrefaudiotime;
2617 offsetvideonotset=true;
2623 lastrefaudiotime=curreftime;
2628 void VideoOMX::ResetTimeOffsets() {
2629 offsetnotset=true; //called from demuxer
2630 offsetvideonotset=true;
2631 offsetaudionotset=true;
2640 void VideoOMX::FirstFrameFix()
2644 Demuxer* demux=Demuxer::getInstance();
2645 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2646 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2648 if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2649 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2650 OMX_ERRORTYPE error;
2651 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2652 memset(&port_def_type,0,sizeof(port_def_type));
2653 port_def_type.nSize=sizeof(port_def_type);
2654 port_def_type.nVersion.nVersion=OMX_VERSION;
2655 port_def_type.nPortIndex=omx_codec_output_port;
2657 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2658 if (error != OMX_ErrorNone) {
2659 Log::getInstance()->log("Video", Log::DEBUG,
2660 "OMX_IndexParamPortDefinition fix failed %x", error);
2661 clock_mutex.unlock();
2666 Log::getInstance()->log("Video", Log::DEBUG,
2667 "Deinit first frame fix %d %d %d %d %d %d %d %d",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2668 port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2669 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2670 port_def_type.format.video.bFlagErrorConcealment );
2671 Log::getInstance()->log("Video", Log::DEBUG,
2672 "Deinit first frame fix2 %d %d",
2673 port_def_type.format.video.eCompressionFormat ,
2674 port_def_type.format.video.eColorFormat );
2677 // we cause the video_decode to determine the interlacing properties
2678 OMX_CONFIG_INTERLACETYPE il;
2679 memset(&il,0,sizeof(il));
2680 il.nSize=sizeof(il);
2681 il.nVersion.nVersion=OMX_VERSION;
2682 il.nPortIndex=omx_codec_output_port;
2683 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2684 if (error != OMX_ErrorNone) {
2685 Log::getInstance()->log("Video", Log::DEBUG,
2686 "OMX_IndexConfigCommonInterlace fix failed %x", error);
2690 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2691 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2694 DisablePort(omx_vid_deint,omx_deint_input_port,true);
2695 // This is a dirty hack
2696 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2699 port_def_type.nPortIndex=omx_deint_output_port;
2700 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2702 if (error != OMX_ErrorNone) {
2703 Log::getInstance()->log("Video", Log::DEBUG,
2704 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2705 clock_mutex.unlock();
2706 pthread_setcancelstate(oldcancelstate, NULL);
2707 pthread_setcanceltype(oldcanceltype, NULL);
2713 port_def_type.nPortIndex=omx_deint_input_port;
2714 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2716 if (error != OMX_ErrorNone) {
2717 Log::getInstance()->log("Video", Log::DEBUG,
2718 "Set OMX_IndexParamPortDefinition1 failed %x", error);
2719 clock_mutex.unlock();
2720 pthread_setcancelstate(oldcancelstate, NULL);
2721 pthread_setcanceltype(oldcanceltype, NULL);
2724 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2726 Log::getInstance()->log("Video", Log::DEBUG,
2728 EnablePort(omx_vid_deint,omx_deint_input_port,true);
2729 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2730 port_def_type.nPortIndex=omx_deint_output_port;
2731 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2733 if (error != OMX_ErrorNone) {
2734 Log::getInstance()->log("Video", Log::DEBUG,
2735 "Get OMX_IndexParamPortDefinition2 failed %x", error);
2736 clock_mutex.unlock();
2737 pthread_setcancelstate(oldcancelstate, NULL);
2738 pthread_setcanceltype(oldcanceltype, NULL);
2741 Log::getInstance()->log("Video", Log::DEBUG,
2742 "Deinit first frame fix3 %d %d %d %d %d %d %d ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2743 port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2744 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2745 port_def_type.format.image.bFlagErrorConcealment );
2746 Log::getInstance()->log("Video", Log::DEBUG,
2747 "Deinit first frame fix4 %d %d",
2748 port_def_type.format.image.eCompressionFormat ,
2749 port_def_type.format.image.eColorFormat );
2750 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2753 port_def_type.nPortIndex=omx_shed_input_port;
2754 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2756 if (error != OMX_ErrorNone) {
2757 Log::getInstance()->log("Video", Log::DEBUG,
2758 "Set OMX_IndexParamPortDefinition3 failed %x", error);
2759 clock_mutex.unlock();
2760 pthread_setcancelstate(oldcancelstate, NULL);
2761 pthread_setcanceltype(oldcanceltype, NULL);
2764 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2768 EnablePort(omx_vid_deint,omx_deint_output_port,true);
2770 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2771 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2773 clock_mutex.unlock();
2774 pthread_setcancelstate(oldcancelstate, NULL);
2775 pthread_setcanceltype(oldcanceltype, NULL);
2782 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2785 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2786 if (error != OMX_ErrorNone) {
2787 Log::getInstance()->log("Video", Log::DEBUG,
2788 "OMX_EmptyThisBuffer failed %x", error);
2790 if (first_frame) FirstFrameFix();
2794 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2796 // protect the call to empty this buffer
2799 /* long long temp =buffer->nTimeStamp.nLowPart
2800 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2802 //pthread_testcancel();
2803 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2804 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2807 /* OMX_ERRORTYPE error;
2808 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2809 memset(×tamp, 0, sizeof(timestamp));
2810 timestamp.nSize = sizeof(timestamp);
2811 timestamp.nVersion.nVersion = OMX_VERSION;
2812 timestamp.nPortIndex =omx_clock_output_port;
2814 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2817 if (error != OMX_ErrorNone) {
2818 Log::getInstance()->log("Audio", Log::DEBUG,
2819 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
2820 omx_rend_input_port);
2822 long long temp2 =timestamp.nTimestamp.nLowPart
2823 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2826 Log::getInstance()->log("Video", Log::NOTICE, "OMXETB %x %lld %lld %x",handle,temp,temp2,buffer->nFlags);*/
2827 OMX_ERRORTYPE ret_val;
2828 ret_val=OMX_EmptyThisBuffer(handle,buffer);
2829 clock_mutex.unlock();
2830 pthread_setcancelstate(oldcancelstate, NULL);
2831 pthread_setcanceltype(oldcanceltype, NULL);
2832 //pthread_testcancel();
2836 bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length)
2838 const UCHAR* curbuf=buffer;
2839 const UCHAR* curbufend=buffer+length;
2840 unsigned int detector=0xFFFFFFFF;
2841 bool gotaud=false; // have seen access unit delimiter
2843 while (curbuf!=curbufend) {
2847 if (detector==0x00000109) {
2849 detector=0xFFFFFFFF;
2850 } else if (gotaud &&detector==0x00000001) {
2852 if (curbuf!=curbufend) {
2853 unsigned char picttype=(*curbuf)& 0x1F;
2854 return picttype==0x07;
2858 if (detector==0x00000100) {
2860 if (curbuf==curbufend) return false;
2862 if (curbuf==curbufend) return false;
2863 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2870 return false; // no frame found
2875 bool VideoOMX::DrainTargetBufferFull()
2877 //Check, if we have OMX output buffers
2879 input_bufs_omx_mutex.lock();
2880 full=(input_bufs_omx_free.size()==0);
2881 input_bufs_omx_mutex.unlock();
2882 checkForStalledBuffers(); // check if the decoder has a problem
2883 if (full && omx_vid_stalled && !omx_first_frame) {
2884 omx_vid_stalled=false;
2885 Log::getInstance()->log("Video", Log::DEBUG, "Decoder is stalled, do a reset!");
2889 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2890 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2893 FlushRenderingPipe();
2894 omx_first_frame=true;
2895 clock_mutex.unlock();
2897 pthread_setcancelstate(oldcancelstate, NULL);
2898 pthread_setcanceltype(oldcanceltype, NULL);
2904 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, UINT /* samplepos */)
2907 mediapackets.clear();
2908 std::list<MediaPacket>::const_iterator begin=mplist.begin();
2909 std::list<MediaPacket>::const_iterator itty=mplist.begin();
2910 advance(itty,min(mplist.size(),10));
2911 mediapackets.insert(mediapackets.begin(),begin,itty);//front
2915 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2918 while (consumed < mediapackets.size()) {
2919 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2920 if (*samplepos == mediapackets[consumed].length) {
2924 } else return consumed;
2929 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2930 const UCHAR* buffer,
2933 if (packet.type == MPTYPE_VIDEO_H264)
2943 //Later add fail back code for libav
2945 *samplepos+=packet.length;
2946 return packet.length;
2950 if (!omx_running) return 0; // if we are not runnig do not do this
2952 if (isClockPaused()) return 0; //Block if we pause
2954 // Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 1");
2955 //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
2958 /*First Check, if we have an video sample*/
2962 return 0; //Not in iframe mode!
2966 if (packet.disconti) {
2968 if (cur_input_buf_omx) {
2969 PutBufferToPres(cur_input_buf_omx);
2970 cur_input_buf_omx=NULL;
2973 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2");
2974 /*Inspect PES-Header */
2976 // OMX_STATETYPE temp_state;
2977 // OMX_GetState(omx_vid_dec,&temp_state);
2979 if (*samplepos==0) {//stripheader
2980 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2981 // if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
2982 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2983 *samplepos+=headerstrip;
2984 if (headerstrip>=packet.length) {
2985 *samplepos=packet.length;// Packet is obviously damaged
2986 return packet.length;//skip it!
2988 if ( packet.synched ) {
2989 if (!firstsynched) {
2990 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 2a");
2991 // check if this is an I frame, the decoder does not like non I frames at startup!
2992 if (!detectIFrame(buffer,packet.length)) {
2993 *samplepos=packet.length;//if we have not processed at least one
2994 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 3");
2995 return packet.length;//synched packet ignore it!
2998 if (cur_input_buf_omx) {
2999 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4a");
3000 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3001 PutBufferToPres(cur_input_buf_omx);
3002 cur_input_buf_omx=NULL;//write out old data
3004 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 4b");
3009 if (!firstsynched) {//
3010 *samplepos=packet.length;//if we have not processed at least one
3011 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 5");
3012 return packet.length;//synched packet ignore it!
3016 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 6");
3017 if (!cur_input_buf_omx) {
3018 input_bufs_omx_mutex.lock();
3019 if (input_bufs_omx_free.size()==0) {
3020 input_bufs_omx_mutex.unlock();
3021 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
3022 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 7");
3023 return 0; // we do not have a free media sample
3026 cur_input_buf_omx=input_bufs_omx_free.front();
3027 cur_input_buf_omx->nFilledLen=0;
3028 cur_input_buf_omx->nOffset=0;
3029 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3030 input_bufs_omx_free.pop_front();
3031 input_bufs_omx_mutex.unlock();
3037 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3038 if (packet.synched) {
3039 // Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
3041 //lastreftimePTS=packet.pts;
3042 if (omx_first_frame) { // TODO time
3043 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3044 Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
3045 omx_first_frame=false;
3047 cur_input_buf_omx->nFlags=0;
3048 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3050 lastreftimeOMX=packet.presentation_time;
3051 // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
3052 lastreftimePTS=packet.pts;
3053 cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3057 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3058 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3059 //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
3061 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3066 unsigned int haveToCopy=packet.length-*samplepos;
3067 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 8");
3069 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3070 //Log::getInstance()->log("Video", Log::DEBUG, "Big buffer %d %d %d",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3071 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3072 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3073 haveToCopy-=cancopy;
3074 cur_input_buf_omx->nFilledLen+=cancopy;
3075 *samplepos+=cancopy;
3076 // push old buffer out
3077 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 9");
3079 PutBufferToPres(cur_input_buf_omx);
3080 cur_input_buf_omx=NULL;
3082 input_bufs_omx_mutex.lock();
3083 if (input_bufs_omx_free.size()==0) {
3084 input_bufs_omx_mutex.unlock();
3085 // Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
3086 return *samplepos; // we do not have a free media sample
3088 cur_input_buf_omx=input_bufs_omx_free.front();
3089 cur_input_buf_omx->nFilledLen=0;
3090 cur_input_buf_omx->nOffset=0;
3091 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3092 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3093 input_bufs_omx_free.pop_front();
3094 input_bufs_omx_mutex.unlock();
3095 //Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 10");
3098 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3099 buffer+packet.pos_buffer+*samplepos,haveToCopy);
3100 cur_input_buf_omx->nFilledLen+=haveToCopy;
3102 // Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 11");
3104 *samplepos+=haveToCopy;
3113 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
3114 if (!omx_running) return false;
3116 EnterIframePlayback();
3118 //int haveToCopy = length;
3120 if (!cur_input_buf_omx) {
3121 input_bufs_omx_mutex.lock();
3122 if (input_bufs_omx_free.size() == 0) {
3123 input_bufs_omx_mutex.unlock();
3124 // Log::getInstance()->log("Video", Log::DEBUG,
3125 // "Deliver MediaPacket no free sample");
3126 return false; // we do not have a free media sample
3129 cur_input_buf_omx = input_bufs_omx_free.front();
3130 cur_input_buf_omx->nFilledLen = 0;
3131 cur_input_buf_omx->nOffset = 0;
3132 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3133 input_bufs_omx_free.pop_front();
3134 input_bufs_omx_mutex.unlock();
3138 unsigned int pattern, packet_length;
3139 unsigned int headerstrip = 0;
3144 //Now we strip the pes header
3145 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3146 while ((read_pos + 7) <= length) {
3147 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3148 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3152 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3153 packet_length = ((buffer[read_pos + 4] << 8)
3154 | (buffer[read_pos + 5])) + 6;
3155 if (read_pos + packet_length > length)
3158 if ((headerstrip < packet_length)
3159 && (cur_input_buf_omx->nFilledLen + packet_length
3160 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3162 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3165 cur_input_buf_omx->nFlags
3166 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3169 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3170 PutBufferToPres(cur_input_buf_omx);
3171 cur_input_buf_omx = NULL;
3173 if (!cur_input_buf_omx) {
3175 while (count < 100 && omx_running && iframemode) {
3178 input_bufs_omx_mutex.lock();
3179 if (input_bufs_omx_free.size() == 0) {
3180 input_bufs_omx_mutex.unlock();
3181 // Log::getInstance()->log("Video", Log::DEBUG,
3182 // "Ifrane no free sample");
3184 if (!omx_running) return false;
3187 cur_input_buf_omx = input_bufs_omx_free.front();
3188 cur_input_buf_omx->nFilledLen = 0;
3189 cur_input_buf_omx->nOffset = 0;
3190 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3191 cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3192 input_bufs_omx_free.pop_front();
3193 input_bufs_omx_mutex.unlock();
3196 if (!cur_input_buf_omx)
3201 if (packet_length > headerstrip) {
3203 cur_input_buf_omx->pBuffer
3204 + cur_input_buf_omx->nFilledLen,
3205 buffer + read_pos + headerstrip,
3206 packet_length - headerstrip);
3207 cur_input_buf_omx->nFilledLen += packet_length
3210 read_pos += packet_length;
3212 pattern = (buffer[read_pos] << 16)
3213 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3219 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3222 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3225 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3227 PutBufferToPres(cur_input_buf_omx);
3228 cur_input_buf_omx = NULL;
3231 MILLISLEEP(40); //Block a bit
3235 int VideoOMX::EnterIframePlayback()
3237 Log::getInstance()->log("Video", Log::DEBUG,
3238 "EnterIframePlayback");
3239 if (cur_input_buf_omx) {
3240 PutBufferToPres(cur_input_buf_omx);
3241 cur_input_buf_omx = NULL;
3243 Log::getInstance()->log("Video", Log::DEBUG,
3244 "EnterIframePlayback 2");
3245 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3246 DeAllocateCodecsOMX();
3247 AllocateCodecsOMX();
3248 Log::getInstance()->log("Video", Log::DEBUG,
3249 "leave IframePlayback");