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/>.
30 #include "woptionpane.h"
31 #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 // Static OMX callbacks
45 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle, OMX_IN OMX_PTR appdata,
46 OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1,
47 OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data)
49 //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data);
51 struct VPE_OMX_EVENT new_event;
52 new_event.handle = handle;
53 new_event.appdata = appdata;
54 new_event.event_type = event_type;
55 new_event.data1 = data1;
56 new_event.data2 = data2;
57 new_event.event_data = event_data;
59 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
60 video->AddOmxEvent(new_event);
62 /* switch (event_type) {
63 case OMX_EventCmdComplete: {
71 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* buffer)
73 // LogNT::getInstance()->info(TAG, "EmptyBufferDone");
74 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
75 /* long long temp =buffer->nTimeStamp.nLowPart
76 | ((long long) buffer->nTimeStamp.nHighPart << 32);
77 LogNT::getInstance()->info(TAG, "EBD Video %lld {:#x}",temp,buffer->nFlags);*/
78 video->ReturnEmptyOMXBuffer(buffer);
82 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* /*buffer*/)
84 //LogNT::getInstance()->info(TAG, "FillBufferDone");
88 // -----------------------------------
92 logger = LogNT::getInstance();
97 deinterlace = 2; //advanced
99 strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
100 strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
101 strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
102 strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
103 strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
104 strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
107 VideoOMX::~VideoOMX()
112 int VideoOMX::init(u1 tformat)
114 if (initted) return 0;
118 // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
119 // Seems safe to call it more than once.
122 int ret = vc_gencmd_send("codec_enabled MPG2");
126 logger->debug(TAG, "vc_gencmd_send failed {:#x}", ret);
131 ret = vc_gencmd_read_response(buffer, sizeof(buffer));
135 logger->debug(TAG, "vc_gencmd_read_response failed {:#x}", ret);
139 if (STRCASECMP(buffer, "MPG2=enabled") == 0)
141 mpeg2_supported = true;
143 else if (STRCASECMP(buffer, "MPG2=disabled") == 0)
145 mpeg2_supported = false;
149 logger->debug(TAG, "Undefined mpg codec answer {}", buffer);
154 if (!setFormat(tformat)) { shutdown(); return 0; }
155 if (!setConnection(HDMI)) { shutdown(); return 0; }
156 if (!setAspectRatio(ASPECT4X3, 12, 11)) { shutdown(); return 0; }
157 if (!setMode(NORMAL)) { shutdown(); return 0; }
158 if (!setSource()) { shutdown(); return 0; }
159 if (!attachFrameBuffer()) { shutdown(); return 0; }
161 setTVsize(ASPECT16X9);
167 if (error != OMX_ErrorNone)
169 logger->debug(TAG, "Init OMX failed {:#x}", error);
177 void VideoOMX::signalOmx()
180 * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
181 * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
182 * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
183 * in what the Signal class used to do here and I'll sort it out later.
184 * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
185 * exact sychronisation and remove the wait spin loops? Unknown.
187 * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
188 * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
190 * Callers of signalOmx:
192 * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
193 * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
194 * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
196 * Surprise: WaitForEvent isn't a long running loop while video is playing.
199 omx_event_ready_signal_mutex.lock();
200 omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
201 omx_event_ready_signal_mutex.unlock();
204 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
206 omx_event_mutex.lock();
207 omx_events.push_back(new_event);
208 omx_event_mutex.unlock();
213 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer)
215 input_bufs_omx_mutex.lock();
216 //logger->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size());
217 input_bufs_omx_free.push_back(buffer);
218 //logger->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
219 input_bufs_omx_mutex.unlock();
224 int VideoOMX::shutdown()
226 if (!initted) return 0;
229 logger->info(TAG, "Shutdown video module");
231 DeAllocateCodecsOMX();
233 //vc_tv_show_info(0); // back to console
236 struct fb_var_screeninfo screeninfo;
237 fd_fbset = open("/dev/fb0", O_RDONLY);
241 logger->crit(TAG, "Could not open frame buffer device {}", fd_fbset);
245 if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo))
248 logger->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device");
252 screeninfo.bits_per_pixel = 8;
254 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
256 logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
259 screeninfo.bits_per_pixel = 16;
261 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
263 logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
270 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
272 logger->debug(TAG, "VideoOMX config load");
273 char* name = vdr->configLoad("VideoOMX", "SDDeinterlacing");
277 if (STRCASECMP(name, "None") == 0)
281 /* else if (STRCASECMP(name, "LineDouble") == 0)
285 else if (STRCASECMP(name, "Advanced") == 0)
289 /* else if (STRCASECMP(name, "Crazy") == 0)
291 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
294 else if (STRCASECMP(name, "Fast") == 0)
299 logger->debug(TAG, "Set deinterlacing to {} {}", name, deinterlace);
307 bool VideoOMX::handleOptionChanges(Option* option)
309 if (Video::handleOptionChanges(option))
316 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0)
320 /* else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble") == 0)
324 else if (STRCASECMP(option->options[option->userSetChoice], "Advanced") == 0)
328 /* else if (STRCASECMP(option->options[option->userSetChoice], "Crazy") == 0)
332 else if (STRCASECMP(option->options[option->userSetChoice], "Fast") == 0)
337 logger->debug(TAG, "Set deinterlacing to {} {}", option->options[option->userSetChoice], deinterlace);
345 bool VideoOMX::saveOptionstoServer()
350 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "None");
353 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
356 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Advanced");
359 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
362 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
369 /*Option(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType,
370 u4 numChoices, u4 defaultChoice, u4 startInt,
371 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
373 bool VideoOMX::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane)
375 if (!Video::addOptionsToPanes(panenumber, options, pane)) return false;
381 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
382 option = new Option(1, tr("SD Deinterlacing"), "VideoOMX", "SDDeinterlacing", Option::TYPE_TEXT,/*4,2*/3, 2, 0, deinterlaceopts, NULL, false, this);
383 options->push_back(option);
384 pane->addOptionLine(option);
390 int VideoOMX::setTVsize(u1 ttvsize)
392 if (tvsize != ttvsize) pendingmodechange = true;
398 u1 VideoOMX::getTVsize()
401 return ASPECT16X9; // in order that aspect ratio changes are reported
405 void VideoOMX::executePendingModeChanges()
407 if (pendingmodechange)
409 logger->info(TAG, "Execute pending mode change");
410 Osd::getInstance()->shutdown();
412 Osd::getInstance()->restore();
413 Osd::getInstance()->init();
414 BoxStack::getInstance()->redrawAllBoxes();
419 int VideoOMX::setDefaultAspect()
421 return setAspectRatio(tvsize, parx, pary);
424 int VideoOMX::setFormat(u1 tformat)
426 if (!initted) return 0;
428 if ((tformat != PAL) && (tformat != NTSC)
429 && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
440 // selectVideoMode(0);
445 void VideoOMX::selectVideoMode(int interlaced)
447 TV_GET_STATE_RESP_T tvstate;
448 vc_tv_get_state(&tvstate);
450 if ((tvstate.state & VC_HDMI_UNPLUGGED))
453 logger->info(TAG, "HDMI unplugged");
458 logger->info(TAG, "HDMI plugged");
460 if (connection == COMPOSITERGB)
463 logger->info(TAG, "SDTV set");
468 logger->info(TAG, "HDMI set");
474 TV_SUPPORTED_MODE_T all_supp_modes[200];
475 HDMI_RES_GROUP_T pref_group;
476 TV_SUPPORTED_MODE_T* mymode = NULL;
477 TV_SUPPORTED_MODE_T* mymode_second_best = NULL;
478 // bool got_optimum=false;
480 HDMI_RES_GROUP_T group = HDMI_RES_GROUP_CEA;
481 int all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
483 &pref_group, &pref_mode);
485 if (all_my_modes <= 0)
487 group = HDMI_RES_GROUP_DMT;
488 all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
490 &pref_group, &pref_mode);
491 logger->info(TAG, "No CEA fall back to DMT modes ");
496 if (format == PAL)target_fps = 50;
497 else if (format == NTSC) target_fps = 60;
499 //Now first determine native resolution
500 int native_width = 1920;
501 int native_height = 1080;
503 for (int i = 0; i < all_my_modes; i++)
505 if (all_supp_modes[i].native)
507 mymode = all_supp_modes + i;
508 logger->info(TAG, "Found native mode {}x{} {} Hz i: {}",
509 mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
510 native_width = mymode->width;
511 native_height = mymode->height;
515 //Now find the mode which matches best
516 for (int i = 0; i < all_my_modes; i++)
518 TV_SUPPORTED_MODE_T* curmode = all_supp_modes + i;
520 if (curmode->width == native_width &&
521 curmode->height == native_height &&
522 curmode->frame_rate == target_fps)
524 if (curmode->scan_mode == interlaced)
528 logger->info(TAG, "Found optimum mode {}x{} {} Hz i: {}",
529 mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
533 mymode_second_best = curmode;
534 logger->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}",
535 mymode_second_best->width, mymode_second_best->height,
536 mymode_second_best->frame_rate, mymode_second_best->scan_mode);
541 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
543 bool disableHDMIModeChange{false};
544 bool confSuccess = Config::getInstance()->getBool("videoomx", "disable-hdmi-modechange", disableHDMIModeChange);
546 if (!(confSuccess && disableHDMIModeChange))
552 logger->info(TAG, "Switch to optimum mode");
553 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode->code);
555 else if (mymode_second_best)
557 logger->info(TAG, "Switch to close to optimum mode");
558 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode_second_best->code);
562 logger->info(TAG, "Switch to prefered mode");
563 vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
564 static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE | HDMI_MODE_MATCH_RESOLUTION | HDMI_MODE_MATCH_SCANMODE));
569 outputinterlaced = interlaced;
574 logger->info(TAG, "Analog tv case");
575 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off();
576 SDTV_MODE_T setmode = SDTV_MODE_PAL;
577 SDTV_OPTIONS_T options;
583 logger->info(TAG, "SDTV aspect 16:9");
584 options.aspect = SDTV_ASPECT_16_9; break;
587 logger->info(TAG, "SDTV aspect 4:3");
588 options.aspect = SDTV_ASPECT_4_3; break;
591 logger->info(TAG, "SDTV aspect 14:9");
592 options.aspect = SDTV_ASPECT_14_9; break;
595 if (format == PAL) setmode = SDTV_MODE_PAL;
596 else if (format == NTSC) setmode = SDTV_MODE_NTSC;
597 else if (format == PAL_M)setmode = SDTV_MODE_PAL_M;
598 else if (format == NTSC_J) setmode = SDTV_MODE_NTSC_J;
600 vc_tv_sdtv_power_on(setmode, &options);
604 // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
605 // If this was just to reinit CEC then funcitons should be made to do that
608 pendingmodechange = false;
611 int VideoOMX::setConnection(u1 tconnection)
613 if (!initted) return 0;
614 if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0;
615 if (connection != tconnection) pendingmodechange = true;
616 connection = tconnection;
617 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
621 int VideoOMX::setAspectRatio(u1 taspectRatio, int tparx, int tpary)
623 if (!initted) return 0;
625 //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
626 aspectRatio = taspectRatio;
630 logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio, parx, pary);
633 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
637 int VideoOMX::setMode(u1 tmode)
639 if (!initted) return 0;
641 if (tmode == LETTERBOX || tmode == NORMAL) mode = tmode;
647 bool VideoOMX::setVideoDisplay(VideoDisplay display)
649 if (!initted) return false;
651 switch (display.mode)
653 case None: return true; //??
664 xpos = ((float) display.x) / ((float) screenWidth);
665 ypos = ((float) display.y) / ((float) screenHeight);
674 xpos = ((float) display.x) / ((float) screenWidth);
675 ypos = ((float) display.y) / ((float) screenHeight);
684 xpos = ((float) display.x) / ((float) screenWidth);
685 ypos = ((float) display.y) / ((float) screenHeight);
686 width = ((float) display.width) / ((float) screenWidth);
687 height = ((float) display.height) / ((float) screenHeight);
696 void VideoOMX::updateMode()
704 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
705 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
707 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
708 memset(&dispconf, 0, sizeof(dispconf));
709 dispconf.nSize = sizeof(dispconf);
710 dispconf.nVersion.nVersion = OMX_VERSION;
711 dispconf.nPortIndex = omx_rend_input_port;
713 dispconf.set = OMX_DISPLAY_SET_LAYER;
714 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
716 if (error != OMX_ErrorNone)
718 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error);
719 pthread_setcancelstate(oldcancelstate, NULL);
720 pthread_setcanceltype(oldcanceltype, NULL);
721 clock_mutex.unlock();
725 dispconf.pixel_x = parx;
726 dispconf.pixel_y = pary;
727 dispconf.set = OMX_DISPLAY_SET_PIXEL;
728 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
730 if (error != OMX_ErrorNone)
732 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error);
733 pthread_setcancelstate(oldcancelstate, NULL);
734 pthread_setcanceltype(oldcanceltype, NULL);
735 clock_mutex.unlock();
739 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
744 dispconf.fullscreen = OMX_TRUE;
748 dispconf.fullscreen = OMX_FALSE;
751 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
752 if (error != OMX_ErrorNone)
754 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error);
755 pthread_setcancelstate(oldcancelstate, NULL);
756 pthread_setcanceltype(oldcanceltype, NULL);
757 clock_mutex.unlock();
761 dispconf.set = OMX_DISPLAY_SET_MODE;
765 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL : OMX_DISPLAY_MODE_LETTERBOX;
769 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
772 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
774 if (error != OMX_ErrorNone)
776 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error);
777 pthread_setcancelstate(oldcancelstate, NULL);
778 pthread_setcanceltype(oldcanceltype, NULL);
779 clock_mutex.unlock();
785 unsigned int display_width, display_height;
786 display_width = display_height = 0;
788 if (graphics_get_display_size(0, &display_width, &display_height) < 0)
790 logger->warn(TAG, "Getting display size failed! (BCM API) ");
791 pthread_setcancelstate(oldcancelstate, NULL);
792 pthread_setcanceltype(oldcanceltype, NULL);
793 clock_mutex.unlock();
797 //UnSetFullscreen with window
798 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
799 dispconf.dest_rect.x_offset = (int) (xpos * ((float) display_width));
800 dispconf.dest_rect.y_offset = (int) (ypos * ((float) display_height));
801 dispconf.dest_rect.width = (int) (width * ((float) display_width));
802 dispconf.dest_rect.height = (int) (height * ((float) display_height));
803 logger->debug(TAG, "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset, dispconf.dest_rect.y_offset,
804 dispconf.dest_rect.width, dispconf.dest_rect.height);
806 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
808 if (error != OMX_ErrorNone)
810 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion failed {:#x}", error);
811 pthread_setcancelstate(oldcancelstate, NULL);
812 pthread_setcanceltype(oldcanceltype, NULL);
813 clock_mutex.unlock();
818 pthread_setcancelstate(oldcancelstate, NULL);
819 pthread_setcanceltype(oldcanceltype, NULL);
822 clock_mutex.unlock();
825 int VideoOMX::signalOff()
828 logger->info(TAG, "signalOff");
829 Osd::getInstance()->stopUpdate(); // turn off drawing thread
830 // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this
831 InputMan::getInstance()->shutdown();
833 InputMan::getInstance()->init();
838 int VideoOMX::signalOn()
842 Osd::getInstance()->shutdown();
843 logger->info(TAG, "signalOn");
845 Osd::getInstance()->restore();
846 Osd::getInstance()->init();
847 BoxStack::getInstance()->redrawAllBoxes();
854 int VideoOMX::setSource()
856 if (!initted) return 0;
858 // What does this do...
859 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
863 int VideoOMX::setPosition(int x, int y)
865 if (!initted) return 0;
867 xpos = ((float) x * 2.f) / ((float) screenWidth);
868 ypos = ((float) y * 2.f) / ((float) screenHeight);
876 if (!initted) return 0;
878 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
882 void VideoOMX::interlaceSwitch4Demux()
885 Demuxer* demux = Demuxer::getInstance();
887 if (hdmi) // only switch if hdmi and HD or interlaced SD material
890 int set_interlaced = 0;
892 if (demux->getHorizontalSize() > 720 && demux->getInterlaced())
897 logger->info(TAG, "switch interlacing {} {} {}", demux->getInterlaced(), outputinterlaced, set_interlaced);
899 if (outputinterlaced != set_interlaced)
901 selectVideoMode(set_interlaced);
902 Osd::getInstance()->shutdown();
903 Osd::getInstance()->restore();
904 Osd::getInstance()->init();
905 BoxStack::getInstance()->redrawAllBoxes();
915 if (!initted) return 0;
918 logger->debug(TAG, "enter play");
920 interlaceSwitch4Demux();
922 if (AllocateCodecsOMX())
925 // Otherwise fall back to libav
932 logger->info(TAG, "Allocate Codecs OMX failed assume h264 unsupported");
937 logger->info(TAG, "Allocate Codecs OMX failed assume mpeg2 unsupported");
944 int VideoOMX::initClock()
949 if (clock_references == 0)
951 static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
952 omx_event_mutex.lock();
954 omx_event_mutex.unlock();
956 error = OMX_GetHandle(&omx_clock, L_VPE_OMX_CLOCK, NULL, &callbacks);
958 if (error != OMX_ErrorNone)
960 logger->debug(TAG, "Init OMX clock failed {:#x}", error);
961 clock_mutex.unlock();
962 DeAllocateCodecsOMX();
966 /* TODO Clock config to separate method */
967 OMX_PORT_PARAM_TYPE p_param;
968 memset(&p_param, 0, sizeof(p_param));
969 p_param.nSize = sizeof(p_param);
970 p_param.nVersion.nVersion = OMX_VERSION;
971 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
973 if (error != OMX_ErrorNone)
975 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
976 clock_mutex.unlock();
977 DeAllocateCodecsOMX();
981 omx_clock_output_port = p_param.nStartPortNumber;
983 for (unsigned int i = 0; i < p_param.nPorts; i++)
985 if (!DisablePort(omx_clock, p_param.nStartPortNumber + i, true) )
987 logger->debug(TAG, "Disable Ports OMX clock failed {}", i);
988 clock_mutex.unlock();
989 DeAllocateCodecsOMX();
995 logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
997 clock_mutex.unlock();
1001 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port)
1003 OMX_ERRORTYPE error;
1004 *p_omx_clock = NULL;
1005 *p_omx_clock_output_port = 0;
1007 if (!initClock()) return 0;
1011 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1012 memset(&refclock, 0, sizeof(refclock));
1013 refclock.nSize = sizeof(refclock);
1014 refclock.nVersion.nVersion = OMX_VERSION;
1016 refclock.eClock = OMX_TIME_RefClockAudio;
1018 //refclock.eClock=OMX_TIME_RefClockVideo;
1019 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1021 if (error != OMX_ErrorNone)
1023 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1024 clock_mutex.unlock();
1025 DeAllocateCodecsOMX();
1029 OMX_PORT_PARAM_TYPE p_param;
1030 memset(&p_param, 0, sizeof(p_param));
1031 p_param.nSize = sizeof(p_param);
1032 p_param.nVersion.nVersion = OMX_VERSION;
1033 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1035 if (error != OMX_ErrorNone)
1037 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1038 clock_mutex.unlock();
1039 DeAllocateCodecsOMX();
1043 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1044 memset(&clock_conf, 0, sizeof(clock_conf));
1045 clock_conf.nSize = sizeof(clock_conf);
1046 clock_conf.nVersion.nVersion = OMX_VERSION;
1047 clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1048 clock_conf.nStartTime = intToOMXTicks(0);
1049 clock_conf.nOffset = intToOMXTicks(0);
1051 if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT1;
1052 else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1054 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1056 if (error != OMX_ErrorNone)
1058 logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
1061 *p_omx_clock_output_port = p_param.nStartPortNumber + 1;
1062 *p_omx_clock = omx_clock;
1063 clock_mutex.unlock();
1067 int VideoOMX::getClockVideoandInit()
1069 OMX_ERRORTYPE error;
1071 if (!initClock()) return 0;
1075 if (clock_references == 1) // only if no audio is attached to this clock!
1077 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1078 memset(&refclock, 0, sizeof(refclock));
1079 refclock.nSize = sizeof(refclock);
1080 refclock.nVersion.nVersion = OMX_VERSION;
1082 //refclock.eClock=OMX_TIME_RefClockAudio;
1084 refclock.eClock = OMX_TIME_RefClockVideo;
1085 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1087 if (error != OMX_ErrorNone)
1089 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1090 clock_mutex.unlock();
1091 DeAllocateCodecsOMX();
1096 OMX_PORT_PARAM_TYPE p_param;
1097 memset(&p_param, 0, sizeof(p_param));
1098 p_param.nSize = sizeof(p_param);
1099 p_param.nVersion.nVersion = OMX_VERSION;
1100 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1102 if (error != OMX_ErrorNone)
1104 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1105 clock_mutex.unlock();
1106 DeAllocateCodecsOMX();
1110 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1111 memset(&clock_conf, 0, sizeof(clock_conf));
1112 clock_conf.nSize = sizeof(clock_conf);
1113 clock_conf.nVersion.nVersion = OMX_VERSION;
1114 clock_conf.eState = OMX_TIME_ClockStateStopped;
1115 clock_conf.nStartTime = intToOMXTicks(0);
1116 clock_conf.nOffset = intToOMXTicks(0);
1117 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1119 if (error != OMX_ErrorNone)
1121 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1124 memset(&clock_conf, 0, sizeof(clock_conf));
1125 clock_conf.nSize = sizeof(clock_conf);
1126 clock_conf.nVersion.nVersion = OMX_VERSION;
1127 clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1128 clock_conf.nStartTime = intToOMXTicks(0);
1129 clock_conf.nOffset = intToOMXTicks(0);
1131 if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT0;
1132 else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1134 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1136 if (error != OMX_ErrorNone)
1138 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1141 omx_clock_output_port = p_param.nStartPortNumber;
1142 clock_mutex.unlock();
1147 void VideoOMX::clockUnpause()
1149 OMX_ERRORTYPE error;
1150 logger->info(TAG, "enter Clockunpause");
1153 if (clock_references > 0 && clockpaused)
1155 OMX_TIME_CONFIG_SCALETYPE scale_type;
1156 memset(&scale_type, 0, sizeof(scale_type));
1157 scale_type.nSize = sizeof(scale_type);
1158 scale_type.nVersion.nVersion = OMX_VERSION;
1159 scale_type.xScale = 1 << 16;
1160 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1162 if (error != OMX_ErrorNone)
1164 logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1167 logger->info(TAG, "set playback speed ClockUnpause");
1168 clockpaused = false;
1171 clock_mutex.unlock();
1175 void VideoOMX::clockPause()
1177 OMX_ERRORTYPE error;
1178 logger->info(TAG, "enter ClockPause");
1181 if (clock_references > 0 && !clockpaused)
1183 OMX_TIME_CONFIG_SCALETYPE scale_type;
1184 memset(&scale_type, 0, sizeof(scale_type));
1185 scale_type.nSize = sizeof(scale_type);
1186 scale_type.nVersion.nVersion = OMX_VERSION;
1187 scale_type.xScale = 0;
1188 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1190 if (error != OMX_ErrorNone)
1192 logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1195 logger->info(TAG, "set playback speed ClockPause");
1199 clock_mutex.unlock();
1202 int VideoOMX::AllocateCodecsOMX()
1204 OMX_ERRORTYPE error;
1205 static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
1207 Demuxer* demux = Demuxer::getInstance();
1212 logger->info(TAG, "Allocate Codecs OMX");
1213 //Clock, move later to audio including events
1215 logger->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(), demux->getVerticalSize(), demux->getInterlaced());
1217 if (deinterlace != 0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced())
1220 logger->info(TAG, "Deinterlacing activated {}", deinterlace);
1223 if (!getClockVideoandInit())
1225 return 0;// get the clock and init it if necessary
1230 logger->debug(TAG, "idleClock failed");
1240 error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_H264_DECODER, NULL, &callbacks);
1244 error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_MPEG2_DECODER, NULL, &callbacks);
1247 if (error != OMX_ErrorNone)
1249 logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1250 clock_mutex.unlock();
1251 DeAllocateCodecsOMX();
1255 logger->debug(TAG, "Nmark3");
1256 OMX_PORT_PARAM_TYPE p_param;
1257 memset(&p_param, 0, sizeof(p_param));
1258 p_param.nSize = sizeof(p_param);
1259 p_param.nVersion.nVersion = OMX_VERSION;
1260 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamVideoInit, &p_param);
1262 if (error != OMX_ErrorNone)
1264 logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1265 clock_mutex.unlock();
1266 DeAllocateCodecsOMX();
1270 omx_codec_input_port = p_param.nStartPortNumber;
1271 omx_codec_output_port = p_param.nStartPortNumber + 1;
1273 if (!DisablePort(omx_vid_dec, omx_codec_input_port) || !DisablePort(omx_vid_dec, omx_codec_output_port))
1275 logger->debug(TAG, "Disable Ports OMX video decoder failed");
1276 clock_mutex.unlock();
1277 DeAllocateCodecsOMX();
1281 logger->debug(TAG, "Nmark4");
1283 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1284 memset(&conceal, 0, sizeof(conceal));
1285 conceal.nSize = sizeof(conceal);
1286 conceal.nVersion.nVersion = OMX_VERSION;
1287 conceal.bStartWithValidFrame = OMX_FALSE;
1289 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &conceal);
1291 if (error != OMX_ErrorNone)
1293 logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1294 clock_mutex.unlock();
1295 DeAllocateCodecsOMX();
1301 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL, &callbacks);
1303 if (error != OMX_ErrorNone)
1305 logger->debug(TAG, "Init OMX video deinterlacer failed {:#x}", error);
1306 clock_mutex.unlock();
1307 DeAllocateCodecsOMX();
1311 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit, &p_param);
1313 if (error != OMX_ErrorNone)
1315 logger->debug(TAG, "Init OMX video deinterlacer OMX_GetParameter failed {:#x}", error);
1316 clock_mutex.unlock();
1317 DeAllocateCodecsOMX();
1321 omx_deint_input_port = p_param.nStartPortNumber;
1322 omx_deint_output_port = p_param.nStartPortNumber + 1;
1324 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1325 || !DisablePort(omx_vid_deint, omx_deint_output_port, true))
1327 logger->debug(TAG, "Disable Ports OMX video deint failed");
1328 clock_mutex.unlock();
1329 DeAllocateCodecsOMX();
1334 error = OMX_GetHandle(&omx_vid_sched, L_VPE_OMX_VIDEO_SCHED, NULL, &callbacks);
1336 if (error != OMX_ErrorNone)
1338 logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1339 clock_mutex.unlock();
1340 DeAllocateCodecsOMX();
1344 error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamVideoInit, &p_param);
1346 if (error != OMX_ErrorNone)
1348 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1349 clock_mutex.unlock();
1350 DeAllocateCodecsOMX();
1354 omx_shed_input_port = p_param.nStartPortNumber;
1355 omx_shed_output_port = p_param.nStartPortNumber + 1;
1357 error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamOtherInit, &p_param);
1359 if (error != OMX_ErrorNone)
1361 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1362 clock_mutex.unlock();
1363 DeAllocateCodecsOMX();
1367 omx_shed_clock_port = p_param.nStartPortNumber;
1368 logger->debug(TAG, "scheduler ports {} {} {}", omx_shed_input_port, omx_shed_output_port, omx_shed_clock_port);
1370 if (!DisablePort(omx_vid_sched, omx_shed_input_port, true) || !DisablePort(omx_vid_sched, omx_shed_output_port, true)
1371 || !DisablePort(omx_vid_sched, omx_shed_clock_port, true))
1373 logger->debug(TAG, "Disable Ports OMX video shed failed");
1374 clock_mutex.unlock();
1375 DeAllocateCodecsOMX();
1379 error = OMX_GetHandle(&omx_vid_rend, L_VPE_OMX_VIDEO_REND, NULL, &callbacks);
1381 if (error != OMX_ErrorNone)
1383 logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1384 clock_mutex.unlock();
1385 DeAllocateCodecsOMX();
1389 error = OMX_GetParameter(omx_vid_rend, OMX_IndexParamVideoInit, &p_param);
1391 if (error != OMX_ErrorNone)
1393 logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1394 clock_mutex.unlock();
1395 DeAllocateCodecsOMX();
1399 omx_rend_input_port = p_param.nStartPortNumber;
1400 //omx_rend_output_port=p_param.nStartPortNumber+1;
1402 if (!DisablePort(omx_vid_rend, omx_rend_input_port, true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1405 logger->debug(TAG, "Disable Ports OMX video rend failed");
1406 clock_mutex.unlock();
1407 DeAllocateCodecsOMX();
1413 error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, omx_vid_sched, omx_shed_clock_port);
1415 if (error != OMX_ErrorNone)
1417 logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error, omx_clock_output_port, omx_shed_clock_port);
1418 clock_mutex.unlock();
1419 DeAllocateCodecsOMX();
1423 if (!EnablePort(omx_clock, omx_clock_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_clock_port, false)
1426 logger->debug(TAG, "Enable Ports OMX clock shed failed");
1427 clock_mutex.unlock();
1428 DeAllocateCodecsOMX();
1432 if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
1434 logger->debug(TAG, "vid_sched idle ChangeComponentState");
1435 clock_mutex.unlock();
1436 DeAllocateCodecsOMX();
1440 if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_clock_port))
1442 clock_mutex.unlock();
1443 DeAllocateCodecsOMX();
1447 if (!CommandFinished(omx_clock, OMX_CommandPortEnable, omx_clock_output_port))
1449 clock_mutex.unlock();
1450 DeAllocateCodecsOMX();
1454 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1455 if (error!=OMX_ErrorNone){
1456 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1460 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1461 memset(&ft_type, 0, sizeof(ft_type));
1462 ft_type.nSize = sizeof(ft_type);
1463 ft_type.nVersion.nVersion = OMX_VERSION;
1465 ft_type.nPortIndex = omx_codec_input_port;
1468 ft_type.eCompressionFormat = OMX_VIDEO_CodingAVC;
1470 ft_type.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1472 ft_type.xFramerate = 0 * (1 << 16); //25*(1<<16);//demux->getFrameRate()*(1<<16);
1473 logger->debug(TAG, "Framerate: {}", demux->getFrameRate());
1474 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamVideoPortFormat, &ft_type);
1476 if (error != OMX_ErrorNone)
1478 logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1479 clock_mutex.unlock();
1480 DeAllocateCodecsOMX();
1484 if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
1486 logger->debug(TAG, "vid_dec ChangeComponentState");
1487 clock_mutex.unlock();
1488 DeAllocateCodecsOMX();
1492 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1493 memset(&stall_conf, 0, sizeof(stall_conf));
1494 stall_conf.nSize = sizeof(stall_conf);
1495 stall_conf.nVersion.nVersion = OMX_VERSION;
1496 stall_conf.nPortIndex = omx_codec_output_port;
1497 stall_conf.nDelay = 1500 * 1000;
1498 error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
1500 if (error != OMX_ErrorNone)
1502 logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1503 clock_mutex.unlock();
1504 DeAllocateCodecsOMX();
1508 omx_vid_stalled = false;
1510 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1511 memset(&req_callback, 0, sizeof(req_callback));
1512 req_callback.nSize = sizeof(req_callback);
1513 req_callback.nVersion.nVersion = OMX_VERSION;
1514 req_callback.nPortIndex = omx_codec_output_port;
1515 req_callback.nIndex = OMX_IndexConfigBufferStall;
1516 req_callback.bEnable = OMX_TRUE;
1517 error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigRequestCallback, &req_callback);
1519 if (error != OMX_ErrorNone)
1521 logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error);
1522 clock_mutex.unlock();
1523 DeAllocateCodecsOMX();
1527 if (!PrepareInputBufsOMX())
1529 clock_mutex.unlock();
1530 DeAllocateCodecsOMX();
1536 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_sched, omx_shed_input_port);
1538 if (error != OMX_ErrorNone)
1540 logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1541 clock_mutex.unlock();
1542 DeAllocateCodecsOMX();
1546 if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1548 logger->debug(TAG, "Enable Ports OMX codec shed failed");
1549 clock_mutex.unlock();
1550 DeAllocateCodecsOMX();
1554 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1556 clock_mutex.unlock();
1557 DeAllocateCodecsOMX();
1563 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_deint, omx_deint_input_port);
1565 if (error != OMX_ErrorNone)
1567 logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1568 clock_mutex.unlock();
1569 DeAllocateCodecsOMX();
1573 if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_deint, omx_deint_input_port, false))
1575 logger->debug(TAG, "Enable Ports OMX codec deint failed");
1576 clock_mutex.unlock();
1577 DeAllocateCodecsOMX();
1581 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_input_port))
1583 clock_mutex.unlock();
1584 DeAllocateCodecsOMX();
1588 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
1590 logger->debug(TAG, "vid_deint ChangeComponentState");
1591 clock_mutex.unlock();
1592 DeAllocateCodecsOMX();
1596 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1597 memset(&imagefilter, 0, sizeof(imagefilter));
1598 imagefilter.nSize = sizeof(imagefilter);
1599 imagefilter.nVersion.nVersion = OMX_VERSION;
1601 imagefilter.nPortIndex = omx_deint_output_port;
1602 imagefilter.nNumParams = 4;
1603 imagefilter.nParams[0] = 3; //???
1604 imagefilter.nParams[1] = 0; //default frame interval
1605 imagefilter.nParams[2] = 0; // frame rate
1607 if (demux->getHorizontalSize() <= 720)
1609 imagefilter.nParams[3] = 1;//use qpus
1613 imagefilter.nParams[3] = 0;//use qpus
1616 switch (deinterlace)
1619 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceLineDouble; break;
1622 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; break;
1625 imagefilter.eImageFilter = OMX_ImageFilterFilm; break;
1628 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1631 error = OMX_SetConfig(omx_vid_deint, OMX_IndexConfigCommonImageFilterParameters, &imagefilter);
1633 if (error != OMX_ErrorNone)
1635 logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1636 clock_mutex.unlock();
1637 DeAllocateCodecsOMX();
1641 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, omx_vid_sched, omx_shed_input_port);
1643 if (error != OMX_ErrorNone)
1645 logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1646 clock_mutex.unlock();
1647 DeAllocateCodecsOMX();
1651 if (!EnablePort(omx_vid_deint, omx_deint_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1653 logger->debug(TAG, "Enable Ports OMX deint shed failed");
1654 clock_mutex.unlock();
1655 DeAllocateCodecsOMX();
1659 if (!CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1661 clock_mutex.unlock();
1662 DeAllocateCodecsOMX();
1667 if (!ChangeComponentState(omx_vid_dec, OMX_StateExecuting))
1669 logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1670 clock_mutex.unlock();
1671 DeAllocateCodecsOMX();
1675 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, omx_vid_rend, omx_rend_input_port);
1677 if (error != OMX_ErrorNone)
1679 logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error);
1680 clock_mutex.unlock();
1681 DeAllocateCodecsOMX();
1685 if (!EnablePort(omx_vid_sched, omx_shed_output_port, false) || !EnablePort(omx_vid_rend, omx_rend_input_port, false))
1687 logger->debug(TAG, "Enable Ports OMX shed rend failed");
1688 clock_mutex.unlock();
1689 DeAllocateCodecsOMX();
1693 if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_output_port)
1694 || !CommandFinished(omx_vid_rend, OMX_CommandPortEnable, omx_rend_input_port))
1696 clock_mutex.unlock();
1697 DeAllocateCodecsOMX();
1701 if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
1703 logger->debug(TAG, "vid_rend ChangeComponentState");
1704 clock_mutex.unlock();
1705 DeAllocateCodecsOMX();
1711 if (!ChangeComponentState(omx_vid_deint, OMX_StateExecuting))
1713 logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1714 clock_mutex.unlock();
1715 DeAllocateCodecsOMX();
1719 DisablePort(omx_vid_deint, omx_deint_output_port, false);
1720 DisablePort(omx_vid_deint, omx_deint_input_port, false);
1723 if (!ChangeComponentState(omx_vid_sched, OMX_StateExecuting))
1725 logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1726 clock_mutex.unlock();
1727 DeAllocateCodecsOMX();
1731 if (!ChangeComponentState(omx_vid_rend, OMX_StateExecuting))
1733 logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1734 clock_mutex.unlock();
1735 DeAllocateCodecsOMX();
1740 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1741 memset(&dispconf,0,sizeof(dispconf));
1742 dispconf.nSize=sizeof(dispconf);
1743 dispconf.nVersion.nVersion=OMX_VERSION;
1745 dispconf.nPortIndex=omx_rend_input_port;
1747 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1749 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1750 if (error!=OMX_ErrorNone){
1751 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1752 clock_mutex.unlock();
1753 DeAllocateCodecsOMX();
1757 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1758 dispconf.fullscreen=OMX_FALSE;
1759 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1760 if (error!=OMX_ErrorNone){
1761 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1762 clock_mutex.unlock();
1763 DeAllocateCodecsOMX();
1767 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1768 dispconf.dest_rect.x_offset=100;
1769 dispconf.dest_rect.y_offset=100;
1770 dispconf.dest_rect.width=640;
1771 dispconf.dest_rect.height=480;
1772 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1773 if (error!=OMX_ErrorNone){
1774 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1775 clock_mutex.unlock();
1776 DeAllocateCodecsOMX();
1781 //playbacktimeoffset=-GetCurrentSystemTime();
1785 clock_mutex.unlock();
1789 setClockExecutingandRunning();
1794 int VideoOMX::idleClock()
1796 //OMX_ERRORTYPE error;
1797 OMX_STATETYPE temp_state;
1799 OMX_GetState(omx_clock, &temp_state);
1801 if (temp_state != OMX_StateIdle)
1803 if (!ChangeComponentState(omx_clock, OMX_StateIdle))
1805 logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1806 clock_mutex.unlock();
1811 clock_mutex.unlock();
1815 int VideoOMX::setClockExecutingandRunning()
1817 OMX_ERRORTYPE error;
1818 OMX_STATETYPE temp_state;
1820 OMX_GetState(omx_clock, &temp_state);
1822 if (temp_state != OMX_StateExecuting)
1824 if (!ChangeComponentState(omx_clock, OMX_StateExecuting))
1826 logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1827 clock_mutex.unlock();
1828 DeAllocateCodecsOMX();
1833 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1834 memset(&clock_conf, 0, sizeof(clock_conf));
1835 clock_conf.nSize = sizeof(clock_conf);
1836 clock_conf.nVersion.nVersion = OMX_VERSION;
1837 clock_conf.eState = OMX_TIME_ClockStateRunning;
1838 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1840 if (error != OMX_ErrorNone)
1842 logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1843 clock_mutex.unlock();
1844 DeAllocateCodecsOMX();
1848 clock_mutex.unlock();
1852 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait) //needs to be called with locked mutex
1854 OMX_ERRORTYPE error;
1855 error = OMX_SendCommand(handle, OMX_CommandStateSet, type, 0);
1857 if (error != OMX_ErrorNone)
1859 logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}", handle, type, error);
1865 if (!CommandFinished(handle, OMX_CommandStateSet, type)) return 0;
1872 int VideoOMX::EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1874 OMX_ERRORTYPE error;
1877 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1878 memset(&pdt, 0, sizeof(pdt));
1879 pdt.nSize = sizeof(pdt);
1880 pdt.nVersion.nVersion = OMX_VERSION;
1881 pdt.nPortIndex = port;
1882 error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1884 if (error == OMX_ErrorNone)
1886 if (pdt.bEnabled == OMX_TRUE)
1888 skip = true; //already disabled;
1894 error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, 0);
1896 if (error != OMX_ErrorNone)
1898 logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}", handle, port, error);
1902 if (!wait) return 1;
1904 if (!CommandFinished(handle, OMX_CommandPortEnable, port))
1913 int VideoOMX::DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1915 OMX_ERRORTYPE error;
1918 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1919 memset(&pdt, 0, sizeof(pdt));
1920 pdt.nSize = sizeof(pdt);
1921 pdt.nVersion.nVersion = OMX_VERSION;
1922 pdt.nPortIndex = port;
1923 error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1925 if (error == OMX_ErrorNone)
1927 if (pdt.bEnabled == OMX_FALSE)
1929 skip = true; //already disabled;
1935 error = OMX_SendCommand(handle, OMX_CommandPortDisable, port, 0);
1937 if (error != OMX_ErrorNone)
1939 logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}", handle, port, error);
1943 if (!wait) return 1;
1945 if (!CommandFinished(handle, OMX_CommandPortDisable, port))
1954 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait) //needs to be called with locked mutex
1957 int iend = (wait / 5 + 1);
1961 omx_event_mutex.lock();
1962 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
1964 while (itty != omx_events.end())
1966 VPE_OMX_EVENT current = *itty;
1968 if (current.handle == handle) //this is ours
1970 if (current.event_type == OMX_EventError)
1972 omx_events.erase(itty);
1973 omx_event_mutex.unlock();
1974 logger->debug(TAG, "WaitForEvent Finished on Error");
1977 else if (current.event_type == event)
1979 omx_events.erase(itty);
1980 omx_event_mutex.unlock();
1981 logger->debug(TAG, "WaitForEvent Finished Completed");
1989 omx_event_mutex.unlock();
1991 //logger->debug(TAG, "WaitForEvent");
1992 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1993 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1999 logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}", (void*)handle, event);
2003 int VideoOMX::clearEvents()
2005 omx_event_mutex.lock();
2007 omx_event_mutex.unlock();
2012 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
2014 omx_event_mutex.lock();
2015 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2017 while (itty != omx_events.end())
2019 VPE_OMX_EVENT current = *itty;
2021 if (current.handle == handle) //this is ours
2023 itty = omx_events.erase(itty);
2030 omx_event_mutex.unlock();
2034 void VideoOMX::checkForStalledBuffers()
2036 //logger->debug(TAG, "Check stalled");
2038 omx_event_mutex.lock();
2039 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2041 while (itty != omx_events.end())
2043 VPE_OMX_EVENT current = *itty;
2045 if (current.event_type == OMX_EventParamOrConfigChanged && current.data1 == omx_codec_output_port
2046 && current.handle == omx_vid_dec && current.data2 == OMX_IndexConfigBufferStall)
2048 OMX_ERRORTYPE error;
2049 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
2050 memset(&stall_conf, 0, sizeof(stall_conf));
2051 stall_conf.nSize = sizeof(stall_conf);
2052 stall_conf.nVersion.nVersion = OMX_VERSION;
2053 stall_conf.nPortIndex = omx_codec_output_port;
2054 stall_conf.nDelay = 200000;
2056 error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
2058 if (error != OMX_ErrorNone)
2060 logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
2061 clock_mutex.unlock();
2062 omx_event_mutex.unlock();
2066 if (stall_conf.bStalled == OMX_TRUE)
2068 omx_vid_stalled = true;
2069 logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
2073 omx_vid_stalled = false;
2074 logger->debug(TAG, "Video decoder unstalled! {}", stall_conf.nDelay);
2077 omx_events.erase(itty);
2084 omx_event_mutex.unlock();
2085 clock_mutex.unlock();
2088 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2) //needs to be called with locked mutex
2092 while (i < 200/*1000*/)
2094 omx_event_mutex.lock();
2095 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2097 while (itty != omx_events.end())
2099 VPE_OMX_EVENT current = *itty;
2101 if (current.handle == handle) //this is ours
2103 if (current.event_type == OMX_EventError)
2105 omx_events.erase(itty);
2106 omx_event_mutex.unlock();
2107 logger->debug(TAG, "Command Finished on Error {:#x}", current.data1);
2110 else if (current.event_type == OMX_EventCmdComplete && current.data1 == command && current.data2 == data2)
2112 omx_events.erase(itty);
2113 omx_event_mutex.unlock();
2114 //logger->debug(TAG, "Command Finished Completed");
2122 omx_event_mutex.unlock();
2124 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
2125 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
2131 logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}", handle, command, data2);
2135 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
2137 OMX_ERRORTYPE error;
2138 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2139 memset(&port_def_type, 0, sizeof(port_def_type));
2140 port_def_type.nSize = sizeof(port_def_type);
2141 port_def_type.nVersion.nVersion = OMX_VERSION;
2142 port_def_type.nPortIndex = omx_codec_input_port;
2144 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2146 if (error != OMX_ErrorNone)
2148 logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2151 /* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
2152 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
2153 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
2155 port_def_type.nBufferCountActual = 100;
2156 port_def_type.nBufferSize = std::max(toi4(port_def_type.nBufferSize), 150000); // for transcoder important
2158 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2160 if (error != OMX_ErrorNone)
2162 logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2165 error = OMX_SendCommand(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port, 0);
2167 if (error != OMX_ErrorNone)
2169 logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
2173 input_bufs_omx_mutex.lock();
2175 for (unsigned int i = 0; i < port_def_type.nBufferCountActual; i++)
2177 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
2178 OMX_BUFFERHEADERTYPE* buf_head = NULL;
2179 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
2180 if (error!=OMX_ErrorNone){
2181 logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
2182 input_bufs_omx_mutex.unlock();
2185 error = OMX_AllocateBuffer(omx_vid_dec, &buf_head, omx_codec_input_port, NULL, port_def_type.nBufferSize);
2187 if (error != OMX_ErrorNone)
2189 logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2190 input_bufs_omx_mutex.unlock();
2194 input_bufs_omx_all.push_back(buf_head);
2195 input_bufs_omx_free.push_back(buf_head);
2198 omx_first_frame = true;
2200 firstsynched = false;
2201 cur_input_buf_omx = NULL;
2202 input_bufs_omx_mutex.unlock();
2204 logger->debug(TAG, "PrepareInputBufsOMX mark3");
2206 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port))
2211 logger->debug(TAG, "PrepareInputBufsOMX mark4");
2216 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2218 OMX_ERRORTYPE error;
2220 cur_input_buf_omx = NULL;
2221 input_bufs_omx_mutex.lock();
2223 for (u4 i = 0; i < input_bufs_omx_all.size(); i++)
2225 // free(input_bufs_omx_all[i]->pBuffer);
2226 // input_bufs_omx_all[i]->pBuffer=NULL;
2227 error = OMX_FreeBuffer(omx_vid_dec, omx_codec_input_port, input_bufs_omx_all[i]);
2229 if (error != OMX_ErrorNone)
2231 logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2232 input_bufs_omx_mutex.unlock();
2238 input_bufs_omx_all.clear();
2239 input_bufs_omx_free.clear();
2240 input_bufs_omx_mutex.unlock();
2245 int VideoOMX::FlushRenderingPipe()
2247 OMX_ERRORTYPE error;
2251 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2253 if (error != OMX_ErrorNone)
2255 logger->debug(TAG, "OMX_Flush codec out 1 failed {:#x}", error);
2258 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2260 if (error != OMX_ErrorNone)
2262 logger->debug(TAG, "OMX_Flush shed in 2 failed {:#x}", error);
2265 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2267 logger->debug(TAG, "flush cmd codec 3 failed");
2270 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2272 logger->debug(TAG, "flush cmd shed 4 failed");
2277 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2279 if (error != OMX_ErrorNone)
2281 logger->debug(TAG, "OMX_Flush codec out 5 failed {:#x}", error);
2284 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port, NULL);
2286 if (error != OMX_ErrorNone)
2288 logger->debug(TAG, "OMX_Flush deint in 6 failed {:#x}", error);
2291 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2293 logger->debug(TAG, "flush cmd codec 7 failed");
2296 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port))
2298 logger->debug(TAG, "flush cmd deint 8 failed");
2302 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port, NULL);
2304 if (error != OMX_ErrorNone)
2306 logger->debug(TAG, "OMX_Flush deint out 9 failed {:#x}", error);
2309 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2311 if (error != OMX_ErrorNone)
2313 logger->debug(TAG, "OMX_Flush shed in 10 failed {:#x}", error);
2316 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port))
2318 logger->debug(TAG, "flush cmd deint 11 failed");
2321 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2323 logger->debug(TAG, "flush cmd shed 12 failed");
2327 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port, NULL);
2329 if (error != OMX_ErrorNone)
2331 logger->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
2335 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port, NULL);
2337 if (error != OMX_ErrorNone)
2339 logger->debug(TAG, "OMX_Flush shed out failed {:#x}", error);
2342 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port))
2344 logger->debug(TAG, "flush cmd shed rend failed");
2347 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port))
2349 logger->debug(TAG, "flush cmd shed rend failed");
2355 int VideoOMX::DeAllocateCodecsOMX()
2357 OMX_ERRORTYPE error;
2358 omx_running = false;
2359 logger->debug(TAG, "enter deallocatecodecsomx");
2361 if (cur_input_buf_omx)
2363 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_EOS;
2364 error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
2366 if (error != OMX_ErrorNone)
2368 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2371 cur_input_buf_omx = NULL; //write out old data
2379 // first stop the omx elements
2380 if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
2382 logger->debug(TAG, "vid_dec ChangeComponentState");
2385 clock_mutex.unlock();
2392 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
2394 logger->debug(TAG, "vid_deint ChangeComponentState");
2398 if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
2400 logger->debug(TAG, "vid_shed ChangeComponentState");
2403 if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
2405 logger->debug(TAG, "vid_rend ChangeComponentState");
2408 // TODO proper deinit sequence
2409 // first flush all buffers
2410 FlushRenderingPipe();
2412 error = OMX_SendCommand(omx_clock, OMX_CommandFlush, omx_clock_output_port, NULL);
2414 if (error != OMX_ErrorNone)
2416 logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2419 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port, NULL);
2421 if (error != OMX_ErrorNone)
2423 logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2426 if (!CommandFinished(omx_clock, OMX_CommandFlush, omx_clock_output_port) ||
2427 !CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port))
2429 logger->debug(TAG, "flush cmd clock shed failed");
2432 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2433 omx_codec_input_port, NULL);
2435 if (error != OMX_ErrorNone)
2437 logger->debug(TAG, "OMX_Flush codec out failed {:#x}", error);
2440 DestroyInputBufsOMX();
2443 if (!DisablePort(omx_vid_sched, omx_shed_output_port, true))
2445 logger->debug(TAG, "Disable Tunnel Port failed 2");
2448 if (!DisablePort(omx_vid_rend, omx_rend_input_port, true))
2450 logger->debug(TAG, "Disable Tunnel Port failed 1");
2453 if (!DisablePort(omx_vid_dec, omx_codec_output_port, true))
2455 logger->debug(TAG, "Disable Tunnel Port failed 6");
2458 if (!DisablePort(omx_vid_dec, omx_codec_input_port, true))
2460 logger->debug(TAG, "Disable Tunnel Port failed 7");
2465 if (!DisablePort(omx_vid_deint, omx_deint_output_port, true))
2467 logger->debug(TAG, "Disable Tunnel Port failed 6a");
2470 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true))
2472 logger->debug(TAG, "Disable Tunnel Port failed 7a");
2476 if (!DisablePort(omx_vid_sched, omx_shed_input_port, true))
2478 logger->debug(TAG, "Disable Tunnel Port failed 3");
2481 if (!DisablePort(omx_vid_sched, omx_shed_clock_port, true))
2483 logger->debug(TAG, "Disable Tunnel Port failed 4");
2486 if (!DisablePort(omx_clock, omx_clock_output_port, true))
2488 logger->debug(TAG, "Disable Tunnel Port failed 5");
2491 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, NULL, 0);
2493 if (error != OMX_ErrorNone)
2495 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2500 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_input_port, NULL, 0);
2502 if (error != OMX_ErrorNone)
2504 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2507 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, NULL, 0);
2509 if (error != OMX_ErrorNone)
2511 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2515 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_input_port, NULL, 0);
2517 if (error != OMX_ErrorNone)
2519 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2522 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, NULL, 0);
2524 if (error != OMX_ErrorNone)
2526 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2529 error = OMX_SetupTunnel(omx_vid_rend, omx_rend_input_port, NULL, 0);
2531 if (error != OMX_ErrorNone)
2533 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2536 error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, NULL, 0);
2538 if (error != OMX_ErrorNone)
2540 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2543 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_clock_port, NULL, 0);
2545 if (error != OMX_ErrorNone)
2547 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2550 error = OMX_FreeHandle(omx_vid_dec);
2551 error = OMX_FreeHandle(omx_vid_sched);
2552 error = OMX_FreeHandle(omx_vid_rend);
2554 if (dodeint) error = OMX_FreeHandle(omx_vid_deint);
2557 omx_vid_stalled = false;
2558 clock_mutex.unlock();
2561 if (error != OMX_ErrorNone)
2563 logger->debug(TAG, "FreeHandle failed {}", error);
2567 clock_mutex.unlock();
2569 logger->debug(TAG, "leave deallocate codecs OMX");
2574 void VideoOMX::destroyClock()
2578 if (clock_references > 0)
2582 if (clock_references == 0)
2584 OMX_ERRORTYPE error;
2585 logger->debug(TAG, "destroy omx clock");
2586 error = OMX_FreeHandle(omx_clock);
2588 if (error != OMX_ErrorNone)
2590 logger->debug(TAG, "FreeHandle failed {}", error);
2595 clock_mutex.unlock();
2598 int VideoOMX::stop()
2600 if (!initted) return 0;
2604 //Check if libav mode
2605 DeAllocateCodecsOMX();
2607 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2611 int VideoOMX::reset()
2613 if (!initted) return 0;
2616 DeAllocateCodecsOMX();
2617 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2621 int VideoOMX::pause()
2623 if (!initted) return 0;
2625 logger->debug(TAG, "enter pause");
2627 // ignore it audio handles this
2631 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2633 if (!initted) return 0;
2635 logger->debug(TAG, "enter unpause");
2638 //ignore it audio handles this
2643 int VideoOMX::fastForward()
2645 if (!initted) return 0;
2647 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2651 int VideoOMX::unFastForward()
2653 if (!initted) return 0;
2655 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2657 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2661 int VideoOMX::attachFrameBuffer()
2663 if (!initted) return 0;
2665 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2669 int VideoOMX::blank(void)
2671 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2672 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2676 u8 VideoOMX::getCurrentTimestamp()
2681 long long ncur_clock_time = cur_clock_time;
2687 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2688 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2690 OMX_ERRORTYPE error;
2691 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2692 memset(&clock_conf, 0, sizeof(clock_conf));
2693 clock_conf.nSize = sizeof(clock_conf);
2694 clock_conf.nVersion.nVersion = OMX_VERSION;
2695 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
2697 if (error != OMX_ErrorNone)
2699 logger->debug(TAG, "getCurrentTimestamp IndexConfigTimeClockState failed {:#x}", error);
2702 if (clock_conf.eState == OMX_TIME_ClockStateRunning)
2704 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2705 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2706 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2707 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2708 cur_time_stamp.nPortIndex = omx_clock_output_port;
2709 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, &cur_time_stamp);
2711 if (error != OMX_ErrorNone)
2713 logger->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}", error);
2717 long long temp = cur_time_stamp.nTimestamp.nLowPart
2718 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2719 ncur_clock_time = cur_clock_time = temp * 10LL;
2723 clock_mutex.unlock();
2724 pthread_setcancelstate(oldcancelstate, NULL);
2725 pthread_setcanceltype(oldcanceltype, NULL);
2728 //ncur_clock_time -= startoffset;
2729 ncur_clock_time -= lastreftimeOMX;
2730 long long result = lastreftimePTS;
2732 if (lastreftimePTS == 0) return 0; // invalid time
2734 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2737 result = (1LL << 33) - result;
2739 //logger->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2747 u4 VideoOMX::timecodeToFrameNumber(u8 timecode)
2749 if (format == PAL) return (u4)(((double)timecode / (double)90000) * (double)25);
2750 else return (u4)(((double)timecode / (double)90000) * (double)30);
2755 int VideoOMX::test()
2760 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2767 int VideoOMX::test2()
2773 long long VideoOMX::SetStartOffset(long long curreftime, bool* rsync)
2779 startoffset = curreftime; //offset is set for audio
2780 offsetnotset = false;
2781 offsetvideonotset = false;
2785 if (offsetvideonotset)
2787 offsetvideonotset = false;
2792 if ( (curreftime - lastrefvideotime) > 10000000LL
2793 || (curreftime - lastrefvideotime) < -10000000LL) //if pts jumps to big resync
2795 startoffset += curreftime - lastrefvideotime;
2796 lastrefaudiotime += curreftime - lastrefvideotime;
2798 offsetaudionotset = true;
2803 lastrefvideotime = curreftime;
2808 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool* rsync)
2814 startoffset = curreftime;
2815 offsetnotset = false;
2816 offsetaudionotset = false;
2820 if (offsetaudionotset)
2822 offsetaudionotset = false;
2827 if ( (curreftime - lastrefaudiotime) > 10000000LL
2828 || (curreftime - lastrefaudiotime) < -10000000LL) //if pts jumps to big resync
2830 startoffset += curreftime - lastrefaudiotime;
2831 lastrefvideotime += curreftime - lastrefaudiotime;
2833 offsetvideonotset = true;
2838 lastrefaudiotime = curreftime;
2842 void VideoOMX::ResetTimeOffsets()
2844 offsetnotset = true; //called from demuxer
2845 offsetvideonotset = true;
2846 offsetaudionotset = true;
2848 lastrefaudiotime = 0;
2849 lastrefvideotime = 0;
2854 void VideoOMX::FirstFrameFix()
2858 Demuxer* demux = Demuxer::getInstance();
2859 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2860 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2863 if (WaitForEvent(omx_vid_dec, OMX_EventPortSettingsChanged, 0))
2865 WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged, 0); //clear old messages
2866 OMX_ERRORTYPE error;
2867 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2868 memset(&port_def_type, 0, sizeof(port_def_type));
2869 port_def_type.nSize = sizeof(port_def_type);
2870 port_def_type.nVersion.nVersion = OMX_VERSION;
2871 port_def_type.nPortIndex = omx_codec_output_port;
2873 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2875 if (error != OMX_ErrorNone)
2877 logger->debug(TAG, "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2878 clock_mutex.unlock();
2883 "Deinit first frame fix {} {} {} {} {} {} {} {}", port_def_type.format.video.nFrameWidth, demux->getHorizontalSize(),
2884 port_def_type.format.video.nFrameHeight, demux->getVerticalSize(), port_def_type.format.video.nStride,
2885 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2886 port_def_type.format.video.bFlagErrorConcealment );
2888 "Deinit first frame fix2 {} {}",
2889 port_def_type.format.video.eCompressionFormat,
2890 port_def_type.format.video.eColorFormat );
2891 first_frame = false;
2893 // we cause the video_decode to determine the interlacing properties
2894 OMX_CONFIG_INTERLACETYPE il;
2895 memset(&il, 0, sizeof(il));
2896 il.nSize = sizeof(il);
2897 il.nVersion.nVersion = OMX_VERSION;
2898 il.nPortIndex = omx_codec_output_port;
2899 error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigCommonInterlace, &il);
2901 if (error != OMX_ErrorNone)
2903 logger->debug(TAG, "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2906 DisablePort(omx_vid_dec, omx_codec_output_port, true);
2907 DisablePort(omx_vid_sched, omx_shed_input_port, true);
2911 DisablePort(omx_vid_deint, omx_deint_input_port, true);
2912 // This is a dirty hack
2913 DisablePort(omx_vid_deint, omx_deint_output_port, true);
2915 port_def_type.nPortIndex = omx_deint_output_port;
2916 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2918 if (error != OMX_ErrorNone)
2920 logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2921 clock_mutex.unlock();
2922 pthread_setcancelstate(oldcancelstate, NULL);
2923 pthread_setcanceltype(oldcanceltype, NULL);
2929 port_def_type.nPortIndex = omx_deint_input_port;
2930 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2932 if (error != OMX_ErrorNone)
2934 logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2935 clock_mutex.unlock();
2936 pthread_setcancelstate(oldcancelstate, NULL);
2937 pthread_setcanceltype(oldcanceltype, NULL);
2941 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2943 logger->debug(TAG, "Marker");
2944 EnablePort(omx_vid_deint, omx_deint_input_port, true);
2945 WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged);
2946 port_def_type.nPortIndex = omx_deint_output_port;
2947 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2949 if (error != OMX_ErrorNone)
2951 logger->debug(TAG, "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2952 clock_mutex.unlock();
2953 pthread_setcancelstate(oldcancelstate, NULL);
2954 pthread_setcanceltype(oldcanceltype, NULL);
2959 "Deinit first frame fix3 {} {} {} {} {} {} {} ", port_def_type.format.image.nFrameWidth, demux->getHorizontalSize(),
2960 port_def_type.format.image.nFrameHeight, demux->getVerticalSize(), port_def_type.format.image.nStride,
2961 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2962 port_def_type.format.image.bFlagErrorConcealment );
2964 "Deinit first frame fix4 {} {}",
2965 port_def_type.format.image.eCompressionFormat,
2966 port_def_type.format.image.eColorFormat );
2968 DisablePort(omx_vid_deint, omx_deint_output_port, true);
2971 port_def_type.nPortIndex = omx_shed_input_port;
2972 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, &port_def_type);
2974 if (error != OMX_ErrorNone)
2976 logger->debug(TAG, "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2977 clock_mutex.unlock();
2978 pthread_setcancelstate(oldcancelstate, NULL);
2979 pthread_setcanceltype(oldcanceltype, NULL);
2983 WaitForEvent(omx_vid_sched, OMX_EventPortSettingsChanged);
2986 EnablePort(omx_vid_deint, omx_deint_output_port, true);
2988 EnablePort(omx_vid_dec, omx_codec_output_port, true);
2989 EnablePort(omx_vid_sched, omx_shed_input_port, true);
2992 clock_mutex.unlock();
2993 pthread_setcancelstate(oldcancelstate, NULL);
2994 pthread_setcanceltype(oldcanceltype, NULL);
2997 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2999 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
3001 if (error != OMX_ErrorNone)
3003 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
3006 if (first_frame) FirstFrameFix();
3009 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
3011 // protect the call to empty this buffer
3014 /* long long temp =buffer->nTimeStamp.nLowPart
3015 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
3017 //pthread_testcancel();
3018 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3019 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3022 /* OMX_ERRORTYPE error;
3023 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
3024 memset(×tamp, 0, sizeof(timestamp));
3025 timestamp.nSize = sizeof(timestamp);
3026 timestamp.nVersion.nVersion = OMX_VERSION;
3027 timestamp.nPortIndex =omx_clock_output_port;
3029 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
3032 if (error != OMX_ErrorNone) {
3034 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
3035 omx_rend_input_port);
3037 long long temp2 =timestamp.nTimestamp.nLowPart
3038 | ((long long) timestamp.nTimestamp.nHighPart << 32);
3040 logger->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
3041 OMX_ERRORTYPE ret_val;
3042 ret_val = OMX_EmptyThisBuffer(handle, buffer);
3043 clock_mutex.unlock();
3044 pthread_setcancelstate(oldcancelstate, NULL);
3045 pthread_setcanceltype(oldcanceltype, NULL);
3046 //pthread_testcancel();
3050 bool VideoOMX::detectIFrame(const u1* buffer, unsigned int length)
3052 const u1* curbuf = buffer;
3053 const u1* curbufend = buffer + length;
3054 unsigned int detector = 0xFFFFFFFF;
3055 bool gotaud = false; // have seen access unit delimiter
3057 while (curbuf != curbufend)
3060 detector |= *curbuf;
3064 if (detector == 0x00000109)
3067 detector = 0xFFFFFFFF;
3069 else if (gotaud && detector == 0x00000001)
3073 if (curbuf != curbufend)
3075 unsigned char picttype = (*curbuf) & 0x1F;
3076 return picttype == 0x07;
3082 if (detector == 0x00000100)
3086 if (curbuf == curbufend) return false;
3090 if (curbuf == curbufend) return false;
3092 unsigned char picttype = ((*curbuf) >> 3) & 0x07;
3093 return picttype == 1;
3100 return false; // no frame found
3103 bool VideoOMX::DrainTargetBufferFull()
3105 //Check, if we have OMX output buffers
3107 input_bufs_omx_mutex.lock();
3108 full = (input_bufs_omx_free.size() == 0);
3109 input_bufs_omx_mutex.unlock();
3110 checkForStalledBuffers(); // check if the decoder has a problem
3112 if (full && omx_vid_stalled && !omx_first_frame)
3114 omx_vid_stalled = false;
3115 logger->debug(TAG, "Decoder is stalled, do a reset!");
3119 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3120 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3123 FlushRenderingPipe();
3124 omx_first_frame = true;
3125 clock_mutex.unlock();
3127 pthread_setcancelstate(oldcancelstate, NULL);
3128 pthread_setcanceltype(oldcanceltype, NULL);
3134 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */)
3136 mediapackets.clear();
3137 std::list<MediaPacket>::const_iterator begin = mplist.begin();
3138 std::list<MediaPacket>::const_iterator itty = mplist.begin();
3139 advance(itty, std::min(mplist.size(), 10U));
3140 mediapackets.insert(mediapackets.begin(), begin, itty); //front
3143 u4 VideoOMX::DeliverMediaSample(u1* buffer, u4* samplepos)
3147 while (consumed < mediapackets.size())
3149 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
3151 if (*samplepos == mediapackets[consumed].length)
3157 else return consumed;
3163 u4 VideoOMX::DeliverMediaPacket(MediaPacket packet, const u1* buffer, u4* samplepos)
3165 if (packet.type == MPTYPE_VIDEO_H264)
3174 //Later add fail back code for libav
3176 *samplepos+=packet.length;
3177 return packet.length;
3180 if (!omx_running) return 0; // if we are not runnig do not do this
3182 if (isClockPaused()) return 0; //Block if we pause
3184 // logger->debug(TAG, "DMP mark 1");
3185 //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
3187 /*First Check, if we have an video sample*/
3192 return 0; //Not in iframe mode!
3197 if (packet.disconti)
3199 firstsynched = false;
3201 if (cur_input_buf_omx)
3203 PutBufferToPres(cur_input_buf_omx);
3204 cur_input_buf_omx = NULL;
3208 //logger->debug(TAG, "DMP mark 2");
3209 /*Inspect PES-Header */
3211 // OMX_STATETYPE temp_state;
3212 // OMX_GetState(omx_vid_dec,&temp_state);
3214 if (*samplepos == 0) //stripheader
3216 headerstrip = buffer[packet.pos_buffer + 8] + 9/*is this right*/;
3217 // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
3218 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
3219 *samplepos += headerstrip;
3221 if (headerstrip >= packet.length)
3223 *samplepos = packet.length; // Packet is obviously damaged
3224 return packet.length;//skip it!
3231 //logger->debug(TAG, "DMP mark 2a");
3232 // check if this is an I frame, the decoder does not like non I frames at startup!
3233 if (!detectIFrame(buffer, packet.length))
3235 *samplepos = packet.length; //if we have not processed at least one
3236 //logger->debug(TAG, "DMP mark 3");
3237 return packet.length;//synched packet ignore it!
3241 if (cur_input_buf_omx)
3243 //logger->debug(TAG, "DMP mark 4a");
3244 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
3245 PutBufferToPres(cur_input_buf_omx);
3246 cur_input_buf_omx = NULL; //write out old data
3248 //logger->debug(TAG, "DMP mark 4b");
3251 firstsynched = true;
3255 if (!firstsynched) //
3257 *samplepos = packet.length; //if we have not processed at least one
3258 //logger->debug(TAG, "DMP mark 5");
3259 return packet.length;//synched packet ignore it!
3264 //logger->debug(TAG, "DMP mark 6");
3265 if (!cur_input_buf_omx)
3267 input_bufs_omx_mutex.lock();
3269 if (input_bufs_omx_free.size() == 0)
3271 input_bufs_omx_mutex.unlock();
3272 //logger->debug(TAG, "Deliver MediaPacket no free sample");
3273 //logger->debug(TAG, "DMP mark 7");
3274 return 0; // we do not have a free media sample
3277 cur_input_buf_omx = input_bufs_omx_free.front();
3278 cur_input_buf_omx->nFilledLen = 0;
3279 cur_input_buf_omx->nOffset = 0;
3280 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3281 input_bufs_omx_free.pop_front();
3282 input_bufs_omx_mutex.unlock();
3285 if (cur_input_buf_omx->nFilledLen == 0) //will only be changed on first packet
3289 // logger->debug(TAG, "packet synched marker");
3291 //lastreftimePTS=packet.pts;
3292 if (omx_first_frame) // TODO time
3294 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3295 logger->debug(TAG, "Starttime");
3296 omx_first_frame = false;
3300 cur_input_buf_omx->nFlags = 0;
3301 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3304 lastreftimeOMX = packet.presentation_time;
3305 // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3306 lastreftimePTS = packet.pts;
3307 cur_input_buf_omx->nTimeStamp = intToOMXTicks(lastreftimeOMX / 10LL); // the clock component is faulty;
3311 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3312 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3313 //logger->debug(TAG, "packet unsynched marker");
3316 if (packet.disconti) cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
3319 unsigned int haveToCopy = packet.length - *samplepos;
3320 //logger->debug(TAG, "DMP mark 8");
3322 while (haveToCopy > (cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen))
3324 //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3325 unsigned int cancopy = cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen;
3326 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + packet.pos_buffer + *samplepos, cancopy);
3327 haveToCopy -= cancopy;
3328 cur_input_buf_omx->nFilledLen += cancopy;
3329 *samplepos += cancopy;
3330 // push old buffer out
3331 //logger->debug(TAG, "DMP mark 9");
3333 PutBufferToPres(cur_input_buf_omx);
3334 cur_input_buf_omx = NULL;
3336 input_bufs_omx_mutex.lock();
3338 if (input_bufs_omx_free.size() == 0)
3340 input_bufs_omx_mutex.unlock();
3341 // logger->debug(TAG, "Deliver MediaPacket no free sample2");
3342 return *samplepos; // we do not have a free media sample
3345 cur_input_buf_omx = input_bufs_omx_free.front();
3346 cur_input_buf_omx->nFilledLen = 0;
3347 cur_input_buf_omx->nOffset = 0;
3348 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3349 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3350 input_bufs_omx_free.pop_front();
3351 input_bufs_omx_mutex.unlock();
3352 //logger->debug(TAG, "DMP mark 10");
3355 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3356 buffer + packet.pos_buffer + *samplepos, haveToCopy);
3357 cur_input_buf_omx->nFilledLen += haveToCopy;
3359 // logger->debug(TAG, "DMP mark 11");
3361 *samplepos += haveToCopy;
3366 bool VideoOMX::displayIFrame(const u1* buffer, u4 length)
3368 if (!omx_running) return false;
3371 EnterIframePlayback();
3373 //int haveToCopy = length;
3375 if (!cur_input_buf_omx)
3377 input_bufs_omx_mutex.lock();
3379 if (input_bufs_omx_free.size() == 0)
3381 input_bufs_omx_mutex.unlock();
3382 // logger->debug(TAG,
3383 // "Deliver MediaPacket no free sample");
3384 return false; // we do not have a free media sample
3387 cur_input_buf_omx = input_bufs_omx_free.front();
3388 cur_input_buf_omx->nFilledLen = 0;
3389 cur_input_buf_omx->nOffset = 0;
3390 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3391 input_bufs_omx_free.pop_front();
3392 input_bufs_omx_mutex.unlock();
3396 unsigned int pattern, packet_length;
3397 unsigned int headerstrip = 0;
3405 //Now we strip the pes header
3406 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3408 while ((read_pos + 7) <= length)
3410 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3412 if (pattern < 0x000001E0 || pattern > 0x000001EF)
3419 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3420 packet_length = ((buffer[read_pos + 4] << 8)
3421 | (buffer[read_pos + 5])) + 6;
3423 if (read_pos + packet_length > length)
3427 if ((headerstrip < packet_length)
3428 && (cur_input_buf_omx->nFilledLen + packet_length
3429 - headerstrip) > cur_input_buf_omx->nAllocLen)
3433 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3437 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3440 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3441 PutBufferToPres(cur_input_buf_omx);
3442 cur_input_buf_omx = NULL;
3444 if (!cur_input_buf_omx)
3448 while (count < 100 && omx_running && iframemode)
3452 input_bufs_omx_mutex.lock();
3454 if (input_bufs_omx_free.size() == 0)
3456 input_bufs_omx_mutex.unlock();
3457 // logger->debug(TAG,
3458 // "Ifrane no free sample");
3461 if (!omx_running) return false;
3466 cur_input_buf_omx = input_bufs_omx_free.front();
3467 cur_input_buf_omx->nFilledLen = 0;
3468 cur_input_buf_omx->nOffset = 0;
3469 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3470 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3471 input_bufs_omx_free.pop_front();
3472 input_bufs_omx_mutex.unlock();
3476 if (!cur_input_buf_omx) return false;
3480 if (packet_length > headerstrip)
3483 cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3484 buffer + read_pos + headerstrip,
3485 packet_length - headerstrip);
3487 cur_input_buf_omx->nFilledLen += packet_length - headerstrip;
3490 read_pos += packet_length;
3492 pattern = (buffer[read_pos] << 16)
3493 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3500 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3504 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3507 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3509 PutBufferToPres(cur_input_buf_omx);
3510 cur_input_buf_omx = NULL;
3512 MILLISLEEP(40); //Block a bit
3516 int VideoOMX::EnterIframePlayback()
3518 logger->debug(TAG, "EnterIframePlayback");
3520 if (cur_input_buf_omx)
3522 PutBufferToPres(cur_input_buf_omx);
3523 cur_input_buf_omx = NULL;
3526 logger->debug(TAG, "EnterIframePlayback 2");
3527 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3528 DeAllocateCodecsOMX();
3529 AllocateCodecsOMX();
3530 logger->debug(TAG, "leave IframePlayback");