From d3985a97e81cb780c388fa523caa265ba7b35c39 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Wed, 22 Feb 2023 17:49:57 +0000 Subject: [PATCH] Formatting, use local logger var, brace-init --- src/videoomx.cc | 5578 +++++++++++++++++++++++++---------------------- src/videoomx.h | 371 ++-- 2 files changed, 3093 insertions(+), 2856 deletions(-) diff --git a/src/videoomx.cc b/src/videoomx.cc index 028c62d..d9b2984 100644 --- a/src/videoomx.cc +++ b/src/videoomx.cc @@ -23,7 +23,6 @@ #include #include - #include "log.h" #include "audioomx.h" #include "demuxer.h" @@ -41,44 +40,68 @@ static const char* TAG = "VideoOMX"; -VideoOMX::VideoOMX() { - logger = LogNT::getInstance(); +// Static OMX callbacks + +OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle, OMX_IN OMX_PTR appdata, + OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1, + OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data) +{ + //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data); + + struct VPE_OMX_EVENT new_event; + new_event.handle = handle; + new_event.appdata = appdata; + new_event.event_type = event_type; + new_event.data1 = data1; + new_event.data2 = data2; + new_event.event_data = event_data; + + VideoOMX* video = static_cast(Video::getInstance()); + video->AddOmxEvent(new_event); + + /* switch (event_type) { + case OMX_EventCmdComplete: { + + } break; + }*/ + + return OMX_ErrorNone; +} - omx_running = false; +OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + // LogNT::getInstance()->info(TAG, "EmptyBufferDone"); + VideoOMX* video = static_cast(Video::getInstance()); + /* long long temp =buffer->nTimeStamp.nLowPart + | ((long long) buffer->nTimeStamp.nHighPart << 32); + LogNT::getInstance()->info(TAG, "EBD Video %lld {:#x}",temp,buffer->nFlags);*/ + video->ReturnEmptyOMXBuffer(buffer); + return OMX_ErrorNone; +} - omx_vid_dec = 0; - cur_input_buf_omx = NULL; - omx_h264 = omx_mpeg2 = true; - clock_references = 0; +OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* /*buffer*/) +{ + //LogNT::getInstance()->info(TAG, "FillBufferDone"); + return OMX_ErrorNone; +} - omx_vid_stalled = false; +// ----------------------------------- - offsetnotset = true; - offsetvideonotset = true; - offsetaudionotset = true; - startoffset = 0; - lastrefaudiotime = 0; - lastrefvideotime = 0; - lastreftimeOMX = 0; - lastreftimePTS = 0; - firstsynched = false; - cur_clock_time=0; - mpeg2_supported=false; - //cur_pts=0; +VideoOMX::VideoOMX() +{ + logger = LogNT::getInstance(); - mode=NORMAL; - xpos=ypos=0.f; - deinterlace=2; //advanced + //cur_pts=0; - signalon=false; - outputinterlaced=0; + mode = NORMAL; + deinterlace = 2; //advanced - strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK); - strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER); - strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER); - strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED); - strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND); - strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE); + strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK); + strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER); + strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER); + strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED); + strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND); + strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE); } VideoOMX::~VideoOMX() @@ -89,34 +112,48 @@ VideoOMX::~VideoOMX() int VideoOMX::init(u1 tformat) { if (initted) return 0; + initted = 1; // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well. // Seems safe to call it more than once. bcm_host_init(); - int ret=vc_gencmd_send("codec_enabled MPG2"); - if (ret!=0) { - logger->debug(TAG, "vc_gencmd_send failed {:#x}",ret); - } else { - char buffer[1024]; - ret=vc_gencmd_read_response(buffer,sizeof(buffer)); - if (ret!=0) { - logger->debug(TAG, "vc_gencmd_read_response failed {:#x}",ret); - } else { - if (STRCASECMP(buffer,"MPG2=enabled")==0) { - mpeg2_supported=true; - } else if (STRCASECMP(buffer,"MPG2=disabled")==0) { - mpeg2_supported=false; - } else { - logger->debug(TAG, "Undefined mpg codec answer {}",buffer); - } - } + int ret = vc_gencmd_send("codec_enabled MPG2"); + + if (ret != 0) + { + logger->debug(TAG, "vc_gencmd_send failed {:#x}", ret); + } + else + { + char buffer[1024]; + ret = vc_gencmd_read_response(buffer, sizeof(buffer)); + + if (ret != 0) + { + logger->debug(TAG, "vc_gencmd_read_response failed {:#x}", ret); + } + else + { + if (STRCASECMP(buffer, "MPG2=enabled") == 0) + { + mpeg2_supported = true; + } + else if (STRCASECMP(buffer, "MPG2=disabled") == 0) + { + mpeg2_supported = false; + } + else + { + logger->debug(TAG, "Undefined mpg codec answer {}", buffer); + } + } } if (!setFormat(tformat)) { shutdown(); return 0; } - if (!setConnection(HDMI)) { shutdown(); return 0; } - if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; } + if (!setConnection(HDMI)) { shutdown(); return 0; } + if (!setAspectRatio(ASPECT4X3, 12, 11)) { shutdown(); return 0; } if (!setMode(NORMAL)) { shutdown(); return 0; } if (!setSource()) { shutdown(); return 0; } if (!attachFrameBuffer()) { shutdown(); return 0; } @@ -124,56 +161,19 @@ int VideoOMX::init(u1 tformat) setTVsize(ASPECT16X9); selectVideoMode(0); - OMX_ERRORTYPE error; - error = OMX_Init(); - if (error != OMX_ErrorNone) { - logger->debug(TAG, "Init OMX failed {:#x}", - error); - return 0; - } - - - + error = OMX_Init(); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX failed {:#x}", error); + return 0; + } //stop(); - - - return 1; } - - - -OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata, - OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1, - OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) { - - //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data); - - struct VPE_OMX_EVENT new_event; - new_event.handle=handle; - new_event.appdata=appdata; - new_event.event_type=event_type; - new_event.data1=data1; - new_event.data2=data2; - new_event.event_data=event_data; - - VideoOMX* video = static_cast(Video::getInstance()); - video->AddOmxEvent(new_event); - -/* switch (event_type) { - case OMX_EventCmdComplete: { - - } break; - }*/ - - return OMX_ErrorNone; - -} - void VideoOMX::signalOmx() { /* @@ -201,7 +201,7 @@ void VideoOMX::signalOmx() omx_event_ready_signal_mutex.unlock(); }; -void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event) +void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event) { omx_event_mutex.lock(); omx_events.push_back(new_event); @@ -210,211 +210,224 @@ void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event) signalOmx(); } -OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* buffer){ - -// LogNT::getInstance()->info(TAG, "EmptyBufferDone"); - VideoOMX* video = static_cast(Video::getInstance()); -/* long long temp =buffer->nTimeStamp.nLowPart - | ((long long) buffer->nTimeStamp.nHighPart << 32); - LogNT::getInstance()->info(TAG, "EBD Video %lld {:#x}",temp,buffer->nFlags);*/ - video->ReturnEmptyOMXBuffer(buffer); - return OMX_ErrorNone; - -} - -void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){ - input_bufs_omx_mutex.lock(); - //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size()); - input_bufs_omx_free.push_back(buffer); - //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size()); - input_bufs_omx_mutex.unlock(); - - signalOmx(); -} +void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer) +{ + input_bufs_omx_mutex.lock(); + //logger->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size()); + input_bufs_omx_free.push_back(buffer); + //logger->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size()); + input_bufs_omx_mutex.unlock(); - OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* /*buffer*/) { - //LogNT::getInstance()->info(TAG, "FillBufferDone"); - return OMX_ErrorNone; + signalOmx(); } - - int VideoOMX::shutdown() { if (!initted) return 0; + initted = 0; - LogNT::getInstance()->info(TAG, "Shutdown video module"); + logger->info(TAG, "Shutdown video module"); DeAllocateCodecsOMX(); OMX_Deinit(); //vc_tv_show_info(0); // back to console // Restore console - int fd_fbset=0; + int fd_fbset = 0; struct fb_var_screeninfo screeninfo; - fd_fbset=open("/dev/fb0",O_RDONLY); - if (fd_fbset<0) { - LogNT::getInstance()->crit(TAG, "Could not open frame buffer device {}", fd_fbset); - return 0; + fd_fbset = open("/dev/fb0", O_RDONLY); + + if (fd_fbset < 0) + { + logger->crit(TAG, "Could not open frame buffer device {}", fd_fbset); + return 0; } - if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)){ - close(fd_fbset); - LogNT::getInstance()->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device"); - return 0; + + if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo)) + { + close(fd_fbset); + logger->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device"); + return 0; } - screeninfo.bits_per_pixel=8; - if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){ - LogNT::getInstance()->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device"); + + screeninfo.bits_per_pixel = 8; + + if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)) + { + logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device"); } - screeninfo.bits_per_pixel=16; - if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)){ - LogNT::getInstance()->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device"); + + screeninfo.bits_per_pixel = 16; + + if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo)) + { + logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device"); } + close(fd_fbset); return 1; } - - bool VideoOMX::loadOptionsFromServer(VDR* vdr) { - logger->debug(TAG, "VideoOMX config load"); - char *name=vdr->configLoad("VideoOMX","SDDeinterlacing"); + logger->debug(TAG, "VideoOMX config load"); + char* name = vdr->configLoad("VideoOMX", "SDDeinterlacing"); + + if (name != NULL) + { + if (STRCASECMP(name, "None") == 0) + { + deinterlace = 0; + } + /* else if (STRCASECMP(name, "LineDouble") == 0) + { + deinterlace = 1; + }*/ + else if (STRCASECMP(name, "Advanced") == 0) + { + deinterlace = 2; + } + /* else if (STRCASECMP(name, "Crazy") == 0) + { + deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun + } + */ + else if (STRCASECMP(name, "Fast") == 0) + { + deinterlace = 4; + } - if (name != NULL) { - if (STRCASECMP(name, "None") == 0) { - deinterlace = 0; - }/* else if (STRCASECMP(name, "LineDouble") == 0) { - deinterlace = 1; - }*/ else if (STRCASECMP(name, "Advanced") == 0) { - deinterlace = 2; - } /*else if (STRCASECMP(name, "Crazy") == 0) { - deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun - }*/ else if (STRCASECMP(name, "Fast") == 0) { - deinterlace = 4; - } - logger->debug(TAG, "Set deinterlacing to {} {}",name,deinterlace); - delete[] name; - } + logger->debug(TAG, "Set deinterlacing to {} {}", name, deinterlace); + delete[] name; + } - return true; + return true; } bool VideoOMX::handleOptionChanges(Option* option) { - if (Video::handleOptionChanges(option)) - return true; - switch (option->id) { - case 1: { - if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) { - deinterlace = 0; - } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble") - == 0) { - deinterlace = 1; - }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced") - == 0) { - deinterlace = 2; - } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy") - == 0) { - deinterlace = 3; - }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Fast") - == 0) { - deinterlace = 4; - } - logger->debug(TAG, "Set deinterlacing to {} {}",option->options[option->userSetChoice],deinterlace); - return true; - } - break; - }; - return false; + if (Video::handleOptionChanges(option)) + return true; + + switch (option->id) + { + case 1: + { + if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) + { + deinterlace = 0; + } + /* else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble") == 0) + { + deinterlace = 1; + }*/ + else if (STRCASECMP(option->options[option->userSetChoice], "Advanced") == 0) + { + deinterlace = 2; + } + /* else if (STRCASECMP(option->options[option->userSetChoice], "Crazy") == 0) + { + deinterlace = 3; + }*/ + else if (STRCASECMP(option->options[option->userSetChoice], "Fast") == 0) + { + deinterlace = 4; + } + + logger->debug(TAG, "Set deinterlacing to {} {}", option->options[option->userSetChoice], deinterlace); + return true; + } + } + return false; } bool VideoOMX::saveOptionstoServer() { + switch (deinterlace) + { + case 0: + VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "None"); + break; + /*case 1: + VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble"); + break;*/ + case 2: + VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Advanced"); + break; + /*case 3: + VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy"); + break;*/ + case 4: + VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast"); + break; + } - switch (deinterlace) { - case 0: - VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None"); - break; - /*case 1: - VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble"); - break;*/ - case 2: - VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced"); - break; - /*case 3: - VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy"); - break;*/ - case 4: - VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast"); - break; - }; - - return true; + return true; } /*Option(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType, u4 numChoices, u4 defaultChoice, u4 startInt, const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/ -bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane) +bool VideoOMX::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane) { - if (!Video::addOptionsToPanes(panenumber,options,pane)) return false; + if (!Video::addOptionsToPanes(panenumber, options, pane)) return false; + Option* option; - Option* option; - if (panenumber == 2) - { - static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ }; - option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/3,2,0,deinterlaceopts,NULL,false,this); - options->push_back(option); - pane->addOptionLine(option); - } + if (panenumber == 2) + { + static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ }; + option = new Option(1, tr("SD Deinterlacing"), "VideoOMX", "SDDeinterlacing", Option::TYPE_TEXT,/*4,2*/3, 2, 0, deinterlaceopts, NULL, false, this); + options->push_back(option); + pane->addOptionLine(option); + } - return true; + return true; } - - int VideoOMX::setTVsize(u1 ttvsize) { - if (tvsize!=ttvsize) pendingmodechange=true; - tvsize=ttvsize; + if (tvsize != ttvsize) pendingmodechange = true; + + tvsize = ttvsize; return 1; } -u1 VideoOMX::getTVsize() { - /*if (hdmi)*/ - return ASPECT16X9; // in order that aspect ratio changes are reported - //return tvsize; +u1 VideoOMX::getTVsize() +{ + /*if (hdmi)*/ + return ASPECT16X9; // in order that aspect ratio changes are reported + //return tvsize; } void VideoOMX::executePendingModeChanges() { - if (pendingmodechange) { - LogNT::getInstance()->info(TAG, "Execute pending mode change"); - Osd::getInstance()->shutdown(); - selectVideoMode(0); - Osd::getInstance()->restore(); - Osd::getInstance()->init(); - BoxStack::getInstance()->redrawAllBoxes(); - initted = 1; - } + if (pendingmodechange) + { + logger->info(TAG, "Execute pending mode change"); + Osd::getInstance()->shutdown(); + selectVideoMode(0); + Osd::getInstance()->restore(); + Osd::getInstance()->init(); + BoxStack::getInstance()->redrawAllBoxes(); + initted = 1; + } } int VideoOMX::setDefaultAspect() { - return setAspectRatio(tvsize,parx,pary); + return setAspectRatio(tvsize, parx, pary); } - - int VideoOMX::setFormat(u1 tformat) { if (!initted) return 0; + if ((tformat != PAL) && (tformat != NTSC) - && (tformat != PAL_M) && (tformat != NTSC_J)) return 0; + && (tformat != PAL_M) && (tformat != NTSC_J)) return 0; + format = PAL; tvsystem = tformat; @@ -424,373 +437,417 @@ int VideoOMX::setFormat(u1 tformat) screenHeight = 576; } -// selectVideoMode(0); + // selectVideoMode(0); return 1; } void VideoOMX::selectVideoMode(int interlaced) { - TV_GET_STATE_RESP_T tvstate; - vc_tv_get_state(&tvstate); - - if ((tvstate.state & VC_HDMI_UNPLUGGED)) { - hdmi = false; - LogNT::getInstance()->info(TAG, "HDMI unplugged"); - } else { - hdmi = true; - LogNT::getInstance()->info(TAG, "HDMI plugged"); - if (connection==COMPOSITERGB) { - hdmi=false; - LogNT::getInstance()->info(TAG, "SDTV set"); - } else { - hdmi=true; - LogNT::getInstance()->info(TAG, "HDMI set"); - } - } - - - if (hdmi) { - TV_SUPPORTED_MODE_T all_supp_modes[200]; - HDMI_RES_GROUP_T pref_group; - TV_SUPPORTED_MODE_T *mymode=NULL; - TV_SUPPORTED_MODE_T *mymode_second_best=NULL; - // bool got_optimum=false; - uint32_t pref_mode; - HDMI_RES_GROUP_T group=HDMI_RES_GROUP_CEA; - int all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA, - all_supp_modes,200, - &pref_group,&pref_mode); - if (all_my_modes<=0) { - group=HDMI_RES_GROUP_DMT; - all_my_modes=vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT, - all_supp_modes,200, - &pref_group,&pref_mode); - LogNT::getInstance()->info(TAG, "No CEA fall back to DMT modes "); - } - - - - - int target_fps=50; - if (format==PAL)target_fps=50; - else if (format==NTSC) target_fps=60; - - //Now first determine native resolution - int native_width=1920; - int native_height=1080; - for (int i=0;iinfo(TAG, "Found native mode {}x{} {} Hz i: {}", - mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode); - native_width=mymode->width; - native_height=mymode->height; - } - - } - //Now find the mode which matches best - for (int i=0;iwidth==native_width && - curmode->height==native_height && - curmode->frame_rate==target_fps) { - if(curmode->scan_mode==interlaced) { - //got_optimum=true; - mymode=curmode; - LogNT::getInstance()->info(TAG, "Found optimum mode {}x{} {} Hz i: {}", - mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode); - } else { - mymode_second_best=curmode; - LogNT::getInstance()->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}", - mymode_second_best->width,mymode_second_best->height, - mymode_second_best->frame_rate,mymode_second_best->scan_mode); - } - - } - } - // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? - - - bool disableHDMIModeChange{false}; - bool confSuccess = Config::getInstance()->getBool("videoomx", "disable-hdmi-modechange", disableHDMIModeChange); - - if (!(confSuccess && disableHDMIModeChange)) - { - vc_tv_power_off(); - if (mymode) { - LogNT::getInstance()->info(TAG, "Switch to optimum mode"); - vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode->code); - } else if (mymode_second_best) { - LogNT::getInstance()->info(TAG, "Switch to close to optimum mode"); - vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI,group,mymode_second_best->code); - } else { - LogNT::getInstance()->info(TAG, "Switch to prefered mode"); - vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED, - static_cast(HDMI_MODE_MATCH_FRAMERATE|HDMI_MODE_MATCH_RESOLUTION|HDMI_MODE_MATCH_SCANMODE)); - } - } - - hdmi=true; - outputinterlaced=interlaced; - } else { - /* analog tv case */ - LogNT::getInstance()->info(TAG, "Analog tv case"); - // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off(); - SDTV_MODE_T setmode=SDTV_MODE_PAL; - SDTV_OPTIONS_T options; - - switch (tvsize) { - default: - case ASPECT16X9: - LogNT::getInstance()->info(TAG, "SDTV aspect 16:9"); - options.aspect=SDTV_ASPECT_16_9; break; - case ASPECT4X3: - LogNT::getInstance()->info(TAG, "SDTV aspect 4:3"); - options.aspect=SDTV_ASPECT_4_3; break; - case ASPECT14X9: - LogNT::getInstance()->info(TAG, "SDTV aspect 14:9"); - options.aspect=SDTV_ASPECT_14_9; break; - }; - - if (format==PAL) setmode=SDTV_MODE_PAL; - else if (format==NTSC) setmode=SDTV_MODE_NTSC; - else if (format==PAL_M)setmode=SDTV_MODE_PAL_M; - else if (format==NTSC_J) setmode=SDTV_MODE_NTSC_J; - vc_tv_sdtv_power_on(setmode,&options); - hdmi=false; - } - -// InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp - // If this was just to reinit CEC then funcitons should be made to do that - - - signalon=true; - pendingmodechange=false; + TV_GET_STATE_RESP_T tvstate; + vc_tv_get_state(&tvstate); -} + if ((tvstate.state & VC_HDMI_UNPLUGGED)) + { + hdmi = false; + logger->info(TAG, "HDMI unplugged"); + } + else + { + hdmi = true; + logger->info(TAG, "HDMI plugged"); + + if (connection == COMPOSITERGB) + { + hdmi = false; + logger->info(TAG, "SDTV set"); + } + else + { + hdmi = true; + logger->info(TAG, "HDMI set"); + } + } + + if (hdmi) + { + TV_SUPPORTED_MODE_T all_supp_modes[200]; + HDMI_RES_GROUP_T pref_group; + TV_SUPPORTED_MODE_T* mymode = NULL; + TV_SUPPORTED_MODE_T* mymode_second_best = NULL; + // bool got_optimum=false; + uint32_t pref_mode; + HDMI_RES_GROUP_T group = HDMI_RES_GROUP_CEA; + int all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA, + all_supp_modes, 200, + &pref_group, &pref_mode); + + if (all_my_modes <= 0) + { + group = HDMI_RES_GROUP_DMT; + all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT, + all_supp_modes, 200, + &pref_group, &pref_mode); + logger->info(TAG, "No CEA fall back to DMT modes "); + } + + int target_fps = 50; + if (format == PAL)target_fps = 50; + else if (format == NTSC) target_fps = 60; + + //Now first determine native resolution + int native_width = 1920; + int native_height = 1080; + + for (int i = 0; i < all_my_modes; i++) + { + if (all_supp_modes[i].native) + { + mymode = all_supp_modes + i; + logger->info(TAG, "Found native mode {}x{} {} Hz i: {}", + mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode); + native_width = mymode->width; + native_height = mymode->height; + } + } + + //Now find the mode which matches best + for (int i = 0; i < all_my_modes; i++) + { + TV_SUPPORTED_MODE_T* curmode = all_supp_modes + i; + + if (curmode->width == native_width && + curmode->height == native_height && + curmode->frame_rate == target_fps) + { + if (curmode->scan_mode == interlaced) + { + //got_optimum=true; + mymode = curmode; + logger->info(TAG, "Found optimum mode {}x{} {} Hz i: {}", + mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode); + } + else + { + mymode_second_best = curmode; + logger->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}", + mymode_second_best->width, mymode_second_best->height, + mymode_second_best->frame_rate, mymode_second_best->scan_mode); + } + } + } + + // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? + + bool disableHDMIModeChange{false}; + bool confSuccess = Config::getInstance()->getBool("videoomx", "disable-hdmi-modechange", disableHDMIModeChange); + + if (!(confSuccess && disableHDMIModeChange)) + { + vc_tv_power_off(); + + if (mymode) + { + logger->info(TAG, "Switch to optimum mode"); + vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode->code); + } + else if (mymode_second_best) + { + logger->info(TAG, "Switch to close to optimum mode"); + vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode_second_best->code); + } + else + { + logger->info(TAG, "Switch to prefered mode"); + vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED, + static_cast(HDMI_MODE_MATCH_FRAMERATE | HDMI_MODE_MATCH_RESOLUTION | HDMI_MODE_MATCH_SCANMODE)); + } + } + + hdmi = true; + outputinterlaced = interlaced; + } + else + { + /* analog tv case */ + logger->info(TAG, "Analog tv case"); + // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off(); + SDTV_MODE_T setmode = SDTV_MODE_PAL; + SDTV_OPTIONS_T options; + + switch (tvsize) + { + default: + case ASPECT16X9: + logger->info(TAG, "SDTV aspect 16:9"); + options.aspect = SDTV_ASPECT_16_9; break; + + case ASPECT4X3: + logger->info(TAG, "SDTV aspect 4:3"); + options.aspect = SDTV_ASPECT_4_3; break; + + case ASPECT14X9: + logger->info(TAG, "SDTV aspect 14:9"); + options.aspect = SDTV_ASPECT_14_9; break; + } + + if (format == PAL) setmode = SDTV_MODE_PAL; + else if (format == NTSC) setmode = SDTV_MODE_NTSC; + else if (format == PAL_M)setmode = SDTV_MODE_PAL_M; + else if (format == NTSC_J) setmode = SDTV_MODE_NTSC_J; + + vc_tv_sdtv_power_on(setmode, &options); + hdmi = false; + } + + // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp + // If this was just to reinit CEC then funcitons should be made to do that + + signalon = true; + pendingmodechange = false; +} int VideoOMX::setConnection(u1 tconnection) { if (!initted) return 0; if ((tconnection != COMPOSITERGB) && (tconnection != HDMI)) return 0; - if (connection!=tconnection) pendingmodechange=true; + if (connection != tconnection) pendingmodechange = true; connection = tconnection; - -// if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0; return 1; } -int VideoOMX::setAspectRatio(u1 taspectRatio, int tparx,int tpary) +int VideoOMX::setAspectRatio(u1 taspectRatio, int tparx, int tpary) { if (!initted) return 0; + //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; aspectRatio = taspectRatio; - parx=tparx; - pary=tpary; + parx = tparx; + pary = tpary; - logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio,parx,pary); + logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio, parx, pary); updateMode(); -// if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0; return 1; } int VideoOMX::setMode(u1 tmode) { if (!initted) return 0; - if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode; + + if (tmode == LETTERBOX || tmode == NORMAL) mode = tmode; + updateMode(); return 1; } bool VideoOMX::setVideoDisplay(VideoDisplay display) { - if (!initted) return false; - switch (display.mode) - { - case None: return true; //?? - case Fullscreen: { - windowed = false; - - } break; - case Quarter: { - windowed =true; - xpos = ((float) display.x) / ((float) screenWidth); - ypos = ((float) display.y) / ((float) screenHeight); - width = 0.5f; - height = 0.5f; - } break; - - case Eighth: { - windowed =true; - xpos = ((float) display.x) / ((float) screenWidth); - ypos = ((float) display.y) / ((float) screenHeight); - width = 0.25f; - height = 0.25f; - } break; - - case Window: { - windowed =true; - xpos = ((float) display.x) / ((float) screenWidth); - ypos = ((float) display.y) / ((float) screenHeight); - width = ((float) display.width) / ((float) screenWidth); - height = ((float) display.height) / ((float) screenHeight); - }break; - } - updateMode(); - return true; -} + if (!initted) return false; + + switch (display.mode) + { + case None: return true; //?? + + case Fullscreen: + { + windowed = false; + break; + } + + case Quarter: + { + windowed = true; + xpos = ((float) display.x) / ((float) screenWidth); + ypos = ((float) display.y) / ((float) screenHeight); + width = 0.5f; + height = 0.5f; + break; + } + + case Eighth: + { + windowed = true; + xpos = ((float) display.x) / ((float) screenWidth); + ypos = ((float) display.y) / ((float) screenHeight); + width = 0.25f; + height = 0.25f; + break; + } + + case Window: + { + windowed = true; + xpos = ((float) display.x) / ((float) screenWidth); + ypos = ((float) display.y) / ((float) screenHeight); + width = ((float) display.width) / ((float) screenWidth); + height = ((float) display.height) / ((float) screenHeight); + break; + } + } + updateMode(); + return true; +} void VideoOMX::updateMode() { - clock_mutex.lock(); - if (omx_running) { - int oldcancelstate; - int oldcanceltype; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - OMX_ERRORTYPE error; - OMX_CONFIG_DISPLAYREGIONTYPE dispconf; - memset(&dispconf, 0, sizeof(dispconf)); - dispconf.nSize = sizeof(dispconf); - dispconf.nVersion.nVersion = OMX_VERSION; - dispconf.nPortIndex = omx_rend_input_port; - dispconf.layer = 1; - dispconf.set = OMX_DISPLAY_SET_LAYER; - error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, - &dispconf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - - - dispconf.pixel_x =parx; - dispconf.pixel_y=pary; - dispconf.set = OMX_DISPLAY_SET_PIXEL; - error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, - &dispconf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - - - - dispconf.set = OMX_DISPLAY_SET_FULLSCREEN; - if (!windowed) { - //Set Fullscreen - dispconf.fullscreen = OMX_TRUE; - } else { - dispconf.fullscreen = OMX_FALSE; - } - error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, - &dispconf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - - dispconf.set = OMX_DISPLAY_SET_MODE; - if (!windowed) { - dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL - : OMX_DISPLAY_MODE_LETTERBOX; - } else { - dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX; - } - error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, - &dispconf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - - if (windowed) { - unsigned int display_width, display_height; - display_width = display_height = 0; - if (graphics_get_display_size(0, &display_width, &display_height) - < 0) { - LogNT::getInstance()->warn(TAG, - "Getting display size failed! (BCM API) "); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - //UnSetFullscreen with window - dispconf.set = OMX_DISPLAY_SET_DEST_RECT; - dispconf.dest_rect.x_offset - = (int) (xpos * ((float) display_width)); - dispconf.dest_rect.y_offset = (int) (ypos - * ((float) display_height)); - dispconf.dest_rect.width = (int) (width * ((float) display_width)); - dispconf.dest_rect.height = (int) (height * ((float) display_height)); - LogNT::getInstance()->debug(TAG, - "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset, - dispconf.dest_rect.width , dispconf.dest_rect.height); - - error = OMX_SetParameter(omx_vid_rend, - OMX_IndexConfigDisplayRegion, &dispconf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigDisplayRegion failed {:#x}", error); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - clock_mutex.unlock(); - return; - } - } - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - - } - clock_mutex.unlock(); + clock_mutex.lock(); + + if (omx_running) + { + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + OMX_ERRORTYPE error; + OMX_CONFIG_DISPLAYREGIONTYPE dispconf; + memset(&dispconf, 0, sizeof(dispconf)); + dispconf.nSize = sizeof(dispconf); + dispconf.nVersion.nVersion = OMX_VERSION; + dispconf.nPortIndex = omx_rend_input_port; + dispconf.layer = 1; + dispconf.set = OMX_DISPLAY_SET_LAYER; + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + + dispconf.pixel_x = parx; + dispconf.pixel_y = pary; + dispconf.set = OMX_DISPLAY_SET_PIXEL; + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + + dispconf.set = OMX_DISPLAY_SET_FULLSCREEN; + + if (!windowed) + { + //Set Fullscreen + dispconf.fullscreen = OMX_TRUE; + } + else + { + dispconf.fullscreen = OMX_FALSE; + } + + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + + dispconf.set = OMX_DISPLAY_SET_MODE; + + if (!windowed) + { + dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL : OMX_DISPLAY_MODE_LETTERBOX; + } + else + { + dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX; + } + + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + + if (windowed) + { + unsigned int display_width, display_height; + display_width = display_height = 0; + + if (graphics_get_display_size(0, &display_width, &display_height) < 0) + { + logger->warn(TAG, "Getting display size failed! (BCM API) "); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + + //UnSetFullscreen with window + dispconf.set = OMX_DISPLAY_SET_DEST_RECT; + dispconf.dest_rect.x_offset = (int) (xpos * ((float) display_width)); + dispconf.dest_rect.y_offset = (int) (ypos * ((float) display_height)); + dispconf.dest_rect.width = (int) (width * ((float) display_width)); + dispconf.dest_rect.height = (int) (height * ((float) display_height)); + logger->debug(TAG, "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset, dispconf.dest_rect.y_offset, + dispconf.dest_rect.width, dispconf.dest_rect.height); + + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion failed {:#x}", error); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + clock_mutex.unlock(); + return; + } + } + + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + } + + clock_mutex.unlock(); } int VideoOMX::signalOff() { - //TODO reinit osd - LogNT::getInstance()->info(TAG, "signalOff"); - Osd::getInstance()->stopUpdate(); // turn off drawing thread - // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this - InputMan::getInstance()->shutdown(); - vc_tv_power_off(); - InputMan::getInstance()->init(); - signalon=false; - return 1; + //TODO reinit osd + logger->info(TAG, "signalOff"); + Osd::getInstance()->stopUpdate(); // turn off drawing thread + // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this + InputMan::getInstance()->shutdown(); + vc_tv_power_off(); + InputMan::getInstance()->init(); + signalon = false; + return 1; } int VideoOMX::signalOn() { - if (!signalon) { - Osd::getInstance()->shutdown(); - LogNT::getInstance()->info(TAG, "signalOn"); - selectVideoMode(0); - Osd::getInstance()->restore(); - Osd::getInstance()->init(); - BoxStack::getInstance()->redrawAllBoxes(); - initted=1; - + if (!signalon) + { + Osd::getInstance()->shutdown(); + logger->info(TAG, "signalOn"); + selectVideoMode(0); + Osd::getInstance()->restore(); + Osd::getInstance()->init(); + BoxStack::getInstance()->redrawAllBoxes(); + initted = 1; } + return 1; } @@ -799,1640 +856,1755 @@ int VideoOMX::setSource() if (!initted) return 0; // What does this do... -// if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0; return 1; } -int VideoOMX::setPosition(int x, int y) { - if (!initted) - return 0; - xpos = ((float) x*2.f) / ((float) screenWidth); - ypos = ((float) y*2.f) / ((float) screenHeight); +int VideoOMX::setPosition(int x, int y) +{ + if (!initted) return 0; + + xpos = ((float) x * 2.f) / ((float) screenWidth); + ypos = ((float) y * 2.f) / ((float) screenHeight); - updateMode(); - return 1; + updateMode(); + return 1; } int VideoOMX::sync() { if (!initted) return 0; -// if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0; return 1; } -void VideoOMX::interlaceSwitch4Demux() { - return; - Demuxer *demux=Demuxer::getInstance(); - - if (hdmi) { // only switch if hdmi and HD or interlaced SD material - +void VideoOMX::interlaceSwitch4Demux() +{ + return; + Demuxer* demux = Demuxer::getInstance(); - //OMX_Deinit(); - int set_interlaced=0; - if (demux->getHorizontalSize()>720 && demux->getInterlaced()) { - set_interlaced=1; - } - LogNT::getInstance()->info(TAG, "switch interlacing {} {} {}",demux->getInterlaced(),outputinterlaced,set_interlaced); - if (outputinterlaced!=set_interlaced) { - selectVideoMode(set_interlaced); - Osd::getInstance()->shutdown(); - Osd::getInstance()->restore(); - Osd::getInstance()->init(); - BoxStack::getInstance()->redrawAllBoxes(); - initted=1; - } - //OMX_Init(); + if (hdmi) // only switch if hdmi and HD or interlaced SD material + { + //OMX_Deinit(); + int set_interlaced = 0; + if (demux->getHorizontalSize() > 720 && demux->getInterlaced()) + { + set_interlaced = 1; + } - } + logger->info(TAG, "switch interlacing {} {} {}", demux->getInterlaced(), outputinterlaced, set_interlaced); + if (outputinterlaced != set_interlaced) + { + selectVideoMode(set_interlaced); + Osd::getInstance()->shutdown(); + Osd::getInstance()->restore(); + Osd::getInstance()->init(); + BoxStack::getInstance()->redrawAllBoxes(); + initted = 1; + } + //OMX_Init(); + } } +int VideoOMX::play() +{ + if (!initted) return 0; -int VideoOMX::play() { - if (!initted) - return 0; - iframemode = false; - logger->debug(TAG, "enter play"); - - interlaceSwitch4Demux(); + iframemode = false; + logger->debug(TAG, "enter play"); - if (AllocateCodecsOMX()) { - return 1; - // Otherwise fall back to libav - } else { - if (h264) { - omx_h264 = false; - LogNT::getInstance()->info(TAG, - "Allocate Codecs OMX failed assume h264 unsupported"); - } else { - omx_mpeg2 = false; - LogNT::getInstance()->info(TAG, - "Allocate Codecs OMX failed assume mpeg2 unsupported"); - } - } + interlaceSwitch4Demux(); - return 0; + if (AllocateCodecsOMX()) + { + return 1; + // Otherwise fall back to libav + } + else + { + if (h264) + { + omx_h264 = false; + logger->info(TAG, "Allocate Codecs OMX failed assume h264 unsupported"); + } + else + { + omx_mpeg2 = false; + logger->info(TAG, "Allocate Codecs OMX failed assume mpeg2 unsupported"); + } + } + return 0; } - int VideoOMX::initClock() { - OMX_ERRORTYPE error; - clock_mutex.lock(); - if (clock_references==0) - { - - static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; - omx_event_mutex.lock(); - omx_events.clear(); - omx_event_mutex.unlock(); - - error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks); - - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "Init OMX clock failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - /* TODO Clock config to separate method */ - OMX_PORT_PARAM_TYPE p_param; - memset(&p_param,0,sizeof(p_param)); - p_param.nSize=sizeof(p_param); - p_param.nVersion.nVersion=OMX_VERSION; - error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_clock_output_port=p_param.nStartPortNumber; - - for (unsigned int i=0;idebug(TAG, "Disable Ports OMX clock failed {}",i); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - } - - - - - } - logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock); - clock_references++; - clock_mutex.unlock(); - return 1; -} - -int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port) -{ - OMX_ERRORTYPE error; - *p_omx_clock=NULL; - *p_omx_clock_output_port=0; - - if (!initClock()) { - return 0; - } - clock_mutex.lock(); - - OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock; - memset(&refclock,0,sizeof(refclock)); - refclock.nSize=sizeof(refclock); - refclock.nVersion.nVersion=OMX_VERSION; - - refclock.eClock=OMX_TIME_RefClockAudio; - - //refclock.eClock=OMX_TIME_RefClockVideo; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - OMX_PORT_PARAM_TYPE p_param; - memset(&p_param,0,sizeof(p_param)); - p_param.nSize=sizeof(p_param); - p_param.nVersion.nVersion=OMX_VERSION; - error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; - memset(&clock_conf,0,sizeof(clock_conf)); - clock_conf.nSize=sizeof(clock_conf); - clock_conf.nVersion.nVersion=OMX_VERSION; - clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime; - clock_conf.nStartTime=intToOMXTicks(0); - clock_conf.nOffset=intToOMXTicks(0); - if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1; - else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error); - } - - - *p_omx_clock_output_port=p_param.nStartPortNumber+1; - *p_omx_clock=omx_clock; - clock_mutex.unlock(); - return 1; -} + OMX_ERRORTYPE error; + clock_mutex.lock(); -int VideoOMX::getClockVideoandInit() -{ - OMX_ERRORTYPE error; - - if (!initClock()) { - return 0; - } - clock_mutex.lock(); - - if (clock_references==1) { // only if no audio is attached to this clock! - OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock; - memset(&refclock,0,sizeof(refclock)); - refclock.nSize=sizeof(refclock); - refclock.nVersion.nVersion=OMX_VERSION; - - //refclock.eClock=OMX_TIME_RefClockAudio; - - refclock.eClock=OMX_TIME_RefClockVideo; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - } - - OMX_PORT_PARAM_TYPE p_param; - memset(&p_param,0,sizeof(p_param)); - p_param.nSize=sizeof(p_param); - p_param.nVersion.nVersion=OMX_VERSION; - error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; - memset(&clock_conf,0,sizeof(clock_conf)); - clock_conf.nSize=sizeof(clock_conf); - clock_conf.nVersion.nVersion=OMX_VERSION; - clock_conf.eState=OMX_TIME_ClockStateStopped; - clock_conf.nStartTime=intToOMXTicks(0); - clock_conf.nOffset=intToOMXTicks(0); - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error); - } - - - memset(&clock_conf,0,sizeof(clock_conf)); - clock_conf.nSize=sizeof(clock_conf); - clock_conf.nVersion.nVersion=OMX_VERSION; - clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime; - clock_conf.nStartTime=intToOMXTicks(0); - clock_conf.nOffset=intToOMXTicks(0); - if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0; - else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error); - } - - omx_clock_output_port=p_param.nStartPortNumber; - clock_mutex.unlock(); - - return 1; -} + if (clock_references == 0) + { + static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX}; + omx_event_mutex.lock(); + omx_events.clear(); + omx_event_mutex.unlock(); -void VideoOMX::clockUnpause() + error = OMX_GetHandle(&omx_clock, L_VPE_OMX_CLOCK, NULL, &callbacks); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX clock failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + /* TODO Clock config to separate method */ + OMX_PORT_PARAM_TYPE p_param; + memset(&p_param, 0, sizeof(p_param)); + p_param.nSize = sizeof(p_param); + p_param.nVersion.nVersion = OMX_VERSION; + error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_clock_output_port = p_param.nStartPortNumber; + + for (unsigned int i = 0; i < p_param.nPorts; i++) + { + if (!DisablePort(omx_clock, p_param.nStartPortNumber + i, true) ) + { + logger->debug(TAG, "Disable Ports OMX clock failed {}", i); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } + } + + logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock); + clock_references++; + clock_mutex.unlock(); + return 1; +} + +int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port) { - OMX_ERRORTYPE error; - LogNT::getInstance()->info(TAG, "enter Clockunpause"); - clock_mutex.lock(); - if (clock_references>0 && clockpaused) { - OMX_TIME_CONFIG_SCALETYPE scale_type; - memset(&scale_type,0,sizeof(scale_type)); - scale_type.nSize=sizeof(scale_type); - scale_type.nVersion.nVersion=OMX_VERSION; - scale_type.xScale=1<<16; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error); - } - LogNT::getInstance()->info(TAG, "set playback speed ClockUnpause"); - clockpaused=false; - } - clock_mutex.unlock(); + OMX_ERRORTYPE error; + *p_omx_clock = NULL; + *p_omx_clock_output_port = 0; + + if (!initClock()) return 0; + + clock_mutex.lock(); + + OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock; + memset(&refclock, 0, sizeof(refclock)); + refclock.nSize = sizeof(refclock); + refclock.nVersion.nVersion = OMX_VERSION; + + refclock.eClock = OMX_TIME_RefClockAudio; + + //refclock.eClock=OMX_TIME_RefClockVideo; + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + OMX_PORT_PARAM_TYPE p_param; + memset(&p_param, 0, sizeof(p_param)); + p_param.nSize = sizeof(p_param); + p_param.nVersion.nVersion = OMX_VERSION; + error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; + memset(&clock_conf, 0, sizeof(clock_conf)); + clock_conf.nSize = sizeof(clock_conf); + clock_conf.nVersion.nVersion = OMX_VERSION; + clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime; + clock_conf.nStartTime = intToOMXTicks(0); + clock_conf.nOffset = intToOMXTicks(0); + + if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT1; + else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1; + + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error); + } + + *p_omx_clock_output_port = p_param.nStartPortNumber + 1; + *p_omx_clock = omx_clock; + clock_mutex.unlock(); + return 1; } +int VideoOMX::getClockVideoandInit() +{ + OMX_ERRORTYPE error; + + if (!initClock()) return 0; -void VideoOMX::clockPause() + clock_mutex.lock(); + + if (clock_references == 1) // only if no audio is attached to this clock! + { + OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock; + memset(&refclock, 0, sizeof(refclock)); + refclock.nSize = sizeof(refclock); + refclock.nVersion.nVersion = OMX_VERSION; + + //refclock.eClock=OMX_TIME_RefClockAudio; + + refclock.eClock = OMX_TIME_RefClockVideo; + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } + + OMX_PORT_PARAM_TYPE p_param; + memset(&p_param, 0, sizeof(p_param)); + p_param.nSize = sizeof(p_param); + p_param.nVersion.nVersion = OMX_VERSION; + error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; + memset(&clock_conf, 0, sizeof(clock_conf)); + clock_conf.nSize = sizeof(clock_conf); + clock_conf.nVersion.nVersion = OMX_VERSION; + clock_conf.eState = OMX_TIME_ClockStateStopped; + clock_conf.nStartTime = intToOMXTicks(0); + clock_conf.nOffset = intToOMXTicks(0); + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error); + } + + memset(&clock_conf, 0, sizeof(clock_conf)); + clock_conf.nSize = sizeof(clock_conf); + clock_conf.nVersion.nVersion = OMX_VERSION; + clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime; + clock_conf.nStartTime = intToOMXTicks(0); + clock_conf.nOffset = intToOMXTicks(0); + + if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT0; + else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1; + + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error); + } + + omx_clock_output_port = p_param.nStartPortNumber; + clock_mutex.unlock(); + + return 1; +} + +void VideoOMX::clockUnpause() { - OMX_ERRORTYPE error; - LogNT::getInstance()->info(TAG, "enter ClockPause"); - clock_mutex.lock(); - if (clock_references>0 && !clockpaused) { - OMX_TIME_CONFIG_SCALETYPE scale_type; - memset(&scale_type,0,sizeof(scale_type)); - scale_type.nSize=sizeof(scale_type); - scale_type.nVersion.nVersion=OMX_VERSION; - scale_type.xScale=0; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error); - } - LogNT::getInstance()->info(TAG, "set playback speed ClockPause"); - clockpaused=true; - } - clock_mutex.unlock(); + OMX_ERRORTYPE error; + logger->info(TAG, "enter Clockunpause"); + clock_mutex.lock(); + + if (clock_references > 0 && clockpaused) + { + OMX_TIME_CONFIG_SCALETYPE scale_type; + memset(&scale_type, 0, sizeof(scale_type)); + scale_type.nSize = sizeof(scale_type); + scale_type.nVersion.nVersion = OMX_VERSION; + scale_type.xScale = 1 << 16; + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error); + } + + logger->info(TAG, "set playback speed ClockUnpause"); + clockpaused = false; + } + + clock_mutex.unlock(); } +void VideoOMX::clockPause() +{ + OMX_ERRORTYPE error; + logger->info(TAG, "enter ClockPause"); + clock_mutex.lock(); + + if (clock_references > 0 && !clockpaused) + { + OMX_TIME_CONFIG_SCALETYPE scale_type; + memset(&scale_type, 0, sizeof(scale_type)); + scale_type.nSize = sizeof(scale_type); + scale_type.nVersion.nVersion = OMX_VERSION; + scale_type.xScale = 0; + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error); + } + + logger->info(TAG, "set playback speed ClockPause"); + clockpaused = true; + } + + clock_mutex.unlock(); +} int VideoOMX::AllocateCodecsOMX() { - OMX_ERRORTYPE error; - static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; - - Demuxer* demux=Demuxer::getInstance(); - - dodeint=false; - first_frame=true; - - LogNT::getInstance()->info(TAG, "Allocate Codecs OMX"); - //Clock, move later to audio including events - - LogNT::getInstance()->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced()); - if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) { - dodeint=true; - - - LogNT::getInstance()->info(TAG, "Deinterlacing activated {}",deinterlace); - - } - - - if (!getClockVideoandInit()){ - return 0;// get the clock and init it if necessary - } - - - if (!idleClock()) { - logger->debug(TAG, "idleClock failed"); - return 0; - } - /* TODO end */ - - clock_mutex.lock(); - if (h264) { - error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks); - } else { - error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks); - } - - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video decoder failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - logger->debug(TAG, "Nmark3 "); - OMX_PORT_PARAM_TYPE p_param; - memset(&p_param,0,sizeof(p_param)); - p_param.nSize=sizeof(p_param); - p_param.nVersion.nVersion=OMX_VERSION; - error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_codec_input_port=p_param.nStartPortNumber; - omx_codec_output_port=p_param.nStartPortNumber+1; - - if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) { - logger->debug(TAG, "Disable Ports OMX video decoder failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - logger->debug(TAG, "Nmark4 "); - - OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal; - memset(&conceal,0,sizeof(conceal)); - conceal.nSize=sizeof(conceal); - conceal.nVersion.nVersion=OMX_VERSION; - conceal.bStartWithValidFrame=OMX_FALSE; - - error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (dodeint) { - error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL, - &callbacks); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX video deinterlacer failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit, - &p_param); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX video deinterlacer OMX_GetParameter failed {:#x}", - error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_deint_input_port = p_param.nStartPortNumber; - omx_deint_output_port = p_param.nStartPortNumber + 1; - - if (!DisablePort(omx_vid_deint, omx_deint_input_port, true) - || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) { - LogNT::getInstance()->debug(TAG, - "Disable Ports OMX video deint failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - } - - - error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_shed_input_port=p_param.nStartPortNumber; - omx_shed_output_port=p_param.nStartPortNumber+1; - - - error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_shed_clock_port=p_param.nStartPortNumber; - logger->debug(TAG, "scheduler ports {} {} {}",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port); - - - if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true) - || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) { - logger->debug(TAG, "Disable Ports OMX video shed failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video rend failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_rend_input_port=p_param.nStartPortNumber; - //omx_rend_output_port=p_param.nStartPortNumber+1; - - - if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/ - ) { - logger->debug(TAG, "Disable Ports OMX video rend failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - //Setuo chain - - - - error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error,omx_clock_output_port,omx_shed_clock_port); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false) - ) { - logger->debug(TAG, "Enable Ports OMX clock shed failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) { - logger->debug(TAG, "vid_sched idle ChangeComponentState"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - - if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - - - if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - -/* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error); - return 0; - }*/ - - OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type; - memset(&ft_type,0,sizeof(ft_type)); - ft_type.nSize=sizeof(ft_type); - ft_type.nVersion.nVersion=OMX_VERSION; - - ft_type.nPortIndex=omx_codec_input_port; - if (h264) { - ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC; - } else { - ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2; - } - - - - ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16); - logger->debug(TAG, "Framerate: {}",demux->getFrameRate()); - error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) { - logger->debug(TAG, "vid_dec ChangeComponentState"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - OMX_CONFIG_BUFFERSTALLTYPE stall_conf; - memset(&stall_conf,0,sizeof(stall_conf)); - stall_conf.nSize=sizeof(stall_conf); - stall_conf.nVersion.nVersion=OMX_VERSION; - stall_conf.nPortIndex=omx_codec_output_port; - stall_conf.nDelay=1500*1000; - error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_vid_stalled = false; - - OMX_CONFIG_REQUESTCALLBACKTYPE req_callback; - memset(&req_callback,0,sizeof(req_callback)); - req_callback.nSize=sizeof(req_callback); - req_callback.nVersion.nVersion=OMX_VERSION; - req_callback.nPortIndex=omx_codec_output_port; - req_callback.nIndex=OMX_IndexConfigBufferStall; - req_callback.bEnable=OMX_TRUE; - error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - if (!PrepareInputBufsOMX()) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!dodeint) { - error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false) - ) { - logger->debug(TAG, "Enable Ports OMX codec shed failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - } else { - - error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - - if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false) - ) { - logger->debug(TAG, "Enable Ports OMX codec deint failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) { - logger->debug(TAG, "vid_deint ChangeComponentState"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter; - memset(&imagefilter,0,sizeof(imagefilter)); - imagefilter.nSize=sizeof(imagefilter); - imagefilter.nVersion.nVersion=OMX_VERSION; - - imagefilter.nPortIndex=omx_deint_output_port; - imagefilter.nNumParams=4; - imagefilter.nParams[0]=3;//??? - imagefilter.nParams[1]=0;//default frame interval - imagefilter.nParams[2]=0;// frame rate - if (demux->getHorizontalSize() <= 720){ - imagefilter.nParams[3] = 1;//use qpus - } - else - { - imagefilter.nParams[3] = 0;//use qpus - } - - switch (deinterlace) { - case 1: - imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break; - case 2: - imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break; - case 3: - imagefilter.eImageFilter=OMX_ImageFilterFilm; break; - case 4: - imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break; - } - - - error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - - error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false) - ) { - logger->debug(TAG, "Enable Ports OMX deint shed failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - } - - if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) { - logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false) - ) { - logger->debug(TAG, "Enable Ports OMX shed rend failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port) - || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) { - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) { - logger->debug(TAG, "vid_rend ChangeComponentState"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (dodeint) { - if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) { - logger->debug(TAG, "vid_vid_deint ChangeComponentState"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - DisablePort(omx_vid_deint,omx_deint_output_port,false); - DisablePort(omx_vid_deint,omx_deint_input_port,false); - } - - if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) { - logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) { - logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - //raspbi specifif - /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf; - memset(&dispconf,0,sizeof(dispconf)); - dispconf.nSize=sizeof(dispconf); - dispconf.nVersion.nVersion=OMX_VERSION; - - dispconf.nPortIndex=omx_rend_input_port; - - dispconf.set=OMX_DISPLAY_SET_LAYER ; - dispconf.layer=1; - error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - }*/ - -/* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ; - dispconf.fullscreen=OMX_FALSE; - error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - - dispconf.set=OMX_DISPLAY_SET_DEST_RECT; - dispconf.dest_rect.x_offset=100; - dispconf.dest_rect.y_offset=100; - dispconf.dest_rect.width=640; - dispconf.dest_rect.height=480; - error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - }*/ - - - //playbacktimeoffset=-GetCurrentSystemTime(); - - iframemode=false; - omx_running=true; - clock_mutex.unlock(); - clockUnpause(); - updateMode(); - - setClockExecutingandRunning(); - - - - - - return 1; + OMX_ERRORTYPE error; + static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX}; + + Demuxer* demux = Demuxer::getInstance(); + + dodeint = false; + first_frame = true; + + logger->info(TAG, "Allocate Codecs OMX"); + //Clock, move later to audio including events + + logger->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(), demux->getVerticalSize(), demux->getInterlaced()); + + if (deinterlace != 0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) + { + dodeint = true; + logger->info(TAG, "Deinterlacing activated {}", deinterlace); + } + + if (!getClockVideoandInit()) + { + return 0;// get the clock and init it if necessary + } + + if (!idleClock()) + { + logger->debug(TAG, "idleClock failed"); + return 0; + } + + /* TODO end */ + + clock_mutex.lock(); + + if (h264) + { + error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_H264_DECODER, NULL, &callbacks); + } + else + { + error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_MPEG2_DECODER, NULL, &callbacks); + } + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video decoder failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + logger->debug(TAG, "Nmark3"); + OMX_PORT_PARAM_TYPE p_param; + memset(&p_param, 0, sizeof(p_param)); + p_param.nSize = sizeof(p_param); + p_param.nVersion.nVersion = OMX_VERSION; + error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamVideoInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_codec_input_port = p_param.nStartPortNumber; + omx_codec_output_port = p_param.nStartPortNumber + 1; + + if (!DisablePort(omx_vid_dec, omx_codec_input_port) || !DisablePort(omx_vid_dec, omx_codec_output_port)) + { + logger->debug(TAG, "Disable Ports OMX video decoder failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + logger->debug(TAG, "Nmark4"); + + OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal; + memset(&conceal, 0, sizeof(conceal)); + conceal.nSize = sizeof(conceal); + conceal.nVersion.nVersion = OMX_VERSION; + conceal.bStartWithValidFrame = OMX_FALSE; + + error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &conceal); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (dodeint) + { + error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL, &callbacks); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video deinterlacer failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video deinterlacer OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_deint_input_port = p_param.nStartPortNumber; + omx_deint_output_port = p_param.nStartPortNumber + 1; + + if (!DisablePort(omx_vid_deint, omx_deint_input_port, true) + || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) + { + logger->debug(TAG, "Disable Ports OMX video deint failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } + + error = OMX_GetHandle(&omx_vid_sched, L_VPE_OMX_VIDEO_SCHED, NULL, &callbacks); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamVideoInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_shed_input_port = p_param.nStartPortNumber; + omx_shed_output_port = p_param.nStartPortNumber + 1; + + error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamOtherInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_shed_clock_port = p_param.nStartPortNumber; + logger->debug(TAG, "scheduler ports {} {} {}", omx_shed_input_port, omx_shed_output_port, omx_shed_clock_port); + + if (!DisablePort(omx_vid_sched, omx_shed_input_port, true) || !DisablePort(omx_vid_sched, omx_shed_output_port, true) + || !DisablePort(omx_vid_sched, omx_shed_clock_port, true)) + { + logger->debug(TAG, "Disable Ports OMX video shed failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_GetHandle(&omx_vid_rend, L_VPE_OMX_VIDEO_REND, NULL, &callbacks); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video rend failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_GetParameter(omx_vid_rend, OMX_IndexParamVideoInit, &p_param); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_rend_input_port = p_param.nStartPortNumber; + //omx_rend_output_port=p_param.nStartPortNumber+1; + + if (!DisablePort(omx_vid_rend, omx_rend_input_port, true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/ + ) + { + logger->debug(TAG, "Disable Ports OMX video rend failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + //Setup chain + + error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, omx_vid_sched, omx_shed_clock_port); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error, omx_clock_output_port, omx_shed_clock_port); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!EnablePort(omx_clock, omx_clock_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_clock_port, false) + ) + { + logger->debug(TAG, "Enable Ports OMX clock shed failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle)) + { + logger->debug(TAG, "vid_sched idle ChangeComponentState"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_clock_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_clock, OMX_CommandPortEnable, omx_clock_output_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0); + if (error!=OMX_ErrorNone){ + logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error); + return 0; + }*/ + + OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type; + memset(&ft_type, 0, sizeof(ft_type)); + ft_type.nSize = sizeof(ft_type); + ft_type.nVersion.nVersion = OMX_VERSION; + + ft_type.nPortIndex = omx_codec_input_port; + + if (h264) + ft_type.eCompressionFormat = OMX_VIDEO_CodingAVC; + else + ft_type.eCompressionFormat = OMX_VIDEO_CodingMPEG2; + + ft_type.xFramerate = 0 * (1 << 16); //25*(1<<16);//demux->getFrameRate()*(1<<16); + logger->debug(TAG, "Framerate: {}", demux->getFrameRate()); + error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamVideoPortFormat, &ft_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle)) + { + logger->debug(TAG, "vid_dec ChangeComponentState"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + OMX_CONFIG_BUFFERSTALLTYPE stall_conf; + memset(&stall_conf, 0, sizeof(stall_conf)); + stall_conf.nSize = sizeof(stall_conf); + stall_conf.nVersion.nVersion = OMX_VERSION; + stall_conf.nPortIndex = omx_codec_output_port; + stall_conf.nDelay = 1500 * 1000; + error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + omx_vid_stalled = false; + + OMX_CONFIG_REQUESTCALLBACKTYPE req_callback; + memset(&req_callback, 0, sizeof(req_callback)); + req_callback.nSize = sizeof(req_callback); + req_callback.nVersion.nVersion = OMX_VERSION; + req_callback.nPortIndex = omx_codec_output_port; + req_callback.nIndex = OMX_IndexConfigBufferStall; + req_callback.bEnable = OMX_TRUE; + error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigRequestCallback, &req_callback); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!PrepareInputBufsOMX()) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!dodeint) + { + error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_sched, omx_shed_input_port); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false)) + { + logger->debug(TAG, "Enable Ports OMX codec shed failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } + else + { + error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_deint, omx_deint_input_port); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_deint, omx_deint_input_port, false)) + { + logger->debug(TAG, "Enable Ports OMX codec deint failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_input_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) + { + logger->debug(TAG, "vid_deint ChangeComponentState"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter; + memset(&imagefilter, 0, sizeof(imagefilter)); + imagefilter.nSize = sizeof(imagefilter); + imagefilter.nVersion.nVersion = OMX_VERSION; + + imagefilter.nPortIndex = omx_deint_output_port; + imagefilter.nNumParams = 4; + imagefilter.nParams[0] = 3; //??? + imagefilter.nParams[1] = 0; //default frame interval + imagefilter.nParams[2] = 0; // frame rate + + if (demux->getHorizontalSize() <= 720) + { + imagefilter.nParams[3] = 1;//use qpus + } + else + { + imagefilter.nParams[3] = 0;//use qpus + } + + switch (deinterlace) + { + case 1: + imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceLineDouble; break; + + case 2: + imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; break; + + case 3: + imagefilter.eImageFilter = OMX_ImageFilterFilm; break; + + case 4: + imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break; + } + + error = OMX_SetConfig(omx_vid_deint, OMX_IndexConfigCommonImageFilterParameters, &imagefilter); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, omx_vid_sched, omx_shed_input_port); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!EnablePort(omx_vid_deint, omx_deint_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false)) + { + logger->debug(TAG, "Enable Ports OMX deint shed failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } + + if (!ChangeComponentState(omx_vid_dec, OMX_StateExecuting)) + { + logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, omx_vid_rend, omx_rend_input_port); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!EnablePort(omx_vid_sched, omx_shed_output_port, false) || !EnablePort(omx_vid_rend, omx_rend_input_port, false)) + { + logger->debug(TAG, "Enable Ports OMX shed rend failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_output_port) + || !CommandFinished(omx_vid_rend, OMX_CommandPortEnable, omx_rend_input_port)) + { + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle)) + { + logger->debug(TAG, "vid_rend ChangeComponentState"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (dodeint) + { + if (!ChangeComponentState(omx_vid_deint, OMX_StateExecuting)) + { + logger->debug(TAG, "vid_vid_deint ChangeComponentState"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + DisablePort(omx_vid_deint, omx_deint_output_port, false); + DisablePort(omx_vid_deint, omx_deint_input_port, false); + } + + if (!ChangeComponentState(omx_vid_sched, OMX_StateExecuting)) + { + logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + if (!ChangeComponentState(omx_vid_rend, OMX_StateExecuting)) + { + logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + //raspbi specifif + /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf; + memset(&dispconf,0,sizeof(dispconf)); + dispconf.nSize=sizeof(dispconf); + dispconf.nVersion.nVersion=OMX_VERSION; + + dispconf.nPortIndex=omx_rend_input_port; + + dispconf.set=OMX_DISPLAY_SET_LAYER ; + dispconf.layer=1; + error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); + if (error!=OMX_ErrorNone){ + logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + + /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ; + dispconf.fullscreen=OMX_FALSE; + error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); + if (error!=OMX_ErrorNone){ + logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + + dispconf.set=OMX_DISPLAY_SET_DEST_RECT; + dispconf.dest_rect.x_offset=100; + dispconf.dest_rect.y_offset=100; + dispconf.dest_rect.width=640; + dispconf.dest_rect.height=480; + error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf); + if (error!=OMX_ErrorNone){ + logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + + + //playbacktimeoffset=-GetCurrentSystemTime(); + + iframemode = false; + omx_running = true; + clock_mutex.unlock(); + clockUnpause(); + updateMode(); + + setClockExecutingandRunning(); + + return 1; } int VideoOMX::idleClock() { - //OMX_ERRORTYPE error; - OMX_STATETYPE temp_state; - clock_mutex.lock(); - OMX_GetState(omx_clock,&temp_state); + //OMX_ERRORTYPE error; + OMX_STATETYPE temp_state; + clock_mutex.lock(); + OMX_GetState(omx_clock, &temp_state); - if (temp_state!=OMX_StateIdle) { - if (!ChangeComponentState(omx_clock,OMX_StateIdle)) { - logger->debug(TAG, "omx_clock ChangeComponentState Idle failed"); - clock_mutex.unlock(); - return 0; - } - } - clock_mutex.unlock(); - return 1; + if (temp_state != OMX_StateIdle) + { + if (!ChangeComponentState(omx_clock, OMX_StateIdle)) + { + logger->debug(TAG, "omx_clock ChangeComponentState Idle failed"); + clock_mutex.unlock(); + return 0; + } + } + + clock_mutex.unlock(); + return 1; } int VideoOMX::setClockExecutingandRunning() { - OMX_ERRORTYPE error; - OMX_STATETYPE temp_state; - clock_mutex.lock(); - OMX_GetState(omx_clock,&temp_state); + OMX_ERRORTYPE error; + OMX_STATETYPE temp_state; + clock_mutex.lock(); + OMX_GetState(omx_clock, &temp_state); - if (temp_state!=OMX_StateExecuting) { - if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) { - logger->debug(TAG, "omx_clock ChangeComponentState Execute failed"); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - } + if (temp_state != OMX_StateExecuting) + { + if (!ChangeComponentState(omx_clock, OMX_StateExecuting)) + { + logger->debug(TAG, "omx_clock ChangeComponentState Execute failed"); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + } - OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; - memset(&clock_conf,0,sizeof(clock_conf)); - clock_conf.nSize=sizeof(clock_conf); - clock_conf.nVersion.nVersion=OMX_VERSION; - clock_conf.eState=OMX_TIME_ClockStateRunning; - error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error); - clock_mutex.unlock(); - DeAllocateCodecsOMX(); - return 0; - } - clock_mutex.unlock(); - return 1; + OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; + memset(&clock_conf, 0, sizeof(clock_conf)); + clock_conf.nSize = sizeof(clock_conf); + clock_conf.nVersion.nVersion = OMX_VERSION; + clock_conf.eState = OMX_TIME_ClockStateRunning; + error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf); -} + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error); + clock_mutex.unlock(); + DeAllocateCodecsOMX(); + return 0; + } + clock_mutex.unlock(); + return 1; +} -int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex +int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait) //needs to be called with locked mutex { - OMX_ERRORTYPE error; - error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}",handle,type, error); - return 0; - } - - if (wait) { - if (!CommandFinished(handle,OMX_CommandStateSet,type)) { - return 0; - } - } - - return 1; -} - - -int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex -{ - OMX_ERRORTYPE error; - bool skip=false; - - OMX_PARAM_PORTDEFINITIONTYPE pdt; - memset(&pdt,0,sizeof(pdt)); - pdt.nSize=sizeof(pdt); - pdt.nVersion.nVersion=OMX_VERSION; - pdt.nPortIndex=port; - error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt); - if (error==OMX_ErrorNone) { - if(pdt.bEnabled==OMX_TRUE) { - skip=true; //already disabled; - } - - } + OMX_ERRORTYPE error; + error = OMX_SendCommand(handle, OMX_CommandStateSet, type, 0); - if (!skip) { - error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}",handle,port, error); - return 0; - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}", handle, type, error); + return 0; + } - if (!wait) return 1; - if (!CommandFinished(handle,OMX_CommandPortEnable,port)) { - return 0; - } + if (wait) + { + if (!CommandFinished(handle, OMX_CommandStateSet, type)) return 0; + } - } - return 1; + return 1; } -int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex +int VideoOMX::EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex { - OMX_ERRORTYPE error; - bool skip=false; + OMX_ERRORTYPE error; + bool skip = false; + + OMX_PARAM_PORTDEFINITIONTYPE pdt; + memset(&pdt, 0, sizeof(pdt)); + pdt.nSize = sizeof(pdt); + pdt.nVersion.nVersion = OMX_VERSION; + pdt.nPortIndex = port; + error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt); - OMX_PARAM_PORTDEFINITIONTYPE pdt; - memset(&pdt,0,sizeof(pdt)); - pdt.nSize=sizeof(pdt); - pdt.nVersion.nVersion=OMX_VERSION; - pdt.nPortIndex=port; - error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt); - if (error==OMX_ErrorNone) { - if(pdt.bEnabled==OMX_FALSE) { - skip=true; //already disabled; - } + if (error == OMX_ErrorNone) + { + if (pdt.bEnabled == OMX_TRUE) + { + skip = true; //already disabled; + } + } - } + if (!skip) + { + error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, 0); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}", handle, port, error); + return 0; + } - if (!skip) { - error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}",handle,port, error); - return 0; - } + if (!wait) return 1; - if (!wait) return 1; - if (!CommandFinished(handle,OMX_CommandPortDisable,port)) { - return 0; - } - } + if (!CommandFinished(handle, OMX_CommandPortEnable, port)) + { + return 0; + } + } - return 1; + return 1; } -int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex +int VideoOMX::DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex { - int i=0; - int iend=(wait/5+1); - while (i::iterator itty=omx_events.begin(); - while (itty!=omx_events.end()) { + OMX_ERRORTYPE error; + bool skip = false; - VPE_OMX_EVENT current=*itty; - if (current.handle==handle) { //this is ours - if (current.event_type==OMX_EventError) { - omx_events.erase(itty); - omx_event_mutex.unlock(); - logger->debug(TAG, "WaitForEvent Finished on Error"); - return 0; + OMX_PARAM_PORTDEFINITIONTYPE pdt; + memset(&pdt, 0, sizeof(pdt)); + pdt.nSize = sizeof(pdt); + pdt.nVersion.nVersion = OMX_VERSION; + pdt.nPortIndex = port; + error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt); - } else if (current.event_type==event) { - omx_events.erase(itty); - omx_event_mutex.unlock(); - logger->debug(TAG, "WaitForEvent Finished Completed"); - return 1; - } - } - itty++; + if (error == OMX_ErrorNone) + { + if (pdt.bEnabled == OMX_FALSE) + { + skip = true; //already disabled; + } + } - } - omx_event_mutex.unlock(); + if (!skip) + { + error = OMX_SendCommand(handle, OMX_CommandPortDisable, port, 0); - //logger->debug(TAG, "WaitForEvent"); - std::unique_lock ul(omx_event_ready_signal_mutex); - omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10)); - ul.unlock(); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}", handle, port, error); + return 0; + } - i++; + if (!wait) return 1; - } - logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}",(void*)handle,event); - return 0; + if (!CommandFinished(handle, OMX_CommandPortDisable, port)) + { + return 0; + } + } + return 1; } -int VideoOMX::clearEvents() +int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait) //needs to be called with locked mutex { - omx_event_mutex.lock(); - omx_events.clear(); - omx_event_mutex.unlock(); + int i = 0; + int iend = (wait / 5 + 1); + + while (i < iend) + { + omx_event_mutex.lock(); + std::list::iterator itty = omx_events.begin(); - return 1; + while (itty != omx_events.end()) + { + VPE_OMX_EVENT current = *itty; + + if (current.handle == handle) //this is ours + { + if (current.event_type == OMX_EventError) + { + omx_events.erase(itty); + omx_event_mutex.unlock(); + logger->debug(TAG, "WaitForEvent Finished on Error"); + return 0; + } + else if (current.event_type == event) + { + omx_events.erase(itty); + omx_event_mutex.unlock(); + logger->debug(TAG, "WaitForEvent Finished Completed"); + return 1; + } + } + + itty++; + } + + omx_event_mutex.unlock(); + + //logger->debug(TAG, "WaitForEvent"); + std::unique_lock ul(omx_event_ready_signal_mutex); + omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10)); + ul.unlock(); + + i++; + } + + logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}", (void*)handle, event); + return 0; } -int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle) +int VideoOMX::clearEvents() { - omx_event_mutex.lock(); - std::list::iterator itty=omx_events.begin(); - while (itty!=omx_events.end()) { - VPE_OMX_EVENT current=*itty; - if (current.handle==handle) { //this is ours - itty=omx_events.erase(itty); - continue; - } - itty++; + omx_event_mutex.lock(); + omx_events.clear(); + omx_event_mutex.unlock(); - } - omx_event_mutex.unlock(); - return 1; + return 1; } -void VideoOMX::checkForStalledBuffers() +int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle) { - //logger->debug(TAG, "Check stalled"); - clock_mutex.lock(); - omx_event_mutex.lock(); - std::list::iterator itty=omx_events.begin(); - while (itty!=omx_events.end()) { - VPE_OMX_EVENT current=*itty; - if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port - && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) { - OMX_ERRORTYPE error; - OMX_CONFIG_BUFFERSTALLTYPE stall_conf; - memset(&stall_conf,0,sizeof(stall_conf)); - stall_conf.nSize=sizeof(stall_conf); - stall_conf.nVersion.nVersion=OMX_VERSION; - stall_conf.nPortIndex=omx_codec_output_port; - stall_conf.nDelay=200000; - - error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error); - clock_mutex.unlock(); - omx_event_mutex.unlock(); - return ; - } - if (stall_conf.bStalled==OMX_TRUE) { - omx_vid_stalled=true; - logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay); - } else { - omx_vid_stalled=false; - logger->debug(TAG, "Video decoder unstalled! {}",stall_conf.nDelay); - } - omx_events.erase(itty); - break; - } - itty++; - } - omx_event_mutex.unlock(); - clock_mutex.unlock(); -} - - - - -int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex -{ - int i=0; - while (i<200/*1000*/) { - omx_event_mutex.lock(); - std::list::iterator itty=omx_events.begin(); - while (itty!=omx_events.end()) { - - VPE_OMX_EVENT current=*itty; - if (current.handle==handle) { //this is ours - if (current.event_type==OMX_EventError) { - omx_events.erase(itty); - omx_event_mutex.unlock(); - logger->debug(TAG, "Command Finished on Error {:#x}",current.data1); - return 0; - - } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) { - omx_events.erase(itty); - omx_event_mutex.unlock(); - //logger->debug(TAG, "Command Finished Completed"); - return 1; - } - } - itty++; - - } - omx_event_mutex.unlock(); - - std::unique_lock ul(omx_event_ready_signal_mutex); - omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10)); - ul.unlock(); - - i++; - - } - logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}",handle,command, data2); - return 0; + omx_event_mutex.lock(); + std::list::iterator itty = omx_events.begin(); -} + while (itty != omx_events.end()) + { + VPE_OMX_EVENT current = *itty; + if (current.handle == handle) //this is ours + { + itty = omx_events.erase(itty); + continue; + } + itty++; + } -int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex -{ - OMX_ERRORTYPE error; - OMX_PARAM_PORTDEFINITIONTYPE port_def_type; - memset(&port_def_type,0,sizeof(port_def_type)); - port_def_type.nSize=sizeof(port_def_type); - port_def_type.nVersion.nVersion=OMX_VERSION; - port_def_type.nPortIndex=omx_codec_input_port; - - error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); - - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error); - } -/* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual, - port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated, - port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/ - - port_def_type.nBufferCountActual=100; - port_def_type.nBufferSize=std::max(toi4(port_def_type.nBufferSize),150000); // for transcoder important - - error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); - - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error); - } - - - error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error); - return 0; - } - - input_bufs_omx_mutex.lock(); - for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) { - - // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize); - OMX_BUFFERHEADERTYPE *buf_head=NULL; - /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error); - input_bufs_omx_mutex.unlock(); - return 0; - }*/ - error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error); - input_bufs_omx_mutex.unlock(); - return 0; - } - input_bufs_omx_all.push_back(buf_head); - input_bufs_omx_free.push_back(buf_head); - } - omx_first_frame=true; - - firstsynched=false; - cur_input_buf_omx=NULL; - input_bufs_omx_mutex.unlock(); - - - logger->debug(TAG, "PrepareInputBufsOMX mark3"); - if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) { - return 0; - } - logger->debug(TAG, "PrepareInputBufsOMX mark4"); - - return 1; + omx_event_mutex.unlock(); + return 1; } -int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex +void VideoOMX::checkForStalledBuffers() { - OMX_ERRORTYPE error; + //logger->debug(TAG, "Check stalled"); + clock_mutex.lock(); + omx_event_mutex.lock(); + std::list::iterator itty = omx_events.begin(); + + while (itty != omx_events.end()) + { + VPE_OMX_EVENT current = *itty; - cur_input_buf_omx=NULL; - input_bufs_omx_mutex.lock(); - for (u4 i=0; i< input_bufs_omx_all.size();i++) { - // free(input_bufs_omx_all[i]->pBuffer); - // input_bufs_omx_all[i]->pBuffer=NULL; - error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error); - input_bufs_omx_mutex.unlock(); - return 0; - } + if (current.event_type == OMX_EventParamOrConfigChanged && current.data1 == omx_codec_output_port + && current.handle == omx_vid_dec && current.data2 == OMX_IndexConfigBufferStall) + { + OMX_ERRORTYPE error; + OMX_CONFIG_BUFFERSTALLTYPE stall_conf; + memset(&stall_conf, 0, sizeof(stall_conf)); + stall_conf.nSize = sizeof(stall_conf); + stall_conf.nVersion.nVersion = OMX_VERSION; + stall_conf.nPortIndex = omx_codec_output_port; + stall_conf.nDelay = 200000; + + error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error); + clock_mutex.unlock(); + omx_event_mutex.unlock(); + return ; + } - } - input_bufs_omx_all.clear(); - input_bufs_omx_free.clear(); - input_bufs_omx_mutex.unlock(); + if (stall_conf.bStalled == OMX_TRUE) + { + omx_vid_stalled = true; + logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay); + } + else + { + omx_vid_stalled = false; + logger->debug(TAG, "Video decoder unstalled! {}", stall_conf.nDelay); + } - return 1; -} + omx_events.erase(itty); + break; + } + itty++; + } + omx_event_mutex.unlock(); + clock_mutex.unlock(); +} -int VideoOMX::FlushRenderingPipe() +int VideoOMX::CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2) //needs to be called with locked mutex { - OMX_ERRORTYPE error; + int i = 0; - if (!dodeint) { + while (i < 200/*1000*/) + { + omx_event_mutex.lock(); + std::list::iterator itty = omx_events.begin(); - error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, - omx_codec_output_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush codec out 1 failed {:#x}", error); + while (itty != omx_events.end()) + { + VPE_OMX_EVENT current = *itty; + + if (current.handle == handle) //this is ours + { + if (current.event_type == OMX_EventError) + { + omx_events.erase(itty); + omx_event_mutex.unlock(); + logger->debug(TAG, "Command Finished on Error {:#x}", current.data1); + return 0; + } + else if (current.event_type == OMX_EventCmdComplete && current.data1 == command && current.data2 == data2) + { + omx_events.erase(itty); + omx_event_mutex.unlock(); + //logger->debug(TAG, "Command Finished Completed"); + return 1; + } + } - } + itty++; + } - error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, - omx_shed_input_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush shed in 2 failed {:#x}", error); + omx_event_mutex.unlock(); - } + std::unique_lock ul(omx_event_ready_signal_mutex); + omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10)); + ul.unlock(); - if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, - omx_codec_output_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd codec 3 failed"); - } + i++; + } - if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, - omx_shed_input_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd shed 4 failed"); - } - } else { - error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, - omx_codec_output_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush codec out 5 failed {:#x}", error); + logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}", handle, command, data2); + return 0; +} - } +int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex +{ + OMX_ERRORTYPE error; + OMX_PARAM_PORTDEFINITIONTYPE port_def_type; + memset(&port_def_type, 0, sizeof(port_def_type)); + port_def_type.nSize = sizeof(port_def_type); + port_def_type.nVersion.nVersion = OMX_VERSION; + port_def_type.nPortIndex = omx_codec_input_port; - error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, - omx_deint_input_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush deint in 6 failed {:#x}", error); + error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error); + } - if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, - omx_codec_output_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd codec 7 failed"); - } + /* logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual, + port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated, + port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/ - if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, - omx_deint_input_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd deint 8 failed"); - } + port_def_type.nBufferCountActual = 100; + port_def_type.nBufferSize = std::max(toi4(port_def_type.nBufferSize), 150000); // for transcoder important - //m - error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, - omx_deint_output_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush deint out 9 failed {:#x}", error); + error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error); + } - error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, - omx_shed_input_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush shed in 10 failed {:#x}", error); + error = OMX_SendCommand(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port, 0); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error); + return 0; + } - if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, - omx_deint_output_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd deint 11 failed"); - } + input_bufs_omx_mutex.lock(); - if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, - omx_shed_input_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd shed 12 failed"); - } + for (unsigned int i = 0; i < port_def_type.nBufferCountActual; i++) + { + // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize); + OMX_BUFFERHEADERTYPE* buf_head = NULL; + /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data); + if (error!=OMX_ErrorNone){ + logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error); + input_bufs_omx_mutex.unlock(); + return 0; + }*/ + error = OMX_AllocateBuffer(omx_vid_dec, &buf_head, omx_codec_input_port, NULL, port_def_type.nBufferSize); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error); + input_bufs_omx_mutex.unlock(); + return 0; + } - } + input_bufs_omx_all.push_back(buf_head); + input_bufs_omx_free.push_back(buf_head); + } + omx_first_frame = true; + firstsynched = false; + cur_input_buf_omx = NULL; + input_bufs_omx_mutex.unlock(); + logger->debug(TAG, "PrepareInputBufsOMX mark3"); - error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush, - omx_rend_input_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush rend in failed {:#x}", error); + if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port)) + { + return 0; + } + + logger->debug(TAG, "PrepareInputBufsOMX mark4"); - } + return 1; +} - error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, - omx_shed_output_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush shed out failed {:#x}", error); +int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex +{ + OMX_ERRORTYPE error; - } + cur_input_buf_omx = NULL; + input_bufs_omx_mutex.lock(); + for (u4 i = 0; i < input_bufs_omx_all.size(); i++) + { + // free(input_bufs_omx_all[i]->pBuffer); + // input_bufs_omx_all[i]->pBuffer=NULL; + error = OMX_FreeBuffer(omx_vid_dec, omx_codec_input_port, input_bufs_omx_all[i]); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error); + input_bufs_omx_mutex.unlock(); + return 0; + } - if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, - omx_rend_input_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd shed rend failed"); - } + } - if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, - omx_shed_output_port)) { - LogNT::getInstance()->debug(TAG, - "flush cmd shed rend failed"); - } + input_bufs_omx_all.clear(); + input_bufs_omx_free.clear(); + input_bufs_omx_mutex.unlock(); - return 1; + return 1; } - -int VideoOMX::DeAllocateCodecsOMX() +int VideoOMX::FlushRenderingPipe() { - OMX_ERRORTYPE error; - omx_running=false; - logger->debug(TAG, "enter deallocatecodecsomx"); + OMX_ERRORTYPE error; - if (cur_input_buf_omx) { - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS; - error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error); - } + if (!dodeint) + { + error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush codec out 1 failed {:#x}", error); + } - cur_input_buf_omx=NULL;//write out old data - } - clock_mutex.lock(); - clearEvents(); - if (omx_vid_dec) { - // first stop the omx elements - if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) { - logger->debug(TAG, "vid_dec ChangeComponentState"); + error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL); - } - clock_mutex.unlock(); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush shed in 2 failed {:#x}", error); + } - idleClock(); - clock_mutex.lock(); + if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port)) + { + logger->debug(TAG, "flush cmd codec 3 failed"); + } - if (dodeint) { - if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) { - LogNT::getInstance()->debug(TAG, - "vid_deint ChangeComponentState"); + if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port)) + { + logger->debug(TAG, "flush cmd shed 4 failed"); + } + } + else + { + error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush codec out 5 failed {:#x}", error); + } - } - } + error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port, NULL); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush deint in 6 failed {:#x}", error); + } - if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) { - logger->debug(TAG, "vid_shed ChangeComponentState"); + if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port)) + { + logger->debug(TAG, "flush cmd codec 7 failed"); + } - } + if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port)) + { + logger->debug(TAG, "flush cmd deint 8 failed"); + } - if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) { - logger->debug(TAG, "vid_rend ChangeComponentState"); + //m + error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port, NULL); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush deint out 9 failed {:#x}", error); + } + error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush shed in 10 failed {:#x}", error); + } - // TODO proper deinit sequence - // first flush all buffers - FlushRenderingPipe(); + if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port)) + { + logger->debug(TAG, "flush cmd deint 11 failed"); + } + if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port)) + { + logger->debug(TAG, "flush cmd shed 12 failed"); + } + } + error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port, NULL); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush rend in failed {:#x}", error); + } - error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error); + error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port, NULL); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush shed out failed {:#x}", error); + } - error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL); - if (error!=OMX_ErrorNone){ - logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error); + if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port)) + { + logger->debug(TAG, "flush cmd shed rend failed"); + } - } + if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port)) + { + logger->debug(TAG, "flush cmd shed rend failed"); + } - if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) || - !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) { - logger->debug(TAG, "flush cmd clock shed failed"); - } + return 1; +} +int VideoOMX::DeAllocateCodecsOMX() +{ + OMX_ERRORTYPE error; + omx_running = false; + logger->debug(TAG, "enter deallocatecodecsomx"); + if (cur_input_buf_omx) + { + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_EOS; + error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error); + } - error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, - omx_codec_input_port, NULL); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_Flush codec out failed {:#x}", error); + cur_input_buf_omx = NULL; //write out old data + } - } + clock_mutex.lock(); + clearEvents(); + if (omx_vid_dec) + { + // first stop the omx elements + if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle)) + { + logger->debug(TAG, "vid_dec ChangeComponentState"); + } + clock_mutex.unlock(); + idleClock(); + clock_mutex.lock(); - DestroyInputBufsOMX(); + if (dodeint) + { + if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) + { + logger->debug(TAG, "vid_deint ChangeComponentState"); + } + } - //todo flushing - if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 2"); - } - if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 1"); - } + if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle)) + { + logger->debug(TAG, "vid_shed ChangeComponentState"); + } + if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle)) + { + logger->debug(TAG, "vid_rend ChangeComponentState"); + } + // TODO proper deinit sequence + // first flush all buffers + FlushRenderingPipe(); + error = OMX_SendCommand(omx_clock, OMX_CommandFlush, omx_clock_output_port, NULL); - if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 6"); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error); + } + error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port, NULL); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error); + } - if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 7"); - } + if (!CommandFinished(omx_clock, OMX_CommandFlush, omx_clock_output_port) || + !CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port)) + { + logger->debug(TAG, "flush cmd clock shed failed"); + } - if (dodeint) { - if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 6a"); - } + error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, + omx_codec_input_port, NULL); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Flush codec out failed {:#x}", error); + } + DestroyInputBufsOMX(); - if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 7a"); - } - } + //todo flushing + if (!DisablePort(omx_vid_sched, omx_shed_output_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 2"); + } + if (!DisablePort(omx_vid_rend, omx_rend_input_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 1"); + } + if (!DisablePort(omx_vid_dec, omx_codec_output_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 6"); + } - if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 3"); - } + if (!DisablePort(omx_vid_dec, omx_codec_input_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 7"); + } - if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 4"); - } + if (dodeint) + { + if (!DisablePort(omx_vid_deint, omx_deint_output_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 6a"); + } - if (!DisablePort(omx_clock,omx_clock_output_port,true)) { - logger->debug(TAG, "Disable Tunnel Port failed 5"); - } + if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 7a"); + } + } + if (!DisablePort(omx_vid_sched, omx_shed_input_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 3"); + } + if (!DisablePort(omx_vid_sched, omx_shed_clock_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 4"); + } + if (!DisablePort(omx_clock, omx_clock_output_port, true)) + { + logger->debug(TAG, "Disable Tunnel Port failed 5"); + } - error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, NULL, 0); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - if (dodeint) { - error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); - } + if (dodeint) + { + error = OMX_SetupTunnel(omx_vid_deint, omx_deint_input_port, NULL, 0); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); - } - } + error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, NULL, 0); - error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } + } - } + error = OMX_SetupTunnel(omx_vid_sched, omx_shed_input_port, NULL, 0); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, NULL, 0); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + error = OMX_SetupTunnel(omx_vid_rend, omx_rend_input_port, NULL, 0); - } + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } + error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, NULL, 0); - error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - } + error = OMX_SetupTunnel(omx_vid_sched, omx_shed_clock_port, NULL, 0); - error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - } + error = OMX_FreeHandle(omx_vid_dec); + error = OMX_FreeHandle(omx_vid_sched); + error = OMX_FreeHandle(omx_vid_rend); + if (dodeint) error = OMX_FreeHandle(omx_vid_deint); + omx_vid_dec = NULL; + omx_vid_stalled = false; + clock_mutex.unlock(); + destroyClock(); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "FreeHandle failed {}", error); + } + } + else + clock_mutex.unlock(); - error=OMX_FreeHandle(omx_vid_dec); - error=OMX_FreeHandle(omx_vid_sched); - error=OMX_FreeHandle(omx_vid_rend); - if (dodeint) error=OMX_FreeHandle(omx_vid_deint); - omx_vid_dec=NULL; - omx_vid_stalled = false; - clock_mutex.unlock(); - destroyClock(); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "FreeHandle failed {}", error); - } - } else clock_mutex.unlock(); - logger->debug(TAG, "leave deallocate codecs OMX"); + logger->debug(TAG, "leave deallocate codecs OMX"); - return 1; + return 1; } - void VideoOMX::destroyClock() { - clock_mutex.lock(); - if (clock_references>0) { - clock_references--; - if (clock_references==0) { - OMX_ERRORTYPE error; - logger->debug(TAG, "destroy omx clock"); - error=OMX_FreeHandle(omx_clock); - if (error!=OMX_ErrorNone) { - logger->debug(TAG, "FreeHandle failed {}", error); - } + clock_mutex.lock(); + + if (clock_references > 0) + { + clock_references--; - } - } - clock_mutex.unlock(); + if (clock_references == 0) + { + OMX_ERRORTYPE error; + logger->debug(TAG, "destroy omx clock"); + error = OMX_FreeHandle(omx_clock); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "FreeHandle failed {}", error); + } + } + } + clock_mutex.unlock(); } int VideoOMX::stop() { if (!initted) return 0; - iframemode=false; + + iframemode = false; //Check if libav mode DeAllocateCodecsOMX(); - - - -// if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0; return 1; } @@ -2440,17 +2612,18 @@ int VideoOMX::reset() { if (!initted) return 0; - iframemode=false; + iframemode = false; DeAllocateCodecsOMX(); -// if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; return 1; } int VideoOMX::pause() { if (!initted) return 0; + logger->debug(TAG, "enter pause"); - // clockPause(); + // clockPause(); // ignore it audio handles this return 1; } @@ -2458,6 +2631,7 @@ int VideoOMX::pause() int VideoOMX::unPause() // FIXME get rid - same as play!! Not here! { if (!initted) return 0; + logger->debug(TAG, "enter unpause"); //clockUnpause(); @@ -2470,7 +2644,7 @@ int VideoOMX::fastForward() { if (!initted) return 0; -// if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0; return 1; } @@ -2478,9 +2652,9 @@ int VideoOMX::unFastForward() { if (!initted) return 0; -// if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this. + // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this. - //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0; + //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0; return 1; } @@ -2488,70 +2662,83 @@ int VideoOMX::attachFrameBuffer() { if (!initted) return 0; -// if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0; return 1; } int VideoOMX::blank(void) { -// if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0; -// if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0; + // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0; return 1; } -u8 VideoOMX::getCurrentTimestamp() { - if (iframemode) - return 0; - long long ncur_clock_time = cur_clock_time; - if (omx_running) { - int oldcancelstate; - int oldcanceltype; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - clock_mutex.lock(); - OMX_ERRORTYPE error; - OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; - memset(&clock_conf, 0, sizeof(clock_conf)); - clock_conf.nSize = sizeof(clock_conf); - clock_conf.nVersion.nVersion = OMX_VERSION; - error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, - &clock_conf); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG,"getCurrentTimestamp IndexConfigTimeClockState failed {:#x}",error); - } - - if (clock_conf.eState == OMX_TIME_ClockStateRunning) { - - OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp; - memset(&cur_time_stamp, 0, sizeof(cur_time_stamp)); - cur_time_stamp.nSize = sizeof(cur_time_stamp); - cur_time_stamp.nVersion.nVersion = OMX_VERSION; - cur_time_stamp.nPortIndex = omx_clock_output_port; - error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, - &cur_time_stamp); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}",error); - } else { - long long temp = cur_time_stamp.nTimestamp.nLowPart - | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32); - ncur_clock_time = cur_clock_time = temp * 10LL; - } - } - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - } - - //ncur_clock_time -= startoffset; - ncur_clock_time -= lastreftimeOMX; - long long result = lastreftimePTS; - if (lastreftimePTS==0) return 0; // invalid time - result += (long long) (ncur_clock_time / 10000LL * 90LL); - if (result < 0) - result = (1LL << 33) - result; - //LogNT::getInstance()->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset); - - return result; +u8 VideoOMX::getCurrentTimestamp() +{ + if (iframemode) + return 0; + + long long ncur_clock_time = cur_clock_time; + + if (omx_running) + { + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + clock_mutex.lock(); + OMX_ERRORTYPE error; + OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; + memset(&clock_conf, 0, sizeof(clock_conf)); + clock_conf.nSize = sizeof(clock_conf); + clock_conf.nVersion.nVersion = OMX_VERSION; + error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "getCurrentTimestamp IndexConfigTimeClockState failed {:#x}", error); + } + + if (clock_conf.eState == OMX_TIME_ClockStateRunning) + { + OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp; + memset(&cur_time_stamp, 0, sizeof(cur_time_stamp)); + cur_time_stamp.nSize = sizeof(cur_time_stamp); + cur_time_stamp.nVersion.nVersion = OMX_VERSION; + cur_time_stamp.nPortIndex = omx_clock_output_port; + error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, &cur_time_stamp); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}", error); + } + else + { + long long temp = cur_time_stamp.nTimestamp.nLowPart + | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32); + ncur_clock_time = cur_clock_time = temp * 10LL; + } + } + + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + } + + //ncur_clock_time -= startoffset; + ncur_clock_time -= lastreftimeOMX; + long long result = lastreftimePTS; + + if (lastreftimePTS == 0) return 0; // invalid time + + result += (long long) (ncur_clock_time / 10000LL * 90LL); + + if (result < 0) + result = (1LL << 33) - result; + + //logger->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset); + + return result; } @@ -2569,12 +2756,12 @@ int VideoOMX::test() { return 0; -// u8 stc = 0; -// return ioctl(fdVideo, AV_SET_VID_STC, &stc); -/* - // reset(); - return 1; -*/ + // u8 stc = 0; + // return ioctl(fdVideo, AV_SET_VID_STC, &stc); + /* + // reset(); + return 1; + */ } int VideoOMX::test2() @@ -2583,691 +2770,766 @@ int VideoOMX::test2() } #endif - - -long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync) +long long VideoOMX::SetStartOffset(long long curreftime, bool* rsync) { - *rsync=false; - if (offsetnotset) { - startoffset=curreftime;//offset is set for audio - offsetnotset=false; - offsetvideonotset=false; - } else { - if (offsetvideonotset) { - offsetvideonotset=false; - *rsync=true; - } else { - if ( (curreftime-lastrefvideotime)>10000000LL - || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync - startoffset+=curreftime-lastrefvideotime; - lastrefaudiotime+=curreftime-lastrefvideotime; - //*rsync=true; - offsetaudionotset=true; + *rsync = false; + if (offsetnotset) + { + startoffset = curreftime; //offset is set for audio + offsetnotset = false; + offsetvideonotset = false; + } + else + { + if (offsetvideonotset) + { + offsetvideonotset = false; + *rsync = true; + } + else + { + if ( (curreftime - lastrefvideotime) > 10000000LL + || (curreftime - lastrefvideotime) < -10000000LL) //if pts jumps to big resync + { + startoffset += curreftime - lastrefvideotime; + lastrefaudiotime += curreftime - lastrefvideotime; + //*rsync=true; + offsetaudionotset = true; } } - } - lastrefvideotime=curreftime; + lastrefvideotime = curreftime; return startoffset; - } -long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync) +long long VideoOMX::SetStartAudioOffset(long long curreftime, bool* rsync) { - *rsync=false; - if (offsetnotset) { - startoffset=curreftime; - offsetnotset=false; - offsetaudionotset=false; - }else { - if (offsetaudionotset) { - offsetaudionotset=false; - *rsync=true; - } else { - if ( (curreftime-lastrefaudiotime)>10000000LL - || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync - startoffset+=curreftime-lastrefaudiotime; - lastrefvideotime+=curreftime-lastrefaudiotime; - //*rsync=true; - offsetvideonotset=true; + *rsync = false; + if (offsetnotset) + { + startoffset = curreftime; + offsetnotset = false; + offsetaudionotset = false; + } + else + { + if (offsetaudionotset) + { + offsetaudionotset = false; + *rsync = true; + } + else + { + if ( (curreftime - lastrefaudiotime) > 10000000LL + || (curreftime - lastrefaudiotime) < -10000000LL) //if pts jumps to big resync + { + startoffset += curreftime - lastrefaudiotime; + lastrefvideotime += curreftime - lastrefaudiotime; + //*rsync=true; + offsetvideonotset = true; } } - } - lastrefaudiotime=curreftime; - return startoffset; + lastrefaudiotime = curreftime; + return startoffset; } -void VideoOMX::ResetTimeOffsets() { - offsetnotset=true; //called from demuxer - offsetvideonotset=true; - offsetaudionotset=true; - startoffset=0; - lastrefaudiotime=0; - lastrefvideotime=0; - lastreftimeOMX=0; - lastreftimePTS=0; +void VideoOMX::ResetTimeOffsets() +{ + offsetnotset = true; //called from demuxer + offsetvideonotset = true; + offsetaudionotset = true; + startoffset = 0; + lastrefaudiotime = 0; + lastrefvideotime = 0; + lastreftimeOMX = 0; + lastreftimePTS = 0; } - void VideoOMX::FirstFrameFix() { - int oldcancelstate; - int oldcanceltype; - Demuxer* demux=Demuxer::getInstance(); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - clock_mutex.lock(); - if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){ - WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages - OMX_ERRORTYPE error; - OMX_PARAM_PORTDEFINITIONTYPE port_def_type; - memset(&port_def_type,0,sizeof(port_def_type)); - port_def_type.nSize=sizeof(port_def_type); - port_def_type.nVersion.nVersion=OMX_VERSION; - port_def_type.nPortIndex=omx_codec_output_port; - - error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_IndexParamPortDefinition fix failed {:#x}", error); - clock_mutex.unlock(); - return; - } - - - LogNT::getInstance()->debug(TAG, - "Deinit first frame fix {} {} {} {} {} {} {} {}",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(), - port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride, - port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate, - port_def_type.format.video.bFlagErrorConcealment ); - LogNT::getInstance()->debug(TAG, - "Deinit first frame fix2 {} {}", - port_def_type.format.video.eCompressionFormat , - port_def_type.format.video.eColorFormat ); - first_frame=false; - - // we cause the video_decode to determine the interlacing properties - OMX_CONFIG_INTERLACETYPE il; - memset(&il,0,sizeof(il)); - il.nSize=sizeof(il); - il.nVersion.nVersion=OMX_VERSION; - il.nPortIndex=omx_codec_output_port; - error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_IndexConfigCommonInterlace fix failed {:#x}", error); - } - - - DisablePort(omx_vid_dec,omx_codec_output_port,true); - DisablePort(omx_vid_sched,omx_shed_input_port,true); - if (dodeint) { - - DisablePort(omx_vid_deint,omx_deint_input_port,true); - // This is a dirty hack - DisablePort(omx_vid_deint,omx_deint_output_port,true); - - - port_def_type.nPortIndex=omx_deint_output_port; - error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, - &port_def_type); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexParamPortDefinition1 failed {:#x}", error); - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - return; - } - // dirty hack end - - - port_def_type.nPortIndex=omx_deint_input_port; - error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, - &port_def_type); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexParamPortDefinition1 failed {:#x}", error); - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - return; - } - // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged); - - LogNT::getInstance()->debug(TAG, - "Marker"); - EnablePort(omx_vid_deint,omx_deint_input_port,true); - WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged); - port_def_type.nPortIndex=omx_deint_output_port; - error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, - &port_def_type); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Get OMX_IndexParamPortDefinition2 failed {:#x}", error); - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - return; - } - LogNT::getInstance()->debug(TAG, - "Deinit first frame fix3 {} {} {} {} {} {} {} ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(), - port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride, - port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/ - port_def_type.format.image.bFlagErrorConcealment ); - LogNT::getInstance()->debug(TAG, - "Deinit first frame fix4 {} {}", - port_def_type.format.image.eCompressionFormat , - port_def_type.format.image.eColorFormat ); - DisablePort(omx_vid_deint,omx_deint_output_port,true); - - } - port_def_type.nPortIndex=omx_shed_input_port; - error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, - &port_def_type); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexParamPortDefinition3 failed {:#x}", error); - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - return; - } - WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged); - - - if (dodeint) { - EnablePort(omx_vid_deint,omx_deint_output_port,true); - } - EnablePort(omx_vid_dec,omx_codec_output_port,true); - EnablePort(omx_vid_sched,omx_shed_input_port,true); - } - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); + int oldcancelstate; + int oldcanceltype; + Demuxer* demux = Demuxer::getInstance(); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + clock_mutex.lock(); + if (WaitForEvent(omx_vid_dec, OMX_EventPortSettingsChanged, 0)) + { + WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged, 0); //clear old messages + OMX_ERRORTYPE error; + OMX_PARAM_PORTDEFINITIONTYPE port_def_type; + memset(&port_def_type, 0, sizeof(port_def_type)); + port_def_type.nSize = sizeof(port_def_type); + port_def_type.nVersion.nVersion = OMX_VERSION; + port_def_type.nPortIndex = omx_codec_output_port; + error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type); -} + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_IndexParamPortDefinition fix failed {:#x}", error); + clock_mutex.unlock(); + return; + } + + logger->debug(TAG, + "Deinit first frame fix {} {} {} {} {} {} {} {}", port_def_type.format.video.nFrameWidth, demux->getHorizontalSize(), + port_def_type.format.video.nFrameHeight, demux->getVerticalSize(), port_def_type.format.video.nStride, + port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate, + port_def_type.format.video.bFlagErrorConcealment ); + logger->debug(TAG, + "Deinit first frame fix2 {} {}", + port_def_type.format.video.eCompressionFormat, + port_def_type.format.video.eColorFormat ); + first_frame = false; + + // we cause the video_decode to determine the interlacing properties + OMX_CONFIG_INTERLACETYPE il; + memset(&il, 0, sizeof(il)); + il.nSize = sizeof(il); + il.nVersion.nVersion = OMX_VERSION; + il.nPortIndex = omx_codec_output_port; + error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigCommonInterlace, &il); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_IndexConfigCommonInterlace fix failed {:#x}", error); + } + + DisablePort(omx_vid_dec, omx_codec_output_port, true); + DisablePort(omx_vid_sched, omx_shed_input_port, true); + if (dodeint) + { + DisablePort(omx_vid_deint, omx_deint_input_port, true); + // This is a dirty hack + DisablePort(omx_vid_deint, omx_deint_output_port, true); + + port_def_type.nPortIndex = omx_deint_output_port; + error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error); + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; + } + + // dirty hack end + + port_def_type.nPortIndex = omx_deint_input_port; + error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error); + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; + } + + // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged); + + logger->debug(TAG, "Marker"); + EnablePort(omx_vid_deint, omx_deint_input_port, true); + WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged); + port_def_type.nPortIndex = omx_deint_output_port; + error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Get OMX_IndexParamPortDefinition2 failed {:#x}", error); + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; + } + + logger->debug(TAG, + "Deinit first frame fix3 {} {} {} {} {} {} {} ", port_def_type.format.image.nFrameWidth, demux->getHorizontalSize(), + port_def_type.format.image.nFrameHeight, demux->getVerticalSize(), port_def_type.format.image.nStride, + port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/ + port_def_type.format.image.bFlagErrorConcealment ); + logger->debug(TAG, + "Deinit first frame fix4 {} {}", + port_def_type.format.image.eCompressionFormat, + port_def_type.format.image.eColorFormat ); + + DisablePort(omx_vid_deint, omx_deint_output_port, true); + } + + port_def_type.nPortIndex = omx_shed_input_port; + error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, &port_def_type); + + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "Set OMX_IndexParamPortDefinition3 failed {:#x}", error); + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; + } + + WaitForEvent(omx_vid_sched, OMX_EventPortSettingsChanged); + + if (dodeint) + EnablePort(omx_vid_deint, omx_deint_output_port, true); + + EnablePort(omx_vid_dec, omx_codec_output_port, true); + EnablePort(omx_vid_sched, omx_shed_input_port, true); + } + + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); +} void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer) { + OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer); - OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer failed {:#x}", error); - } - if (first_frame) FirstFrameFix(); + if (error != OMX_ErrorNone) + { + logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error); + } + if (first_frame) FirstFrameFix(); } OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer) { - // protect the call to empty this buffer - int oldcancelstate; - int oldcanceltype; -/* long long temp =buffer->nTimeStamp.nLowPart - | ((long long) buffer->nTimeStamp.nHighPart << 32);*/ - - //pthread_testcancel(); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - clock_mutex.lock(); -// Diagnosis code -/* OMX_ERRORTYPE error; - OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; - memset(×tamp, 0, sizeof(timestamp)); - timestamp.nSize = sizeof(timestamp); - timestamp.nVersion.nVersion = OMX_VERSION; - timestamp.nPortIndex =omx_clock_output_port; - - error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, - ×tamp); - - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error, - omx_rend_input_port); - } - long long temp2 =timestamp.nTimestamp.nLowPart - | ((long long) timestamp.nTimestamp.nHighPart << 32); - - - LogNT::getInstance()->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/ - OMX_ERRORTYPE ret_val; - ret_val=OMX_EmptyThisBuffer(handle,buffer); - clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - //pthread_testcancel(); - return ret_val; -} - -bool VideoOMX::detectIFrame(const u1 *buffer,unsigned int length) -{ - const u1* curbuf=buffer; - const u1* curbufend=buffer+length; - unsigned int detector=0xFFFFFFFF; - bool gotaud=false; // have seen access unit delimiter - - while (curbuf!=curbufend) { - detector<<=8; - detector|=*curbuf; - if (h264) { - if (detector==0x00000109) { - gotaud=true; - detector=0xFFFFFFFF; - } else if (gotaud &&detector==0x00000001) { - curbuf++; - if (curbuf!=curbufend) { - unsigned char picttype=(*curbuf)& 0x1F; - return picttype==0x07; - } - } - } else { - if (detector==0x00000100) { - curbuf++; - if (curbuf==curbufend) return false; - curbuf++; - if (curbuf==curbufend) return false; - unsigned char picttype=((*curbuf) >> 3) & 0x07; - return picttype==1; - } - } - curbuf++; - } - - return false; // no frame found -} + // protect the call to empty this buffer + int oldcancelstate; + int oldcanceltype; + /* long long temp =buffer->nTimeStamp.nLowPart + | ((long long) buffer->nTimeStamp.nHighPart << 32);*/ + + //pthread_testcancel(); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + clock_mutex.lock(); + // Diagnosis code + /* OMX_ERRORTYPE error; + OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; + memset(×tamp, 0, sizeof(timestamp)); + timestamp.nSize = sizeof(timestamp); + timestamp.nVersion.nVersion = OMX_VERSION; + timestamp.nPortIndex =omx_clock_output_port; + + error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, + ×tamp); + + if (error != OMX_ErrorNone) { + logger->debug(TAG, + "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error, + omx_rend_input_port); + } + long long temp2 =timestamp.nTimestamp.nLowPart + | ((long long) timestamp.nTimestamp.nHighPart << 32); + + logger->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/ + OMX_ERRORTYPE ret_val; + ret_val = OMX_EmptyThisBuffer(handle, buffer); + clock_mutex.unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + //pthread_testcancel(); + return ret_val; +} + +bool VideoOMX::detectIFrame(const u1* buffer, unsigned int length) +{ + const u1* curbuf = buffer; + const u1* curbufend = buffer + length; + unsigned int detector = 0xFFFFFFFF; + bool gotaud = false; // have seen access unit delimiter + + while (curbuf != curbufend) + { + detector <<= 8; + detector |= *curbuf; + + if (h264) + { + if (detector == 0x00000109) + { + gotaud = true; + detector = 0xFFFFFFFF; + } + else if (gotaud && detector == 0x00000001) + { + curbuf++; + + if (curbuf != curbufend) + { + unsigned char picttype = (*curbuf) & 0x1F; + return picttype == 0x07; + } + } + } + else + { + if (detector == 0x00000100) + { + curbuf++; + + if (curbuf == curbufend) return false; + + curbuf++; + if (curbuf == curbufend) return false; + unsigned char picttype = ((*curbuf) >> 3) & 0x07; + return picttype == 1; + } + } + + curbuf++; + } + + return false; // no frame found +} bool VideoOMX::DrainTargetBufferFull() { - //Check, if we have OMX output buffers - bool full; - input_bufs_omx_mutex.lock(); - full=(input_bufs_omx_free.size()==0); - input_bufs_omx_mutex.unlock(); - checkForStalledBuffers(); // check if the decoder has a problem - if (full && omx_vid_stalled && !omx_first_frame) { - omx_vid_stalled=false; - logger->debug(TAG, "Decoder is stalled, do a reset!"); + //Check, if we have OMX output buffers + bool full; + input_bufs_omx_mutex.lock(); + full = (input_bufs_omx_free.size() == 0); + input_bufs_omx_mutex.unlock(); + checkForStalledBuffers(); // check if the decoder has a problem + + if (full && omx_vid_stalled && !omx_first_frame) + { + omx_vid_stalled = false; + logger->debug(TAG, "Decoder is stalled, do a reset!"); - int oldcancelstate; - int oldcanceltype; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - clock_mutex.lock(); - FlushRenderingPipe(); - omx_first_frame=true; - clock_mutex.unlock(); + clock_mutex.lock(); + FlushRenderingPipe(); + omx_first_frame = true; + clock_mutex.unlock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - } - return full; + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + } + return full; } void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */) { + mediapackets.clear(); + std::list::const_iterator begin = mplist.begin(); + std::list::const_iterator itty = mplist.begin(); + advance(itty, std::min(mplist.size(), 10U)); + mediapackets.insert(mediapackets.begin(), begin, itty); //front +} + +u4 VideoOMX::DeliverMediaSample(u1* buffer, u4* samplepos) +{ + u4 consumed = 0; + + while (consumed < mediapackets.size()) + { + DeliverMediaPacket(mediapackets[consumed], buffer, samplepos); + + if (*samplepos == mediapackets[consumed].length) + { + *samplepos = 0; + consumed++; + //return 1; + } + else return consumed; + } - mediapackets.clear(); - std::list::const_iterator begin=mplist.begin(); - std::list::const_iterator itty=mplist.begin(); - advance(itty,std::min(mplist.size(),10U)); - mediapackets.insert(mediapackets.begin(),begin,itty);//front - -} - -u4 VideoOMX::DeliverMediaSample(u1* buffer, u4 *samplepos) -{ - u4 consumed=0; - while (consumed < mediapackets.size()) { - DeliverMediaPacket(mediapackets[consumed], buffer, samplepos); - if (*samplepos == mediapackets[consumed].length) { - *samplepos = 0; - consumed++; - //return 1; - } else return consumed; - } - return consumed; -} - -u4 VideoOMX::DeliverMediaPacket(MediaPacket packet, - const u1* buffer, - u4 *samplepos) -{ - if (packet.type == MPTYPE_VIDEO_H264) - { - h264=true; - } - else - { - h264=false; - } - - - //Later add fail back code for libav -/* if (!videoon) { - *samplepos+=packet.length; - return packet.length; - }*/ - - - if (!omx_running) return 0; // if we are not runnig do not do this - - if (isClockPaused()) return 0; //Block if we pause - -// logger->debug(TAG, "DMP mark 1"); - //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time); - - - /*First Check, if we have an video sample*/ - if (iframemode) { - //samplepos=0; - MILLISLEEP(10); - return 0; //Not in iframe mode! - } - - u4 headerstrip=0; - if (packet.disconti) { - firstsynched=false; - if (cur_input_buf_omx) { - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx=NULL; - } - } - //logger->debug(TAG, "DMP mark 2"); - /*Inspect PES-Header */ - -// OMX_STATETYPE temp_state; -// OMX_GetState(omx_vid_dec,&temp_state); - - if (*samplepos==0) {//stripheader - headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/; - // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}", - // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]); - *samplepos+=headerstrip; - if (headerstrip>=packet.length) { - *samplepos=packet.length;// Packet is obviously damaged - return packet.length;//skip it! - } - if ( packet.synched ) { - if (!firstsynched) { - //logger->debug(TAG, "DMP mark 2a"); - // check if this is an I frame, the decoder does not like non I frames at startup! - if (!detectIFrame(buffer,packet.length)) { - *samplepos=packet.length;//if we have not processed at least one - //logger->debug(TAG, "DMP mark 3"); - return packet.length;//synched packet ignore it! - } - } - if (cur_input_buf_omx) { - //logger->debug(TAG, "DMP mark 4a"); - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME; - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx=NULL;//write out old data - - //logger->debug(TAG, "DMP mark 4b"); - - } - firstsynched=true; - } else { - if (!firstsynched) {// - *samplepos=packet.length;//if we have not processed at least one - //logger->debug(TAG, "DMP mark 5"); - return packet.length;//synched packet ignore it! - } - } - } - //logger->debug(TAG, "DMP mark 6"); - if (!cur_input_buf_omx) { - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size()==0) { - input_bufs_omx_mutex.unlock(); - //logger->debug(TAG, "Deliver MediaPacket no free sample"); - //logger->debug(TAG, "DMP mark 7"); - return 0; // we do not have a free media sample - - } - cur_input_buf_omx=input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen=0; - cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - } - - - - - if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet - if (packet.synched) { - // logger->debug(TAG, "packet synched marker"); - - //lastreftimePTS=packet.pts; - if (omx_first_frame) { // TODO time - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME; - logger->debug(TAG, "Starttime"); - omx_first_frame=false; - } else { - cur_input_buf_omx->nFlags=0; - //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; - } - lastreftimeOMX=packet.presentation_time; - // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts); - lastreftimePTS=packet.pts; - cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty; - } - else - { - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); - //logger->debug(TAG, "packet unsynched marker"); - } - if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY; - - - - } - unsigned int haveToCopy=packet.length-*samplepos; - //logger->debug(TAG, "DMP mark 8"); - - while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) { - //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen); - unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen; - memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy); - haveToCopy-=cancopy; - cur_input_buf_omx->nFilledLen+=cancopy; - *samplepos+=cancopy; - // push old buffer out - //logger->debug(TAG, "DMP mark 9"); - - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx=NULL; - // get5 new buffer - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size()==0) { - input_bufs_omx_mutex.unlock(); - // logger->debug(TAG, "Deliver MediaPacket no free sample2"); - return *samplepos; // we do not have a free media sample - } - cur_input_buf_omx=input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen=0; - cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - //logger->debug(TAG, "DMP mark 10"); - - } - memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen, - buffer+packet.pos_buffer+*samplepos,haveToCopy); - cur_input_buf_omx->nFilledLen+=haveToCopy; - -// logger->debug(TAG, "DMP mark 11"); - - *samplepos+=haveToCopy; - - return *samplepos; - -} - - - - -bool VideoOMX::displayIFrame(const u1* buffer, u4 length) { - if (!omx_running) return false; - if (!iframemode) - EnterIframePlayback(); - - //int haveToCopy = length; - - if (!cur_input_buf_omx) { - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size() == 0) { - input_bufs_omx_mutex.unlock(); - // LogNT::getInstance()->debug(TAG, - // "Deliver MediaPacket no free sample"); - return false; // we do not have a free media sample - - } - cur_input_buf_omx = input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen = 0; - cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - } - - u4 read_pos = 0; - unsigned int pattern, packet_length; - unsigned int headerstrip = 0; - bool first = true; - if (length < 4){ - return false; - } - //Now we strip the pes header - pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]); - while ((read_pos + 7) <= length) { - pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3]; - if (pattern < 0x000001E0 || pattern > 0x000001EF) { - read_pos++; - continue; - } else { - headerstrip = buffer[read_pos + 8] + 9/*is this right*/; - packet_length = ((buffer[read_pos + 4] << 8) - | (buffer[read_pos + 5])) + 6; - if (read_pos + packet_length > length) - read_pos = length; - else { - if ((headerstrip < packet_length) - && (cur_input_buf_omx->nFilledLen + packet_length - - headerstrip) > cur_input_buf_omx->nAllocLen) { - if (first) { - cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; - - } else { - cur_input_buf_omx->nFlags - |= OMX_BUFFERFLAG_TIME_UNKNOWN; - - } - cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx = NULL; - - if (!cur_input_buf_omx) { - int count = 0; - while (count < 100 && omx_running && iframemode) { - count++; - - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size() == 0) { - input_bufs_omx_mutex.unlock(); - // LogNT::getInstance()->debug(TAG, - // "Ifrane no free sample"); - MILLISLEEP(5); - if (!omx_running) return false; - continue; - } - cur_input_buf_omx = input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen = 0; - cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN; - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - break; - } - if (!cur_input_buf_omx) - return false; - } - - } - if (packet_length > headerstrip) { - memcpy( - cur_input_buf_omx->pBuffer - + cur_input_buf_omx->nFilledLen, - buffer + read_pos + headerstrip, - packet_length - headerstrip); - cur_input_buf_omx->nFilledLen += packet_length - - headerstrip; - } - read_pos += packet_length; - - pattern = (buffer[read_pos] << 16) - | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]); - } - } - } - - if (first) { - cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; - - } else { - cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; - - } - cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx = NULL; - - - MILLISLEEP(40); //Block a bit - return true; + return consumed; } -int VideoOMX::EnterIframePlayback() +u4 VideoOMX::DeliverMediaPacket(MediaPacket packet, const u1* buffer, u4* samplepos) +{ + if (packet.type == MPTYPE_VIDEO_H264) + { + h264 = true; + } + else + { + h264 = false; + } + + //Later add fail back code for libav + /* if (!videoon) { + *samplepos+=packet.length; + return packet.length; + }*/ + + if (!omx_running) return 0; // if we are not runnig do not do this + + if (isClockPaused()) return 0; //Block if we pause + + // logger->debug(TAG, "DMP mark 1"); + //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time); + + /*First Check, if we have an video sample*/ + if (iframemode) + { + //samplepos=0; + MILLISLEEP(10); + return 0; //Not in iframe mode! + } + + u4 headerstrip = 0; + + if (packet.disconti) + { + firstsynched = false; + + if (cur_input_buf_omx) + { + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; + } + } + + //logger->debug(TAG, "DMP mark 2"); + /*Inspect PES-Header */ + + // OMX_STATETYPE temp_state; + // OMX_GetState(omx_vid_dec,&temp_state); + + if (*samplepos == 0) //stripheader + { + headerstrip = buffer[packet.pos_buffer + 8] + 9/*is this right*/; + // if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}", + // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]); + *samplepos += headerstrip; + + if (headerstrip >= packet.length) + { + *samplepos = packet.length; // Packet is obviously damaged + return packet.length;//skip it! + } + + if (packet.synched) + { + if (!firstsynched) + { + //logger->debug(TAG, "DMP mark 2a"); + // check if this is an I frame, the decoder does not like non I frames at startup! + if (!detectIFrame(buffer, packet.length)) + { + *samplepos = packet.length; //if we have not processed at least one + //logger->debug(TAG, "DMP mark 3"); + return packet.length;//synched packet ignore it! + } + } + + if (cur_input_buf_omx) + { + //logger->debug(TAG, "DMP mark 4a"); + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; //write out old data + + //logger->debug(TAG, "DMP mark 4b"); + } + + firstsynched = true; + } + else + { + if (!firstsynched) // + { + *samplepos = packet.length; //if we have not processed at least one + //logger->debug(TAG, "DMP mark 5"); + return packet.length;//synched packet ignore it! + } + } + } + + //logger->debug(TAG, "DMP mark 6"); + if (!cur_input_buf_omx) + { + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + //logger->debug(TAG, "Deliver MediaPacket no free sample"); + //logger->debug(TAG, "DMP mark 7"); + return 0; // we do not have a free media sample + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + } + + if (cur_input_buf_omx->nFilledLen == 0) //will only be changed on first packet + { + if (packet.synched) + { + // logger->debug(TAG, "packet synched marker"); + + //lastreftimePTS=packet.pts; + if (omx_first_frame) // TODO time + { + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; + logger->debug(TAG, "Starttime"); + omx_first_frame = false; + } + else + { + cur_input_buf_omx->nFlags = 0; + //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; + } + + lastreftimeOMX = packet.presentation_time; + // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts); + lastreftimePTS = packet.pts; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(lastreftimeOMX / 10LL); // the clock component is faulty; + } + else + { + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + //logger->debug(TAG, "packet unsynched marker"); + } + + if (packet.disconti) cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY; + } + + unsigned int haveToCopy = packet.length - *samplepos; + //logger->debug(TAG, "DMP mark 8"); + + while (haveToCopy > (cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen)) + { + //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen); + unsigned int cancopy = cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen; + memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + packet.pos_buffer + *samplepos, cancopy); + haveToCopy -= cancopy; + cur_input_buf_omx->nFilledLen += cancopy; + *samplepos += cancopy; + // push old buffer out + //logger->debug(TAG, "DMP mark 9"); + + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; + // get5 new buffer + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + // logger->debug(TAG, "Deliver MediaPacket no free sample2"); + return *samplepos; // we do not have a free media sample + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + //logger->debug(TAG, "DMP mark 10"); + } + + memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, + buffer + packet.pos_buffer + *samplepos, haveToCopy); + cur_input_buf_omx->nFilledLen += haveToCopy; + + // logger->debug(TAG, "DMP mark 11"); + + *samplepos += haveToCopy; + + return *samplepos; +} + +bool VideoOMX::displayIFrame(const u1* buffer, u4 length) { - LogNT::getInstance()->debug(TAG, - "EnterIframePlayback"); - if (cur_input_buf_omx) { - PutBufferToPres(cur_input_buf_omx); - cur_input_buf_omx = NULL; - } - LogNT::getInstance()->debug(TAG, - "EnterIframePlayback 2"); - dynamic_cast(Audio::getInstance())->DeAllocateCodecsOMX(); - DeAllocateCodecsOMX(); - AllocateCodecsOMX(); - LogNT::getInstance()->debug(TAG, - "leave IframePlayback"); + if (!omx_running) return false; + + if (!iframemode) + EnterIframePlayback(); + + //int haveToCopy = length; + + if (!cur_input_buf_omx) + { + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + // logger->debug(TAG, + // "Deliver MediaPacket no free sample"); + return false; // we do not have a free media sample + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + } + + u4 read_pos = 0; + unsigned int pattern, packet_length; + unsigned int headerstrip = 0; + bool first = true; + + if (length < 4) + { + return false; + } + + //Now we strip the pes header + pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]); + + while ((read_pos + 7) <= length) + { + pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3]; + + if (pattern < 0x000001E0 || pattern > 0x000001EF) + { + read_pos++; + continue; + } + else + { + headerstrip = buffer[read_pos + 8] + 9/*is this right*/; + packet_length = ((buffer[read_pos + 4] << 8) + | (buffer[read_pos + 5])) + 6; + + if (read_pos + packet_length > length) + read_pos = length; + else + { + if ((headerstrip < packet_length) + && (cur_input_buf_omx->nFilledLen + packet_length + - headerstrip) > cur_input_buf_omx->nAllocLen) + { + if (first) + { + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; + } + else + { + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; + } + + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; + + if (!cur_input_buf_omx) + { + int count = 0; + + while (count < 100 && omx_running && iframemode) + { + count++; + + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + // logger->debug(TAG, + // "Ifrane no free sample"); + MILLISLEEP(5); + + if (!omx_running) return false; + + continue; + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + break; + } + + if (!cur_input_buf_omx) return false; + } + } + + if (packet_length > headerstrip) + { + memcpy( + cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, + buffer + read_pos + headerstrip, + packet_length - headerstrip); + + cur_input_buf_omx->nFilledLen += packet_length - headerstrip; + } + + read_pos += packet_length; + + pattern = (buffer[read_pos] << 16) + | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]); + } + } + } + + if (first) + { + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; + } + else + { + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; + } - iframemode=true; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - return 1; + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; + + MILLISLEEP(40); //Block a bit + return true; } +int VideoOMX::EnterIframePlayback() +{ + logger->debug(TAG, "EnterIframePlayback"); + + if (cur_input_buf_omx) + { + PutBufferToPres(cur_input_buf_omx); + cur_input_buf_omx = NULL; + } + + logger->debug(TAG, "EnterIframePlayback 2"); + dynamic_cast(Audio::getInstance())->DeAllocateCodecsOMX(); + DeAllocateCodecsOMX(); + AllocateCodecsOMX(); + logger->debug(TAG, "leave IframePlayback"); + + iframemode = true; + + return 1; +} diff --git a/src/videoomx.h b/src/videoomx.h index 31f24fd..27ce998 100644 --- a/src/videoomx.h +++ b/src/videoomx.h @@ -17,7 +17,6 @@ along with VOMP. If not, see . */ - #ifndef VIDEOOMX_H #define VIDEOOMX_H @@ -35,7 +34,6 @@ #include "defines.h" #include "video.h" - #define OMX_SKIP64BIT #include @@ -43,18 +41,16 @@ #include #include - -struct VPE_OMX_EVENT { - OMX_IN OMX_HANDLETYPE handle; - OMX_IN OMX_PTR appdata; - OMX_IN OMX_EVENTTYPE event_type; - OMX_IN OMX_U32 data1; - OMX_IN OMX_U32 data2; - OMX_IN OMX_PTR event_data; +struct VPE_OMX_EVENT +{ + OMX_IN OMX_HANDLETYPE handle; + OMX_IN OMX_PTR appdata; + OMX_IN OMX_EVENTTYPE event_type; + OMX_IN OMX_U32 data1; + OMX_IN OMX_U32 data2; + OMX_IN OMX_PTR event_data; }; - - class LogNT; class AudioVPE; @@ -62,6 +58,7 @@ class VideoOMX : public Video { friend class AudioOMX; friend class ImageOMX; + public: VideoOMX(); virtual ~VideoOMX(); @@ -69,16 +66,16 @@ class VideoOMX : public Video int init(u1 format); int shutdown(); - u1 getSupportedFormats() { return COMPOSITERGB | HDMI;}; - u4 supportedTVsize() { return ASPECT4X3|ASPECT16X9|ASPECT14X9 ;}; - u1 supportedTVFormats() { return NTSC|PAL|PAL_M|NTSC_J;}; + u1 getSupportedFormats() { return COMPOSITERGB | HDMI; } + u4 supportedTVsize() { return ASPECT4X3 | ASPECT16X9 | ASPECT14X9; } + u1 supportedTVFormats() { return NTSC | PAL | PAL_M | NTSC_J; } int setFormat(u1 format); int setConnection(u1 connection); - int setAspectRatio(u1 aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching + int setAspectRatio(u1 aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching int setMode(u1 mode); bool setVideoDisplay(VideoDisplay display); - int setTVsize(u1 size); // Is the TV a widescreen? + int setTVsize(u1 size); // Is the TV a widescreen? u1 getTVsize(); void executePendingModeChanges(); @@ -101,31 +98,27 @@ class VideoOMX : public Video u8 getCurrentTimestamp(); bool displayIFrame(const u1* bulibaver, u4 length); - virtual bool dtsTimefix(){return false;} //please we need dts time values - virtual int getTeletextBufferFaktor(){return 5;}; + virtual bool dtsTimefix() { return false; } // please we need dts time values + virtual int getTeletextBufferFaktor() { return 5; } // Writing Data to Videodevice virtual void PrepareMediaSample(const MediaPacketList&, u4 samplepos); virtual u4 DeliverMediaSample(u1* bulibaver, u4* samplepos); + virtual bool supportsh264() { return true; } + virtual bool supportsmpeg2() { return mpeg2_supported; } - virtual bool supportsh264(){return true;}; - virtual bool supportsmpeg2(){return mpeg2_supported;}; - - int WriteOutTS(const unsigned char *bulibaver,int length, int type); - void WriteOutPATPMT(); + int WriteOutTS(const unsigned char *bulibaver, int length, int type); + void WriteOutPATPMT(); + virtual long long SetStartOffset(long long curreftime, bool *rsync); + long long SetStartAudioOffset(long long curreftime, bool *rsync); + virtual void ResetTimeOffsets(); - - virtual long long SetStartOffset(long long curreftime, bool *rsync); - long long SetStartAudioOffset(long long curreftime, bool *rsync); - virtual void ResetTimeOffsets(); - - bool loadOptionsFromServer(VDR* vdr); - bool saveOptionstoServer(); - bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane); - bool handleOptionChanges(Option* option); - + bool loadOptionsFromServer(VDR* vdr); + bool saveOptionstoServer(); + bool addOptionsToPanes(int panenumber, Options *options, WOptionPane* pane); + bool handleOptionChanges(Option* option); #ifdef DEV int test(); @@ -143,176 +136,158 @@ class VideoOMX : public Video } private: - LogNT* logger; - int EnterIframePlayback(); - bool iframemode; - bool InIframemode() {return iframemode;}; - - virtual bool DrainTargetBufferFull(); - - u4 DeliverMediaPacket(MediaPacket packet,const u1* bulibaver,u4 *samplepos); - -#define VPE_DECODER_OMX 1 - - - - bool offsetnotset; - bool offsetvideonotset; - bool offsetaudionotset; - long long startoffset; - long long lastrefvideotime; - long long lastrefaudiotime; - // long long cur_pts; - long long lastreftimeOMX; - u8 lastreftimePTS; - - // long long playbacktimeoffset; //this is the offset between the media time and system clock - // long long pausetimecode; - bool clockpaused; - - /* static long long GetCurrentSystemTime(); - static void WaitUntil(long long time); - void FrameWaitforDisplay(long long pts); - bool FrameSkip(long long pts); - bool skipping; - void AdjustAudioPTS(long long pts);*/ - - - - - static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata, - OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1, - OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data); - static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - - u4 DeliverMediaPacketOMX(MediaPacket packet, - const u1* bulibaver, - u4 *samplepos); - - bool detectIFrame(const u1 *buffer,unsigned int length); - - int PrepareInputBufsOMX(); - int DestroyInputBufsOMX(); - - void AddOmxEvent(VPE_OMX_EVENT new_event); - void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver); - - int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type, bool wait=true); - int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2); - int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event,int wait=200); - int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait); - int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true); - int clearEvents(); - int clearEventsForComponent(OMX_HANDLETYPE handle); - void checkForStalledBuffers(); - + static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata, + OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1, + OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data); + static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); + static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - int setClockExecutingandRunning(); - int initClock(); - void destroyClock(); - int idleClock(); - int getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port); - int getClockVideoandInit(); - void LockClock() {clock_mutex.lock();}; - void UnlockClock() {clock_mutex.unlock();}; - OMX_ERRORTYPE ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer); - void clockPause(); - void clockUnpause(); - bool isClockPaused() {return clockpaused;}; - void signalOmx(); - std::condition_variable omx_event_ready_signal; - std::mutex omx_event_ready_signal_mutex; + LogNT* logger; + int EnterIframePlayback(); + bool iframemode; + bool InIframemode() { return iframemode; } + virtual bool DrainTargetBufferFull(); + u4 DeliverMediaPacket(MediaPacket packet, const u1* bulibaver, u4 *samplepos); - void interlaceSwitch4Demux(); - - std::mutex clock_mutex; //clock mutex is now responsible for all omx stuff - long long cur_clock_time; - - - - OMX_HANDLETYPE omx_vid_dec; - OMX_HANDLETYPE omx_vid_sched; - OMX_HANDLETYPE omx_vid_deint; - OMX_HANDLETYPE omx_vid_rend; - OMX_HANDLETYPE omx_clock; - int clock_references; - bool dodeint; //deinterlacer was activated in omx filtergraph - bool first_frame; //handle frame change - void FirstFrameFix(); - - - OMX_U32 omx_codec_input_port; - OMX_U32 omx_codec_output_port; - OMX_U32 omx_deint_input_port; - OMX_U32 omx_deint_output_port; - OMX_U32 omx_rend_input_port; - OMX_U32 omx_shed_input_port; - OMX_U32 omx_shed_output_port; - OMX_U32 omx_shed_clock_port; - OMX_U32 omx_clock_output_port; - // OMX_NALUFORMATSTYPE omx_nalu_format; - bool omx_vid_stalled; - - - - - - int AllocateCodecsOMX(); - int DeAllocateCodecsOMX(); - int FlushRenderingPipe(); - - std::vector input_bufs_omx_all; - std::list input_bufs_omx_free; - std::mutex input_bufs_omx_mutex; - OMX_BUFFERHEADERTYPE* cur_input_buf_omx; - - void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer); - - - - bool omx_running; - bool omx_first_frame; - - std::mutex omx_event_mutex; - - std::list omx_events; - - bool omx_mpeg2; - bool omx_h264; - float xpos,ypos; - float width, height; - bool windowed; - int deinterlace; - void updateMode();//called internally to adjust for different parameters - void selectVideoMode(int interlaced); - - u1 tvsystem; - bool signalon; - bool pendingmodechange; - bool hdmi; - bool mpeg2_supported; - int outputinterlaced; - - - - - - bool firstsynched; - - - std::vector mediapackets; - - char L_VPE_OMX_CLOCK[128]; - char L_VPE_OMX_H264_DECODER[128]; - char L_VPE_OMX_MPEG2_DECODER[128]; - char L_VPE_OMX_VIDEO_SCHED[128]; - char L_VPE_OMX_VIDEO_REND[128]; - char L_VPE_OMX_VIDEO_DEINTERLACE[128]; +#define VPE_DECODER_OMX 1 + bool offsetnotset{true}; + bool offsetvideonotset{true}; + bool offsetaudionotset{true}; + long long startoffset{}; + long long lastrefvideotime{}; + long long lastrefaudiotime{}; + // long long cur_pts; + long long lastreftimeOMX{}; + u8 lastreftimePTS{}; + + // long long playbacktimeoffset; //this is the offset between the media time and system clock + // long long pausetimecode; + bool clockpaused; + + /* + static long long GetCurrentSystemTime(); + static void WaitUntil(long long time); + void FrameWaitforDisplay(long long pts); + bool FrameSkip(long long pts); + bool skipping; + void AdjustAudioPTS(long long pts); + */ + + u4 DeliverMediaPacketOMX(MediaPacket packet, const u1* bulibaver, u4 *samplepos); + + bool detectIFrame(const u1 *buffer, unsigned int length); + + int PrepareInputBufsOMX(); + int DestroyInputBufsOMX(); + + void AddOmxEvent(VPE_OMX_EVENT new_event); + void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver); + + int ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait = true); + int CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2); + int WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait = 200); + int EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait); + int DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait = true); + int clearEvents(); + int clearEventsForComponent(OMX_HANDLETYPE handle); + void checkForStalledBuffers(); + + + int setClockExecutingandRunning(); + int initClock(); + void destroyClock(); + int idleClock(); + int getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port); + int getClockVideoandInit(); + void LockClock() { clock_mutex.lock(); } + void UnlockClock() { clock_mutex.unlock(); } + OMX_ERRORTYPE ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer); + void clockPause(); + void clockUnpause(); + bool isClockPaused() { return clockpaused; } + + void signalOmx(); + std::condition_variable omx_event_ready_signal; + std::mutex omx_event_ready_signal_mutex; + + void interlaceSwitch4Demux(); + + std::mutex clock_mutex; //clock mutex is now responsible for all omx stuff + long long cur_clock_time{}; + + + OMX_HANDLETYPE omx_vid_dec{}; + OMX_HANDLETYPE omx_vid_sched; + OMX_HANDLETYPE omx_vid_deint; + OMX_HANDLETYPE omx_vid_rend; + OMX_HANDLETYPE omx_clock; + int clock_references{}; + bool dodeint; //deinterlacer was activated in omx filtergraph + bool first_frame; //handle frame change + void FirstFrameFix(); + + + OMX_U32 omx_codec_input_port; + OMX_U32 omx_codec_output_port; + OMX_U32 omx_deint_input_port; + OMX_U32 omx_deint_output_port; + OMX_U32 omx_rend_input_port; + OMX_U32 omx_shed_input_port; + OMX_U32 omx_shed_output_port; + OMX_U32 omx_shed_clock_port; + OMX_U32 omx_clock_output_port; + // OMX_NALUFORMATSTYPE omx_nalu_format; + bool omx_vid_stalled{}; + + + int AllocateCodecsOMX(); + int DeAllocateCodecsOMX(); + int FlushRenderingPipe(); + + std::vector input_bufs_omx_all; + std::list input_bufs_omx_free; + std::mutex input_bufs_omx_mutex; + OMX_BUFFERHEADERTYPE* cur_input_buf_omx{}; + + void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer); + + bool omx_running{}; + bool omx_first_frame; + + std::mutex omx_event_mutex; + + std::list omx_events; + + bool omx_mpeg2{true}; + bool omx_h264{true}; + float xpos{0.f}, ypos{0.f}; + float width, height; + bool windowed; + int deinterlace; + void updateMode(); //called internally to adjust for different parameters + void selectVideoMode(int interlaced); + + u1 tvsystem; + bool signalon{}; + bool pendingmodechange; + bool hdmi; + bool mpeg2_supported{}; + int outputinterlaced{}; + + bool firstsynched{}; + + std::vector mediapackets; + + char L_VPE_OMX_CLOCK[128]; + char L_VPE_OMX_H264_DECODER[128]; + char L_VPE_OMX_MPEG2_DECODER[128]; + char L_VPE_OMX_VIDEO_SCHED[128]; + char L_VPE_OMX_VIDEO_REND[128]; + char L_VPE_OMX_VIDEO_DEINTERLACE[128]; }; #endif -- 2.39.2