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"
40 //A lot of parts of this file are heavily inspired by xbmc omx implementations
42 static const char* TAG = "VideoOMX";
44 // Static OMX callbacks
46 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle, OMX_IN OMX_PTR appdata,
47 OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1,
48 OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data)
50 //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data);
52 struct VPE_OMX_EVENT new_event;
53 new_event.handle = handle;
54 new_event.appdata = appdata;
55 new_event.event_type = event_type;
56 new_event.data1 = data1;
57 new_event.data2 = data2;
58 new_event.event_data = event_data;
60 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
61 video->AddOmxEvent(new_event);
63 /* switch (event_type) {
64 case OMX_EventCmdComplete: {
72 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* buffer)
74 // LogNT::getInstance()->info(TAG, "EmptyBufferDone");
75 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
76 /* long long temp =buffer->nTimeStamp.nLowPart
77 | ((long long) buffer->nTimeStamp.nHighPart << 32);
78 LogNT::getInstance()->info(TAG, "EBD Video %lld {:#x}",temp,buffer->nFlags);*/
79 video->ReturnEmptyOMXBuffer(buffer);
83 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* /*buffer*/)
85 //LogNT::getInstance()->info(TAG, "FillBufferDone");
89 // -----------------------------------
93 logger = LogNT::getInstance();
98 deinterlace = 2; //advanced
100 strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
101 strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
102 strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
103 strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
104 strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
105 strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
108 VideoOMX::~VideoOMX()
113 int VideoOMX::init(u1 tformat)
115 if (initted) return 0;
119 // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
120 // Seems safe to call it more than once.
123 int ret = vc_gencmd_send("codec_enabled MPG2");
127 logger->debug(TAG, "vc_gencmd_send failed {:#x}", ret);
132 ret = vc_gencmd_read_response(buffer, sizeof(buffer));
136 logger->debug(TAG, "vc_gencmd_read_response failed {:#x}", ret);
140 if (STRCASECMP(buffer, "MPG2=enabled") == 0)
142 mpeg2_supported = true;
144 else if (STRCASECMP(buffer, "MPG2=disabled") == 0)
146 mpeg2_supported = false;
150 logger->debug(TAG, "Undefined mpg codec answer {}", buffer);
155 if (!setFormat(tformat)) { shutdown(); return 0; }
156 if (!setConnection(HDMI)) { shutdown(); return 0; }
157 if (!setAspectRatio(ASPECT4X3, 12, 11)) { shutdown(); return 0; }
158 if (!setMode(NORMAL)) { shutdown(); return 0; }
159 if (!setSource()) { shutdown(); return 0; }
160 if (!attachFrameBuffer()) { shutdown(); return 0; }
162 setTVsize(ASPECT16X9);
168 if (error != OMX_ErrorNone)
170 logger->debug(TAG, "Init OMX failed {:#x}", error);
178 void VideoOMX::signalOmx()
181 * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
182 * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
183 * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
184 * in what the Signal class used to do here and I'll sort it out later.
185 * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
186 * exact sychronisation and remove the wait spin loops? Unknown.
188 * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
189 * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
191 * Callers of signalOmx:
193 * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
194 * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
195 * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
197 * Surprise: WaitForEvent isn't a long running loop while video is playing.
200 omx_event_ready_signal_mutex.lock();
201 omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
202 omx_event_ready_signal_mutex.unlock();
205 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
207 omx_event_mutex.lock();
208 omx_events.push_back(new_event);
209 omx_event_mutex.unlock();
214 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer)
216 input_bufs_omx_mutex.lock();
217 //logger->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size());
218 input_bufs_omx_free.push_back(buffer);
219 //logger->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
220 input_bufs_omx_mutex.unlock();
225 int VideoOMX::shutdown()
227 if (!initted) return 0;
230 logger->info(TAG, "Shutdown video module");
232 DeAllocateCodecsOMX();
234 //vc_tv_show_info(0); // back to console
237 struct fb_var_screeninfo screeninfo;
238 fd_fbset = open("/dev/fb0", O_RDONLY);
242 logger->crit(TAG, "Could not open frame buffer device {}", fd_fbset);
246 if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo))
249 logger->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device");
253 screeninfo.bits_per_pixel = 8;
255 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
257 logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
260 screeninfo.bits_per_pixel = 16;
262 if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
264 logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
271 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
273 logger->debug(TAG, "VideoOMX config load");
274 char* name = vdr->configLoad("VideoOMX", "SDDeinterlacing");
278 if (STRCASECMP(name, "None") == 0)
282 /* else if (STRCASECMP(name, "LineDouble") == 0)
286 else if (STRCASECMP(name, "Advanced") == 0)
290 /* else if (STRCASECMP(name, "Crazy") == 0)
292 deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
295 else if (STRCASECMP(name, "Fast") == 0)
300 logger->debug(TAG, "Set deinterlacing to {} {}", name, deinterlace);
308 bool VideoOMX::handleOptionChanges(Option* option)
310 if (Video::handleOptionChanges(option))
317 if (STRCASECMP(option->options[option->userSetChoice], "None") == 0)
321 /* else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble") == 0)
325 else if (STRCASECMP(option->options[option->userSetChoice], "Advanced") == 0)
329 /* else if (STRCASECMP(option->options[option->userSetChoice], "Crazy") == 0)
333 else if (STRCASECMP(option->options[option->userSetChoice], "Fast") == 0)
338 logger->debug(TAG, "Set deinterlacing to {} {}", option->options[option->userSetChoice], deinterlace);
346 bool VideoOMX::saveOptionstoServer()
351 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "None");
354 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
357 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Advanced");
360 VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
363 VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
370 /*Option(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType,
371 u4 numChoices, u4 defaultChoice, u4 startInt,
372 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
374 bool VideoOMX::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane)
376 if (!Video::addOptionsToPanes(panenumber, options, pane)) return false;
382 static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
383 option = new Option(1, tr("SD Deinterlacing"), "VideoOMX", "SDDeinterlacing", Option::TYPE_TEXT,/*4,2*/3, 2, 0, deinterlaceopts, NULL, false, this);
384 options->push_back(option);
385 pane->addOptionLine(option);
391 int VideoOMX::setTVsize(u1 ttvsize)
393 if (tvsize != ttvsize) pendingmodechange = true;
399 u1 VideoOMX::getTVsize()
402 return ASPECT16X9; // in order that aspect ratio changes are reported
406 void VideoOMX::executePendingModeChanges()
408 if (pendingmodechange)
410 logger->info(TAG, "Execute pending mode change");
411 Osd::getInstance()->shutdown();
413 Osd::getInstance()->restore();
414 Osd::getInstance()->init();
415 BoxStack::getInstance()->redrawAllBoxes();
420 int VideoOMX::setDefaultAspect()
422 return setAspectRatio(tvsize, parx, pary);
425 int VideoOMX::setFormat(u1 tformat)
427 if (!initted) return 0;
429 if ((tformat != PAL) && (tformat != NTSC)
430 && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
441 // selectVideoMode(0);
446 void VideoOMX::selectVideoMode(int interlaced)
448 TV_GET_STATE_RESP_T tvstate;
449 vc_tv_get_state(&tvstate);
451 if ((tvstate.state & VC_HDMI_UNPLUGGED))
454 logger->info(TAG, "HDMI unplugged");
459 logger->info(TAG, "HDMI plugged");
461 if (connection == COMPOSITERGB)
464 logger->info(TAG, "SDTV set");
469 logger->info(TAG, "HDMI set");
475 TV_SUPPORTED_MODE_T all_supp_modes[200];
476 HDMI_RES_GROUP_T pref_group;
477 TV_SUPPORTED_MODE_T* mymode = NULL;
478 TV_SUPPORTED_MODE_T* mymode_second_best = NULL;
479 // bool got_optimum=false;
481 HDMI_RES_GROUP_T group = HDMI_RES_GROUP_CEA;
482 int all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
484 &pref_group, &pref_mode);
486 if (all_my_modes <= 0)
488 group = HDMI_RES_GROUP_DMT;
489 all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
491 &pref_group, &pref_mode);
492 logger->info(TAG, "No CEA fall back to DMT modes ");
497 if (format == PAL)target_fps = 50;
498 else if (format == NTSC) target_fps = 60;
500 //Now first determine native resolution
501 int native_width = 1920;
502 int native_height = 1080;
504 for (int i = 0; i < all_my_modes; i++)
506 if (all_supp_modes[i].native)
508 mymode = all_supp_modes + i;
509 logger->info(TAG, "Found native mode {}x{} {} Hz i: {}",
510 mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
511 native_width = mymode->width;
512 native_height = mymode->height;
516 //Now find the mode which matches best
517 for (int i = 0; i < all_my_modes; i++)
519 TV_SUPPORTED_MODE_T* curmode = all_supp_modes + i;
521 if (curmode->width == native_width &&
522 curmode->height == native_height &&
523 curmode->frame_rate == target_fps)
525 if (curmode->scan_mode == interlaced)
529 logger->info(TAG, "Found optimum mode {}x{} {} Hz i: {}",
530 mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
534 mymode_second_best = curmode;
535 logger->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}",
536 mymode_second_best->width, mymode_second_best->height,
537 mymode_second_best->frame_rate, mymode_second_best->scan_mode);
542 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
544 bool disableHDMIModeChange{false};
545 bool confSuccess = Config::getInstance()->getBool("videoomx", "disable-hdmi-modechange", disableHDMIModeChange);
547 if (!(confSuccess && disableHDMIModeChange))
553 logger->info(TAG, "Switch to optimum mode");
554 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode->code);
556 else if (mymode_second_best)
558 logger->info(TAG, "Switch to close to optimum mode");
559 vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode_second_best->code);
563 logger->info(TAG, "Switch to prefered mode");
564 vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
565 static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE | HDMI_MODE_MATCH_RESOLUTION | HDMI_MODE_MATCH_SCANMODE));
570 outputinterlaced = interlaced;
575 logger->info(TAG, "Analog tv case");
576 // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off();
577 SDTV_MODE_T setmode = SDTV_MODE_PAL;
578 SDTV_OPTIONS_T options;
584 logger->info(TAG, "SDTV aspect 16:9");
585 options.aspect = SDTV_ASPECT_16_9; break;
588 logger->info(TAG, "SDTV aspect 4:3");
589 options.aspect = SDTV_ASPECT_4_3; break;
592 logger->info(TAG, "SDTV aspect 14:9");
593 options.aspect = SDTV_ASPECT_14_9; break;
596 if (format == PAL) setmode = SDTV_MODE_PAL;
597 else if (format == NTSC) setmode = SDTV_MODE_NTSC;
598 else if (format == PAL_M)setmode = SDTV_MODE_PAL_M;
599 else if (format == NTSC_J) setmode = SDTV_MODE_NTSC_J;
601 vc_tv_sdtv_power_on(setmode, &options);
605 // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
606 // If this was just to reinit CEC then funcitons should be made to do that
609 pendingmodechange = false;
612 int VideoOMX::setConnection(u1 tconnection)
614 if (!initted) return 0;
615 if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0;
616 if (connection != tconnection) pendingmodechange = true;
617 connection = tconnection;
618 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
622 int VideoOMX::setAspectRatio(u1 taspectRatio, int tparx, int tpary)
624 if (!initted) return 0;
626 //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
627 aspectRatio = taspectRatio;
631 logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio, parx, pary);
634 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
638 int VideoOMX::setMode(u1 tmode)
640 if (!initted) return 0;
642 if (tmode == LETTERBOX || tmode == NORMAL) mode = tmode;
648 bool VideoOMX::setVideoDisplay(VideoDisplay display)
650 if (!initted) return false;
652 switch (display.mode)
654 case None: return true; //??
665 xpos = ((float) display.x) / ((float) screenWidth);
666 ypos = ((float) display.y) / ((float) screenHeight);
675 xpos = ((float) display.x) / ((float) screenWidth);
676 ypos = ((float) display.y) / ((float) screenHeight);
685 xpos = ((float) display.x) / ((float) screenWidth);
686 ypos = ((float) display.y) / ((float) screenHeight);
687 width = ((float) display.width) / ((float) screenWidth);
688 height = ((float) display.height) / ((float) screenHeight);
697 void VideoOMX::updateMode()
705 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
706 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
708 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
709 memset(&dispconf, 0, sizeof(dispconf));
710 dispconf.nSize = sizeof(dispconf);
711 dispconf.nVersion.nVersion = OMX_VERSION;
712 dispconf.nPortIndex = omx_rend_input_port;
714 dispconf.set = OMX_DISPLAY_SET_LAYER;
715 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
717 if (error != OMX_ErrorNone)
719 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error);
720 pthread_setcancelstate(oldcancelstate, NULL);
721 pthread_setcanceltype(oldcanceltype, NULL);
722 clock_mutex.unlock();
726 dispconf.pixel_x = parx;
727 dispconf.pixel_y = pary;
728 dispconf.set = OMX_DISPLAY_SET_PIXEL;
729 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
731 if (error != OMX_ErrorNone)
733 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error);
734 pthread_setcancelstate(oldcancelstate, NULL);
735 pthread_setcanceltype(oldcanceltype, NULL);
736 clock_mutex.unlock();
740 dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
745 dispconf.fullscreen = OMX_TRUE;
749 dispconf.fullscreen = OMX_FALSE;
752 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
753 if (error != OMX_ErrorNone)
755 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error);
756 pthread_setcancelstate(oldcancelstate, NULL);
757 pthread_setcanceltype(oldcanceltype, NULL);
758 clock_mutex.unlock();
762 dispconf.set = OMX_DISPLAY_SET_MODE;
766 dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL : OMX_DISPLAY_MODE_LETTERBOX;
770 dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
773 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
775 if (error != OMX_ErrorNone)
777 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error);
778 pthread_setcancelstate(oldcancelstate, NULL);
779 pthread_setcanceltype(oldcanceltype, NULL);
780 clock_mutex.unlock();
786 unsigned int display_width, display_height;
787 display_width = display_height = 0;
789 if (graphics_get_display_size(0, &display_width, &display_height) < 0)
791 logger->warn(TAG, "Getting display size failed! (BCM API) ");
792 pthread_setcancelstate(oldcancelstate, NULL);
793 pthread_setcanceltype(oldcanceltype, NULL);
794 clock_mutex.unlock();
798 //UnSetFullscreen with window
799 dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
800 dispconf.dest_rect.x_offset = (int) (xpos * ((float) display_width));
801 dispconf.dest_rect.y_offset = (int) (ypos * ((float) display_height));
802 dispconf.dest_rect.width = (int) (width * ((float) display_width));
803 dispconf.dest_rect.height = (int) (height * ((float) display_height));
804 logger->debug(TAG, "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset, dispconf.dest_rect.y_offset,
805 dispconf.dest_rect.width, dispconf.dest_rect.height);
807 error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
809 if (error != OMX_ErrorNone)
811 logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion failed {:#x}", error);
812 pthread_setcancelstate(oldcancelstate, NULL);
813 pthread_setcanceltype(oldcanceltype, NULL);
814 clock_mutex.unlock();
819 pthread_setcancelstate(oldcancelstate, NULL);
820 pthread_setcanceltype(oldcanceltype, NULL);
823 clock_mutex.unlock();
826 int VideoOMX::signalOff()
829 logger->info(TAG, "signalOff");
830 Osd::getInstance()->stopUpdate(); // turn off drawing thread
831 // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this
832 InputMan::getInstance()->shutdown();
834 InputMan::getInstance()->init();
839 int VideoOMX::signalOn()
843 Osd::getInstance()->shutdown();
844 logger->info(TAG, "signalOn");
846 Osd::getInstance()->restore();
847 Osd::getInstance()->init();
848 BoxStack::getInstance()->redrawAllBoxes();
855 int VideoOMX::setSource()
857 if (!initted) return 0;
859 // What does this do...
860 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
864 int VideoOMX::setPosition(int x, int y)
866 if (!initted) return 0;
868 xpos = ((float) x * 2.f) / ((float) screenWidth);
869 ypos = ((float) y * 2.f) / ((float) screenHeight);
877 if (!initted) return 0;
879 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
883 void VideoOMX::interlaceSwitch4Demux()
886 Demuxer* demux = Demuxer::getInstance();
888 if (hdmi) // only switch if hdmi and HD or interlaced SD material
891 int set_interlaced = 0;
893 if (demux->getHorizontalSize() > 720 && demux->getInterlaced())
898 logger->info(TAG, "switch interlacing {} {} {}", demux->getInterlaced(), outputinterlaced, set_interlaced);
900 if (outputinterlaced != set_interlaced)
902 selectVideoMode(set_interlaced);
903 Osd::getInstance()->shutdown();
904 Osd::getInstance()->restore();
905 Osd::getInstance()->init();
906 BoxStack::getInstance()->redrawAllBoxes();
916 if (!initted) return 0;
919 logger->debug(TAG, "enter play");
921 interlaceSwitch4Demux();
923 if (AllocateCodecsOMX())
926 // Otherwise fall back to libav
933 logger->info(TAG, "Allocate Codecs OMX failed assume h264 unsupported");
938 logger->info(TAG, "Allocate Codecs OMX failed assume mpeg2 unsupported");
945 int VideoOMX::initClock()
950 if (clock_references == 0)
952 static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
953 omx_event_mutex.lock();
955 omx_event_mutex.unlock();
957 error = OMX_GetHandle(&omx_clock, L_VPE_OMX_CLOCK, NULL, &callbacks);
959 if (error != OMX_ErrorNone)
961 logger->debug(TAG, "Init OMX clock failed {:#x}", error);
962 clock_mutex.unlock();
963 DeAllocateCodecsOMX();
967 /* TODO Clock config to separate method */
968 OMX_PORT_PARAM_TYPE p_param;
969 memset(&p_param, 0, sizeof(p_param));
970 p_param.nSize = sizeof(p_param);
971 p_param.nVersion.nVersion = OMX_VERSION;
972 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
974 if (error != OMX_ErrorNone)
976 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
977 clock_mutex.unlock();
978 DeAllocateCodecsOMX();
982 omx_clock_output_port = p_param.nStartPortNumber;
984 for (unsigned int i = 0; i < p_param.nPorts; i++)
986 if (!DisablePort(omx_clock, p_param.nStartPortNumber + i, true) )
988 logger->debug(TAG, "Disable Ports OMX clock failed {}", i);
989 clock_mutex.unlock();
990 DeAllocateCodecsOMX();
996 logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
998 clock_mutex.unlock();
1002 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port)
1004 OMX_ERRORTYPE error;
1005 *p_omx_clock = NULL;
1006 *p_omx_clock_output_port = 0;
1008 if (!initClock()) return 0;
1012 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1013 memset(&refclock, 0, sizeof(refclock));
1014 refclock.nSize = sizeof(refclock);
1015 refclock.nVersion.nVersion = OMX_VERSION;
1017 refclock.eClock = OMX_TIME_RefClockAudio;
1019 //refclock.eClock=OMX_TIME_RefClockVideo;
1020 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1022 if (error != OMX_ErrorNone)
1024 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1025 clock_mutex.unlock();
1026 DeAllocateCodecsOMX();
1030 OMX_PORT_PARAM_TYPE p_param;
1031 memset(&p_param, 0, sizeof(p_param));
1032 p_param.nSize = sizeof(p_param);
1033 p_param.nVersion.nVersion = OMX_VERSION;
1034 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1036 if (error != OMX_ErrorNone)
1038 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1039 clock_mutex.unlock();
1040 DeAllocateCodecsOMX();
1044 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1045 memset(&clock_conf, 0, sizeof(clock_conf));
1046 clock_conf.nSize = sizeof(clock_conf);
1047 clock_conf.nVersion.nVersion = OMX_VERSION;
1048 clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1049 clock_conf.nStartTime = intToOMXTicks(0);
1050 clock_conf.nOffset = intToOMXTicks(0);
1052 if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT1;
1053 else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1055 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1057 if (error != OMX_ErrorNone)
1059 logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
1062 *p_omx_clock_output_port = p_param.nStartPortNumber + 1;
1063 *p_omx_clock = omx_clock;
1064 clock_mutex.unlock();
1068 int VideoOMX::getClockVideoandInit()
1070 OMX_ERRORTYPE error;
1072 if (!initClock()) return 0;
1076 if (clock_references == 1) // only if no audio is attached to this clock!
1078 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1079 memset(&refclock, 0, sizeof(refclock));
1080 refclock.nSize = sizeof(refclock);
1081 refclock.nVersion.nVersion = OMX_VERSION;
1083 //refclock.eClock=OMX_TIME_RefClockAudio;
1085 refclock.eClock = OMX_TIME_RefClockVideo;
1086 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1088 if (error != OMX_ErrorNone)
1090 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1091 clock_mutex.unlock();
1092 DeAllocateCodecsOMX();
1097 OMX_PORT_PARAM_TYPE p_param;
1098 memset(&p_param, 0, sizeof(p_param));
1099 p_param.nSize = sizeof(p_param);
1100 p_param.nVersion.nVersion = OMX_VERSION;
1101 error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1103 if (error != OMX_ErrorNone)
1105 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1106 clock_mutex.unlock();
1107 DeAllocateCodecsOMX();
1111 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1112 memset(&clock_conf, 0, sizeof(clock_conf));
1113 clock_conf.nSize = sizeof(clock_conf);
1114 clock_conf.nVersion.nVersion = OMX_VERSION;
1115 clock_conf.eState = OMX_TIME_ClockStateStopped;
1116 clock_conf.nStartTime = intToOMXTicks(0);
1117 clock_conf.nOffset = intToOMXTicks(0);
1118 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1120 if (error != OMX_ErrorNone)
1122 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1125 memset(&clock_conf, 0, sizeof(clock_conf));
1126 clock_conf.nSize = sizeof(clock_conf);
1127 clock_conf.nVersion.nVersion = OMX_VERSION;
1128 clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1129 clock_conf.nStartTime = intToOMXTicks(0);
1130 clock_conf.nOffset = intToOMXTicks(0);
1132 if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT0;
1133 else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1135 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1137 if (error != OMX_ErrorNone)
1139 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1142 omx_clock_output_port = p_param.nStartPortNumber;
1143 clock_mutex.unlock();
1148 void VideoOMX::clockUnpause()
1150 OMX_ERRORTYPE error;
1151 logger->info(TAG, "enter Clockunpause");
1154 if (clock_references > 0 && clockpaused)
1156 OMX_TIME_CONFIG_SCALETYPE scale_type;
1157 memset(&scale_type, 0, sizeof(scale_type));
1158 scale_type.nSize = sizeof(scale_type);
1159 scale_type.nVersion.nVersion = OMX_VERSION;
1160 scale_type.xScale = 1 << 16;
1161 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1163 if (error != OMX_ErrorNone)
1165 logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1168 logger->info(TAG, "set playback speed ClockUnpause");
1169 clockpaused = false;
1172 clock_mutex.unlock();
1176 void VideoOMX::clockPause()
1178 OMX_ERRORTYPE error;
1179 logger->info(TAG, "enter ClockPause");
1182 if (clock_references > 0 && !clockpaused)
1184 OMX_TIME_CONFIG_SCALETYPE scale_type;
1185 memset(&scale_type, 0, sizeof(scale_type));
1186 scale_type.nSize = sizeof(scale_type);
1187 scale_type.nVersion.nVersion = OMX_VERSION;
1188 scale_type.xScale = 0;
1189 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1191 if (error != OMX_ErrorNone)
1193 logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1196 logger->info(TAG, "set playback speed ClockPause");
1200 clock_mutex.unlock();
1203 int VideoOMX::AllocateCodecsOMX()
1205 OMX_ERRORTYPE error;
1206 static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
1208 Demuxer* demux = Demuxer::getInstance();
1213 logger->info(TAG, "Allocate Codecs OMX");
1214 //Clock, move later to audio including events
1216 logger->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(), demux->getVerticalSize(), demux->getInterlaced());
1218 if (deinterlace != 0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced())
1221 logger->info(TAG, "Deinterlacing activated {}", deinterlace);
1224 if (!getClockVideoandInit())
1226 return 0;// get the clock and init it if necessary
1231 logger->debug(TAG, "idleClock failed");
1241 error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_H264_DECODER, NULL, &callbacks);
1245 error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_MPEG2_DECODER, NULL, &callbacks);
1248 if (error != OMX_ErrorNone)
1250 logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1251 clock_mutex.unlock();
1252 DeAllocateCodecsOMX();
1256 logger->debug(TAG, "Nmark3");
1257 OMX_PORT_PARAM_TYPE p_param;
1258 memset(&p_param, 0, sizeof(p_param));
1259 p_param.nSize = sizeof(p_param);
1260 p_param.nVersion.nVersion = OMX_VERSION;
1261 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamVideoInit, &p_param);
1263 if (error != OMX_ErrorNone)
1265 logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1266 clock_mutex.unlock();
1267 DeAllocateCodecsOMX();
1271 omx_codec_input_port = p_param.nStartPortNumber;
1272 omx_codec_output_port = p_param.nStartPortNumber + 1;
1274 if (!DisablePort(omx_vid_dec, omx_codec_input_port) || !DisablePort(omx_vid_dec, omx_codec_output_port))
1276 logger->debug(TAG, "Disable Ports OMX video decoder failed");
1277 clock_mutex.unlock();
1278 DeAllocateCodecsOMX();
1282 logger->debug(TAG, "Nmark4");
1284 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1285 memset(&conceal, 0, sizeof(conceal));
1286 conceal.nSize = sizeof(conceal);
1287 conceal.nVersion.nVersion = OMX_VERSION;
1288 conceal.bStartWithValidFrame = OMX_FALSE;
1290 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &conceal);
1292 if (error != OMX_ErrorNone)
1294 logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1295 clock_mutex.unlock();
1296 DeAllocateCodecsOMX();
1302 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL, &callbacks);
1304 if (error != OMX_ErrorNone)
1306 logger->debug(TAG, "Init OMX video deinterlacer failed {:#x}", error);
1307 clock_mutex.unlock();
1308 DeAllocateCodecsOMX();
1312 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit, &p_param);
1314 if (error != OMX_ErrorNone)
1316 logger->debug(TAG, "Init OMX video deinterlacer OMX_GetParameter failed {:#x}", error);
1317 clock_mutex.unlock();
1318 DeAllocateCodecsOMX();
1322 omx_deint_input_port = p_param.nStartPortNumber;
1323 omx_deint_output_port = p_param.nStartPortNumber + 1;
1325 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1326 || !DisablePort(omx_vid_deint, omx_deint_output_port, true))
1328 logger->debug(TAG, "Disable Ports OMX video deint failed");
1329 clock_mutex.unlock();
1330 DeAllocateCodecsOMX();
1335 error = OMX_GetHandle(&omx_vid_sched, L_VPE_OMX_VIDEO_SCHED, NULL, &callbacks);
1337 if (error != OMX_ErrorNone)
1339 logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1340 clock_mutex.unlock();
1341 DeAllocateCodecsOMX();
1345 error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamVideoInit, &p_param);
1347 if (error != OMX_ErrorNone)
1349 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1350 clock_mutex.unlock();
1351 DeAllocateCodecsOMX();
1355 omx_shed_input_port = p_param.nStartPortNumber;
1356 omx_shed_output_port = p_param.nStartPortNumber + 1;
1358 error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamOtherInit, &p_param);
1360 if (error != OMX_ErrorNone)
1362 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1363 clock_mutex.unlock();
1364 DeAllocateCodecsOMX();
1368 omx_shed_clock_port = p_param.nStartPortNumber;
1369 logger->debug(TAG, "scheduler ports {} {} {}", omx_shed_input_port, omx_shed_output_port, omx_shed_clock_port);
1371 if (!DisablePort(omx_vid_sched, omx_shed_input_port, true) || !DisablePort(omx_vid_sched, omx_shed_output_port, true)
1372 || !DisablePort(omx_vid_sched, omx_shed_clock_port, true))
1374 logger->debug(TAG, "Disable Ports OMX video shed failed");
1375 clock_mutex.unlock();
1376 DeAllocateCodecsOMX();
1380 error = OMX_GetHandle(&omx_vid_rend, L_VPE_OMX_VIDEO_REND, NULL, &callbacks);
1382 if (error != OMX_ErrorNone)
1384 logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1385 clock_mutex.unlock();
1386 DeAllocateCodecsOMX();
1390 error = OMX_GetParameter(omx_vid_rend, OMX_IndexParamVideoInit, &p_param);
1392 if (error != OMX_ErrorNone)
1394 logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1395 clock_mutex.unlock();
1396 DeAllocateCodecsOMX();
1400 omx_rend_input_port = p_param.nStartPortNumber;
1401 //omx_rend_output_port=p_param.nStartPortNumber+1;
1403 if (!DisablePort(omx_vid_rend, omx_rend_input_port, true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1406 logger->debug(TAG, "Disable Ports OMX video rend failed");
1407 clock_mutex.unlock();
1408 DeAllocateCodecsOMX();
1414 error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, omx_vid_sched, omx_shed_clock_port);
1416 if (error != OMX_ErrorNone)
1418 logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error, omx_clock_output_port, omx_shed_clock_port);
1419 clock_mutex.unlock();
1420 DeAllocateCodecsOMX();
1424 if (!EnablePort(omx_clock, omx_clock_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_clock_port, false)
1427 logger->debug(TAG, "Enable Ports OMX clock shed failed");
1428 clock_mutex.unlock();
1429 DeAllocateCodecsOMX();
1433 if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
1435 logger->debug(TAG, "vid_sched idle ChangeComponentState");
1436 clock_mutex.unlock();
1437 DeAllocateCodecsOMX();
1441 if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_clock_port))
1443 clock_mutex.unlock();
1444 DeAllocateCodecsOMX();
1448 if (!CommandFinished(omx_clock, OMX_CommandPortEnable, omx_clock_output_port))
1450 clock_mutex.unlock();
1451 DeAllocateCodecsOMX();
1455 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1456 if (error!=OMX_ErrorNone){
1457 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1461 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1462 memset(&ft_type, 0, sizeof(ft_type));
1463 ft_type.nSize = sizeof(ft_type);
1464 ft_type.nVersion.nVersion = OMX_VERSION;
1466 ft_type.nPortIndex = omx_codec_input_port;
1469 ft_type.eCompressionFormat = OMX_VIDEO_CodingAVC;
1471 ft_type.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1473 ft_type.xFramerate = 0 * (1 << 16); //25*(1<<16);//demux->getFrameRate()*(1<<16);
1474 logger->debug(TAG, "Framerate: {}", demux->getFrameRate());
1475 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamVideoPortFormat, &ft_type);
1477 if (error != OMX_ErrorNone)
1479 logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1480 clock_mutex.unlock();
1481 DeAllocateCodecsOMX();
1485 if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
1487 logger->debug(TAG, "vid_dec ChangeComponentState");
1488 clock_mutex.unlock();
1489 DeAllocateCodecsOMX();
1493 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1494 memset(&stall_conf, 0, sizeof(stall_conf));
1495 stall_conf.nSize = sizeof(stall_conf);
1496 stall_conf.nVersion.nVersion = OMX_VERSION;
1497 stall_conf.nPortIndex = omx_codec_output_port;
1498 stall_conf.nDelay = 1500 * 1000;
1499 error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
1501 if (error != OMX_ErrorNone)
1503 logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1504 clock_mutex.unlock();
1505 DeAllocateCodecsOMX();
1509 omx_vid_stalled = false;
1511 OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1512 memset(&req_callback, 0, sizeof(req_callback));
1513 req_callback.nSize = sizeof(req_callback);
1514 req_callback.nVersion.nVersion = OMX_VERSION;
1515 req_callback.nPortIndex = omx_codec_output_port;
1516 req_callback.nIndex = OMX_IndexConfigBufferStall;
1517 req_callback.bEnable = OMX_TRUE;
1518 error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigRequestCallback, &req_callback);
1520 if (error != OMX_ErrorNone)
1522 logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error);
1523 clock_mutex.unlock();
1524 DeAllocateCodecsOMX();
1528 if (!PrepareInputBufsOMX())
1530 clock_mutex.unlock();
1531 DeAllocateCodecsOMX();
1537 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_sched, omx_shed_input_port);
1539 if (error != OMX_ErrorNone)
1541 logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1542 clock_mutex.unlock();
1543 DeAllocateCodecsOMX();
1547 if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1549 logger->debug(TAG, "Enable Ports OMX codec shed failed");
1550 clock_mutex.unlock();
1551 DeAllocateCodecsOMX();
1555 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1557 clock_mutex.unlock();
1558 DeAllocateCodecsOMX();
1564 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_deint, omx_deint_input_port);
1566 if (error != OMX_ErrorNone)
1568 logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1569 clock_mutex.unlock();
1570 DeAllocateCodecsOMX();
1574 if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_deint, omx_deint_input_port, false))
1576 logger->debug(TAG, "Enable Ports OMX codec deint failed");
1577 clock_mutex.unlock();
1578 DeAllocateCodecsOMX();
1582 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_input_port))
1584 clock_mutex.unlock();
1585 DeAllocateCodecsOMX();
1589 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
1591 logger->debug(TAG, "vid_deint ChangeComponentState");
1592 clock_mutex.unlock();
1593 DeAllocateCodecsOMX();
1597 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1598 memset(&imagefilter, 0, sizeof(imagefilter));
1599 imagefilter.nSize = sizeof(imagefilter);
1600 imagefilter.nVersion.nVersion = OMX_VERSION;
1602 imagefilter.nPortIndex = omx_deint_output_port;
1603 imagefilter.nNumParams = 4;
1604 imagefilter.nParams[0] = 3; //???
1605 imagefilter.nParams[1] = 0; //default frame interval
1606 imagefilter.nParams[2] = 0; // frame rate
1608 if (demux->getHorizontalSize() <= 720)
1610 imagefilter.nParams[3] = 1;//use qpus
1614 imagefilter.nParams[3] = 0;//use qpus
1617 switch (deinterlace)
1620 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceLineDouble; break;
1623 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; break;
1626 imagefilter.eImageFilter = OMX_ImageFilterFilm; break;
1629 imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1632 error = OMX_SetConfig(omx_vid_deint, OMX_IndexConfigCommonImageFilterParameters, &imagefilter);
1634 if (error != OMX_ErrorNone)
1636 logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1637 clock_mutex.unlock();
1638 DeAllocateCodecsOMX();
1642 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, omx_vid_sched, omx_shed_input_port);
1644 if (error != OMX_ErrorNone)
1646 logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1647 clock_mutex.unlock();
1648 DeAllocateCodecsOMX();
1652 if (!EnablePort(omx_vid_deint, omx_deint_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1654 logger->debug(TAG, "Enable Ports OMX deint shed failed");
1655 clock_mutex.unlock();
1656 DeAllocateCodecsOMX();
1660 if (!CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1662 clock_mutex.unlock();
1663 DeAllocateCodecsOMX();
1668 if (!ChangeComponentState(omx_vid_dec, OMX_StateExecuting))
1670 logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1671 clock_mutex.unlock();
1672 DeAllocateCodecsOMX();
1676 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, omx_vid_rend, omx_rend_input_port);
1678 if (error != OMX_ErrorNone)
1680 logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error);
1681 clock_mutex.unlock();
1682 DeAllocateCodecsOMX();
1686 if (!EnablePort(omx_vid_sched, omx_shed_output_port, false) || !EnablePort(omx_vid_rend, omx_rend_input_port, false))
1688 logger->debug(TAG, "Enable Ports OMX shed rend failed");
1689 clock_mutex.unlock();
1690 DeAllocateCodecsOMX();
1694 if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_output_port)
1695 || !CommandFinished(omx_vid_rend, OMX_CommandPortEnable, omx_rend_input_port))
1697 clock_mutex.unlock();
1698 DeAllocateCodecsOMX();
1702 if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
1704 logger->debug(TAG, "vid_rend ChangeComponentState");
1705 clock_mutex.unlock();
1706 DeAllocateCodecsOMX();
1712 if (!ChangeComponentState(omx_vid_deint, OMX_StateExecuting))
1714 logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1715 clock_mutex.unlock();
1716 DeAllocateCodecsOMX();
1720 DisablePort(omx_vid_deint, omx_deint_output_port, false);
1721 DisablePort(omx_vid_deint, omx_deint_input_port, false);
1724 if (!ChangeComponentState(omx_vid_sched, OMX_StateExecuting))
1726 logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1727 clock_mutex.unlock();
1728 DeAllocateCodecsOMX();
1732 if (!ChangeComponentState(omx_vid_rend, OMX_StateExecuting))
1734 logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1735 clock_mutex.unlock();
1736 DeAllocateCodecsOMX();
1741 /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1742 memset(&dispconf,0,sizeof(dispconf));
1743 dispconf.nSize=sizeof(dispconf);
1744 dispconf.nVersion.nVersion=OMX_VERSION;
1746 dispconf.nPortIndex=omx_rend_input_port;
1748 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1750 error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1751 if (error!=OMX_ErrorNone){
1752 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1753 clock_mutex.unlock();
1754 DeAllocateCodecsOMX();
1758 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1759 dispconf.fullscreen=OMX_FALSE;
1760 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1761 if (error!=OMX_ErrorNone){
1762 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1763 clock_mutex.unlock();
1764 DeAllocateCodecsOMX();
1768 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1769 dispconf.dest_rect.x_offset=100;
1770 dispconf.dest_rect.y_offset=100;
1771 dispconf.dest_rect.width=640;
1772 dispconf.dest_rect.height=480;
1773 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1774 if (error!=OMX_ErrorNone){
1775 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1776 clock_mutex.unlock();
1777 DeAllocateCodecsOMX();
1782 //playbacktimeoffset=-GetCurrentSystemTime();
1786 clock_mutex.unlock();
1790 setClockExecutingandRunning();
1795 int VideoOMX::idleClock()
1797 //OMX_ERRORTYPE error;
1798 OMX_STATETYPE temp_state;
1800 OMX_GetState(omx_clock, &temp_state);
1802 if (temp_state != OMX_StateIdle)
1804 if (!ChangeComponentState(omx_clock, OMX_StateIdle))
1806 logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1807 clock_mutex.unlock();
1812 clock_mutex.unlock();
1816 int VideoOMX::setClockExecutingandRunning()
1818 OMX_ERRORTYPE error;
1819 OMX_STATETYPE temp_state;
1821 OMX_GetState(omx_clock, &temp_state);
1823 if (temp_state != OMX_StateExecuting)
1825 if (!ChangeComponentState(omx_clock, OMX_StateExecuting))
1827 logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1828 clock_mutex.unlock();
1829 DeAllocateCodecsOMX();
1834 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1835 memset(&clock_conf, 0, sizeof(clock_conf));
1836 clock_conf.nSize = sizeof(clock_conf);
1837 clock_conf.nVersion.nVersion = OMX_VERSION;
1838 clock_conf.eState = OMX_TIME_ClockStateRunning;
1839 error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1841 if (error != OMX_ErrorNone)
1843 logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1844 clock_mutex.unlock();
1845 DeAllocateCodecsOMX();
1849 clock_mutex.unlock();
1853 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait) //needs to be called with locked mutex
1855 OMX_ERRORTYPE error;
1856 error = OMX_SendCommand(handle, OMX_CommandStateSet, type, 0);
1858 if (error != OMX_ErrorNone)
1860 logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}", handle, type, error);
1866 if (!CommandFinished(handle, OMX_CommandStateSet, type)) return 0;
1873 int VideoOMX::EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1875 OMX_ERRORTYPE error;
1878 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1879 memset(&pdt, 0, sizeof(pdt));
1880 pdt.nSize = sizeof(pdt);
1881 pdt.nVersion.nVersion = OMX_VERSION;
1882 pdt.nPortIndex = port;
1883 error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1885 if (error == OMX_ErrorNone)
1887 if (pdt.bEnabled == OMX_TRUE)
1889 skip = true; //already disabled;
1895 error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, 0);
1897 if (error != OMX_ErrorNone)
1899 logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}", handle, port, error);
1903 if (!wait) return 1;
1905 if (!CommandFinished(handle, OMX_CommandPortEnable, port))
1914 int VideoOMX::DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1916 OMX_ERRORTYPE error;
1919 OMX_PARAM_PORTDEFINITIONTYPE pdt;
1920 memset(&pdt, 0, sizeof(pdt));
1921 pdt.nSize = sizeof(pdt);
1922 pdt.nVersion.nVersion = OMX_VERSION;
1923 pdt.nPortIndex = port;
1924 error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1926 if (error == OMX_ErrorNone)
1928 if (pdt.bEnabled == OMX_FALSE)
1930 skip = true; //already disabled;
1936 error = OMX_SendCommand(handle, OMX_CommandPortDisable, port, 0);
1938 if (error != OMX_ErrorNone)
1940 logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}", handle, port, error);
1944 if (!wait) return 1;
1946 if (!CommandFinished(handle, OMX_CommandPortDisable, port))
1955 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait) //needs to be called with locked mutex
1958 int iend = (wait / 5 + 1);
1962 omx_event_mutex.lock();
1963 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
1965 while (itty != omx_events.end())
1967 VPE_OMX_EVENT current = *itty;
1969 if (current.handle == handle) //this is ours
1971 if (current.event_type == OMX_EventError)
1973 omx_events.erase(itty);
1974 omx_event_mutex.unlock();
1975 logger->debug(TAG, "WaitForEvent Finished on Error");
1978 else if (current.event_type == event)
1980 omx_events.erase(itty);
1981 omx_event_mutex.unlock();
1982 logger->debug(TAG, "WaitForEvent Finished Completed");
1990 omx_event_mutex.unlock();
1992 //logger->debug(TAG, "WaitForEvent");
1993 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1994 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
2000 logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}", (void*)handle, event);
2004 int VideoOMX::clearEvents()
2006 omx_event_mutex.lock();
2008 omx_event_mutex.unlock();
2013 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
2015 omx_event_mutex.lock();
2016 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2018 while (itty != omx_events.end())
2020 VPE_OMX_EVENT current = *itty;
2022 if (current.handle == handle) //this is ours
2024 itty = omx_events.erase(itty);
2031 omx_event_mutex.unlock();
2035 void VideoOMX::checkForStalledBuffers()
2037 //logger->debug(TAG, "Check stalled");
2039 omx_event_mutex.lock();
2040 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2042 while (itty != omx_events.end())
2044 VPE_OMX_EVENT current = *itty;
2046 if (current.event_type == OMX_EventParamOrConfigChanged && current.data1 == omx_codec_output_port
2047 && current.handle == omx_vid_dec && current.data2 == OMX_IndexConfigBufferStall)
2049 OMX_ERRORTYPE error;
2050 OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
2051 memset(&stall_conf, 0, sizeof(stall_conf));
2052 stall_conf.nSize = sizeof(stall_conf);
2053 stall_conf.nVersion.nVersion = OMX_VERSION;
2054 stall_conf.nPortIndex = omx_codec_output_port;
2055 stall_conf.nDelay = 200000;
2057 error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
2059 if (error != OMX_ErrorNone)
2061 logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
2062 clock_mutex.unlock();
2063 omx_event_mutex.unlock();
2067 if (stall_conf.bStalled == OMX_TRUE)
2069 omx_vid_stalled = true;
2070 logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
2074 omx_vid_stalled = false;
2075 logger->debug(TAG, "Video decoder unstalled! {}", stall_conf.nDelay);
2078 omx_events.erase(itty);
2085 omx_event_mutex.unlock();
2086 clock_mutex.unlock();
2089 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2) //needs to be called with locked mutex
2093 while (i < 200/*1000*/)
2095 omx_event_mutex.lock();
2096 std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2098 while (itty != omx_events.end())
2100 VPE_OMX_EVENT current = *itty;
2102 if (current.handle == handle) //this is ours
2104 if (current.event_type == OMX_EventError)
2106 omx_events.erase(itty);
2107 omx_event_mutex.unlock();
2108 logger->debug(TAG, "Command Finished on Error {:#x}", current.data1);
2111 else if (current.event_type == OMX_EventCmdComplete && current.data1 == command && current.data2 == data2)
2113 omx_events.erase(itty);
2114 omx_event_mutex.unlock();
2115 //logger->debug(TAG, "Command Finished Completed");
2123 omx_event_mutex.unlock();
2125 std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
2126 omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
2132 logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}", handle, command, data2);
2136 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
2138 OMX_ERRORTYPE error;
2139 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2140 memset(&port_def_type, 0, sizeof(port_def_type));
2141 port_def_type.nSize = sizeof(port_def_type);
2142 port_def_type.nVersion.nVersion = OMX_VERSION;
2143 port_def_type.nPortIndex = omx_codec_input_port;
2145 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2147 if (error != OMX_ErrorNone)
2149 logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2152 /* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
2153 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
2154 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
2156 port_def_type.nBufferCountActual = 100;
2157 port_def_type.nBufferSize = std::max(toi4(port_def_type.nBufferSize), 150000); // for transcoder important
2159 error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2161 if (error != OMX_ErrorNone)
2163 logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2166 error = OMX_SendCommand(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port, 0);
2168 if (error != OMX_ErrorNone)
2170 logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
2174 input_bufs_omx_mutex.lock();
2176 for (unsigned int i = 0; i < port_def_type.nBufferCountActual; i++)
2178 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
2179 OMX_BUFFERHEADERTYPE* buf_head = NULL;
2180 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
2181 if (error!=OMX_ErrorNone){
2182 logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
2183 input_bufs_omx_mutex.unlock();
2186 error = OMX_AllocateBuffer(omx_vid_dec, &buf_head, omx_codec_input_port, NULL, port_def_type.nBufferSize);
2188 if (error != OMX_ErrorNone)
2190 logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2191 input_bufs_omx_mutex.unlock();
2195 input_bufs_omx_all.push_back(buf_head);
2196 input_bufs_omx_free.push_back(buf_head);
2199 omx_first_frame = true;
2201 firstsynched = false;
2202 cur_input_buf_omx = NULL;
2203 input_bufs_omx_mutex.unlock();
2205 logger->debug(TAG, "PrepareInputBufsOMX mark3");
2207 if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port))
2212 logger->debug(TAG, "PrepareInputBufsOMX mark4");
2217 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2219 OMX_ERRORTYPE error;
2221 cur_input_buf_omx = NULL;
2222 input_bufs_omx_mutex.lock();
2224 for (u4 i = 0; i < input_bufs_omx_all.size(); i++)
2226 // free(input_bufs_omx_all[i]->pBuffer);
2227 // input_bufs_omx_all[i]->pBuffer=NULL;
2228 error = OMX_FreeBuffer(omx_vid_dec, omx_codec_input_port, input_bufs_omx_all[i]);
2230 if (error != OMX_ErrorNone)
2232 logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2233 input_bufs_omx_mutex.unlock();
2239 input_bufs_omx_all.clear();
2240 input_bufs_omx_free.clear();
2241 input_bufs_omx_mutex.unlock();
2246 int VideoOMX::FlushRenderingPipe()
2248 OMX_ERRORTYPE error;
2252 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2254 if (error != OMX_ErrorNone)
2256 logger->debug(TAG, "OMX_Flush codec out 1 failed {:#x}", error);
2259 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2261 if (error != OMX_ErrorNone)
2263 logger->debug(TAG, "OMX_Flush shed in 2 failed {:#x}", error);
2266 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2268 logger->debug(TAG, "flush cmd codec 3 failed");
2271 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2273 logger->debug(TAG, "flush cmd shed 4 failed");
2278 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2280 if (error != OMX_ErrorNone)
2282 logger->debug(TAG, "OMX_Flush codec out 5 failed {:#x}", error);
2285 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port, NULL);
2287 if (error != OMX_ErrorNone)
2289 logger->debug(TAG, "OMX_Flush deint in 6 failed {:#x}", error);
2292 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2294 logger->debug(TAG, "flush cmd codec 7 failed");
2297 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port))
2299 logger->debug(TAG, "flush cmd deint 8 failed");
2303 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port, NULL);
2305 if (error != OMX_ErrorNone)
2307 logger->debug(TAG, "OMX_Flush deint out 9 failed {:#x}", error);
2310 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2312 if (error != OMX_ErrorNone)
2314 logger->debug(TAG, "OMX_Flush shed in 10 failed {:#x}", error);
2317 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port))
2319 logger->debug(TAG, "flush cmd deint 11 failed");
2322 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2324 logger->debug(TAG, "flush cmd shed 12 failed");
2328 error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port, NULL);
2330 if (error != OMX_ErrorNone)
2332 logger->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
2336 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port, NULL);
2338 if (error != OMX_ErrorNone)
2340 logger->debug(TAG, "OMX_Flush shed out failed {:#x}", error);
2343 if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port))
2345 logger->debug(TAG, "flush cmd shed rend failed");
2348 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port))
2350 logger->debug(TAG, "flush cmd shed rend failed");
2356 int VideoOMX::DeAllocateCodecsOMX()
2358 OMX_ERRORTYPE error;
2359 omx_running = false;
2360 logger->debug(TAG, "enter deallocatecodecsomx");
2362 if (cur_input_buf_omx)
2364 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_EOS;
2365 error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
2367 if (error != OMX_ErrorNone)
2369 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2372 cur_input_buf_omx = NULL; //write out old data
2380 // first stop the omx elements
2381 if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
2383 logger->debug(TAG, "vid_dec ChangeComponentState");
2386 clock_mutex.unlock();
2393 if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
2395 logger->debug(TAG, "vid_deint ChangeComponentState");
2399 if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
2401 logger->debug(TAG, "vid_shed ChangeComponentState");
2404 if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
2406 logger->debug(TAG, "vid_rend ChangeComponentState");
2409 // TODO proper deinit sequence
2410 // first flush all buffers
2411 FlushRenderingPipe();
2413 error = OMX_SendCommand(omx_clock, OMX_CommandFlush, omx_clock_output_port, NULL);
2415 if (error != OMX_ErrorNone)
2417 logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2420 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port, NULL);
2422 if (error != OMX_ErrorNone)
2424 logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2427 if (!CommandFinished(omx_clock, OMX_CommandFlush, omx_clock_output_port) ||
2428 !CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port))
2430 logger->debug(TAG, "flush cmd clock shed failed");
2433 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2434 omx_codec_input_port, NULL);
2436 if (error != OMX_ErrorNone)
2438 logger->debug(TAG, "OMX_Flush codec out failed {:#x}", error);
2441 DestroyInputBufsOMX();
2444 if (!DisablePort(omx_vid_sched, omx_shed_output_port, true))
2446 logger->debug(TAG, "Disable Tunnel Port failed 2");
2449 if (!DisablePort(omx_vid_rend, omx_rend_input_port, true))
2451 logger->debug(TAG, "Disable Tunnel Port failed 1");
2454 if (!DisablePort(omx_vid_dec, omx_codec_output_port, true))
2456 logger->debug(TAG, "Disable Tunnel Port failed 6");
2459 if (!DisablePort(omx_vid_dec, omx_codec_input_port, true))
2461 logger->debug(TAG, "Disable Tunnel Port failed 7");
2466 if (!DisablePort(omx_vid_deint, omx_deint_output_port, true))
2468 logger->debug(TAG, "Disable Tunnel Port failed 6a");
2471 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true))
2473 logger->debug(TAG, "Disable Tunnel Port failed 7a");
2477 if (!DisablePort(omx_vid_sched, omx_shed_input_port, true))
2479 logger->debug(TAG, "Disable Tunnel Port failed 3");
2482 if (!DisablePort(omx_vid_sched, omx_shed_clock_port, true))
2484 logger->debug(TAG, "Disable Tunnel Port failed 4");
2487 if (!DisablePort(omx_clock, omx_clock_output_port, true))
2489 logger->debug(TAG, "Disable Tunnel Port failed 5");
2492 error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, NULL, 0);
2494 if (error != OMX_ErrorNone)
2496 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2501 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_input_port, NULL, 0);
2503 if (error != OMX_ErrorNone)
2505 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2508 error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, NULL, 0);
2510 if (error != OMX_ErrorNone)
2512 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2516 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_input_port, NULL, 0);
2518 if (error != OMX_ErrorNone)
2520 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2523 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, NULL, 0);
2525 if (error != OMX_ErrorNone)
2527 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2530 error = OMX_SetupTunnel(omx_vid_rend, omx_rend_input_port, NULL, 0);
2532 if (error != OMX_ErrorNone)
2534 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2537 error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, NULL, 0);
2539 if (error != OMX_ErrorNone)
2541 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2544 error = OMX_SetupTunnel(omx_vid_sched, omx_shed_clock_port, NULL, 0);
2546 if (error != OMX_ErrorNone)
2548 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2551 error = OMX_FreeHandle(omx_vid_dec);
2552 error = OMX_FreeHandle(omx_vid_sched);
2553 error = OMX_FreeHandle(omx_vid_rend);
2555 if (dodeint) error = OMX_FreeHandle(omx_vid_deint);
2558 omx_vid_stalled = false;
2559 clock_mutex.unlock();
2562 if (error != OMX_ErrorNone)
2564 logger->debug(TAG, "FreeHandle failed {}", error);
2568 clock_mutex.unlock();
2570 logger->debug(TAG, "leave deallocate codecs OMX");
2575 void VideoOMX::destroyClock()
2579 if (clock_references > 0)
2583 if (clock_references == 0)
2585 OMX_ERRORTYPE error;
2586 logger->debug(TAG, "destroy omx clock");
2587 error = OMX_FreeHandle(omx_clock);
2589 if (error != OMX_ErrorNone)
2591 logger->debug(TAG, "FreeHandle failed {}", error);
2596 clock_mutex.unlock();
2599 int VideoOMX::stop()
2601 if (!initted) return 0;
2605 //Check if libav mode
2606 DeAllocateCodecsOMX();
2608 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2612 int VideoOMX::reset()
2614 if (!initted) return 0;
2617 DeAllocateCodecsOMX();
2618 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2622 int VideoOMX::pause()
2624 if (!initted) return 0;
2626 logger->debug(TAG, "enter pause");
2628 // ignore it audio handles this
2632 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2634 if (!initted) return 0;
2636 logger->debug(TAG, "enter unpause");
2639 //ignore it audio handles this
2644 int VideoOMX::fastForward()
2646 if (!initted) return 0;
2648 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2652 int VideoOMX::unFastForward()
2654 if (!initted) return 0;
2656 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2658 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2662 int VideoOMX::attachFrameBuffer()
2664 if (!initted) return 0;
2666 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2670 int VideoOMX::blank(void)
2672 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2673 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2677 u8 VideoOMX::getCurrentTimestamp()
2682 long long ncur_clock_time = cur_clock_time;
2688 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2689 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2691 OMX_ERRORTYPE error;
2692 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2693 memset(&clock_conf, 0, sizeof(clock_conf));
2694 clock_conf.nSize = sizeof(clock_conf);
2695 clock_conf.nVersion.nVersion = OMX_VERSION;
2696 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
2698 if (error != OMX_ErrorNone)
2700 logger->debug(TAG, "getCurrentTimestamp IndexConfigTimeClockState failed {:#x}", error);
2703 if (clock_conf.eState == OMX_TIME_ClockStateRunning)
2705 OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2706 memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2707 cur_time_stamp.nSize = sizeof(cur_time_stamp);
2708 cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2709 cur_time_stamp.nPortIndex = omx_clock_output_port;
2710 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, &cur_time_stamp);
2712 if (error != OMX_ErrorNone)
2714 logger->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}", error);
2718 long long temp = cur_time_stamp.nTimestamp.nLowPart
2719 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2720 ncur_clock_time = cur_clock_time = temp * 10LL;
2724 clock_mutex.unlock();
2725 pthread_setcancelstate(oldcancelstate, NULL);
2726 pthread_setcanceltype(oldcanceltype, NULL);
2729 //ncur_clock_time -= startoffset;
2730 ncur_clock_time -= lastreftimeOMX;
2731 long long result = lastreftimePTS;
2733 if (lastreftimePTS == 0) return 0; // invalid time
2735 result += (long long) (ncur_clock_time / 10000LL * 90LL);
2738 result = (1LL << 33) - result;
2740 //logger->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2748 u4 VideoOMX::timecodeToFrameNumber(u8 timecode)
2750 if (format == PAL) return (u4)(((double)timecode / (double)90000) * (double)25);
2751 else return (u4)(((double)timecode / (double)90000) * (double)30);
2756 int VideoOMX::test()
2761 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2768 int VideoOMX::test2()
2774 long long VideoOMX::SetStartOffset(long long curreftime, bool* rsync)
2780 startoffset = curreftime; //offset is set for audio
2781 offsetnotset = false;
2782 offsetvideonotset = false;
2786 if (offsetvideonotset)
2788 offsetvideonotset = false;
2793 if ( (curreftime - lastrefvideotime) > 10000000LL
2794 || (curreftime - lastrefvideotime) < -10000000LL) //if pts jumps to big resync
2796 startoffset += curreftime - lastrefvideotime;
2797 lastrefaudiotime += curreftime - lastrefvideotime;
2799 offsetaudionotset = true;
2804 lastrefvideotime = curreftime;
2809 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool* rsync)
2815 startoffset = curreftime;
2816 offsetnotset = false;
2817 offsetaudionotset = false;
2821 if (offsetaudionotset)
2823 offsetaudionotset = false;
2828 if ( (curreftime - lastrefaudiotime) > 10000000LL
2829 || (curreftime - lastrefaudiotime) < -10000000LL) //if pts jumps to big resync
2831 startoffset += curreftime - lastrefaudiotime;
2832 lastrefvideotime += curreftime - lastrefaudiotime;
2834 offsetvideonotset = true;
2839 lastrefaudiotime = curreftime;
2843 void VideoOMX::ResetTimeOffsets()
2845 offsetnotset = true; //called from demuxer
2846 offsetvideonotset = true;
2847 offsetaudionotset = true;
2849 lastrefaudiotime = 0;
2850 lastrefvideotime = 0;
2855 void VideoOMX::FirstFrameFix()
2859 Demuxer* demux = Demuxer::getInstance();
2860 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2861 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2864 if (WaitForEvent(omx_vid_dec, OMX_EventPortSettingsChanged, 0))
2866 WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged, 0); //clear old messages
2867 OMX_ERRORTYPE error;
2868 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2869 memset(&port_def_type, 0, sizeof(port_def_type));
2870 port_def_type.nSize = sizeof(port_def_type);
2871 port_def_type.nVersion.nVersion = OMX_VERSION;
2872 port_def_type.nPortIndex = omx_codec_output_port;
2874 error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2876 if (error != OMX_ErrorNone)
2878 logger->debug(TAG, "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2879 clock_mutex.unlock();
2884 "Deinit first frame fix {} {} {} {} {} {} {} {}", port_def_type.format.video.nFrameWidth, demux->getHorizontalSize(),
2885 port_def_type.format.video.nFrameHeight, demux->getVerticalSize(), port_def_type.format.video.nStride,
2886 port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2887 port_def_type.format.video.bFlagErrorConcealment );
2889 "Deinit first frame fix2 {} {}",
2890 port_def_type.format.video.eCompressionFormat,
2891 port_def_type.format.video.eColorFormat );
2892 first_frame = false;
2894 // we cause the video_decode to determine the interlacing properties
2895 OMX_CONFIG_INTERLACETYPE il;
2896 memset(&il, 0, sizeof(il));
2897 il.nSize = sizeof(il);
2898 il.nVersion.nVersion = OMX_VERSION;
2899 il.nPortIndex = omx_codec_output_port;
2900 error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigCommonInterlace, &il);
2902 if (error != OMX_ErrorNone)
2904 logger->debug(TAG, "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2907 DisablePort(omx_vid_dec, omx_codec_output_port, true);
2908 DisablePort(omx_vid_sched, omx_shed_input_port, true);
2912 DisablePort(omx_vid_deint, omx_deint_input_port, true);
2913 // This is a dirty hack
2914 DisablePort(omx_vid_deint, omx_deint_output_port, true);
2916 port_def_type.nPortIndex = omx_deint_output_port;
2917 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2919 if (error != OMX_ErrorNone)
2921 logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2922 clock_mutex.unlock();
2923 pthread_setcancelstate(oldcancelstate, NULL);
2924 pthread_setcanceltype(oldcanceltype, NULL);
2930 port_def_type.nPortIndex = omx_deint_input_port;
2931 error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2933 if (error != OMX_ErrorNone)
2935 logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2936 clock_mutex.unlock();
2937 pthread_setcancelstate(oldcancelstate, NULL);
2938 pthread_setcanceltype(oldcanceltype, NULL);
2942 // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2944 logger->debug(TAG, "Marker");
2945 EnablePort(omx_vid_deint, omx_deint_input_port, true);
2946 WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged);
2947 port_def_type.nPortIndex = omx_deint_output_port;
2948 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2950 if (error != OMX_ErrorNone)
2952 logger->debug(TAG, "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2953 clock_mutex.unlock();
2954 pthread_setcancelstate(oldcancelstate, NULL);
2955 pthread_setcanceltype(oldcanceltype, NULL);
2960 "Deinit first frame fix3 {} {} {} {} {} {} {} ", port_def_type.format.image.nFrameWidth, demux->getHorizontalSize(),
2961 port_def_type.format.image.nFrameHeight, demux->getVerticalSize(), port_def_type.format.image.nStride,
2962 port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2963 port_def_type.format.image.bFlagErrorConcealment );
2965 "Deinit first frame fix4 {} {}",
2966 port_def_type.format.image.eCompressionFormat,
2967 port_def_type.format.image.eColorFormat );
2969 DisablePort(omx_vid_deint, omx_deint_output_port, true);
2972 port_def_type.nPortIndex = omx_shed_input_port;
2973 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, &port_def_type);
2975 if (error != OMX_ErrorNone)
2977 logger->debug(TAG, "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2978 clock_mutex.unlock();
2979 pthread_setcancelstate(oldcancelstate, NULL);
2980 pthread_setcanceltype(oldcanceltype, NULL);
2984 WaitForEvent(omx_vid_sched, OMX_EventPortSettingsChanged);
2987 EnablePort(omx_vid_deint, omx_deint_output_port, true);
2989 EnablePort(omx_vid_dec, omx_codec_output_port, true);
2990 EnablePort(omx_vid_sched, omx_shed_input_port, true);
2993 clock_mutex.unlock();
2994 pthread_setcancelstate(oldcancelstate, NULL);
2995 pthread_setcanceltype(oldcanceltype, NULL);
2998 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
3000 OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
3002 if (error != OMX_ErrorNone)
3004 logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
3007 if (first_frame) FirstFrameFix();
3010 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
3012 // protect the call to empty this buffer
3015 /* long long temp =buffer->nTimeStamp.nLowPart
3016 | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
3018 //pthread_testcancel();
3019 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3020 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3023 /* OMX_ERRORTYPE error;
3024 OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
3025 memset(×tamp, 0, sizeof(timestamp));
3026 timestamp.nSize = sizeof(timestamp);
3027 timestamp.nVersion.nVersion = OMX_VERSION;
3028 timestamp.nPortIndex =omx_clock_output_port;
3030 error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
3033 if (error != OMX_ErrorNone) {
3035 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
3036 omx_rend_input_port);
3038 long long temp2 =timestamp.nTimestamp.nLowPart
3039 | ((long long) timestamp.nTimestamp.nHighPart << 32);
3041 logger->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
3042 OMX_ERRORTYPE ret_val;
3043 ret_val = OMX_EmptyThisBuffer(handle, buffer);
3044 clock_mutex.unlock();
3045 pthread_setcancelstate(oldcancelstate, NULL);
3046 pthread_setcanceltype(oldcanceltype, NULL);
3047 //pthread_testcancel();
3051 bool VideoOMX::detectIFrame(const u1* buffer, unsigned int length)
3053 const u1* curbuf = buffer;
3054 const u1* curbufend = buffer + length;
3055 unsigned int detector = 0xFFFFFFFF;
3056 bool gotaud = false; // have seen access unit delimiter
3058 while (curbuf != curbufend)
3061 detector |= *curbuf;
3065 if (detector == 0x00000109)
3068 detector = 0xFFFFFFFF;
3070 else if (gotaud && detector == 0x00000001)
3074 if (curbuf != curbufend)
3076 unsigned char picttype = (*curbuf) & 0x1F;
3077 return picttype == 0x07;
3083 if (detector == 0x00000100)
3087 if (curbuf == curbufend) return false;
3091 if (curbuf == curbufend) return false;
3093 unsigned char picttype = ((*curbuf) >> 3) & 0x07;
3094 return picttype == 1;
3101 return false; // no frame found
3104 bool VideoOMX::DrainTargetBufferFull()
3106 //Check, if we have OMX output buffers
3108 input_bufs_omx_mutex.lock();
3109 full = (input_bufs_omx_free.size() == 0);
3110 input_bufs_omx_mutex.unlock();
3111 checkForStalledBuffers(); // check if the decoder has a problem
3113 if (full && omx_vid_stalled && !omx_first_frame)
3115 omx_vid_stalled = false;
3116 logger->debug(TAG, "Decoder is stalled, do a reset!");
3120 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3121 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3124 FlushRenderingPipe();
3125 omx_first_frame = true;
3126 clock_mutex.unlock();
3128 pthread_setcancelstate(oldcancelstate, NULL);
3129 pthread_setcanceltype(oldcanceltype, NULL);
3135 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */)
3137 mediapackets.clear();
3138 std::list<MediaPacket>::const_iterator begin = mplist.begin();
3139 std::list<MediaPacket>::const_iterator itty = mplist.begin();
3140 advance(itty, std::min(mplist.size(), 10U));
3141 mediapackets.insert(mediapackets.begin(), begin, itty); //front
3144 u4 VideoOMX::DeliverMediaSample(u1* buffer, u4* samplepos)
3148 while (consumed < mediapackets.size())
3150 DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
3152 if (*samplepos == mediapackets[consumed].length)
3158 else return consumed;
3164 u4 VideoOMX::DeliverMediaPacket(MediaPacket packet, const u1* buffer, u4* samplepos)
3166 if (packet.type == MPTYPE_VIDEO_H264)
3175 //Later add fail back code for libav
3177 *samplepos+=packet.length;
3178 return packet.length;
3181 if (!omx_running) return 0; // if we are not runnig do not do this
3183 if (isClockPaused()) return 0; //Block if we pause
3185 // logger->debug(TAG, "DMP mark 1");
3186 //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
3188 TELEM(9, packet.presentation_time);
3190 /*First Check, if we have an video sample*/
3195 return 0; //Not in iframe mode!
3200 if (packet.disconti)
3202 firstsynched = false;
3204 if (cur_input_buf_omx)
3206 PutBufferToPres(cur_input_buf_omx);
3207 cur_input_buf_omx = NULL;
3211 //logger->debug(TAG, "DMP mark 2");
3212 /*Inspect PES-Header */
3214 // OMX_STATETYPE temp_state;
3215 // OMX_GetState(omx_vid_dec,&temp_state);
3217 if (*samplepos == 0) //stripheader
3219 headerstrip = buffer[packet.pos_buffer + 8] + 9/*is this right*/;
3220 // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
3221 // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
3222 *samplepos += headerstrip;
3224 if (headerstrip >= packet.length)
3226 *samplepos = packet.length; // Packet is obviously damaged
3227 return packet.length;//skip it!
3234 //logger->debug(TAG, "DMP mark 2a");
3235 // check if this is an I frame, the decoder does not like non I frames at startup!
3236 if (!detectIFrame(buffer, packet.length))
3238 *samplepos = packet.length; //if we have not processed at least one
3239 //logger->debug(TAG, "DMP mark 3");
3240 return packet.length;//synched packet ignore it!
3244 if (cur_input_buf_omx)
3246 //logger->debug(TAG, "DMP mark 4a");
3247 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
3248 PutBufferToPres(cur_input_buf_omx);
3249 cur_input_buf_omx = NULL; //write out old data
3251 //logger->debug(TAG, "DMP mark 4b");
3254 firstsynched = true;
3258 if (!firstsynched) //
3260 *samplepos = packet.length; //if we have not processed at least one
3261 //logger->debug(TAG, "DMP mark 5");
3262 return packet.length;//synched packet ignore it!
3267 //logger->debug(TAG, "DMP mark 6");
3268 if (!cur_input_buf_omx)
3270 input_bufs_omx_mutex.lock();
3272 if (input_bufs_omx_free.size() == 0)
3274 input_bufs_omx_mutex.unlock();
3275 //logger->debug(TAG, "Deliver MediaPacket no free sample");
3276 //logger->debug(TAG, "DMP mark 7");
3277 return 0; // we do not have a free media sample
3280 cur_input_buf_omx = input_bufs_omx_free.front();
3281 cur_input_buf_omx->nFilledLen = 0;
3282 cur_input_buf_omx->nOffset = 0;
3283 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3284 input_bufs_omx_free.pop_front();
3285 input_bufs_omx_mutex.unlock();
3288 if (cur_input_buf_omx->nFilledLen == 0) //will only be changed on first packet
3292 // logger->debug(TAG, "packet synched marker");
3294 //lastreftimePTS=packet.pts;
3295 if (omx_first_frame) // TODO time
3297 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3298 logger->debug(TAG, "Starttime");
3299 omx_first_frame = false;
3303 cur_input_buf_omx->nFlags = 0;
3304 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3307 lastreftimeOMX = packet.presentation_time;
3308 TELEM(10, lastreftimeOMX);
3309 // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3310 lastreftimePTS = packet.pts;
3311 cur_input_buf_omx->nTimeStamp = intToOMXTicks(lastreftimeOMX / 10LL); // the clock component is faulty;
3315 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3316 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3317 //logger->debug(TAG, "packet unsynched marker");
3320 if (packet.disconti) cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
3323 unsigned int haveToCopy = packet.length - *samplepos;
3324 //logger->debug(TAG, "DMP mark 8");
3326 while (haveToCopy > (cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen))
3328 //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3329 unsigned int cancopy = cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen;
3330 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + packet.pos_buffer + *samplepos, cancopy);
3331 haveToCopy -= cancopy;
3332 cur_input_buf_omx->nFilledLen += cancopy;
3333 *samplepos += cancopy;
3334 // push old buffer out
3335 //logger->debug(TAG, "DMP mark 9");
3337 PutBufferToPres(cur_input_buf_omx);
3338 cur_input_buf_omx = NULL;
3340 input_bufs_omx_mutex.lock();
3342 if (input_bufs_omx_free.size() == 0)
3344 input_bufs_omx_mutex.unlock();
3345 // logger->debug(TAG, "Deliver MediaPacket no free sample2");
3346 return *samplepos; // we do not have a free media sample
3349 cur_input_buf_omx = input_bufs_omx_free.front();
3350 cur_input_buf_omx->nFilledLen = 0;
3351 cur_input_buf_omx->nOffset = 0;
3352 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3353 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3354 input_bufs_omx_free.pop_front();
3355 input_bufs_omx_mutex.unlock();
3356 //logger->debug(TAG, "DMP mark 10");
3359 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3360 buffer + packet.pos_buffer + *samplepos, haveToCopy);
3361 cur_input_buf_omx->nFilledLen += haveToCopy;
3363 // logger->debug(TAG, "DMP mark 11");
3365 *samplepos += haveToCopy;
3370 bool VideoOMX::displayIFrame(const u1* buffer, u4 length)
3372 if (!omx_running) return false;
3375 EnterIframePlayback();
3377 //int haveToCopy = length;
3379 if (!cur_input_buf_omx)
3381 input_bufs_omx_mutex.lock();
3383 if (input_bufs_omx_free.size() == 0)
3385 input_bufs_omx_mutex.unlock();
3386 // logger->debug(TAG,
3387 // "Deliver MediaPacket no free sample");
3388 return false; // we do not have a free media sample
3391 cur_input_buf_omx = input_bufs_omx_free.front();
3392 cur_input_buf_omx->nFilledLen = 0;
3393 cur_input_buf_omx->nOffset = 0;
3394 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3395 input_bufs_omx_free.pop_front();
3396 input_bufs_omx_mutex.unlock();
3400 unsigned int pattern, packet_length;
3401 unsigned int headerstrip = 0;
3409 //Now we strip the pes header
3410 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3412 while ((read_pos + 7) <= length)
3414 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3416 if (pattern < 0x000001E0 || pattern > 0x000001EF)
3423 headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3424 packet_length = ((buffer[read_pos + 4] << 8)
3425 | (buffer[read_pos + 5])) + 6;
3427 if (read_pos + packet_length > length)
3431 if ((headerstrip < packet_length)
3432 && (cur_input_buf_omx->nFilledLen + packet_length
3433 - headerstrip) > cur_input_buf_omx->nAllocLen)
3437 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3441 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3444 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3445 PutBufferToPres(cur_input_buf_omx);
3446 cur_input_buf_omx = NULL;
3448 if (!cur_input_buf_omx)
3452 while (count < 100 && omx_running && iframemode)
3456 input_bufs_omx_mutex.lock();
3458 if (input_bufs_omx_free.size() == 0)
3460 input_bufs_omx_mutex.unlock();
3461 // logger->debug(TAG,
3462 // "Ifrane no free sample");
3465 if (!omx_running) return false;
3470 cur_input_buf_omx = input_bufs_omx_free.front();
3471 cur_input_buf_omx->nFilledLen = 0;
3472 cur_input_buf_omx->nOffset = 0;
3473 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3474 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3475 input_bufs_omx_free.pop_front();
3476 input_bufs_omx_mutex.unlock();
3480 if (!cur_input_buf_omx) return false;
3484 if (packet_length > headerstrip)
3487 cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3488 buffer + read_pos + headerstrip,
3489 packet_length - headerstrip);
3491 cur_input_buf_omx->nFilledLen += packet_length - headerstrip;
3494 read_pos += packet_length;
3496 pattern = (buffer[read_pos] << 16)
3497 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3504 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3508 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3511 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3513 PutBufferToPres(cur_input_buf_omx);
3514 cur_input_buf_omx = NULL;
3516 MILLISLEEP(40); //Block a bit
3520 int VideoOMX::EnterIframePlayback()
3522 logger->debug(TAG, "EnterIframePlayback");
3524 if (cur_input_buf_omx)
3526 PutBufferToPres(cur_input_buf_omx);
3527 cur_input_buf_omx = NULL;
3530 logger->debug(TAG, "EnterIframePlayback 2");
3531 dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3532 DeAllocateCodecsOMX();
3533 AllocateCodecsOMX();
3534 logger->debug(TAG, "leave IframePlayback");