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/>.
31 #include "woptionpane.h"
32 #include "osdopenvg.h"
39 //A lot of parts of this file are heavily inspired by xbmc omx implementations
41 static const char* TAG = "VideoOMX";
43 VideoOMX::VideoOMX() {
44 logger = LogNT::getInstance();
49 cur_input_buf_omx = NULL;
50 omx_h264 = omx_mpeg2 = true;
53 omx_vid_stalled = false;
56 offsetvideonotset = true;
57 offsetaudionotset = true;
65 mpeg2_supported=false;
70 deinterlace=2; //advanced
75 strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
76 strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
77 strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
78 strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
79 strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
80 strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
88 int VideoOMX::init(UCHAR tformat)
90 if (initted) return 0;
93 // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
94 // Seems safe to call it more than once.
97 int ret=vc_gencmd_send("codec_enabled MPG2");
99 logger->debug(TAG, "vc_gencmd_send failed {:#x}",ret);
102 ret=vc_gencmd_read_response(buffer,sizeof(buffer));
104 logger->debug(TAG, "vc_gencmd_read_response failed {:#x}",ret);
106 if (STRCASECMP(buffer,"MPG2=enabled")==0) {
107 mpeg2_supported=true;
108 } else if (STRCASECMP(buffer,"MPG2=disabled")==0) {
109 mpeg2_supported=false;
111 logger->debug(TAG, "Undefined mpg codec answer {}",buffer);
116 if (!setFormat(tformat)) { shutdown(); return 0; }
117 if (!setConnection(HDMI)) { shutdown(); return 0; }
118 if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; }
119 if (!setMode(NORMAL)) { shutdown(); return 0; }
120 if (!setSource()) { shutdown(); return 0; }
121 if (!attachFrameBuffer()) { shutdown(); return 0; }
123 setTVsize(ASPECT16X9);
129 if (error != OMX_ErrorNone) {
130 logger->debug(TAG, "Init OMX failed {:#x}",
149 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
150 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
151 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
153 //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data);
155 struct VPE_OMX_EVENT new_event;
156 new_event.handle=handle;
157 new_event.appdata=appdata;
158 new_event.event_type=event_type;
159 new_event.data1=data1;
160 new_event.data2=data2;
161 new_event.event_data=event_data;
163 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
164 video->AddOmxEvent(new_event);
166 /* switch (event_type) {
167 case OMX_EventCmdComplete: {
172 return OMX_ErrorNone;
176 void VideoOMX::signalOmx()
179 * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
180 * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
181 * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
182 * in what the Signal class used to do here and I'll sort it out later.
183 * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
184 * exact sychronisation and remove the wait spin loops? Unknown.
186 * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
187 * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
189 * Callers of signalOmx:
191 * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
192 * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
193 * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
195 * Surprise: WaitForEvent isn't a long running loop while video is playing.
198 omx_event_ready_signal_mutex.lock();
199 omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
200 omx_event_ready_signal_mutex.unlock();
203 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
205 omx_event_mutex.lock();
206 omx_events.push_back(new_event);
207 omx_event_mutex.unlock();
212 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
214 // LogNT::getInstance()->info(TAG, "EmptyBufferDone");
215 VideoOMX* video = static_cast<VideoOMX *>(Video::getInstance());
216 /* long long temp =buffer->nTimeStamp.nLowPart
217 | ((long long) buffer->nTimeStamp.nHighPart << 32);
218 LogNT::getInstance()->info(TAG, "EBD Video %lld {:#x}",temp,buffer->nFlags);*/
219 video->ReturnEmptyOMXBuffer(buffer);
220 return OMX_ErrorNone;
224 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
225 input_bufs_omx_mutex.lock();
226 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size());
227 input_bufs_omx_free.push_back(buffer);
228 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
229 input_bufs_omx_mutex.unlock();
234 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
235 //LogNT::getInstance()->info(TAG, "FillBufferDone");
236 return OMX_ErrorNone;
241 int VideoOMX::shutdown()
243 if (!initted) return 0;
245 LogNT::getInstance()->info(TAG, "Shutdown video module");
247 DeAllocateCodecsOMX();
249 //vc_tv_show_info(0); // back to console
252 struct fb_var_screeninfo screeninfo;
253 fd_fbset=open("/dev/fb0",O_RDONLY);
255 LogNT::getInstance()->crit(TAG, "Could not open frame buffer device {}", fd_fbset);
258 if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)){
260 LogNT::getInstance()->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device");
263 screeninfo.bits_per_pixel=8;
264 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
265 LogNT::getInstance()->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
267 screeninfo.bits_per_pixel=16;
268 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){
269 LogNT::getInstance()->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
277 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
279 logger->debug(TAG, "VideoOMX config load");
280 char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
283 if (STRCASECMP(name, "None") == 0) {
285 }/* else if (STRCASECMP(name, "LineDouble") == 0) {
287 }*/ else if (STRCASECMP(name, "Advanced") == 0) {
289 } /*else if (STRCASECMP(name, "Crazy") == 0) {
290 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
291 }*/ else if (STRCASECMP(name, "Fast") == 0) {
294 logger->debug(TAG, "Set deinterlacing to {} {}",name,deinterlace);
302 bool VideoOMX::handleOptionChanges(Option* option)
304 if (Video::handleOptionChanges(option))
306 switch (option->id) {
308 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
310 } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
313 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
316 } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
319 }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Fast")
323 logger->debug(TAG, "Set deinterlacing to {} {}",option->options[option->userSetChoice],deinterlace);
332 bool VideoOMX::saveOptionstoServer()
335 switch (deinterlace) {
337 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
340 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
343 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
346 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
349 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
356 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
357 UINT numChoices, UINT defaultChoice, UINT startInt,
358 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
360 bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
362 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
368 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
369 option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/3,2,0,deinterlaceopts,NULL,false,this);
370 options->push_back(option);
371 pane->addOptionLine(option);
379 int VideoOMX::setTVsize(UCHAR ttvsize)
381 if (tvsize!=ttvsize) pendingmodechange=true;
386 UCHAR VideoOMX::getTVsize() {
388 return ASPECT16X9; // in order that aspect ratio changes are reported
392 void VideoOMX::executePendingModeChanges()
394 if (pendingmodechange) {
395 LogNT::getInstance()->info(TAG, "Execute pending mode change");
396 Osd::getInstance()->shutdown();
398 Osd::getInstance()->restore();
399 Osd::getInstance()->init();
400 BoxStack::getInstance()->redrawAllBoxes();
405 int VideoOMX::setDefaultAspect()
407 return setAspectRatio(tvsize,parx,pary);
412 int VideoOMX::setFormat(UCHAR tformat)
414 if (!initted) return 0;
415 if ((tformat != PAL) && (tformat != NTSC)
416 && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
426 // selectVideoMode(0);
431 void VideoOMX::selectVideoMode(int interlaced)
433 TV_GET_STATE_RESP_T tvstate;
434 vc_tv_get_state(&tvstate);
436 if ((tvstate.state & VC_HDMI_UNPLUGGED)) {
438 LogNT::getInstance()->info(TAG, "HDMI unplugged");
441 LogNT::getInstance()->info(TAG, "HDMI plugged");
442 if (connection==COMPOSITERGB) {
444 LogNT::getInstance()->info(TAG, "SDTV set");
447 LogNT::getInstance()->info(TAG, "HDMI set");
453 TV_SUPPORTED_MODE_T all_supp_modes[200];
454 HDMI_RES_GROUP_T pref_group;
455 TV_SUPPORTED_MODE_T *mymode=NULL;
456 TV_SUPPORTED_MODE_T *mymode_second_best=NULL;
457 // bool got_optimum=false;
459 HDMI_RES_GROUP_T group=HDMI_RES_GROUP_CEA;
460 int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
462 &pref_group,&pref_mode);
463 if (all_my_modes<=0) {
464 group=HDMI_RES_GROUP_DMT;
465 all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
467 &pref_group,&pref_mode);
468 LogNT::getInstance()->info(TAG, "No CEA fall back to DMT modes ");
475 if (format==PAL)target_fps=50;
476 else if (format==NTSC) target_fps=60;
478 //Now first determine native resolution
479 int native_width=1920;
480 int native_height=1080;
481 for (int i=0;i<all_my_modes;i++) {
482 if (all_supp_modes[i].native) {
483 mymode=all_supp_modes+i;
484 LogNT::getInstance()->info(TAG, "Found native mode {}x{} {} Hz i: {}",
485 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
486 native_width=mymode->width;
487 native_height=mymode->height;
491 //Now find the mode which matches best
492 for (int i=0;i<all_my_modes;i++) {
493 TV_SUPPORTED_MODE_T *curmode=all_supp_modes+i;
494 if (curmode->width==native_width &&
495 curmode->height==native_height &&
496 curmode->frame_rate==target_fps) {
497 if(curmode->scan_mode==interlaced) {
500 LogNT::getInstance()->info(TAG, "Found optimum mode {}x{} {} Hz i: {}",
501 mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode);
503 mymode_second_best=curmode;
504 LogNT::getInstance()->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}",
505 mymode_second_best->width,mymode_second_best->height,
506 mymode_second_best->frame_rate,mymode_second_best->scan_mode);
511 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
514 LogNT::getInstance()->info(TAG, "Switch to optimum mode");
515 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode->code);
516 } else if (mymode_second_best) {
517 LogNT::getInstance()->info(TAG, "Switch to close to optimum mode");
518 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode_second_best->code);
520 LogNT::getInstance()->info(TAG, "Switch to prefered mode");
521 vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
522 static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE));
525 outputinterlaced=interlaced;
528 LogNT::getInstance()->info(TAG, "Analog tv case");
529 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off();
530 SDTV_MODE_T setmode=SDTV_MODE_PAL;
531 SDTV_OPTIONS_T options;
536 LogNT::getInstance()->info(TAG, "SDTV aspect 16:9");
537 options.aspect=SDTV_ASPECT_16_9; break;
539 LogNT::getInstance()->info(TAG, "SDTV aspect 4:3");
540 options.aspect=SDTV_ASPECT_4_3; break;
542 LogNT::getInstance()->info(TAG, "SDTV aspect 14:9");
543 options.aspect=SDTV_ASPECT_14_9; break;
546 if (format==PAL) setmode=SDTV_MODE_PAL;
547 else if (format==NTSC) setmode=SDTV_MODE_NTSC;
548 else if (format==PAL_M)setmode=SDTV_MODE_PAL_M;
549 else if (format==NTSC_J) setmode=SDTV_MODE_NTSC_J;
550 vc_tv_sdtv_power_on(setmode,&options);
554 // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
555 // If this was just to reinit CEC then funcitons should be made to do that
559 pendingmodechange=false;
564 int VideoOMX::setConnection(UCHAR tconnection)
566 if (!initted) return 0;
567 if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0;
568 if (connection!=tconnection) pendingmodechange=true;
569 connection = tconnection;
571 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
575 int VideoOMX::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
577 if (!initted) return 0;
578 //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
579 aspectRatio = taspectRatio;
583 logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio,parx,pary);
586 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
590 int VideoOMX::setMode(UCHAR tmode)
592 if (!initted) return 0;
593 if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode;
598 bool VideoOMX::setVideoDisplay(VideoDisplay display)
600 if (!initted) return false;
601 switch (display.mode)
603 case None: return true; //??
610 xpos = ((float) display.x) / ((float) screenWidth);
611 ypos = ((float) display.y) / ((float) screenHeight);
618 xpos = ((float) display.x) / ((float) screenWidth);
619 ypos = ((float) display.y) / ((float) screenHeight);
626 xpos = ((float) display.x) / ((float) screenWidth);
627 ypos = ((float) display.y) / ((float) screenHeight);
628 width = ((float) display.width) / ((float) screenWidth);
629 height = ((float) display.height) / ((float) screenHeight);
637 void VideoOMX::updateMode()
643 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
644 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
646 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
647 memset(&dispconf, 0, sizeof(dispconf));
648 dispconf.nSize = sizeof(dispconf);
649 dispconf.nVersion.nVersion = OMX_VERSION;
650 dispconf.nPortIndex = omx_rend_input_port;
652 dispconf.set = OMX_DISPLAY_SET_LAYER;
653 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
655 if (error != OMX_ErrorNone) {
656 LogNT::getInstance()->debug(TAG,
657 "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error);
658 pthread_setcancelstate(oldcancelstate, NULL);
659 pthread_setcanceltype(oldcanceltype, NULL);
660 clock_mutex.unlock();
665 dispconf.pixel_x =parx;
666 dispconf.pixel_y=pary;
667 dispconf.set = OMX_DISPLAY_SET_PIXEL;
668 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
670 if (error != OMX_ErrorNone) {
671 LogNT::getInstance()->debug(TAG,
672 "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error);
673 pthread_setcancelstate(oldcancelstate, NULL);
674 pthread_setcanceltype(oldcanceltype, NULL);
675 clock_mutex.unlock();
681 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
684 dispconf.fullscreen = OMX_TRUE;
686 dispconf.fullscreen = OMX_FALSE;
688 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
690 if (error != OMX_ErrorNone) {
691 LogNT::getInstance()->debug(TAG,
692 "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error);
693 pthread_setcancelstate(oldcancelstate, NULL);
694 pthread_setcanceltype(oldcanceltype, NULL);
695 clock_mutex.unlock();
699 dispconf.set = OMX_DISPLAY_SET_MODE;
701 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
702 : OMX_DISPLAY_MODE_LETTERBOX;
704 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
706 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion,
708 if (error != OMX_ErrorNone) {
709 LogNT::getInstance()->debug(TAG,
710 "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error);
711 pthread_setcancelstate(oldcancelstate, NULL);
712 pthread_setcanceltype(oldcanceltype, NULL);
713 clock_mutex.unlock();
718 unsigned int display_width, display_height;
719 display_width = display_height = 0;
720 if (graphics_get_display_size(0, &display_width, &display_height)
722 LogNT::getInstance()->warn(TAG,
723 "Getting display size failed! (BCM API) ");
724 pthread_setcancelstate(oldcancelstate, NULL);
725 pthread_setcanceltype(oldcanceltype, NULL);
726 clock_mutex.unlock();
729 //UnSetFullscreen with window
730 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
731 dispconf.dest_rect.x_offset
732 = (int) (xpos * ((float) display_width));
733 dispconf.dest_rect.y_offset = (int) (ypos
734 * ((float) display_height));
735 dispconf.dest_rect.width = (int) (width * ((float) display_width));
736 dispconf.dest_rect.height = (int) (height * ((float) display_height));
737 LogNT::getInstance()->debug(TAG,
738 "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset,
739 dispconf.dest_rect.width , dispconf.dest_rect.height);
741 error = OMX_SetParameter(omx_vid_rend,
742 OMX_IndexConfigDisplayRegion, &dispconf);
743 if (error != OMX_ErrorNone) {
744 LogNT::getInstance()->debug(TAG,
745 "Set OMX_IndexConfigDisplayRegion failed {:#x}", error);
746 pthread_setcancelstate(oldcancelstate, NULL);
747 pthread_setcanceltype(oldcanceltype, NULL);
748 clock_mutex.unlock();
752 pthread_setcancelstate(oldcancelstate, NULL);
753 pthread_setcanceltype(oldcanceltype, NULL);
756 clock_mutex.unlock();
759 int VideoOMX::signalOff()
762 LogNT::getInstance()->info(TAG, "signalOff");
763 Osd::getInstance()->stopUpdate(); // turn off drawing thread
764 InputMan::getInstance()->shutdown();
766 InputMan::getInstance()->init(); // FIXME
771 int VideoOMX::signalOn()
774 Osd::getInstance()->shutdown();
775 LogNT::getInstance()->info(TAG, "signalOn");
777 Osd::getInstance()->restore();
778 Osd::getInstance()->init();
779 BoxStack::getInstance()->redrawAllBoxes();
786 int VideoOMX::setSource()
788 if (!initted) return 0;
790 // What does this do...
791 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
795 int VideoOMX::setPosition(int x, int y) {
798 xpos = ((float) x*2.f) / ((float) screenWidth);
799 ypos = ((float) y*2.f) / ((float) screenHeight);
807 if (!initted) return 0;
809 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
813 void VideoOMX::interlaceSwitch4Demux() {
815 Demuxer *demux=Demuxer::getInstance();
817 if (hdmi) { // only switch if hdmi and HD or interlaced SD material
821 int set_interlaced=0;
822 if (demux->getHorizontalSize()>720 && demux->getInterlaced()) {
825 LogNT::getInstance()->info(TAG, "switch interlacing {} {} {}",demux->getInterlaced(),outputinterlaced,set_interlaced);
826 if (outputinterlaced!=set_interlaced) {
827 selectVideoMode(set_interlaced);
828 Osd::getInstance()->shutdown();
829 Osd::getInstance()->restore();
830 Osd::getInstance()->init();
831 BoxStack::getInstance()->redrawAllBoxes();
843 int VideoOMX::play() {
847 logger->debug(TAG, "enter play");
849 interlaceSwitch4Demux();
851 if (AllocateCodecsOMX()) {
853 // Otherwise fall back to libav
857 LogNT::getInstance()->info(TAG,
858 "Allocate Codecs OMX failed assume h264 unsupported");
861 LogNT::getInstance()->info(TAG,
862 "Allocate Codecs OMX failed assume mpeg2 unsupported");
871 int VideoOMX::initClock()
875 if (clock_references==0)
878 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
879 omx_event_mutex.lock();
881 omx_event_mutex.unlock();
883 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
885 if (error!=OMX_ErrorNone) {
886 logger->debug(TAG, "Init OMX clock failed {:#x}", error);
887 clock_mutex.unlock();
888 DeAllocateCodecsOMX();
892 /* TODO Clock config to separate method */
893 OMX_PORT_PARAM_TYPE p_param;
894 memset(&p_param,0,sizeof(p_param));
895 p_param.nSize=sizeof(p_param);
896 p_param.nVersion.nVersion=OMX_VERSION;
897 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
898 if (error!=OMX_ErrorNone) {
899 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
900 clock_mutex.unlock();
901 DeAllocateCodecsOMX();
904 omx_clock_output_port=p_param.nStartPortNumber;
906 for (unsigned int i=0;i<p_param.nPorts;i++) {
907 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
908 logger->debug(TAG, "Disable Ports OMX clock failed {}",i);
909 clock_mutex.unlock();
910 DeAllocateCodecsOMX();
919 logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
921 clock_mutex.unlock();
925 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
929 *p_omx_clock_output_port=0;
936 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
937 memset(&refclock,0,sizeof(refclock));
938 refclock.nSize=sizeof(refclock);
939 refclock.nVersion.nVersion=OMX_VERSION;
941 refclock.eClock=OMX_TIME_RefClockAudio;
943 //refclock.eClock=OMX_TIME_RefClockVideo;
944 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
945 if (error!=OMX_ErrorNone){
946 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
947 clock_mutex.unlock();
948 DeAllocateCodecsOMX();
952 OMX_PORT_PARAM_TYPE p_param;
953 memset(&p_param,0,sizeof(p_param));
954 p_param.nSize=sizeof(p_param);
955 p_param.nVersion.nVersion=OMX_VERSION;
956 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
957 if (error!=OMX_ErrorNone){
958 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
959 clock_mutex.unlock();
960 DeAllocateCodecsOMX();
964 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
965 memset(&clock_conf,0,sizeof(clock_conf));
966 clock_conf.nSize=sizeof(clock_conf);
967 clock_conf.nVersion.nVersion=OMX_VERSION;
968 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
969 clock_conf.nStartTime=intToOMXTicks(0);
970 clock_conf.nOffset=intToOMXTicks(0);
971 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
972 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
973 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
974 if (error!=OMX_ErrorNone) {
975 logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
979 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
980 *p_omx_clock=omx_clock;
981 clock_mutex.unlock();
985 int VideoOMX::getClockVideoandInit()
994 if (clock_references==1) { // only if no audio is attached to this clock!
995 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
996 memset(&refclock,0,sizeof(refclock));
997 refclock.nSize=sizeof(refclock);
998 refclock.nVersion.nVersion=OMX_VERSION;
1000 //refclock.eClock=OMX_TIME_RefClockAudio;
1002 refclock.eClock=OMX_TIME_RefClockVideo;
1003 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1004 if (error!=OMX_ErrorNone) {
1005 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1006 clock_mutex.unlock();
1007 DeAllocateCodecsOMX();
1012 OMX_PORT_PARAM_TYPE p_param;
1013 memset(&p_param,0,sizeof(p_param));
1014 p_param.nSize=sizeof(p_param);
1015 p_param.nVersion.nVersion=OMX_VERSION;
1016 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1017 if (error!=OMX_ErrorNone){
1018 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1019 clock_mutex.unlock();
1020 DeAllocateCodecsOMX();
1025 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1026 memset(&clock_conf,0,sizeof(clock_conf));
1027 clock_conf.nSize=sizeof(clock_conf);
1028 clock_conf.nVersion.nVersion=OMX_VERSION;
1029 clock_conf.eState=OMX_TIME_ClockStateStopped;
1030 clock_conf.nStartTime=intToOMXTicks(0);
1031 clock_conf.nOffset=intToOMXTicks(0);
1032 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1033 if (error!=OMX_ErrorNone) {
1034 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1038 memset(&clock_conf,0,sizeof(clock_conf));
1039 clock_conf.nSize=sizeof(clock_conf);
1040 clock_conf.nVersion.nVersion=OMX_VERSION;
1041 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1042 clock_conf.nStartTime=intToOMXTicks(0);
1043 clock_conf.nOffset=intToOMXTicks(0);
1044 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1045 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1046 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1047 if (error!=OMX_ErrorNone) {
1048 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1051 omx_clock_output_port=p_param.nStartPortNumber;
1052 clock_mutex.unlock();
1057 void VideoOMX::clockUnpause()
1059 OMX_ERRORTYPE error;
1060 LogNT::getInstance()->info(TAG, "enter Clockunpause");
1062 if (clock_references>0 && clockpaused) {
1063 OMX_TIME_CONFIG_SCALETYPE scale_type;
1064 memset(&scale_type,0,sizeof(scale_type));
1065 scale_type.nSize=sizeof(scale_type);
1066 scale_type.nVersion.nVersion=OMX_VERSION;
1067 scale_type.xScale=1<<16;
1068 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1069 if (error!=OMX_ErrorNone) {
1070 logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1072 LogNT::getInstance()->info(TAG, "set playback speed ClockUnpause");
1075 clock_mutex.unlock();
1079 void VideoOMX::clockPause()
1081 OMX_ERRORTYPE error;
1082 LogNT::getInstance()->info(TAG, "enter ClockPause");
1084 if (clock_references>0 && !clockpaused) {
1085 OMX_TIME_CONFIG_SCALETYPE scale_type;
1086 memset(&scale_type,0,sizeof(scale_type));
1087 scale_type.nSize=sizeof(scale_type);
1088 scale_type.nVersion.nVersion=OMX_VERSION;
1089 scale_type.xScale=0;
1090 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1091 if (error!=OMX_ErrorNone) {
1092 logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1094 LogNT::getInstance()->info(TAG, "set playback speed ClockPause");
1097 clock_mutex.unlock();
1102 int VideoOMX::AllocateCodecsOMX()
1104 OMX_ERRORTYPE error;
1105 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1107 Demuxer* demux=Demuxer::getInstance();
1112 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
1113 //Clock, move later to audio including events
1115 LogNT::getInstance()->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1116 if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) {
1120 LogNT::getInstance()->info(TAG, "Deinterlacing activated {}",deinterlace);
1125 if (!getClockVideoandInit()){
1126 return 0;// get the clock and init it if necessary
1131 logger->debug(TAG, "idleClock failed");
1138 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1140 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1143 if (error!=OMX_ErrorNone){
1144 logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1145 clock_mutex.unlock();
1146 DeAllocateCodecsOMX();
1151 logger->debug(TAG, "Nmark3 ");
1152 OMX_PORT_PARAM_TYPE p_param;
1153 memset(&p_param,0,sizeof(p_param));
1154 p_param.nSize=sizeof(p_param);
1155 p_param.nVersion.nVersion=OMX_VERSION;
1156 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1157 if (error!=OMX_ErrorNone){
1158 logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1159 clock_mutex.unlock();
1160 DeAllocateCodecsOMX();
1163 omx_codec_input_port=p_param.nStartPortNumber;
1164 omx_codec_output_port=p_param.nStartPortNumber+1;
1166 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1167 logger->debug(TAG, "Disable Ports OMX video decoder failed");
1168 clock_mutex.unlock();
1169 DeAllocateCodecsOMX();
1173 logger->debug(TAG, "Nmark4 ");
1175 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1176 memset(&conceal,0,sizeof(conceal));
1177 conceal.nSize=sizeof(conceal);
1178 conceal.nVersion.nVersion=OMX_VERSION;
1179 conceal.bStartWithValidFrame=OMX_FALSE;
1181 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1182 if (error!=OMX_ErrorNone){
1183 logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1184 clock_mutex.unlock();
1185 DeAllocateCodecsOMX();
1190 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1192 if (error != OMX_ErrorNone) {
1193 LogNT::getInstance()->debug(TAG,
1194 "Init OMX video deinterlacer failed {:#x}", error);
1195 clock_mutex.unlock();
1196 DeAllocateCodecsOMX();
1200 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1202 if (error != OMX_ErrorNone) {
1203 LogNT::getInstance()->debug(TAG,
1204 "Init OMX video deinterlacer OMX_GetParameter failed {:#x}",
1206 clock_mutex.unlock();
1207 DeAllocateCodecsOMX();
1210 omx_deint_input_port = p_param.nStartPortNumber;
1211 omx_deint_output_port = p_param.nStartPortNumber + 1;
1213 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1214 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1215 LogNT::getInstance()->debug(TAG,
1216 "Disable Ports OMX video deint failed");
1217 clock_mutex.unlock();
1218 DeAllocateCodecsOMX();
1225 error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1226 if (error!=OMX_ErrorNone){
1227 logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1228 clock_mutex.unlock();
1229 DeAllocateCodecsOMX();
1235 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1236 if (error!=OMX_ErrorNone){
1237 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1238 clock_mutex.unlock();
1239 DeAllocateCodecsOMX();
1242 omx_shed_input_port=p_param.nStartPortNumber;
1243 omx_shed_output_port=p_param.nStartPortNumber+1;
1246 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1247 if (error!=OMX_ErrorNone){
1248 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1249 clock_mutex.unlock();
1250 DeAllocateCodecsOMX();
1253 omx_shed_clock_port=p_param.nStartPortNumber;
1254 logger->debug(TAG, "scheduler ports {} {} {}",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1257 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1258 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1259 logger->debug(TAG, "Disable Ports OMX video shed failed");
1260 clock_mutex.unlock();
1261 DeAllocateCodecsOMX();
1266 error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1267 if (error!=OMX_ErrorNone){
1268 logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1269 clock_mutex.unlock();
1270 DeAllocateCodecsOMX();
1274 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1275 if (error!=OMX_ErrorNone){
1276 logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1277 clock_mutex.unlock();
1278 DeAllocateCodecsOMX();
1281 omx_rend_input_port=p_param.nStartPortNumber;
1282 //omx_rend_output_port=p_param.nStartPortNumber+1;
1285 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1287 logger->debug(TAG, "Disable Ports OMX video rend failed");
1288 clock_mutex.unlock();
1289 DeAllocateCodecsOMX();
1297 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1298 if (error!=OMX_ErrorNone){
1299 logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error,omx_clock_output_port,omx_shed_clock_port);
1300 clock_mutex.unlock();
1301 DeAllocateCodecsOMX();
1305 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1307 logger->debug(TAG, "Enable Ports OMX clock shed failed");
1308 clock_mutex.unlock();
1309 DeAllocateCodecsOMX();
1315 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1316 logger->debug(TAG, "vid_sched idle ChangeComponentState");
1317 clock_mutex.unlock();
1318 DeAllocateCodecsOMX();
1325 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1326 clock_mutex.unlock();
1327 DeAllocateCodecsOMX();
1335 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1336 clock_mutex.unlock();
1337 DeAllocateCodecsOMX();
1343 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1344 if (error!=OMX_ErrorNone){
1345 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1349 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1350 memset(&ft_type,0,sizeof(ft_type));
1351 ft_type.nSize=sizeof(ft_type);
1352 ft_type.nVersion.nVersion=OMX_VERSION;
1354 ft_type.nPortIndex=omx_codec_input_port;
1356 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1358 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1363 ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1364 logger->debug(TAG, "Framerate: {}",demux->getFrameRate());
1365 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1366 if (error!=OMX_ErrorNone){
1367 logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1368 clock_mutex.unlock();
1369 DeAllocateCodecsOMX();
1374 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1375 logger->debug(TAG, "vid_dec ChangeComponentState");
1376 clock_mutex.unlock();
1377 DeAllocateCodecsOMX();
1381 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1382 memset(&stall_conf,0,sizeof(stall_conf));
1383 stall_conf.nSize=sizeof(stall_conf);
1384 stall_conf.nVersion.nVersion=OMX_VERSION;
1385 stall_conf.nPortIndex=omx_codec_output_port;
1386 stall_conf.nDelay=1500*1000;
1387 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1388 if (error!=OMX_ErrorNone){
1389 logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1390 clock_mutex.unlock();
1391 DeAllocateCodecsOMX();
1394 omx_vid_stalled = false;
1396 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1397 memset(&req_callback,0,sizeof(req_callback));
1398 req_callback.nSize=sizeof(req_callback);
1399 req_callback.nVersion.nVersion=OMX_VERSION;
1400 req_callback.nPortIndex=omx_codec_output_port;
1401 req_callback.nIndex=OMX_IndexConfigBufferStall;
1402 req_callback.bEnable=OMX_TRUE;
1403 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1404 if (error!=OMX_ErrorNone){
1405 logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error);
1406 clock_mutex.unlock();
1407 DeAllocateCodecsOMX();
1413 if (!PrepareInputBufsOMX()) {
1414 clock_mutex.unlock();
1415 DeAllocateCodecsOMX();
1420 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1421 if (error!=OMX_ErrorNone){
1422 logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1423 clock_mutex.unlock();
1424 DeAllocateCodecsOMX();
1430 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1432 logger->debug(TAG, "Enable Ports OMX codec shed failed");
1433 clock_mutex.unlock();
1434 DeAllocateCodecsOMX();
1438 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1439 clock_mutex.unlock();
1440 DeAllocateCodecsOMX();
1446 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1447 if (error!=OMX_ErrorNone){
1448 logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1449 clock_mutex.unlock();
1450 DeAllocateCodecsOMX();
1456 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1458 logger->debug(TAG, "Enable Ports OMX codec deint failed");
1459 clock_mutex.unlock();
1460 DeAllocateCodecsOMX();
1464 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1465 clock_mutex.unlock();
1466 DeAllocateCodecsOMX();
1470 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1471 logger->debug(TAG, "vid_deint ChangeComponentState");
1472 clock_mutex.unlock();
1473 DeAllocateCodecsOMX();
1477 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1478 memset(&imagefilter,0,sizeof(imagefilter));
1479 imagefilter.nSize=sizeof(imagefilter);
1480 imagefilter.nVersion.nVersion=OMX_VERSION;
1482 imagefilter.nPortIndex=omx_deint_output_port;
1483 imagefilter.nNumParams=4;
1484 imagefilter.nParams[0]=3;//???
1485 imagefilter.nParams[1]=0;//default frame interval
1486 imagefilter.nParams[2]=0;// frame rate
1487 if (demux->getHorizontalSize() <= 720){
1488 imagefilter.nParams[3] = 1;//use qpus
1492 imagefilter.nParams[3] = 0;//use qpus
1495 switch (deinterlace) {
1497 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1499 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1501 imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1503 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1507 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1508 if (error!=OMX_ErrorNone){
1509 logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1510 clock_mutex.unlock();
1511 DeAllocateCodecsOMX();
1516 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1517 if (error!=OMX_ErrorNone){
1518 logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1519 clock_mutex.unlock();
1520 DeAllocateCodecsOMX();
1524 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1526 logger->debug(TAG, "Enable Ports OMX deint shed failed");
1527 clock_mutex.unlock();
1528 DeAllocateCodecsOMX();
1532 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1533 clock_mutex.unlock();
1534 DeAllocateCodecsOMX();
1540 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1541 logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1542 clock_mutex.unlock();
1543 DeAllocateCodecsOMX();
1547 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1548 if (error!=OMX_ErrorNone){
1549 logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error);
1550 clock_mutex.unlock();
1551 DeAllocateCodecsOMX();
1555 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1557 logger->debug(TAG, "Enable Ports OMX shed rend failed");
1558 clock_mutex.unlock();
1559 DeAllocateCodecsOMX();
1563 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1564 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1565 clock_mutex.unlock();
1566 DeAllocateCodecsOMX();
1570 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1571 logger->debug(TAG, "vid_rend ChangeComponentState");
1572 clock_mutex.unlock();
1573 DeAllocateCodecsOMX();
1578 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1579 logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1580 clock_mutex.unlock();
1581 DeAllocateCodecsOMX();
1584 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1585 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1588 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1589 logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1590 clock_mutex.unlock();
1591 DeAllocateCodecsOMX();
1595 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1596 logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1597 clock_mutex.unlock();
1598 DeAllocateCodecsOMX();
1603 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1604 memset(&dispconf,0,sizeof(dispconf));
1605 dispconf.nSize=sizeof(dispconf);
1606 dispconf.nVersion.nVersion=OMX_VERSION;
1608 dispconf.nPortIndex=omx_rend_input_port;
1610 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1612 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1613 if (error!=OMX_ErrorNone){
1614 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1615 clock_mutex.unlock();
1616 DeAllocateCodecsOMX();
1620 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1621 dispconf.fullscreen=OMX_FALSE;
1622 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1623 if (error!=OMX_ErrorNone){
1624 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1625 clock_mutex.unlock();
1626 DeAllocateCodecsOMX();
1630 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1631 dispconf.dest_rect.x_offset=100;
1632 dispconf.dest_rect.y_offset=100;
1633 dispconf.dest_rect.width=640;
1634 dispconf.dest_rect.height=480;
1635 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1636 if (error!=OMX_ErrorNone){
1637 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1638 clock_mutex.unlock();
1639 DeAllocateCodecsOMX();
1644 //playbacktimeoffset=-GetCurrentSystemTime();
1648 clock_mutex.unlock();
1652 setClockExecutingandRunning();
1661 int VideoOMX::idleClock()
1663 //OMX_ERRORTYPE error;
1664 OMX_STATETYPE temp_state;
1666 OMX_GetState(omx_clock,&temp_state);
1668 if (temp_state!=OMX_StateIdle) {
1669 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1670 logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1671 clock_mutex.unlock();
1675 clock_mutex.unlock();
1679 int VideoOMX::setClockExecutingandRunning()
1681 OMX_ERRORTYPE error;
1682 OMX_STATETYPE temp_state;
1684 OMX_GetState(omx_clock,&temp_state);
1686 if (temp_state!=OMX_StateExecuting) {
1687 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1688 logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1689 clock_mutex.unlock();
1690 DeAllocateCodecsOMX();
1695 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1696 memset(&clock_conf,0,sizeof(clock_conf));
1697 clock_conf.nSize=sizeof(clock_conf);
1698 clock_conf.nVersion.nVersion=OMX_VERSION;
1699 clock_conf.eState=OMX_TIME_ClockStateRunning;
1700 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1701 if (error!=OMX_ErrorNone) {
1702 logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1703 clock_mutex.unlock();
1704 DeAllocateCodecsOMX();
1707 clock_mutex.unlock();
1713 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1715 OMX_ERRORTYPE error;
1716 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1717 if (error!=OMX_ErrorNone){
1718 logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}",handle,type, error);
1723 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1732 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1734 OMX_ERRORTYPE error;
1737 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1738 memset(&pdt,0,sizeof(pdt));
1739 pdt.nSize=sizeof(pdt);
1740 pdt.nVersion.nVersion=OMX_VERSION;
1741 pdt.nPortIndex=port;
1742 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1743 if (error==OMX_ErrorNone) {
1744 if(pdt.bEnabled==OMX_TRUE) {
1745 skip=true; //already disabled;
1751 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1752 if (error!=OMX_ErrorNone){
1753 logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}",handle,port, error);
1757 if (!wait) return 1;
1758 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1767 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1769 OMX_ERRORTYPE error;
1772 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1773 memset(&pdt,0,sizeof(pdt));
1774 pdt.nSize=sizeof(pdt);
1775 pdt.nVersion.nVersion=OMX_VERSION;
1776 pdt.nPortIndex=port;
1777 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1778 if (error==OMX_ErrorNone) {
1779 if(pdt.bEnabled==OMX_FALSE) {
1780 skip=true; //already disabled;
1787 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1788 if (error!=OMX_ErrorNone){
1789 logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}",handle,port, error);
1793 if (!wait) return 1;
1794 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1802 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1805 int iend=(wait/5+1);
1807 omx_event_mutex.lock();
1808 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1809 while (itty!=omx_events.end()) {
1811 VPE_OMX_EVENT current=*itty;
1812 if (current.handle==handle) { //this is ours
1813 if (current.event_type==OMX_EventError) {
1814 omx_events.erase(itty);
1815 omx_event_mutex.unlock();
1816 logger->debug(TAG, "WaitForEvent Finished on Error");
1819 } else if (current.event_type==event) {
1820 omx_events.erase(itty);
1821 omx_event_mutex.unlock();
1822 logger->debug(TAG, "WaitForEvent Finished Completed");
1829 omx_event_mutex.unlock();
1831 //logger->debug(TAG, "WaitForEvent");
1832 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1833 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1839 logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}",(void*)handle,event);
1844 int VideoOMX::clearEvents()
1846 omx_event_mutex.lock();
1848 omx_event_mutex.unlock();
1853 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1855 omx_event_mutex.lock();
1856 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1857 while (itty!=omx_events.end()) {
1858 VPE_OMX_EVENT current=*itty;
1859 if (current.handle==handle) { //this is ours
1860 itty=omx_events.erase(itty);
1866 omx_event_mutex.unlock();
1870 void VideoOMX::checkForStalledBuffers()
1872 //logger->debug(TAG, "Check stalled");
1874 omx_event_mutex.lock();
1875 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1876 while (itty!=omx_events.end()) {
1877 VPE_OMX_EVENT current=*itty;
1878 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1879 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1880 OMX_ERRORTYPE error;
1881 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1882 memset(&stall_conf,0,sizeof(stall_conf));
1883 stall_conf.nSize=sizeof(stall_conf);
1884 stall_conf.nVersion.nVersion=OMX_VERSION;
1885 stall_conf.nPortIndex=omx_codec_output_port;
1886 stall_conf.nDelay=200000;
1888 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1889 if (error!=OMX_ErrorNone){
1890 logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
1891 clock_mutex.unlock();
1892 omx_event_mutex.unlock();
1895 if (stall_conf.bStalled==OMX_TRUE) {
1896 omx_vid_stalled=true;
1897 logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
1899 omx_vid_stalled=false;
1900 logger->debug(TAG, "Video decoder unstalled! {}",stall_conf.nDelay);
1902 omx_events.erase(itty);
1907 omx_event_mutex.unlock();
1908 clock_mutex.unlock();
1914 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1917 while (i<200/*1000*/) {
1918 omx_event_mutex.lock();
1919 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1920 while (itty!=omx_events.end()) {
1922 VPE_OMX_EVENT current=*itty;
1923 if (current.handle==handle) { //this is ours
1924 if (current.event_type==OMX_EventError) {
1925 omx_events.erase(itty);
1926 omx_event_mutex.unlock();
1927 logger->debug(TAG, "Command Finished on Error {:#x}",current.data1);
1930 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1931 omx_events.erase(itty);
1932 omx_event_mutex.unlock();
1933 //logger->debug(TAG, "Command Finished Completed");
1940 omx_event_mutex.unlock();
1942 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1943 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1949 logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}",handle,command, data2);
1956 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1958 OMX_ERRORTYPE error;
1959 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1960 memset(&port_def_type,0,sizeof(port_def_type));
1961 port_def_type.nSize=sizeof(port_def_type);
1962 port_def_type.nVersion.nVersion=OMX_VERSION;
1963 port_def_type.nPortIndex=omx_codec_input_port;
1965 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1967 if (error!=OMX_ErrorNone){
1968 logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1970 /* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
1971 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1972 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1974 port_def_type.nBufferCountActual=100;
1975 port_def_type.nBufferSize=std::max(static_cast<int>(port_def_type.nBufferSize),150000); // for transcoder important
1977 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1979 if (error!=OMX_ErrorNone){
1980 logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1984 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1985 if (error!=OMX_ErrorNone){
1986 logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
1990 input_bufs_omx_mutex.lock();
1991 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1993 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1994 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1995 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1996 if (error!=OMX_ErrorNone){
1997 logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
1998 input_bufs_omx_mutex.unlock();
2001 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
2002 if (error!=OMX_ErrorNone){
2003 logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2004 input_bufs_omx_mutex.unlock();
2007 input_bufs_omx_all.push_back(buf_head);
2008 input_bufs_omx_free.push_back(buf_head);
2010 omx_first_frame=true;
2013 cur_input_buf_omx=NULL;
2014 input_bufs_omx_mutex.unlock();
2017 logger->debug(TAG, "PrepareInputBufsOMX mark3");
2018 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
2021 logger->debug(TAG, "PrepareInputBufsOMX mark4");
2026 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2028 OMX_ERRORTYPE error;
2030 cur_input_buf_omx=NULL;
2031 input_bufs_omx_mutex.lock();
2032 for (UINT i=0; i< input_bufs_omx_all.size();i++) {
2033 // free(input_bufs_omx_all[i]->pBuffer);
2034 // input_bufs_omx_all[i]->pBuffer=NULL;
2035 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
2036 if (error!=OMX_ErrorNone){
2037 logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2038 input_bufs_omx_mutex.unlock();
2043 input_bufs_omx_all.clear();
2044 input_bufs_omx_free.clear();
2045 input_bufs_omx_mutex.unlock();
2052 int VideoOMX::FlushRenderingPipe()
2054 OMX_ERRORTYPE error;
2058 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2059 omx_codec_output_port, NULL);
2060 if (error != OMX_ErrorNone) {
2061 LogNT::getInstance()->debug(TAG,
2062 "OMX_Flush codec out 1 failed {:#x}", error);
2066 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2067 omx_shed_input_port, NULL);
2068 if (error != OMX_ErrorNone) {
2069 LogNT::getInstance()->debug(TAG,
2070 "OMX_Flush shed in 2 failed {:#x}", error);
2074 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2075 omx_codec_output_port)) {
2076 LogNT::getInstance()->debug(TAG,
2077 "flush cmd codec 3 failed");
2080 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2081 omx_shed_input_port)) {
2082 LogNT::getInstance()->debug(TAG,
2083 "flush cmd shed 4 failed");
2086 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2087 omx_codec_output_port, NULL);
2088 if (error != OMX_ErrorNone) {
2089 LogNT::getInstance()->debug(TAG,
2090 "OMX_Flush codec out 5 failed {:#x}", error);
2094 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2095 omx_deint_input_port, NULL);
2096 if (error != OMX_ErrorNone) {
2097 LogNT::getInstance()->debug(TAG,
2098 "OMX_Flush deint in 6 failed {:#x}", error);
2102 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2103 omx_codec_output_port)) {
2104 LogNT::getInstance()->debug(TAG,
2105 "flush cmd codec 7 failed");
2108 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2109 omx_deint_input_port)) {
2110 LogNT::getInstance()->debug(TAG,
2111 "flush cmd deint 8 failed");
2115 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2116 omx_deint_output_port, NULL);
2117 if (error != OMX_ErrorNone) {
2118 LogNT::getInstance()->debug(TAG,
2119 "OMX_Flush deint out 9 failed {:#x}", error);
2123 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2124 omx_shed_input_port, NULL);
2125 if (error != OMX_ErrorNone) {
2126 LogNT::getInstance()->debug(TAG,
2127 "OMX_Flush shed in 10 failed {:#x}", error);
2131 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2132 omx_deint_output_port)) {
2133 LogNT::getInstance()->debug(TAG,
2134 "flush cmd deint 11 failed");
2137 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2138 omx_shed_input_port)) {
2139 LogNT::getInstance()->debug(TAG,
2140 "flush cmd shed 12 failed");
2148 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2149 omx_rend_input_port, NULL);
2150 if (error != OMX_ErrorNone) {
2151 LogNT::getInstance()->debug(TAG,
2152 "OMX_Flush rend in failed {:#x}", error);
2156 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2157 omx_shed_output_port, NULL);
2158 if (error != OMX_ErrorNone) {
2159 LogNT::getInstance()->debug(TAG,
2160 "OMX_Flush shed out failed {:#x}", error);
2166 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2167 omx_rend_input_port)) {
2168 LogNT::getInstance()->debug(TAG,
2169 "flush cmd shed rend failed");
2172 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2173 omx_shed_output_port)) {
2174 LogNT::getInstance()->debug(TAG,
2175 "flush cmd shed rend failed");
2182 int VideoOMX::DeAllocateCodecsOMX()
2184 OMX_ERRORTYPE error;
2186 logger->debug(TAG, "enter deallocatecodecsomx");
2188 if (cur_input_buf_omx) {
2189 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2190 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2191 if (error!=OMX_ErrorNone) {
2192 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2195 cur_input_buf_omx=NULL;//write out old data
2200 // first stop the omx elements
2201 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2202 logger->debug(TAG, "vid_dec ChangeComponentState");
2205 clock_mutex.unlock();
2211 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2212 LogNT::getInstance()->debug(TAG,
2213 "vid_deint ChangeComponentState");
2219 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2220 logger->debug(TAG, "vid_shed ChangeComponentState");
2224 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2225 logger->debug(TAG, "vid_rend ChangeComponentState");
2231 // TODO proper deinit sequence
2232 // first flush all buffers
2233 FlushRenderingPipe();
2239 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2240 if (error!=OMX_ErrorNone){
2241 logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2245 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2246 if (error!=OMX_ErrorNone){
2247 logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2251 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2252 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2253 logger->debug(TAG, "flush cmd clock shed failed");
2259 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2260 omx_codec_input_port, NULL);
2261 if (error != OMX_ErrorNone) {
2262 LogNT::getInstance()->debug(TAG,
2263 "OMX_Flush codec out failed {:#x}", error);
2270 DestroyInputBufsOMX();
2273 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2274 logger->debug(TAG, "Disable Tunnel Port failed 2");
2276 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2277 logger->debug(TAG, "Disable Tunnel Port failed 1");
2283 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2284 logger->debug(TAG, "Disable Tunnel Port failed 6");
2289 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2290 logger->debug(TAG, "Disable Tunnel Port failed 7");
2294 if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2295 logger->debug(TAG, "Disable Tunnel Port failed 6a");
2300 if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2301 logger->debug(TAG, "Disable Tunnel Port failed 7a");
2307 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2308 logger->debug(TAG, "Disable Tunnel Port failed 3");
2311 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2312 logger->debug(TAG, "Disable Tunnel Port failed 4");
2315 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2316 logger->debug(TAG, "Disable Tunnel Port failed 5");
2322 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2323 if (error!=OMX_ErrorNone) {
2324 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2329 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2330 if (error!=OMX_ErrorNone) {
2331 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2335 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2336 if (error!=OMX_ErrorNone) {
2337 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2341 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2342 if (error!=OMX_ErrorNone) {
2343 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2348 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2349 if (error!=OMX_ErrorNone) {
2350 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2354 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2355 if (error!=OMX_ErrorNone) {
2356 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2361 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2362 if (error!=OMX_ErrorNone) {
2363 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2367 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2368 if (error!=OMX_ErrorNone) {
2369 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2376 error=OMX_FreeHandle(omx_vid_dec);
2377 error=OMX_FreeHandle(omx_vid_sched);
2378 error=OMX_FreeHandle(omx_vid_rend);
2379 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2381 clock_mutex.unlock();
2383 if (error!=OMX_ErrorNone) {
2384 logger->debug(TAG, "FreeHandle failed {}", error);
2386 } else clock_mutex.unlock();
2387 logger->debug(TAG, "leave deallocate codecs OMX");
2393 void VideoOMX::destroyClock()
2396 if (clock_references>0) {
2398 if (clock_references==0) {
2399 OMX_ERRORTYPE error;
2400 logger->debug(TAG, "destroy omx clock");
2401 error=OMX_FreeHandle(omx_clock);
2402 if (error!=OMX_ErrorNone) {
2403 logger->debug(TAG, "FreeHandle failed {}", error);
2408 clock_mutex.unlock();
2412 int VideoOMX::stop()
2414 if (!initted) return 0;
2417 //Check if libav mode
2418 DeAllocateCodecsOMX();
2423 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2427 int VideoOMX::reset()
2429 if (!initted) return 0;
2432 DeAllocateCodecsOMX();
2433 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2437 int VideoOMX::pause()
2439 if (!initted) return 0;
2440 logger->debug(TAG, "enter pause");
2442 // ignore it audio handles this
2446 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2448 if (!initted) return 0;
2449 logger->debug(TAG, "enter unpause");
2452 //ignore it audio handles this
2457 int VideoOMX::fastForward()
2459 if (!initted) return 0;
2461 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2465 int VideoOMX::unFastForward()
2467 if (!initted) return 0;
2469 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2471 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2475 int VideoOMX::attachFrameBuffer()
2477 if (!initted) return 0;
2479 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2483 int VideoOMX::blank(void)
2485 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2486 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2490 ULLONG VideoOMX::getCurrentTimestamp() {
2493 long long ncur_clock_time = cur_clock_time;
2497 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2498 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2500 OMX_ERRORTYPE error;
2501 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2502 memset(&clock_conf, 0, sizeof(clock_conf));
2503 clock_conf.nSize = sizeof(clock_conf);
2504 clock_conf.nVersion.nVersion = OMX_VERSION;
2505 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2507 if (error != OMX_ErrorNone) {
2508 LogNT::getInstance()->debug(TAG,"getCurrentTimestamp IndexConfigTimeClockState failed {:#x}",error);
2511 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2513 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2514 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2515 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2516 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2517 cur_time_stamp.nPortIndex = omx_clock_output_port;
2518 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2520 if (error != OMX_ErrorNone) {
2521 LogNT::getInstance()->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}",error);
2523 long long temp = cur_time_stamp.nTimestamp.nLowPart
2524 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2525 ncur_clock_time = cur_clock_time = temp * 10LL;
2528 clock_mutex.unlock();
2529 pthread_setcancelstate(oldcancelstate, NULL);
2530 pthread_setcanceltype(oldcanceltype, NULL);
2533 //ncur_clock_time -= startoffset;
2534 ncur_clock_time -= lastreftimeOMX;
2535 long long result = lastreftimePTS;
2536 if (lastreftimePTS==0) return 0; // invalid time
2537 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2539 result = (1LL << 33) - result;
2540 //LogNT::getInstance()->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2548 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
2550 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2551 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
2556 int VideoOMX::test()
2561 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2568 int VideoOMX::test2()
2576 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2580 startoffset=curreftime;//offset is set for audio
2582 offsetvideonotset=false;
2584 if (offsetvideonotset) {
2585 offsetvideonotset=false;
2588 if ( (curreftime-lastrefvideotime)>10000000LL
2589 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2590 startoffset+=curreftime-lastrefvideotime;
2591 lastrefaudiotime+=curreftime-lastrefvideotime;
2593 offsetaudionotset=true;
2600 lastrefvideotime=curreftime;
2606 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2610 startoffset=curreftime;
2612 offsetaudionotset=false;
2614 if (offsetaudionotset) {
2615 offsetaudionotset=false;
2618 if ( (curreftime-lastrefaudiotime)>10000000LL
2619 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2620 startoffset+=curreftime-lastrefaudiotime;
2621 lastrefvideotime+=curreftime-lastrefaudiotime;
2623 offsetvideonotset=true;
2629 lastrefaudiotime=curreftime;
2634 void VideoOMX::ResetTimeOffsets() {
2635 offsetnotset=true; //called from demuxer
2636 offsetvideonotset=true;
2637 offsetaudionotset=true;
2646 void VideoOMX::FirstFrameFix()
2650 Demuxer* demux=Demuxer::getInstance();
2651 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2652 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2654 if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2655 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2656 OMX_ERRORTYPE error;
2657 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2658 memset(&port_def_type,0,sizeof(port_def_type));
2659 port_def_type.nSize=sizeof(port_def_type);
2660 port_def_type.nVersion.nVersion=OMX_VERSION;
2661 port_def_type.nPortIndex=omx_codec_output_port;
2663 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2664 if (error != OMX_ErrorNone) {
2665 LogNT::getInstance()->debug(TAG,
2666 "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2667 clock_mutex.unlock();
2672 LogNT::getInstance()->debug(TAG,
2673 "Deinit first frame fix {} {} {} {} {} {} {} {}",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2674 port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2675 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2676 port_def_type.format.video.bFlagErrorConcealment );
2677 LogNT::getInstance()->debug(TAG,
2678 "Deinit first frame fix2 {} {}",
2679 port_def_type.format.video.eCompressionFormat ,
2680 port_def_type.format.video.eColorFormat );
2683 // we cause the video_decode to determine the interlacing properties
2684 OMX_CONFIG_INTERLACETYPE il;
2685 memset(&il,0,sizeof(il));
2686 il.nSize=sizeof(il);
2687 il.nVersion.nVersion=OMX_VERSION;
2688 il.nPortIndex=omx_codec_output_port;
2689 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2690 if (error != OMX_ErrorNone) {
2691 LogNT::getInstance()->debug(TAG,
2692 "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2696 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2697 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2700 DisablePort(omx_vid_deint,omx_deint_input_port,true);
2701 // This is a dirty hack
2702 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2705 port_def_type.nPortIndex=omx_deint_output_port;
2706 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2708 if (error != OMX_ErrorNone) {
2709 LogNT::getInstance()->debug(TAG,
2710 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2711 clock_mutex.unlock();
2712 pthread_setcancelstate(oldcancelstate, NULL);
2713 pthread_setcanceltype(oldcanceltype, NULL);
2719 port_def_type.nPortIndex=omx_deint_input_port;
2720 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2722 if (error != OMX_ErrorNone) {
2723 LogNT::getInstance()->debug(TAG,
2724 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2725 clock_mutex.unlock();
2726 pthread_setcancelstate(oldcancelstate, NULL);
2727 pthread_setcanceltype(oldcanceltype, NULL);
2730 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2732 LogNT::getInstance()->debug(TAG,
2734 EnablePort(omx_vid_deint,omx_deint_input_port,true);
2735 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2736 port_def_type.nPortIndex=omx_deint_output_port;
2737 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2739 if (error != OMX_ErrorNone) {
2740 LogNT::getInstance()->debug(TAG,
2741 "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2742 clock_mutex.unlock();
2743 pthread_setcancelstate(oldcancelstate, NULL);
2744 pthread_setcanceltype(oldcanceltype, NULL);
2747 LogNT::getInstance()->debug(TAG,
2748 "Deinit first frame fix3 {} {} {} {} {} {} {} ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2749 port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2750 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2751 port_def_type.format.image.bFlagErrorConcealment );
2752 LogNT::getInstance()->debug(TAG,
2753 "Deinit first frame fix4 {} {}",
2754 port_def_type.format.image.eCompressionFormat ,
2755 port_def_type.format.image.eColorFormat );
2756 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2759 port_def_type.nPortIndex=omx_shed_input_port;
2760 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2762 if (error != OMX_ErrorNone) {
2763 LogNT::getInstance()->debug(TAG,
2764 "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2765 clock_mutex.unlock();
2766 pthread_setcancelstate(oldcancelstate, NULL);
2767 pthread_setcanceltype(oldcanceltype, NULL);
2770 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2774 EnablePort(omx_vid_deint,omx_deint_output_port,true);
2776 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2777 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2779 clock_mutex.unlock();
2780 pthread_setcancelstate(oldcancelstate, NULL);
2781 pthread_setcanceltype(oldcanceltype, NULL);
2788 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2791 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2792 if (error != OMX_ErrorNone) {
2793 LogNT::getInstance()->debug(TAG,
2794 "OMX_EmptyThisBuffer failed {:#x}", error);
2796 if (first_frame) FirstFrameFix();
2800 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2802 // protect the call to empty this buffer
2805 /* long long temp =buffer->nTimeStamp.nLowPart
2806 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2808 //pthread_testcancel();
2809 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2810 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2813 /* OMX_ERRORTYPE error;
2814 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2815 memset(×tamp, 0, sizeof(timestamp));
2816 timestamp.nSize = sizeof(timestamp);
2817 timestamp.nVersion.nVersion = OMX_VERSION;
2818 timestamp.nPortIndex =omx_clock_output_port;
2820 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2823 if (error != OMX_ErrorNone) {
2824 LogNT::getInstance()->debug(TAG,
2825 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
2826 omx_rend_input_port);
2828 long long temp2 =timestamp.nTimestamp.nLowPart
2829 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2832 LogNT::getInstance()->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
2833 OMX_ERRORTYPE ret_val;
2834 ret_val=OMX_EmptyThisBuffer(handle,buffer);
2835 clock_mutex.unlock();
2836 pthread_setcancelstate(oldcancelstate, NULL);
2837 pthread_setcanceltype(oldcanceltype, NULL);
2838 //pthread_testcancel();
2842 bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length)
2844 const UCHAR* curbuf=buffer;
2845 const UCHAR* curbufend=buffer+length;
2846 unsigned int detector=0xFFFFFFFF;
2847 bool gotaud=false; // have seen access unit delimiter
2849 while (curbuf!=curbufend) {
2853 if (detector==0x00000109) {
2855 detector=0xFFFFFFFF;
2856 } else if (gotaud &&detector==0x00000001) {
2858 if (curbuf!=curbufend) {
2859 unsigned char picttype=(*curbuf)& 0x1F;
2860 return picttype==0x07;
2864 if (detector==0x00000100) {
2866 if (curbuf==curbufend) return false;
2868 if (curbuf==curbufend) return false;
2869 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2876 return false; // no frame found
2881 bool VideoOMX::DrainTargetBufferFull()
2883 //Check, if we have OMX output buffers
2885 input_bufs_omx_mutex.lock();
2886 full=(input_bufs_omx_free.size()==0);
2887 input_bufs_omx_mutex.unlock();
2888 checkForStalledBuffers(); // check if the decoder has a problem
2889 if (full && omx_vid_stalled && !omx_first_frame) {
2890 omx_vid_stalled=false;
2891 logger->debug(TAG, "Decoder is stalled, do a reset!");
2895 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2896 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2899 FlushRenderingPipe();
2900 omx_first_frame=true;
2901 clock_mutex.unlock();
2903 pthread_setcancelstate(oldcancelstate, NULL);
2904 pthread_setcanceltype(oldcanceltype, NULL);
2910 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, UINT /* samplepos */)
2913 mediapackets.clear();
2914 std::list<MediaPacket>::const_iterator begin=mplist.begin();
2915 std::list<MediaPacket>::const_iterator itty=mplist.begin();
2916 advance(itty,std::min(mplist.size(),10U));
2917 mediapackets.insert(mediapackets.begin(),begin,itty);//front
2921 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2924 while (consumed < mediapackets.size()) {
2925 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2926 if (*samplepos == mediapackets[consumed].length) {
2930 } else return consumed;
2935 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
2936 const UCHAR* buffer,
2939 if (packet.type == MPTYPE_VIDEO_H264)
2949 //Later add fail back code for libav
2951 *samplepos+=packet.length;
2952 return packet.length;
2956 if (!omx_running) return 0; // if we are not runnig do not do this
2958 if (isClockPaused()) return 0; //Block if we pause
2960 // logger->debug(TAG, "DMP mark 1");
2961 //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
2964 /*First Check, if we have an video sample*/
2968 return 0; //Not in iframe mode!
2972 if (packet.disconti) {
2974 if (cur_input_buf_omx) {
2975 PutBufferToPres(cur_input_buf_omx);
2976 cur_input_buf_omx=NULL;
2979 //logger->debug(TAG, "DMP mark 2");
2980 /*Inspect PES-Header */
2982 // OMX_STATETYPE temp_state;
2983 // OMX_GetState(omx_vid_dec,&temp_state);
2985 if (*samplepos==0) {//stripheader
2986 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2987 // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
2988 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2989 *samplepos+=headerstrip;
2990 if (headerstrip>=packet.length) {
2991 *samplepos=packet.length;// Packet is obviously damaged
2992 return packet.length;//skip it!
2994 if ( packet.synched ) {
2995 if (!firstsynched) {
2996 //logger->debug(TAG, "DMP mark 2a");
2997 // check if this is an I frame, the decoder does not like non I frames at startup!
2998 if (!detectIFrame(buffer,packet.length)) {
2999 *samplepos=packet.length;//if we have not processed at least one
3000 //logger->debug(TAG, "DMP mark 3");
3001 return packet.length;//synched packet ignore it!
3004 if (cur_input_buf_omx) {
3005 //logger->debug(TAG, "DMP mark 4a");
3006 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3007 PutBufferToPres(cur_input_buf_omx);
3008 cur_input_buf_omx=NULL;//write out old data
3010 //logger->debug(TAG, "DMP mark 4b");
3015 if (!firstsynched) {//
3016 *samplepos=packet.length;//if we have not processed at least one
3017 //logger->debug(TAG, "DMP mark 5");
3018 return packet.length;//synched packet ignore it!
3022 //logger->debug(TAG, "DMP mark 6");
3023 if (!cur_input_buf_omx) {
3024 input_bufs_omx_mutex.lock();
3025 if (input_bufs_omx_free.size()==0) {
3026 input_bufs_omx_mutex.unlock();
3027 //logger->debug(TAG, "Deliver MediaPacket no free sample");
3028 //logger->debug(TAG, "DMP mark 7");
3029 return 0; // we do not have a free media sample
3032 cur_input_buf_omx=input_bufs_omx_free.front();
3033 cur_input_buf_omx->nFilledLen=0;
3034 cur_input_buf_omx->nOffset=0;
3035 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3036 input_bufs_omx_free.pop_front();
3037 input_bufs_omx_mutex.unlock();
3043 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3044 if (packet.synched) {
3045 // logger->debug(TAG, "packet synched marker");
3047 //lastreftimePTS=packet.pts;
3048 if (omx_first_frame) { // TODO time
3049 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3050 logger->debug(TAG, "Starttime");
3051 omx_first_frame=false;
3053 cur_input_buf_omx->nFlags=0;
3054 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3056 lastreftimeOMX=packet.presentation_time;
3057 // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3058 lastreftimePTS=packet.pts;
3059 cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3063 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3064 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3065 //logger->debug(TAG, "packet unsynched marker");
3067 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3072 unsigned int haveToCopy=packet.length-*samplepos;
3073 //logger->debug(TAG, "DMP mark 8");
3075 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3076 //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3077 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3078 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3079 haveToCopy-=cancopy;
3080 cur_input_buf_omx->nFilledLen+=cancopy;
3081 *samplepos+=cancopy;
3082 // push old buffer out
3083 //logger->debug(TAG, "DMP mark 9");
3085 PutBufferToPres(cur_input_buf_omx);
3086 cur_input_buf_omx=NULL;
3088 input_bufs_omx_mutex.lock();
3089 if (input_bufs_omx_free.size()==0) {
3090 input_bufs_omx_mutex.unlock();
3091 // logger->debug(TAG, "Deliver MediaPacket no free sample2");
3092 return *samplepos; // we do not have a free media sample
3094 cur_input_buf_omx=input_bufs_omx_free.front();
3095 cur_input_buf_omx->nFilledLen=0;
3096 cur_input_buf_omx->nOffset=0;
3097 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3098 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3099 input_bufs_omx_free.pop_front();
3100 input_bufs_omx_mutex.unlock();
3101 //logger->debug(TAG, "DMP mark 10");
3104 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3105 buffer+packet.pos_buffer+*samplepos,haveToCopy);
3106 cur_input_buf_omx->nFilledLen+=haveToCopy;
3108 // logger->debug(TAG, "DMP mark 11");
3110 *samplepos+=haveToCopy;
3119 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
3120 if (!omx_running) return false;
3122 EnterIframePlayback();
3124 //int haveToCopy = length;
3126 if (!cur_input_buf_omx) {
3127 input_bufs_omx_mutex.lock();
3128 if (input_bufs_omx_free.size() == 0) {
3129 input_bufs_omx_mutex.unlock();
3130 // LogNT::getInstance()->debug(TAG,
3131 // "Deliver MediaPacket no free sample");
3132 return false; // we do not have a free media sample
3135 cur_input_buf_omx = input_bufs_omx_free.front();
3136 cur_input_buf_omx->nFilledLen = 0;
3137 cur_input_buf_omx->nOffset = 0;
3138 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3139 input_bufs_omx_free.pop_front();
3140 input_bufs_omx_mutex.unlock();
3144 unsigned int pattern, packet_length;
3145 unsigned int headerstrip = 0;
3150 //Now we strip the pes header
3151 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3152 while ((read_pos + 7) <= length) {
3153 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3154 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3158 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3159 packet_length = ((buffer[read_pos + 4] << 8)
3160 | (buffer[read_pos + 5])) + 6;
3161 if (read_pos + packet_length > length)
3164 if ((headerstrip < packet_length)
3165 && (cur_input_buf_omx->nFilledLen + packet_length
3166 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3168 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3171 cur_input_buf_omx->nFlags
3172 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3175 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3176 PutBufferToPres(cur_input_buf_omx);
3177 cur_input_buf_omx = NULL;
3179 if (!cur_input_buf_omx) {
3181 while (count < 100 && omx_running && iframemode) {
3184 input_bufs_omx_mutex.lock();
3185 if (input_bufs_omx_free.size() == 0) {
3186 input_bufs_omx_mutex.unlock();
3187 // LogNT::getInstance()->debug(TAG,
3188 // "Ifrane no free sample");
3190 if (!omx_running) return false;
3193 cur_input_buf_omx = input_bufs_omx_free.front();
3194 cur_input_buf_omx->nFilledLen = 0;
3195 cur_input_buf_omx->nOffset = 0;
3196 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3197 cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3198 input_bufs_omx_free.pop_front();
3199 input_bufs_omx_mutex.unlock();
3202 if (!cur_input_buf_omx)
3207 if (packet_length > headerstrip) {
3209 cur_input_buf_omx->pBuffer
3210 + cur_input_buf_omx->nFilledLen,
3211 buffer + read_pos + headerstrip,
3212 packet_length - headerstrip);
3213 cur_input_buf_omx->nFilledLen += packet_length
3216 read_pos += packet_length;
3218 pattern = (buffer[read_pos] << 16)
3219 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3225 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3228 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3231 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3233 PutBufferToPres(cur_input_buf_omx);
3234 cur_input_buf_omx = NULL;
3237 MILLISLEEP(40); //Block a bit
3241 int VideoOMX::EnterIframePlayback()
3243 LogNT::getInstance()->debug(TAG,
3244 "EnterIframePlayback");
3245 if (cur_input_buf_omx) {
3246 PutBufferToPres(cur_input_buf_omx);
3247 cur_input_buf_omx = NULL;
3249 LogNT::getInstance()->debug(TAG,
3250 "EnterIframePlayback 2");
3251 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3252 DeAllocateCodecsOMX();
3253 AllocateCodecsOMX();
3254 LogNT::getInstance()->debug(TAG,
3255 "leave IframePlayback");