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(u1 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(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType,
357 u4 numChoices, u4 defaultChoice, u4 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(u1 ttvsize)
381 if (tvsize!=ttvsize) pendingmodechange=true;
386 u1 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(u1 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(u1 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(u1 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(u1 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 // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this
765 InputMan::getInstance()->shutdown();
767 InputMan::getInstance()->init();
772 int VideoOMX::signalOn()
775 Osd::getInstance()->shutdown();
776 LogNT::getInstance()->info(TAG, "signalOn");
778 Osd::getInstance()->restore();
779 Osd::getInstance()->init();
780 BoxStack::getInstance()->redrawAllBoxes();
787 int VideoOMX::setSource()
789 if (!initted) return 0;
791 // What does this do...
792 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
796 int VideoOMX::setPosition(int x, int y) {
799 xpos = ((float) x*2.f) / ((float) screenWidth);
800 ypos = ((float) y*2.f) / ((float) screenHeight);
808 if (!initted) return 0;
810 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
814 void VideoOMX::interlaceSwitch4Demux() {
816 Demuxer *demux=Demuxer::getInstance();
818 if (hdmi) { // only switch if hdmi and HD or interlaced SD material
822 int set_interlaced=0;
823 if (demux->getHorizontalSize()>720 && demux->getInterlaced()) {
826 LogNT::getInstance()->info(TAG, "switch interlacing {} {} {}",demux->getInterlaced(),outputinterlaced,set_interlaced);
827 if (outputinterlaced!=set_interlaced) {
828 selectVideoMode(set_interlaced);
829 Osd::getInstance()->shutdown();
830 Osd::getInstance()->restore();
831 Osd::getInstance()->init();
832 BoxStack::getInstance()->redrawAllBoxes();
844 int VideoOMX::play() {
848 logger->debug(TAG, "enter play");
850 interlaceSwitch4Demux();
852 if (AllocateCodecsOMX()) {
854 // Otherwise fall back to libav
858 LogNT::getInstance()->info(TAG,
859 "Allocate Codecs OMX failed assume h264 unsupported");
862 LogNT::getInstance()->info(TAG,
863 "Allocate Codecs OMX failed assume mpeg2 unsupported");
872 int VideoOMX::initClock()
876 if (clock_references==0)
879 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
880 omx_event_mutex.lock();
882 omx_event_mutex.unlock();
884 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
886 if (error!=OMX_ErrorNone) {
887 logger->debug(TAG, "Init OMX clock failed {:#x}", error);
888 clock_mutex.unlock();
889 DeAllocateCodecsOMX();
893 /* TODO Clock config to separate method */
894 OMX_PORT_PARAM_TYPE p_param;
895 memset(&p_param,0,sizeof(p_param));
896 p_param.nSize=sizeof(p_param);
897 p_param.nVersion.nVersion=OMX_VERSION;
898 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
899 if (error!=OMX_ErrorNone) {
900 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
901 clock_mutex.unlock();
902 DeAllocateCodecsOMX();
905 omx_clock_output_port=p_param.nStartPortNumber;
907 for (unsigned int i=0;i<p_param.nPorts;i++) {
908 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
909 logger->debug(TAG, "Disable Ports OMX clock failed {}",i);
910 clock_mutex.unlock();
911 DeAllocateCodecsOMX();
920 logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
922 clock_mutex.unlock();
926 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
930 *p_omx_clock_output_port=0;
937 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
938 memset(&refclock,0,sizeof(refclock));
939 refclock.nSize=sizeof(refclock);
940 refclock.nVersion.nVersion=OMX_VERSION;
942 refclock.eClock=OMX_TIME_RefClockAudio;
944 //refclock.eClock=OMX_TIME_RefClockVideo;
945 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
946 if (error!=OMX_ErrorNone){
947 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
948 clock_mutex.unlock();
949 DeAllocateCodecsOMX();
953 OMX_PORT_PARAM_TYPE p_param;
954 memset(&p_param,0,sizeof(p_param));
955 p_param.nSize=sizeof(p_param);
956 p_param.nVersion.nVersion=OMX_VERSION;
957 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
958 if (error!=OMX_ErrorNone){
959 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
960 clock_mutex.unlock();
961 DeAllocateCodecsOMX();
965 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
966 memset(&clock_conf,0,sizeof(clock_conf));
967 clock_conf.nSize=sizeof(clock_conf);
968 clock_conf.nVersion.nVersion=OMX_VERSION;
969 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
970 clock_conf.nStartTime=intToOMXTicks(0);
971 clock_conf.nOffset=intToOMXTicks(0);
972 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
973 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
974 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
975 if (error!=OMX_ErrorNone) {
976 logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
980 *p_omx_clock_output_port=p_param.nStartPortNumber+1;
981 *p_omx_clock=omx_clock;
982 clock_mutex.unlock();
986 int VideoOMX::getClockVideoandInit()
995 if (clock_references==1) { // only if no audio is attached to this clock!
996 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
997 memset(&refclock,0,sizeof(refclock));
998 refclock.nSize=sizeof(refclock);
999 refclock.nVersion.nVersion=OMX_VERSION;
1001 //refclock.eClock=OMX_TIME_RefClockAudio;
1003 refclock.eClock=OMX_TIME_RefClockVideo;
1004 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1005 if (error!=OMX_ErrorNone) {
1006 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1007 clock_mutex.unlock();
1008 DeAllocateCodecsOMX();
1013 OMX_PORT_PARAM_TYPE p_param;
1014 memset(&p_param,0,sizeof(p_param));
1015 p_param.nSize=sizeof(p_param);
1016 p_param.nVersion.nVersion=OMX_VERSION;
1017 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1018 if (error!=OMX_ErrorNone){
1019 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1020 clock_mutex.unlock();
1021 DeAllocateCodecsOMX();
1026 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1027 memset(&clock_conf,0,sizeof(clock_conf));
1028 clock_conf.nSize=sizeof(clock_conf);
1029 clock_conf.nVersion.nVersion=OMX_VERSION;
1030 clock_conf.eState=OMX_TIME_ClockStateStopped;
1031 clock_conf.nStartTime=intToOMXTicks(0);
1032 clock_conf.nOffset=intToOMXTicks(0);
1033 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1034 if (error!=OMX_ErrorNone) {
1035 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1039 memset(&clock_conf,0,sizeof(clock_conf));
1040 clock_conf.nSize=sizeof(clock_conf);
1041 clock_conf.nVersion.nVersion=OMX_VERSION;
1042 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1043 clock_conf.nStartTime=intToOMXTicks(0);
1044 clock_conf.nOffset=intToOMXTicks(0);
1045 if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1046 else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1047 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1048 if (error!=OMX_ErrorNone) {
1049 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1052 omx_clock_output_port=p_param.nStartPortNumber;
1053 clock_mutex.unlock();
1058 void VideoOMX::clockUnpause()
1060 OMX_ERRORTYPE error;
1061 LogNT::getInstance()->info(TAG, "enter Clockunpause");
1063 if (clock_references>0 && clockpaused) {
1064 OMX_TIME_CONFIG_SCALETYPE scale_type;
1065 memset(&scale_type,0,sizeof(scale_type));
1066 scale_type.nSize=sizeof(scale_type);
1067 scale_type.nVersion.nVersion=OMX_VERSION;
1068 scale_type.xScale=1<<16;
1069 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1070 if (error!=OMX_ErrorNone) {
1071 logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1073 LogNT::getInstance()->info(TAG, "set playback speed ClockUnpause");
1076 clock_mutex.unlock();
1080 void VideoOMX::clockPause()
1082 OMX_ERRORTYPE error;
1083 LogNT::getInstance()->info(TAG, "enter ClockPause");
1085 if (clock_references>0 && !clockpaused) {
1086 OMX_TIME_CONFIG_SCALETYPE scale_type;
1087 memset(&scale_type,0,sizeof(scale_type));
1088 scale_type.nSize=sizeof(scale_type);
1089 scale_type.nVersion.nVersion=OMX_VERSION;
1090 scale_type.xScale=0;
1091 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1092 if (error!=OMX_ErrorNone) {
1093 logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1095 LogNT::getInstance()->info(TAG, "set playback speed ClockPause");
1098 clock_mutex.unlock();
1103 int VideoOMX::AllocateCodecsOMX()
1105 OMX_ERRORTYPE error;
1106 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1108 Demuxer* demux=Demuxer::getInstance();
1113 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
1114 //Clock, move later to audio including events
1116 LogNT::getInstance()->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1117 if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) {
1121 LogNT::getInstance()->info(TAG, "Deinterlacing activated {}",deinterlace);
1126 if (!getClockVideoandInit()){
1127 return 0;// get the clock and init it if necessary
1132 logger->debug(TAG, "idleClock failed");
1139 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1141 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1144 if (error!=OMX_ErrorNone){
1145 logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1146 clock_mutex.unlock();
1147 DeAllocateCodecsOMX();
1152 logger->debug(TAG, "Nmark3 ");
1153 OMX_PORT_PARAM_TYPE p_param;
1154 memset(&p_param,0,sizeof(p_param));
1155 p_param.nSize=sizeof(p_param);
1156 p_param.nVersion.nVersion=OMX_VERSION;
1157 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1158 if (error!=OMX_ErrorNone){
1159 logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1160 clock_mutex.unlock();
1161 DeAllocateCodecsOMX();
1164 omx_codec_input_port=p_param.nStartPortNumber;
1165 omx_codec_output_port=p_param.nStartPortNumber+1;
1167 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1168 logger->debug(TAG, "Disable Ports OMX video decoder failed");
1169 clock_mutex.unlock();
1170 DeAllocateCodecsOMX();
1174 logger->debug(TAG, "Nmark4 ");
1176 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1177 memset(&conceal,0,sizeof(conceal));
1178 conceal.nSize=sizeof(conceal);
1179 conceal.nVersion.nVersion=OMX_VERSION;
1180 conceal.bStartWithValidFrame=OMX_FALSE;
1182 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1183 if (error!=OMX_ErrorNone){
1184 logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1185 clock_mutex.unlock();
1186 DeAllocateCodecsOMX();
1191 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1193 if (error != OMX_ErrorNone) {
1194 LogNT::getInstance()->debug(TAG,
1195 "Init OMX video deinterlacer failed {:#x}", error);
1196 clock_mutex.unlock();
1197 DeAllocateCodecsOMX();
1201 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1203 if (error != OMX_ErrorNone) {
1204 LogNT::getInstance()->debug(TAG,
1205 "Init OMX video deinterlacer OMX_GetParameter failed {:#x}",
1207 clock_mutex.unlock();
1208 DeAllocateCodecsOMX();
1211 omx_deint_input_port = p_param.nStartPortNumber;
1212 omx_deint_output_port = p_param.nStartPortNumber + 1;
1214 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1215 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1216 LogNT::getInstance()->debug(TAG,
1217 "Disable Ports OMX video deint failed");
1218 clock_mutex.unlock();
1219 DeAllocateCodecsOMX();
1226 error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1227 if (error!=OMX_ErrorNone){
1228 logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1229 clock_mutex.unlock();
1230 DeAllocateCodecsOMX();
1236 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1237 if (error!=OMX_ErrorNone){
1238 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1239 clock_mutex.unlock();
1240 DeAllocateCodecsOMX();
1243 omx_shed_input_port=p_param.nStartPortNumber;
1244 omx_shed_output_port=p_param.nStartPortNumber+1;
1247 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1248 if (error!=OMX_ErrorNone){
1249 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1250 clock_mutex.unlock();
1251 DeAllocateCodecsOMX();
1254 omx_shed_clock_port=p_param.nStartPortNumber;
1255 logger->debug(TAG, "scheduler ports {} {} {}",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1258 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1259 || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1260 logger->debug(TAG, "Disable Ports OMX video shed failed");
1261 clock_mutex.unlock();
1262 DeAllocateCodecsOMX();
1267 error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1268 if (error!=OMX_ErrorNone){
1269 logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1270 clock_mutex.unlock();
1271 DeAllocateCodecsOMX();
1275 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1276 if (error!=OMX_ErrorNone){
1277 logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1278 clock_mutex.unlock();
1279 DeAllocateCodecsOMX();
1282 omx_rend_input_port=p_param.nStartPortNumber;
1283 //omx_rend_output_port=p_param.nStartPortNumber+1;
1286 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1288 logger->debug(TAG, "Disable Ports OMX video rend failed");
1289 clock_mutex.unlock();
1290 DeAllocateCodecsOMX();
1298 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1299 if (error!=OMX_ErrorNone){
1300 logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error,omx_clock_output_port,omx_shed_clock_port);
1301 clock_mutex.unlock();
1302 DeAllocateCodecsOMX();
1306 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1308 logger->debug(TAG, "Enable Ports OMX clock shed failed");
1309 clock_mutex.unlock();
1310 DeAllocateCodecsOMX();
1316 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1317 logger->debug(TAG, "vid_sched idle ChangeComponentState");
1318 clock_mutex.unlock();
1319 DeAllocateCodecsOMX();
1326 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1327 clock_mutex.unlock();
1328 DeAllocateCodecsOMX();
1336 if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1337 clock_mutex.unlock();
1338 DeAllocateCodecsOMX();
1344 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1345 if (error!=OMX_ErrorNone){
1346 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1350 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1351 memset(&ft_type,0,sizeof(ft_type));
1352 ft_type.nSize=sizeof(ft_type);
1353 ft_type.nVersion.nVersion=OMX_VERSION;
1355 ft_type.nPortIndex=omx_codec_input_port;
1357 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1359 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1364 ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1365 logger->debug(TAG, "Framerate: {}",demux->getFrameRate());
1366 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1367 if (error!=OMX_ErrorNone){
1368 logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1369 clock_mutex.unlock();
1370 DeAllocateCodecsOMX();
1375 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1376 logger->debug(TAG, "vid_dec ChangeComponentState");
1377 clock_mutex.unlock();
1378 DeAllocateCodecsOMX();
1382 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1383 memset(&stall_conf,0,sizeof(stall_conf));
1384 stall_conf.nSize=sizeof(stall_conf);
1385 stall_conf.nVersion.nVersion=OMX_VERSION;
1386 stall_conf.nPortIndex=omx_codec_output_port;
1387 stall_conf.nDelay=1500*1000;
1388 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1389 if (error!=OMX_ErrorNone){
1390 logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1391 clock_mutex.unlock();
1392 DeAllocateCodecsOMX();
1395 omx_vid_stalled = false;
1397 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1398 memset(&req_callback,0,sizeof(req_callback));
1399 req_callback.nSize=sizeof(req_callback);
1400 req_callback.nVersion.nVersion=OMX_VERSION;
1401 req_callback.nPortIndex=omx_codec_output_port;
1402 req_callback.nIndex=OMX_IndexConfigBufferStall;
1403 req_callback.bEnable=OMX_TRUE;
1404 error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1405 if (error!=OMX_ErrorNone){
1406 logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error);
1407 clock_mutex.unlock();
1408 DeAllocateCodecsOMX();
1414 if (!PrepareInputBufsOMX()) {
1415 clock_mutex.unlock();
1416 DeAllocateCodecsOMX();
1421 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1422 if (error!=OMX_ErrorNone){
1423 logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1424 clock_mutex.unlock();
1425 DeAllocateCodecsOMX();
1431 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1433 logger->debug(TAG, "Enable Ports OMX codec shed failed");
1434 clock_mutex.unlock();
1435 DeAllocateCodecsOMX();
1439 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1440 clock_mutex.unlock();
1441 DeAllocateCodecsOMX();
1447 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1448 if (error!=OMX_ErrorNone){
1449 logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1450 clock_mutex.unlock();
1451 DeAllocateCodecsOMX();
1457 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1459 logger->debug(TAG, "Enable Ports OMX codec deint failed");
1460 clock_mutex.unlock();
1461 DeAllocateCodecsOMX();
1465 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1466 clock_mutex.unlock();
1467 DeAllocateCodecsOMX();
1471 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1472 logger->debug(TAG, "vid_deint ChangeComponentState");
1473 clock_mutex.unlock();
1474 DeAllocateCodecsOMX();
1478 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1479 memset(&imagefilter,0,sizeof(imagefilter));
1480 imagefilter.nSize=sizeof(imagefilter);
1481 imagefilter.nVersion.nVersion=OMX_VERSION;
1483 imagefilter.nPortIndex=omx_deint_output_port;
1484 imagefilter.nNumParams=4;
1485 imagefilter.nParams[0]=3;//???
1486 imagefilter.nParams[1]=0;//default frame interval
1487 imagefilter.nParams[2]=0;// frame rate
1488 if (demux->getHorizontalSize() <= 720){
1489 imagefilter.nParams[3] = 1;//use qpus
1493 imagefilter.nParams[3] = 0;//use qpus
1496 switch (deinterlace) {
1498 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1500 imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1502 imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1504 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1508 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1509 if (error!=OMX_ErrorNone){
1510 logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1511 clock_mutex.unlock();
1512 DeAllocateCodecsOMX();
1517 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1518 if (error!=OMX_ErrorNone){
1519 logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1520 clock_mutex.unlock();
1521 DeAllocateCodecsOMX();
1525 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1527 logger->debug(TAG, "Enable Ports OMX deint shed failed");
1528 clock_mutex.unlock();
1529 DeAllocateCodecsOMX();
1533 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1534 clock_mutex.unlock();
1535 DeAllocateCodecsOMX();
1541 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1542 logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1543 clock_mutex.unlock();
1544 DeAllocateCodecsOMX();
1548 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1549 if (error!=OMX_ErrorNone){
1550 logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error);
1551 clock_mutex.unlock();
1552 DeAllocateCodecsOMX();
1556 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1558 logger->debug(TAG, "Enable Ports OMX shed rend failed");
1559 clock_mutex.unlock();
1560 DeAllocateCodecsOMX();
1564 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1565 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1566 clock_mutex.unlock();
1567 DeAllocateCodecsOMX();
1571 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1572 logger->debug(TAG, "vid_rend ChangeComponentState");
1573 clock_mutex.unlock();
1574 DeAllocateCodecsOMX();
1579 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1580 logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1581 clock_mutex.unlock();
1582 DeAllocateCodecsOMX();
1585 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1586 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1589 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1590 logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1591 clock_mutex.unlock();
1592 DeAllocateCodecsOMX();
1596 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1597 logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1598 clock_mutex.unlock();
1599 DeAllocateCodecsOMX();
1604 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1605 memset(&dispconf,0,sizeof(dispconf));
1606 dispconf.nSize=sizeof(dispconf);
1607 dispconf.nVersion.nVersion=OMX_VERSION;
1609 dispconf.nPortIndex=omx_rend_input_port;
1611 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1613 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1614 if (error!=OMX_ErrorNone){
1615 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1616 clock_mutex.unlock();
1617 DeAllocateCodecsOMX();
1621 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1622 dispconf.fullscreen=OMX_FALSE;
1623 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1624 if (error!=OMX_ErrorNone){
1625 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1626 clock_mutex.unlock();
1627 DeAllocateCodecsOMX();
1631 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1632 dispconf.dest_rect.x_offset=100;
1633 dispconf.dest_rect.y_offset=100;
1634 dispconf.dest_rect.width=640;
1635 dispconf.dest_rect.height=480;
1636 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1637 if (error!=OMX_ErrorNone){
1638 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1639 clock_mutex.unlock();
1640 DeAllocateCodecsOMX();
1645 //playbacktimeoffset=-GetCurrentSystemTime();
1649 clock_mutex.unlock();
1653 setClockExecutingandRunning();
1662 int VideoOMX::idleClock()
1664 //OMX_ERRORTYPE error;
1665 OMX_STATETYPE temp_state;
1667 OMX_GetState(omx_clock,&temp_state);
1669 if (temp_state!=OMX_StateIdle) {
1670 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1671 logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1672 clock_mutex.unlock();
1676 clock_mutex.unlock();
1680 int VideoOMX::setClockExecutingandRunning()
1682 OMX_ERRORTYPE error;
1683 OMX_STATETYPE temp_state;
1685 OMX_GetState(omx_clock,&temp_state);
1687 if (temp_state!=OMX_StateExecuting) {
1688 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1689 logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1690 clock_mutex.unlock();
1691 DeAllocateCodecsOMX();
1696 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1697 memset(&clock_conf,0,sizeof(clock_conf));
1698 clock_conf.nSize=sizeof(clock_conf);
1699 clock_conf.nVersion.nVersion=OMX_VERSION;
1700 clock_conf.eState=OMX_TIME_ClockStateRunning;
1701 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1702 if (error!=OMX_ErrorNone) {
1703 logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1704 clock_mutex.unlock();
1705 DeAllocateCodecsOMX();
1708 clock_mutex.unlock();
1714 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1716 OMX_ERRORTYPE error;
1717 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1718 if (error!=OMX_ErrorNone){
1719 logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}",handle,type, error);
1724 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1733 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1735 OMX_ERRORTYPE error;
1738 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1739 memset(&pdt,0,sizeof(pdt));
1740 pdt.nSize=sizeof(pdt);
1741 pdt.nVersion.nVersion=OMX_VERSION;
1742 pdt.nPortIndex=port;
1743 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1744 if (error==OMX_ErrorNone) {
1745 if(pdt.bEnabled==OMX_TRUE) {
1746 skip=true; //already disabled;
1752 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1753 if (error!=OMX_ErrorNone){
1754 logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}",handle,port, error);
1758 if (!wait) return 1;
1759 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1768 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1770 OMX_ERRORTYPE error;
1773 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1774 memset(&pdt,0,sizeof(pdt));
1775 pdt.nSize=sizeof(pdt);
1776 pdt.nVersion.nVersion=OMX_VERSION;
1777 pdt.nPortIndex=port;
1778 error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1779 if (error==OMX_ErrorNone) {
1780 if(pdt.bEnabled==OMX_FALSE) {
1781 skip=true; //already disabled;
1788 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1789 if (error!=OMX_ErrorNone){
1790 logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}",handle,port, error);
1794 if (!wait) return 1;
1795 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1803 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1806 int iend=(wait/5+1);
1808 omx_event_mutex.lock();
1809 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1810 while (itty!=omx_events.end()) {
1812 VPE_OMX_EVENT current=*itty;
1813 if (current.handle==handle) { //this is ours
1814 if (current.event_type==OMX_EventError) {
1815 omx_events.erase(itty);
1816 omx_event_mutex.unlock();
1817 logger->debug(TAG, "WaitForEvent Finished on Error");
1820 } else if (current.event_type==event) {
1821 omx_events.erase(itty);
1822 omx_event_mutex.unlock();
1823 logger->debug(TAG, "WaitForEvent Finished Completed");
1830 omx_event_mutex.unlock();
1832 //logger->debug(TAG, "WaitForEvent");
1833 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1834 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1840 logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}",(void*)handle,event);
1845 int VideoOMX::clearEvents()
1847 omx_event_mutex.lock();
1849 omx_event_mutex.unlock();
1854 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1856 omx_event_mutex.lock();
1857 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1858 while (itty!=omx_events.end()) {
1859 VPE_OMX_EVENT current=*itty;
1860 if (current.handle==handle) { //this is ours
1861 itty=omx_events.erase(itty);
1867 omx_event_mutex.unlock();
1871 void VideoOMX::checkForStalledBuffers()
1873 //logger->debug(TAG, "Check stalled");
1875 omx_event_mutex.lock();
1876 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1877 while (itty!=omx_events.end()) {
1878 VPE_OMX_EVENT current=*itty;
1879 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1880 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1881 OMX_ERRORTYPE error;
1882 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1883 memset(&stall_conf,0,sizeof(stall_conf));
1884 stall_conf.nSize=sizeof(stall_conf);
1885 stall_conf.nVersion.nVersion=OMX_VERSION;
1886 stall_conf.nPortIndex=omx_codec_output_port;
1887 stall_conf.nDelay=200000;
1889 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1890 if (error!=OMX_ErrorNone){
1891 logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
1892 clock_mutex.unlock();
1893 omx_event_mutex.unlock();
1896 if (stall_conf.bStalled==OMX_TRUE) {
1897 omx_vid_stalled=true;
1898 logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
1900 omx_vid_stalled=false;
1901 logger->debug(TAG, "Video decoder unstalled! {}",stall_conf.nDelay);
1903 omx_events.erase(itty);
1908 omx_event_mutex.unlock();
1909 clock_mutex.unlock();
1915 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1918 while (i<200/*1000*/) {
1919 omx_event_mutex.lock();
1920 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1921 while (itty!=omx_events.end()) {
1923 VPE_OMX_EVENT current=*itty;
1924 if (current.handle==handle) { //this is ours
1925 if (current.event_type==OMX_EventError) {
1926 omx_events.erase(itty);
1927 omx_event_mutex.unlock();
1928 logger->debug(TAG, "Command Finished on Error {:#x}",current.data1);
1931 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1932 omx_events.erase(itty);
1933 omx_event_mutex.unlock();
1934 //logger->debug(TAG, "Command Finished Completed");
1941 omx_event_mutex.unlock();
1943 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1944 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1950 logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}",handle,command, data2);
1957 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1959 OMX_ERRORTYPE error;
1960 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1961 memset(&port_def_type,0,sizeof(port_def_type));
1962 port_def_type.nSize=sizeof(port_def_type);
1963 port_def_type.nVersion.nVersion=OMX_VERSION;
1964 port_def_type.nPortIndex=omx_codec_input_port;
1966 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1968 if (error!=OMX_ErrorNone){
1969 logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1971 /* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
1972 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1973 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1975 port_def_type.nBufferCountActual=100;
1976 port_def_type.nBufferSize=std::max(toi4(port_def_type.nBufferSize),150000); // for transcoder important
1978 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1980 if (error!=OMX_ErrorNone){
1981 logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1985 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1986 if (error!=OMX_ErrorNone){
1987 logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
1991 input_bufs_omx_mutex.lock();
1992 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1994 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1995 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1996 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1997 if (error!=OMX_ErrorNone){
1998 logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
1999 input_bufs_omx_mutex.unlock();
2002 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
2003 if (error!=OMX_ErrorNone){
2004 logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2005 input_bufs_omx_mutex.unlock();
2008 input_bufs_omx_all.push_back(buf_head);
2009 input_bufs_omx_free.push_back(buf_head);
2011 omx_first_frame=true;
2014 cur_input_buf_omx=NULL;
2015 input_bufs_omx_mutex.unlock();
2018 logger->debug(TAG, "PrepareInputBufsOMX mark3");
2019 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
2022 logger->debug(TAG, "PrepareInputBufsOMX mark4");
2027 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2029 OMX_ERRORTYPE error;
2031 cur_input_buf_omx=NULL;
2032 input_bufs_omx_mutex.lock();
2033 for (u4 i=0; i< input_bufs_omx_all.size();i++) {
2034 // free(input_bufs_omx_all[i]->pBuffer);
2035 // input_bufs_omx_all[i]->pBuffer=NULL;
2036 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
2037 if (error!=OMX_ErrorNone){
2038 logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2039 input_bufs_omx_mutex.unlock();
2044 input_bufs_omx_all.clear();
2045 input_bufs_omx_free.clear();
2046 input_bufs_omx_mutex.unlock();
2053 int VideoOMX::FlushRenderingPipe()
2055 OMX_ERRORTYPE error;
2059 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2060 omx_codec_output_port, NULL);
2061 if (error != OMX_ErrorNone) {
2062 LogNT::getInstance()->debug(TAG,
2063 "OMX_Flush codec out 1 failed {:#x}", error);
2067 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2068 omx_shed_input_port, NULL);
2069 if (error != OMX_ErrorNone) {
2070 LogNT::getInstance()->debug(TAG,
2071 "OMX_Flush shed in 2 failed {:#x}", error);
2075 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2076 omx_codec_output_port)) {
2077 LogNT::getInstance()->debug(TAG,
2078 "flush cmd codec 3 failed");
2081 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2082 omx_shed_input_port)) {
2083 LogNT::getInstance()->debug(TAG,
2084 "flush cmd shed 4 failed");
2087 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2088 omx_codec_output_port, NULL);
2089 if (error != OMX_ErrorNone) {
2090 LogNT::getInstance()->debug(TAG,
2091 "OMX_Flush codec out 5 failed {:#x}", error);
2095 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2096 omx_deint_input_port, NULL);
2097 if (error != OMX_ErrorNone) {
2098 LogNT::getInstance()->debug(TAG,
2099 "OMX_Flush deint in 6 failed {:#x}", error);
2103 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2104 omx_codec_output_port)) {
2105 LogNT::getInstance()->debug(TAG,
2106 "flush cmd codec 7 failed");
2109 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2110 omx_deint_input_port)) {
2111 LogNT::getInstance()->debug(TAG,
2112 "flush cmd deint 8 failed");
2116 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2117 omx_deint_output_port, NULL);
2118 if (error != OMX_ErrorNone) {
2119 LogNT::getInstance()->debug(TAG,
2120 "OMX_Flush deint out 9 failed {:#x}", error);
2124 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2125 omx_shed_input_port, NULL);
2126 if (error != OMX_ErrorNone) {
2127 LogNT::getInstance()->debug(TAG,
2128 "OMX_Flush shed in 10 failed {:#x}", error);
2132 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2133 omx_deint_output_port)) {
2134 LogNT::getInstance()->debug(TAG,
2135 "flush cmd deint 11 failed");
2138 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2139 omx_shed_input_port)) {
2140 LogNT::getInstance()->debug(TAG,
2141 "flush cmd shed 12 failed");
2149 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2150 omx_rend_input_port, NULL);
2151 if (error != OMX_ErrorNone) {
2152 LogNT::getInstance()->debug(TAG,
2153 "OMX_Flush rend in failed {:#x}", error);
2157 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2158 omx_shed_output_port, NULL);
2159 if (error != OMX_ErrorNone) {
2160 LogNT::getInstance()->debug(TAG,
2161 "OMX_Flush shed out failed {:#x}", error);
2167 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2168 omx_rend_input_port)) {
2169 LogNT::getInstance()->debug(TAG,
2170 "flush cmd shed rend failed");
2173 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2174 omx_shed_output_port)) {
2175 LogNT::getInstance()->debug(TAG,
2176 "flush cmd shed rend failed");
2183 int VideoOMX::DeAllocateCodecsOMX()
2185 OMX_ERRORTYPE error;
2187 logger->debug(TAG, "enter deallocatecodecsomx");
2189 if (cur_input_buf_omx) {
2190 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2191 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2192 if (error!=OMX_ErrorNone) {
2193 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2196 cur_input_buf_omx=NULL;//write out old data
2201 // first stop the omx elements
2202 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2203 logger->debug(TAG, "vid_dec ChangeComponentState");
2206 clock_mutex.unlock();
2212 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2213 LogNT::getInstance()->debug(TAG,
2214 "vid_deint ChangeComponentState");
2220 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2221 logger->debug(TAG, "vid_shed ChangeComponentState");
2225 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2226 logger->debug(TAG, "vid_rend ChangeComponentState");
2232 // TODO proper deinit sequence
2233 // first flush all buffers
2234 FlushRenderingPipe();
2240 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2241 if (error!=OMX_ErrorNone){
2242 logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2246 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2247 if (error!=OMX_ErrorNone){
2248 logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2252 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2253 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2254 logger->debug(TAG, "flush cmd clock shed failed");
2260 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2261 omx_codec_input_port, NULL);
2262 if (error != OMX_ErrorNone) {
2263 LogNT::getInstance()->debug(TAG,
2264 "OMX_Flush codec out failed {:#x}", error);
2271 DestroyInputBufsOMX();
2274 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2275 logger->debug(TAG, "Disable Tunnel Port failed 2");
2277 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2278 logger->debug(TAG, "Disable Tunnel Port failed 1");
2284 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2285 logger->debug(TAG, "Disable Tunnel Port failed 6");
2290 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2291 logger->debug(TAG, "Disable Tunnel Port failed 7");
2295 if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2296 logger->debug(TAG, "Disable Tunnel Port failed 6a");
2301 if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2302 logger->debug(TAG, "Disable Tunnel Port failed 7a");
2308 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2309 logger->debug(TAG, "Disable Tunnel Port failed 3");
2312 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2313 logger->debug(TAG, "Disable Tunnel Port failed 4");
2316 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2317 logger->debug(TAG, "Disable Tunnel Port failed 5");
2323 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2324 if (error!=OMX_ErrorNone) {
2325 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2330 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2331 if (error!=OMX_ErrorNone) {
2332 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2336 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2337 if (error!=OMX_ErrorNone) {
2338 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2342 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2343 if (error!=OMX_ErrorNone) {
2344 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2349 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2350 if (error!=OMX_ErrorNone) {
2351 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2355 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2356 if (error!=OMX_ErrorNone) {
2357 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2362 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2363 if (error!=OMX_ErrorNone) {
2364 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2368 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2369 if (error!=OMX_ErrorNone) {
2370 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2377 error=OMX_FreeHandle(omx_vid_dec);
2378 error=OMX_FreeHandle(omx_vid_sched);
2379 error=OMX_FreeHandle(omx_vid_rend);
2380 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2382 omx_vid_stalled = false;
2383 clock_mutex.unlock();
2385 if (error!=OMX_ErrorNone) {
2386 logger->debug(TAG, "FreeHandle failed {}", error);
2388 } else clock_mutex.unlock();
2389 logger->debug(TAG, "leave deallocate codecs OMX");
2395 void VideoOMX::destroyClock()
2398 if (clock_references>0) {
2400 if (clock_references==0) {
2401 OMX_ERRORTYPE error;
2402 logger->debug(TAG, "destroy omx clock");
2403 error=OMX_FreeHandle(omx_clock);
2404 if (error!=OMX_ErrorNone) {
2405 logger->debug(TAG, "FreeHandle failed {}", error);
2410 clock_mutex.unlock();
2414 int VideoOMX::stop()
2416 if (!initted) return 0;
2419 //Check if libav mode
2420 DeAllocateCodecsOMX();
2425 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2429 int VideoOMX::reset()
2431 if (!initted) return 0;
2434 DeAllocateCodecsOMX();
2435 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2439 int VideoOMX::pause()
2441 if (!initted) return 0;
2442 logger->debug(TAG, "enter pause");
2444 // ignore it audio handles this
2448 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2450 if (!initted) return 0;
2451 logger->debug(TAG, "enter unpause");
2454 //ignore it audio handles this
2459 int VideoOMX::fastForward()
2461 if (!initted) return 0;
2463 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2467 int VideoOMX::unFastForward()
2469 if (!initted) return 0;
2471 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2473 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2477 int VideoOMX::attachFrameBuffer()
2479 if (!initted) return 0;
2481 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2485 int VideoOMX::blank(void)
2487 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2488 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2492 u8 VideoOMX::getCurrentTimestamp() {
2495 long long ncur_clock_time = cur_clock_time;
2499 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2500 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2502 OMX_ERRORTYPE error;
2503 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2504 memset(&clock_conf, 0, sizeof(clock_conf));
2505 clock_conf.nSize = sizeof(clock_conf);
2506 clock_conf.nVersion.nVersion = OMX_VERSION;
2507 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2509 if (error != OMX_ErrorNone) {
2510 LogNT::getInstance()->debug(TAG,"getCurrentTimestamp IndexConfigTimeClockState failed {:#x}",error);
2513 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2515 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2516 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2517 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2518 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2519 cur_time_stamp.nPortIndex = omx_clock_output_port;
2520 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2522 if (error != OMX_ErrorNone) {
2523 LogNT::getInstance()->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}",error);
2525 long long temp = cur_time_stamp.nTimestamp.nLowPart
2526 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2527 ncur_clock_time = cur_clock_time = temp * 10LL;
2530 clock_mutex.unlock();
2531 pthread_setcancelstate(oldcancelstate, NULL);
2532 pthread_setcanceltype(oldcanceltype, NULL);
2535 //ncur_clock_time -= startoffset;
2536 ncur_clock_time -= lastreftimeOMX;
2537 long long result = lastreftimePTS;
2538 if (lastreftimePTS==0) return 0; // invalid time
2539 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2541 result = (1LL << 33) - result;
2542 //LogNT::getInstance()->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2550 u4 VideoOMX::timecodeToFrameNumber(u8 timecode)
2552 if (format == PAL) return (u4)(((double)timecode / (double)90000) * (double)25);
2553 else return (u4)(((double)timecode / (double)90000) * (double)30);
2558 int VideoOMX::test()
2563 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2570 int VideoOMX::test2()
2578 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2582 startoffset=curreftime;//offset is set for audio
2584 offsetvideonotset=false;
2586 if (offsetvideonotset) {
2587 offsetvideonotset=false;
2590 if ( (curreftime-lastrefvideotime)>10000000LL
2591 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2592 startoffset+=curreftime-lastrefvideotime;
2593 lastrefaudiotime+=curreftime-lastrefvideotime;
2595 offsetaudionotset=true;
2602 lastrefvideotime=curreftime;
2608 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2612 startoffset=curreftime;
2614 offsetaudionotset=false;
2616 if (offsetaudionotset) {
2617 offsetaudionotset=false;
2620 if ( (curreftime-lastrefaudiotime)>10000000LL
2621 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2622 startoffset+=curreftime-lastrefaudiotime;
2623 lastrefvideotime+=curreftime-lastrefaudiotime;
2625 offsetvideonotset=true;
2631 lastrefaudiotime=curreftime;
2636 void VideoOMX::ResetTimeOffsets() {
2637 offsetnotset=true; //called from demuxer
2638 offsetvideonotset=true;
2639 offsetaudionotset=true;
2648 void VideoOMX::FirstFrameFix()
2652 Demuxer* demux=Demuxer::getInstance();
2653 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2654 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2656 if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2657 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2658 OMX_ERRORTYPE error;
2659 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2660 memset(&port_def_type,0,sizeof(port_def_type));
2661 port_def_type.nSize=sizeof(port_def_type);
2662 port_def_type.nVersion.nVersion=OMX_VERSION;
2663 port_def_type.nPortIndex=omx_codec_output_port;
2665 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2666 if (error != OMX_ErrorNone) {
2667 LogNT::getInstance()->debug(TAG,
2668 "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2669 clock_mutex.unlock();
2674 LogNT::getInstance()->debug(TAG,
2675 "Deinit first frame fix {} {} {} {} {} {} {} {}",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2676 port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2677 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2678 port_def_type.format.video.bFlagErrorConcealment );
2679 LogNT::getInstance()->debug(TAG,
2680 "Deinit first frame fix2 {} {}",
2681 port_def_type.format.video.eCompressionFormat ,
2682 port_def_type.format.video.eColorFormat );
2685 // we cause the video_decode to determine the interlacing properties
2686 OMX_CONFIG_INTERLACETYPE il;
2687 memset(&il,0,sizeof(il));
2688 il.nSize=sizeof(il);
2689 il.nVersion.nVersion=OMX_VERSION;
2690 il.nPortIndex=omx_codec_output_port;
2691 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2692 if (error != OMX_ErrorNone) {
2693 LogNT::getInstance()->debug(TAG,
2694 "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2698 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2699 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2702 DisablePort(omx_vid_deint,omx_deint_input_port,true);
2703 // This is a dirty hack
2704 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2707 port_def_type.nPortIndex=omx_deint_output_port;
2708 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2710 if (error != OMX_ErrorNone) {
2711 LogNT::getInstance()->debug(TAG,
2712 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2713 clock_mutex.unlock();
2714 pthread_setcancelstate(oldcancelstate, NULL);
2715 pthread_setcanceltype(oldcanceltype, NULL);
2721 port_def_type.nPortIndex=omx_deint_input_port;
2722 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2724 if (error != OMX_ErrorNone) {
2725 LogNT::getInstance()->debug(TAG,
2726 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2727 clock_mutex.unlock();
2728 pthread_setcancelstate(oldcancelstate, NULL);
2729 pthread_setcanceltype(oldcanceltype, NULL);
2732 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2734 LogNT::getInstance()->debug(TAG,
2736 EnablePort(omx_vid_deint,omx_deint_input_port,true);
2737 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2738 port_def_type.nPortIndex=omx_deint_output_port;
2739 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2741 if (error != OMX_ErrorNone) {
2742 LogNT::getInstance()->debug(TAG,
2743 "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2744 clock_mutex.unlock();
2745 pthread_setcancelstate(oldcancelstate, NULL);
2746 pthread_setcanceltype(oldcanceltype, NULL);
2749 LogNT::getInstance()->debug(TAG,
2750 "Deinit first frame fix3 {} {} {} {} {} {} {} ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2751 port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2752 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2753 port_def_type.format.image.bFlagErrorConcealment );
2754 LogNT::getInstance()->debug(TAG,
2755 "Deinit first frame fix4 {} {}",
2756 port_def_type.format.image.eCompressionFormat ,
2757 port_def_type.format.image.eColorFormat );
2758 DisablePort(omx_vid_deint,omx_deint_output_port,true);
2761 port_def_type.nPortIndex=omx_shed_input_port;
2762 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2764 if (error != OMX_ErrorNone) {
2765 LogNT::getInstance()->debug(TAG,
2766 "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2767 clock_mutex.unlock();
2768 pthread_setcancelstate(oldcancelstate, NULL);
2769 pthread_setcanceltype(oldcanceltype, NULL);
2772 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2776 EnablePort(omx_vid_deint,omx_deint_output_port,true);
2778 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2779 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2781 clock_mutex.unlock();
2782 pthread_setcancelstate(oldcancelstate, NULL);
2783 pthread_setcanceltype(oldcanceltype, NULL);
2790 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2793 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2794 if (error != OMX_ErrorNone) {
2795 LogNT::getInstance()->debug(TAG,
2796 "OMX_EmptyThisBuffer failed {:#x}", error);
2798 if (first_frame) FirstFrameFix();
2802 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2804 // protect the call to empty this buffer
2807 /* long long temp =buffer->nTimeStamp.nLowPart
2808 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2810 //pthread_testcancel();
2811 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2812 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2815 /* OMX_ERRORTYPE error;
2816 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2817 memset(×tamp, 0, sizeof(timestamp));
2818 timestamp.nSize = sizeof(timestamp);
2819 timestamp.nVersion.nVersion = OMX_VERSION;
2820 timestamp.nPortIndex =omx_clock_output_port;
2822 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2825 if (error != OMX_ErrorNone) {
2826 LogNT::getInstance()->debug(TAG,
2827 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
2828 omx_rend_input_port);
2830 long long temp2 =timestamp.nTimestamp.nLowPart
2831 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2834 LogNT::getInstance()->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
2835 OMX_ERRORTYPE ret_val;
2836 ret_val=OMX_EmptyThisBuffer(handle,buffer);
2837 clock_mutex.unlock();
2838 pthread_setcancelstate(oldcancelstate, NULL);
2839 pthread_setcanceltype(oldcanceltype, NULL);
2840 //pthread_testcancel();
2844 bool VideoOMX::detectIFrame(const u1 *buffer,unsigned int length)
2846 const u1* curbuf=buffer;
2847 const u1* curbufend=buffer+length;
2848 unsigned int detector=0xFFFFFFFF;
2849 bool gotaud=false; // have seen access unit delimiter
2851 while (curbuf!=curbufend) {
2855 if (detector==0x00000109) {
2857 detector=0xFFFFFFFF;
2858 } else if (gotaud &&detector==0x00000001) {
2860 if (curbuf!=curbufend) {
2861 unsigned char picttype=(*curbuf)& 0x1F;
2862 return picttype==0x07;
2866 if (detector==0x00000100) {
2868 if (curbuf==curbufend) return false;
2870 if (curbuf==curbufend) return false;
2871 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2878 return false; // no frame found
2883 bool VideoOMX::DrainTargetBufferFull()
2885 //Check, if we have OMX output buffers
2887 input_bufs_omx_mutex.lock();
2888 full=(input_bufs_omx_free.size()==0);
2889 input_bufs_omx_mutex.unlock();
2890 checkForStalledBuffers(); // check if the decoder has a problem
2891 if (full && omx_vid_stalled && !omx_first_frame) {
2892 omx_vid_stalled=false;
2893 logger->debug(TAG, "Decoder is stalled, do a reset!");
2897 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2898 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2901 FlushRenderingPipe();
2902 omx_first_frame=true;
2903 clock_mutex.unlock();
2905 pthread_setcancelstate(oldcancelstate, NULL);
2906 pthread_setcanceltype(oldcanceltype, NULL);
2912 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */)
2915 mediapackets.clear();
2916 std::list<MediaPacket>::const_iterator begin=mplist.begin();
2917 std::list<MediaPacket>::const_iterator itty=mplist.begin();
2918 advance(itty,std::min(mplist.size(),10U));
2919 mediapackets.insert(mediapackets.begin(),begin,itty);//front
2923 u4 VideoOMX::DeliverMediaSample(u1* buffer, u4 *samplepos)
2926 while (consumed < mediapackets.size()) {
2927 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2928 if (*samplepos == mediapackets[consumed].length) {
2932 } else return consumed;
2937 u4 VideoOMX::DeliverMediaPacket(MediaPacket packet,
2941 if (packet.type == MPTYPE_VIDEO_H264)
2951 //Later add fail back code for libav
2953 *samplepos+=packet.length;
2954 return packet.length;
2958 if (!omx_running) return 0; // if we are not runnig do not do this
2960 if (isClockPaused()) return 0; //Block if we pause
2962 // logger->debug(TAG, "DMP mark 1");
2963 //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
2966 /*First Check, if we have an video sample*/
2970 return 0; //Not in iframe mode!
2974 if (packet.disconti) {
2976 if (cur_input_buf_omx) {
2977 PutBufferToPres(cur_input_buf_omx);
2978 cur_input_buf_omx=NULL;
2981 //logger->debug(TAG, "DMP mark 2");
2982 /*Inspect PES-Header */
2984 // OMX_STATETYPE temp_state;
2985 // OMX_GetState(omx_vid_dec,&temp_state);
2987 if (*samplepos==0) {//stripheader
2988 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2989 // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
2990 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2991 *samplepos+=headerstrip;
2992 if (headerstrip>=packet.length) {
2993 *samplepos=packet.length;// Packet is obviously damaged
2994 return packet.length;//skip it!
2996 if ( packet.synched ) {
2997 if (!firstsynched) {
2998 //logger->debug(TAG, "DMP mark 2a");
2999 // check if this is an I frame, the decoder does not like non I frames at startup!
3000 if (!detectIFrame(buffer,packet.length)) {
3001 *samplepos=packet.length;//if we have not processed at least one
3002 //logger->debug(TAG, "DMP mark 3");
3003 return packet.length;//synched packet ignore it!
3006 if (cur_input_buf_omx) {
3007 //logger->debug(TAG, "DMP mark 4a");
3008 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3009 PutBufferToPres(cur_input_buf_omx);
3010 cur_input_buf_omx=NULL;//write out old data
3012 //logger->debug(TAG, "DMP mark 4b");
3017 if (!firstsynched) {//
3018 *samplepos=packet.length;//if we have not processed at least one
3019 //logger->debug(TAG, "DMP mark 5");
3020 return packet.length;//synched packet ignore it!
3024 //logger->debug(TAG, "DMP mark 6");
3025 if (!cur_input_buf_omx) {
3026 input_bufs_omx_mutex.lock();
3027 if (input_bufs_omx_free.size()==0) {
3028 input_bufs_omx_mutex.unlock();
3029 //logger->debug(TAG, "Deliver MediaPacket no free sample");
3030 //logger->debug(TAG, "DMP mark 7");
3031 return 0; // we do not have a free media sample
3034 cur_input_buf_omx=input_bufs_omx_free.front();
3035 cur_input_buf_omx->nFilledLen=0;
3036 cur_input_buf_omx->nOffset=0;
3037 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3038 input_bufs_omx_free.pop_front();
3039 input_bufs_omx_mutex.unlock();
3045 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3046 if (packet.synched) {
3047 // logger->debug(TAG, "packet synched marker");
3049 //lastreftimePTS=packet.pts;
3050 if (omx_first_frame) { // TODO time
3051 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3052 logger->debug(TAG, "Starttime");
3053 omx_first_frame=false;
3055 cur_input_buf_omx->nFlags=0;
3056 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3058 lastreftimeOMX=packet.presentation_time;
3059 // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3060 lastreftimePTS=packet.pts;
3061 cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3065 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3066 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3067 //logger->debug(TAG, "packet unsynched marker");
3069 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3074 unsigned int haveToCopy=packet.length-*samplepos;
3075 //logger->debug(TAG, "DMP mark 8");
3077 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3078 //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3079 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3080 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3081 haveToCopy-=cancopy;
3082 cur_input_buf_omx->nFilledLen+=cancopy;
3083 *samplepos+=cancopy;
3084 // push old buffer out
3085 //logger->debug(TAG, "DMP mark 9");
3087 PutBufferToPres(cur_input_buf_omx);
3088 cur_input_buf_omx=NULL;
3090 input_bufs_omx_mutex.lock();
3091 if (input_bufs_omx_free.size()==0) {
3092 input_bufs_omx_mutex.unlock();
3093 // logger->debug(TAG, "Deliver MediaPacket no free sample2");
3094 return *samplepos; // we do not have a free media sample
3096 cur_input_buf_omx=input_bufs_omx_free.front();
3097 cur_input_buf_omx->nFilledLen=0;
3098 cur_input_buf_omx->nOffset=0;
3099 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3100 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3101 input_bufs_omx_free.pop_front();
3102 input_bufs_omx_mutex.unlock();
3103 //logger->debug(TAG, "DMP mark 10");
3106 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3107 buffer+packet.pos_buffer+*samplepos,haveToCopy);
3108 cur_input_buf_omx->nFilledLen+=haveToCopy;
3110 // logger->debug(TAG, "DMP mark 11");
3112 *samplepos+=haveToCopy;
3121 bool VideoOMX::displayIFrame(const u1* buffer, u4 length) {
3122 if (!omx_running) return false;
3124 EnterIframePlayback();
3126 //int haveToCopy = length;
3128 if (!cur_input_buf_omx) {
3129 input_bufs_omx_mutex.lock();
3130 if (input_bufs_omx_free.size() == 0) {
3131 input_bufs_omx_mutex.unlock();
3132 // LogNT::getInstance()->debug(TAG,
3133 // "Deliver MediaPacket no free sample");
3134 return false; // we do not have a free media sample
3137 cur_input_buf_omx = input_bufs_omx_free.front();
3138 cur_input_buf_omx->nFilledLen = 0;
3139 cur_input_buf_omx->nOffset = 0;
3140 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3141 input_bufs_omx_free.pop_front();
3142 input_bufs_omx_mutex.unlock();
3146 unsigned int pattern, packet_length;
3147 unsigned int headerstrip = 0;
3152 //Now we strip the pes header
3153 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3154 while ((read_pos + 7) <= length) {
3155 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3156 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3160 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3161 packet_length = ((buffer[read_pos + 4] << 8)
3162 | (buffer[read_pos + 5])) + 6;
3163 if (read_pos + packet_length > length)
3166 if ((headerstrip < packet_length)
3167 && (cur_input_buf_omx->nFilledLen + packet_length
3168 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3170 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3173 cur_input_buf_omx->nFlags
3174 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3177 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3178 PutBufferToPres(cur_input_buf_omx);
3179 cur_input_buf_omx = NULL;
3181 if (!cur_input_buf_omx) {
3183 while (count < 100 && omx_running && iframemode) {
3186 input_bufs_omx_mutex.lock();
3187 if (input_bufs_omx_free.size() == 0) {
3188 input_bufs_omx_mutex.unlock();
3189 // LogNT::getInstance()->debug(TAG,
3190 // "Ifrane no free sample");
3192 if (!omx_running) return false;
3195 cur_input_buf_omx = input_bufs_omx_free.front();
3196 cur_input_buf_omx->nFilledLen = 0;
3197 cur_input_buf_omx->nOffset = 0;
3198 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3199 cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3200 input_bufs_omx_free.pop_front();
3201 input_bufs_omx_mutex.unlock();
3204 if (!cur_input_buf_omx)
3209 if (packet_length > headerstrip) {
3211 cur_input_buf_omx->pBuffer
3212 + cur_input_buf_omx->nFilledLen,
3213 buffer + read_pos + headerstrip,
3214 packet_length - headerstrip);
3215 cur_input_buf_omx->nFilledLen += packet_length
3218 read_pos += packet_length;
3220 pattern = (buffer[read_pos] << 16)
3221 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3227 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3230 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3233 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3235 PutBufferToPres(cur_input_buf_omx);
3236 cur_input_buf_omx = NULL;
3239 MILLISLEEP(40); //Block a bit
3243 int VideoOMX::EnterIframePlayback()
3245 LogNT::getInstance()->debug(TAG,
3246 "EnterIframePlayback");
3247 if (cur_input_buf_omx) {
3248 PutBufferToPres(cur_input_buf_omx);
3249 cur_input_buf_omx = NULL;
3251 LogNT::getInstance()->debug(TAG,
3252 "EnterIframePlayback 2");
3253 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3254 DeAllocateCodecsOMX();
3255 AllocateCodecsOMX();
3256 LogNT::getInstance()->debug(TAG,
3257 "leave IframePlayback");