Low FPS and freeze while streaming high resolution cameras with opencv - opencv
I've recently purchased a new camera that is capable of streaming 60fps on HD resolution.
while using the most basic gst-launch-1.0 line : gst-launch-1.0 v4l2src ! xvimagesink it opens the camera on high res with high FPS with no lag and no freezing.
However, when trying to start the camera on opencv VideoCapture module, anything above 640x480 freezes a lot and gives very low FPS.
My best guess is that my pipelines are not ideal and I am not running the camera as intended on HW accelerated pipeline, but rather eating up my CPU which can't handle the stream, as well as running on an uncompressed format UYVY.
A few pipelines examples that i've tried:
cv2.VideoCapture('v4l2src device=/dev/video0 ! video/x-raw,width=1920,height=1080! nvvidconv flip-method=2 ! video/x-raw(memory:NVMM), format=I420! nvvidconv ! video/x-raw, format=BGRx , width=1920, height=1080, framerate=60/1 ! videoconvert ! video/x-raw, format=BGR ! appsink drop=True sync=False')
cv2.VideoCapture('v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, format=BGR ! appsink')
I am running on Jetson Xavier NX.
Would appreciate any help and examples of better pipelines, I haven't found many v4l2src examples if any and non worked well for me.
i should add basic camera information from gst-device-monitor-1.0 :
Device found:
name : See3CAM_CU30
class : Video/Source
caps : video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 24/1, 12/1 };
video/x-raw, format=(string)UYVY, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 42/1, 21/1 };
video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 15/1 };
video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 50/1, 25/1 };
video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1, 15/1 };
video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 58/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
video/x-raw, format=(string)UYVY, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 60/1, 30/1 };
image/jpeg, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)48/1;
image/jpeg, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
image/jpeg, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
image/jpeg, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)58/1;
image/jpeg, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
image/jpeg, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
properties:
udev-probed = true
device.bus_path = platform-3610000.xhci-usb-0:3.4:1.0
sysfs.path = /sys/devices/3610000.xhci/usb2/2-3/2-3.4/2-3.4:1.0/video4linux/video0
device.bus = usb
device.subsystem = video4linux
device.vendor.id = 2560
device.vendor.name = "e-con\\x20systems"
device.product.id = c130
device.product.name = See3CAM_CU30
device.serial = e-con_systems_See3CAM_CU30_152B9904
device.capabilities = :capture:
device.api = v4l2
device.path = /dev/video0
v4l2.device.driver = uvcvideo
v4l2.device.card = See3CAM_CU30
v4l2.device.bus_info = usb-3610000.xhci-3.4
v4l2.device.version = 264701 (0x000409fd)
v4l2.device.capabilities = 2216689665 (0x84200001)
v4l2.device.device_caps = 69206017 (0x04200001)
gst-launch-1.0 v4l2src ! ...
Related
ffmpeg conversion: Twitter rejects video with "Not valid video"
I have an app that uploads via twitter api chunked upload, and it finally works with photos. However, I am trying to get it to work with videos. Uploading didnt work out-of-the-box even though the video format is mp4. The twitter guidelines for uploads are these With that in mind, I have this ffmpeg command so far: ffmpeg -i in.mp4 -vf \"scale=1280:720\" -b:v 5000K -minrate 5000K -maxrate 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -profile:v high -pix_fmt yuv420p -strict -2 -ac 2 -acodec aac out.mp4 I still get "Not valid video", and I don't know why. Here's my mediainfo output for out.mp4: General Count : 328 Count of stream of this kind : 1 Kind of stream : General Kind of stream : General Stream identifier : 0 Count of video streams : 1 Count of audio streams : 1 Video_Format_List : AVC Video_Format_WithHint_List : AVC Codecs Video : AVC Video_Language_List : English Audio_Format_List : AAC Audio_Format_WithHint_List : AAC Audio codecs : AAC LC Audio_Language_List : English Complete name : video-5e4405cd4348a5e4405cd434d2.mp4 File name : video-5e4405cd4348a5e4405cd434d2 File extension : mp4 Format : MPEG-4 Format : MPEG-4 Format/Extensions usually used : mov mp4 m4v m4a m4b m4p 3ga 3gpa 3gpp 3gp 3gpp2 3g2 k3g jpm jpx mqv ismv isma ismt f4a f4b f4v Commercial name : MPEG-4 Format profile : Base Media Internet media type : video/mp4 Codec ID : isom Codec ID : isom (isom/iso2/avc1/mp41) Codec ID/Url : http://www.apple.com/quicktime/download/standalone.html CodecID_Compatible : isom/iso2/avc1/mp41 Codec : MPEG-4 Codec : MPEG-4 Codec/Extensions usually used : mov mp4 m4v m4a m4b m4p 3ga 3gpa 3gpp 3gp 3gpp2 3g2 k3g jpm jpx mqv ismv isma ismt f4a f4b f4v File size : 52664272 File size : 50.2 MiB File size : 50 MiB File size : 50 MiB File size : 50.2 MiB File size : 50.22 MiB Duration : 79744 Duration : 1 min 19 s Duration : 1 min 19 s 744 ms Duration : 1 min 19 s Duration : 00:01:19.744 Duration : 00:01:19:20 Duration : 00:01:19.744 (00:01:19:20) Overall bit rate : 5283334 Overall bit rate : 5 283 kb/s Frame rate : 30.000 Frame rate : 30.000 FPS Frame count : 2390 Stream size : 88780 Stream size : 86.7 KiB (0%) Stream size : 87 KiB Stream size : 87 KiB Stream size : 86.7 KiB Stream size : 86.70 KiB Stream size : 86.7 KiB (0%) Proportion of this stream : 0.00169 HeaderSize : 40 DataSize : 52575500 FooterSize : 88732 IsStreamable : No File last modification date : UTC 2020-02-12 14:05:37 File last modification date (local) : 2020-02-12 15:05:37 Writing application : Lavf57.83.100 Writing application : Lavf57.83.100 Video Count : 342 Count of stream of this kind : 1 Kind of stream : Video Kind of stream : Video Stream identifier : 0 StreamOrder : 0 ID : 1 ID : 1 Format : AVC Format/Info : Advanced Video Codec Format/Url : http://developers.videolan.org/x264.html Commercial name : AVC Format profile : High#L3.1 Format settings : CABAC / 4 Ref Frames Format settings, CABAC : Yes Format settings, CABAC : Yes Format settings, ReFrames : 4 Format settings, ReFrames : 4 frames Internet media type : video/H264 Codec ID : avc1 Codec ID/Info : Advanced Video Coding Codec : AVC Codec : AVC Codec/Family : AVC Codec/Info : Advanced Video Codec Codec/Url : http://developers.videolan.org/x264.html Codec/CC : avc1 Codec profile : High#L3.1 Codec settings : CABAC / 4 Ref Frames Codec settings, CABAC : Yes Codec_Settings_RefFrames : 4 Duration : 79667 Duration : 1 min 19 s Duration : 1 min 19 s 667 ms Duration : 1 min 19 s Duration : 00:01:19.667 Duration : 00:01:19:20 Duration : 00:01:19.667 (00:01:19:20) Bit rate : 5000000 Bit rate : 5 000 kb/s Width : 1280 Width : 1 280 pixels Height : 720 Height : 720 pixels Sampled_Width : 1280 Sampled_Height : 720 Pixel aspect ratio : 1.000 Display aspect ratio : 1.778 Display aspect ratio : 16:9 Rotation : 0.000 Frame rate mode : CFR Frame rate mode : Constant FrameRate_Mode_Original : VFR Frame rate : 30.000 Frame rate : 30.000 FPS Frame count : 2390 Resolution : 8 Resolution : 8 bits Colorimetry : 4:2:0 Color space : YUV Chroma subsampling : 4:2:0 Chroma subsampling : 4:2:0 Bit depth : 8 Bit depth : 8 bits Scan type : Progressive Scan type : Progressive Interlacement : PPF Interlacement : Progressive Bits/(Pixel*Frame) : 0.181 Stream size : 51297022 Stream size : 48.9 MiB (97%) Stream size : 49 MiB Stream size : 49 MiB Stream size : 48.9 MiB Stream size : 48.92 MiB Stream size : 48.9 MiB (97%) Proportion of this stream : 0.97404 Writing library : x264 - core 152 r2854 e9a5903 Writing library : x264 core 152 r2854 e9a5903 Encoded_Library_Name : x264 Encoded_Library_Version : core 152 r2854 e9a5903 Encoding settings : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=12 / lookahead_threads=2 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=5000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00 Language : en Language : English Language : English Language : en Language : eng Language : en Audio Count : 275 Count of stream of this kind : 1 Kind of stream : Audio Kind of stream : Audio Stream identifier : 0 StreamOrder : 1 ID : 2 ID : 2 Format : AAC Format/Info : Advanced Audio Codec Commercial name : AAC Format profile : LC Format settings, SBR : No (Explicit) Format settings, SBR : No (Explicit) Codec ID : mp4a-40-2 Codec : AAC LC Codec : AAC LC Codec/Family : AAC Codec/CC : 40 Duration : 79744 Duration : 1 min 19 s Duration : 1 min 19 s 744 ms Duration : 1 min 19 s Duration : 00:01:19.744 Duration : 00:01:19:25 Duration : 00:01:19.744 (00:01:19:25) Bit rate mode : CBR Bit rate mode : Constant Bit rate : 128257 Bit rate : 128 kb/s Channel(s) : 2 Channel(s) : 2 channels Channel positions : Front: L R Channel positions : 2/0/0 ChannelLayout : L R Samples per frame : 1024 Sampling rate : 48000 Sampling rate : 48.0 kHz Samples count : 3827712 Frame rate : 46.875 Frame rate : 46.875 FPS (1024 SPF) Frame count : 3738 Compression mode : Lossy Compression mode : Lossy Stream size : 1278470 Stream size : 1.22 MiB (2%) Stream size : 1 MiB Stream size : 1.2 MiB Stream size : 1.22 MiB Stream size : 1.219 MiB Stream size : 1.22 MiB (2%) Proportion of this stream : 0.02428 Language : en Language : English Language : English Language : en Language : eng Language : en Default : Yes Default : Yes Alternate group : 1 Alternate group : 1 Edit: Guess Ill add my PHP code too (This is chopped in a sensible manner because the actual file is very large): // Set up Codebird \Codebird\Codebird::setConsumerKey($consumer_key, $consumer_secret); // static, see README $cb = \Codebird\Codebird::getInstance(); $cb->setToken($token, $token_secret); $cb->setTimeout(60 * 1000); // 60 second request timeout $video = new Video($path); // Convert to the parameter required by twitter. $converted = $video->convert(); $path = realpath('videos/' . $converted); $file = fopen($path, 'rb'); $size = fstat($file)['size']; $mime_type = mime_content_type($path); $media = $cb->media_upload([ 'command' => 'INIT', 'media_type' => $mime_type, 'media_category' => 'tweet_video', 'total_bytes' => $size, ]); $success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx if (!$success) { throw new TwitterException("Failed to INIT upload for $path..."); } // APPEND chunks to upload. $mediaId = $media->media_id_string; $segmentId = 0; while (!feof($file)) { echo "chunk #$segmentId...."; $chunk = fread($file, 512 * 1024); // caps out at 512 MB echo "chunk size: ". strlen($chunk); $media = $cb->media_upload([ 'command' => 'APPEND', 'media_id' => $mediaId, 'segment_index' => $segmentId, 'media' => $chunk, ]); $success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx if (!$success) { throw new TwitterException("Failed to APPEND to upload for $path, chunk $segmentId..."); } $segmentId++; } // Close file and FINALIZE upload. fclose($file); echo "FINALIZING id $mediaId..."; $media = $cb->media_upload([ 'command' => 'FINALIZE', 'media_id' => $mediaId, ]); $success = $media->httpstatus >= 200 && $media->httpstatus < 300; # 2xx if (!$success) { var_dump($media); throw new TwitterException("Failed to FINALIZE upload for $path..."); } return $mediaId; Video is my ffmpeg class, which I'll paste below, and $path is a URL leading to a perfectly valid mp4 video. Video.php: <?php class VideoConversionException extends \Exception {} class Video { public $name; public $converted; public function __construct($name) { self::clear(); $this->name = $name; } public function convert() { $tmpVideo = 'video-' . uniqid() . uniqid() . '.mp4'; $videoPath = 'videos/' . $tmpVideo; //$ffmpeg = "ffmpeg -i https://tvcanarias.acfipress.com/BC_190907_gc_teror.mp4 -vf "scale=1280:720" -b:v 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -acodec aac output_video.mp4"; $ffmpeg = "ffmpeg -i {$this->name} -vf \"scale=1280:720\" -b:v 5000K -minrate 5000K -maxrate 5000K -b:a 128K -r 30 -f mp4 -vcodec libx264 -profile:v high -pix_fmt yuv420p -strict -2 -ac 2 -acodec aac $videoPath"; //$ffmpeg = "ffmpeg -i {$this->name} -pix_fmt yuv420p -vcodec libx264 -vf scale=640:-1 -acodec aac -vb 1024k -minrate 1024k -maxrate 1024k -bufsize 1024k -ar 44100 -ac 2 -strict experimental -r 30 $videoPath"; $output = []; exec($ffmpeg, $output, $status); if ($status != 0) { //die("Couldnt run ffmpeg. (Error code: #$status)"); throw new VideoConversionException("Couldn't run ffmpeg. (Error code: #$status)"); } $this->converted = $tmpVideo; return $tmpVideo; } public function shredConverted() { // delete video. #unlink("videos/{$this->$converted}"); } public static function clear() { // We can't really shred videos right away as they might be still uploading. // Therefore, every time this library is used, we will just delete videos older // than, say, an hour. $files = scandir('videos'); $curtime = time(); foreach ($files as $file) { if ($file == '.gitignore' || $file == '.' || $file == '..') { continue; } $mtime = filemtime("videos/$file"); $diff = $curtime - $mtime; $overAnHour = $diff > (60 * 60); if ($overAnHour) { #unlink("videos/$file"); } } } }
How to make Erlang client/server connect with arguments/nodes from config?
I'm writing a client/server System in Erlang and can't get them to connect. The nodes they should use are stored in config files, which are loaded upon starting them. They also use several distributed data structures. Problem is, I'm first starting the data structure, then the server (works fine) but when I start the client, it doesn't connect to anything and throws an exception. Server: -module(server). -export([startServer/0,loopServer/7,node/0,log/0,name/0]). -compile({no_auto_import,[node/0]}). -import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2]). -import(erlang, [append/2]). log() -> erlang:list_to_atom(lists:concat(["Server#", node(),".log"])). node() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Node} = werkzeug:get_config_value(node,Config), Node. name() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Name} = werkzeug:get_config_value(servername,Config), Name. %%Startet den Server und die darin enthaltene Schleife startServer() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Name} = get_config_value(servername,Config), %%CMEM initialisieren {ok, RemTime} = get_config_value(cmemtime,Config), CMEM = cmem:initCMEM(RemTime, log()), %%HBQ-Prozess erzeugen {ok,HBQName} = get_config_value(hbqname,Config), {ok,HBQNode} = get_config_value(node,Config), HBQ = {HBQName,HBQNode}, {ok,Serverzeit} = get_config_value(serverzeit,Config), %%Zeitpunkt des Timer übergeben {ok, Timer} = timer:send_after(round(RemTime * 1000),Name,delServer), %%Prozess registrieren, Serverschleife mit allen Infos starten, plus NNr 1 ServerPid = spawn(?MODULE, loopServer, [Name,CMEM,HBQ,Timer,Serverzeit,Config,1]), register(Name,ServerPid), %%HBQ initialisieren HBQ ! {ServerPid, {request,initHBQ}}, {Config,CMEM,HBQ,ServerPid}. loopServer(Name,CMEM,HBQ,Timer,Serverzeit,Config,NNr) -> receive %%Client fragt neue Nachrichten ab, dazu wird aus CMEM die aktuelle NNr für %%den Client angefordert und mit der ClientPID an die HBQ weitergegeben {ClientPID,getmessages} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), ClientNNr = cmem:getClientNNr(CMEM, ClientPID), HBQ ! {self(), {request, deliverMSG, ClientNNr, ClientPID}}, logging(log(), lists:concat(["Server: Nachricht ", NNr, " wurde zugestellt.\n"])), loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr); %%Nachricht soll in HBQ verschoben werden {dropmessage,[INNr,Msg,TSclientout]} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), HBQ ! {self(), {request,pushHBQ,[INNr,Msg,TSclientout]}}, receive {reply,ok} -> logging(log(), lists:concat(["Server: Nachricht ", INNr, " wurde in HBQ eingefuegt.\n"])) end, loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr); %%Client fragt naechste NNr ab, diese wird dem Zustand des Server entnommen {ClientPID,getmsgid} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), ClientPID ! {nid, NNr}, NewNNr = NNr + 1, logging(log(), lists:concat(["Server: Nachrichtennumer ", NNr, " an ", erlang:pid_to_list(ClientPID), "gesendet.\n"])), loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NewNNr); %%Server beendet sich selbst und zugleich die HBQ delServer -> HBQ ! {self(),{request,delHBQ}}, receive {reply,ok} -> logging(log(), lists:concat([lists:concat(["Server: Downtime ", werkzeug:timeMilliSecond(), " von ", name() ,"\n"])])), ok end end. Client: -module(client). -export([startClients/0,loopClient/4,spawnC/1,forLoop/3,mitServerVerbinden/6,configLaden/0]). -import(werkzeug, [get_config_value/2]). -import(timer, [apply_after/4]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Client %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%initClient startClients() -> Config = configLaden(), {ok, ClientAnzahl} = werkzeug:get_config_value(clientanzahl, Config), {ok, ServerName} = werkzeug:get_config_value(servername, Config), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), ServerPid = {ServerName,ServerNode}, forLoop(ClientAnzahl, fun client:spawnC/1, ServerPid). %%Hilfsfunktion fuer for-Schleife: Zaehlt runter, %%ruft Funktion auf und gibt Ergebnisse als Liste zurueck forLoop(Clients, Spawn, SPid) -> forLoop(Clients, Spawn, SPid, []). forLoop(0, _Spawn, _SPid, ClientListe) -> ClientListe; forLoop(Clients, Spawn, SPid, ClientListe) -> ClientListeNew = ClientListe ++ [Spawn(SPid)], ClientsNew = Clients - 1, forLoop(ClientsNew, Spawn, SPid, ClientListeNew). %%Neuen ClientProzess erzeugen spawnC(ServerPid) -> Config = configLaden(), {ok, Lebenszeit} = werkzeug:get_config_value(lebenszeit, Config), {ok, Cookie} = werkzeug:get_config_value(cookie, Config), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), {ok, Wartezeit} = werkzeug:get_config_value(wartezeit, Config), ClientPid = erlang:spawn(?MODULE, mitServerVerbinden, [ServerPid, [], [], Wartezeit, ServerNode, Cookie]), timer:kill_after(Lebenszeit, ClientPid), ClientPid. %%mit Server Verbinden mitServerVerbinden(ServerPid,Datei,NNummern,Wartezeit,ServerNode,Cookie) -> erlang:set_cookie(ServerNode,Cookie), pong = net_adm:ping(ServerNode), loopClient(ServerPid,NNummern,Wartezeit,Datei). %%loopClient loopClient(ServerPid,NNummern,Wartezeit,Datei) -> %%Client wird zum Redakteur {NNummernNew, WartezeitNew, DateiNew} = nachrichtenSenden(5,ServerPid,NNummern,Wartezeit,Datei), %%Client wird zum Leser nachrichtenLesen(false, NNummernNew, ServerPid,DateiNew), %%Methode ruft sich selbst wieder auf loopClient(ServerPid, NNummernNew, WartezeitNew,DateiNew). configLaden() -> {ok, Config} = file:consult("configs/client.cfg"), Config. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Redakteur %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%Nachricht soll vergessen werden nachrichtenSenden(0,ServerPid,NNummern,Wartezeit,Datei) -> %%Naechste NNr beim Server anfragen ServerPid ! {self(),getmsgid}, receive %%Server sendet NNr {nid,NNr} -> %%Logeintrag werkzeug:logging(Datei,lists:concat([NNr, "te Nachricht um ", werkzeug:timeMilliSecond(), " vergessen zu senden. ******\n"])) end, WartezeitNew = wartezeitBerechnen(Wartezeit), %%Rückgabewerte: Liste mit Nachrichtennummern fuer leser, neue Wartezeit, Logfile {NNummern,WartezeitNew,Datei}; %%Nachrichtennummer anfragen und erhalten, Nachricht schreiben nachrichtenSenden(NachrichtenVorVergessen,ServerPid,NNummern,Wartezeit,Datei) -> Config = configLaden(), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), %%Naechste NNr beim Server anfragen ServerPid ! {self(),getmsgid}, receive %%Server sendet NNr {nid,NNr} -> %%Nachricht schreiben Nachricht = nachrichtSchreiben(NNr), %%NNr zur Liste hinzufuegen fuer Leser NNummernNew = NNummern ++[NNr], timer:sleep(Wartezeit), %%Nachricht an Server senden ServerPid ! {dropmessage,[NNr,Nachricht,erlang:now()]}, %%Logeintrag schreiben werkzeug:logging(Datei,lists:concat([Nachricht, " gesendet"])), %%Neue Wartezeit berechnen WartezeitNew = wartezeitBerechnen(Wartezeit), %%Zaehler dekrementieren NachrichtenVorVergessenNew = NachrichtenVorVergessen -1, %%Methode neu aufrufen nachrichtenSenden(ServerPid,NNummernNew,WartezeitNew,NachrichtenVorVergessenNew,Datei) end. %%nachrichtSchreiben nachrichtSchreiben(NNr) -> Config = configLaden(), {ok, Rechner} = werkzeug:get_config_value(rechner, Config), {ok, Praktikumsgruppe} = werkzeug:get_config_value(praktikumsgruppe, Config), {ok, Teamnummer} = werkzeug:get_config_value(teamnummer, Config), lists:concat(["client#",Rechner, "_", Praktikumsgruppe, "_", Teamnummer, ": ", integer_to_list(NNr), "_te Nachricht. Sendezeit: ", werkzeug:timeMilliSecond()]). %%Hilfsmethode: Intervall darf nicht kleiner als zwei Sekunden werden minimumTime() -> 2000. %%Berechnet das neue Zeitintervall, um die Haelfte groesser oder %%kleiner als die alte Zeit, solange sie groesser gleich 2 Sekunden ist wartezeitBerechnen(Wartezeit) -> GroesserKleiner = werkzeug:bool_rand(), HaelfteZeit = trunc(max(Wartezeit * 0.5, minimumTime())), if GroesserKleiner -> Wartezeit + HaelfteZeit; true -> max(Wartezeit - HaelfteZeit, minimumTime()) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Leser %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nachrichtenLesen(true,NNummern,ServerPid,Datei) -> ok; nachrichtenLesen(false,NNummern,ServerPid,Datei) -> ServerPid ! {self(),getmessages}, receive {reply,Message,Terminated} -> nachrichtInLogSchreiben(Message,NNummern,Datei), nachrichtenLesen(Terminated,NNummern,ServerPid,Datei) end. nachrichtInLogSchreiben([NNr,Msg,TSclientout,TShbqin,TSdlqin,TSdlqout],NNummern,Datei) -> Now = erlang:timestamp(), DLQInTrue = werkzeug:validTS(TSdlqin), DLQOutTrue = werkzeug:validTS(TSdlqout), DLQInZukunft = werkzeug:lessTS(Now, TSdlqin), DLQOutZukunft = werkzeug:lessTS(Now, TSdlqout), MsgVonGleichemClient = msgVonGleichemClient(NNr, Msg, NNummern), if DLQInTrue and DLQInZukunft -> Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqin, Now)), MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied, werkzeug:logging(Datei, MsgNew ++ "\n"); DLQOutTrue and DLQOutZukunft -> Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqout, Now)), MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied, werkzeug:logging(Datei, MsgNew ++ "\n"); true -> werkzeug:logging(Datei, MsgVonGleichemClient ++ "\n") end. msgVonGleichemClient(NNr,Msg,NNummern) -> MsgVonGleichemClient = lists:member(NNr, NNummern), if MsgVonGleichemClient -> Msg ++ "*******"; true -> Msg end. Config file for server: {sizedlq,400}. {servername,'serverpa'}. {cmemtime,2000}. {hbqname,'hbqpa'}. {node,'hbqnode'}. {serverzeit,50}. Config file for client: {wartezeit,20}. {lebenszeit,240}. {pratikumsgruppe,'2'}. {teamnummer,'02'}. {servername,'serverpa'}. {clientanzahl,5}. {servernode,'servernode'}. {cookie,pa}. {rechner,'rechner'}. There are also distributed data strutures which are essentially queues and seem to be working fine: HBQ: -module(hbq). -export([startHBQ/0, checkTransfer/6,loophbq/4]). %% HBQ !{self(), {request,pushHBQ,[INNr,Msg,TSclientout]}} startHBQ() -> startHBQ("./configs/server.cfg"). %% Used for starting the HBQ with a custom config file startHBQ(Configfile) -> %%Config und Namen auslesen Config = loadConfig(Configfile), Config = loadConfig(Configfile), %%{ok,Config} = file:consult("./config/server.cfg"), {ok,HBQName} = werkzeug:get_config_value(hbqname,Config), %%Prozess der HBQ starten HBQPid = spawn(?MODULE,loophbq,[[],[],Config, 1]), %%Prozess registrieren register(HBQName,HBQPid), HBQPid. loophbq(HBQ,DLQ,Config,CurrNumber) -> receive %%initialisere HBQ und DLQ, sendet ok an Server {ServerPid,{request,initHBQ}} -> HBQList = [], Log = log(Config,["HBQ>>> initialisiert worden von ", ServerPid, ".\n"]), {ok,DLQSize} = werkzeug:get_config_file(sizedlq,Config), DLQ = dlq:initDLQ(DLQSize,Log), ServerPid ! {reply,ok}, loophbq(HBQList, DLQ ,Config, CurrNumber); %%fuegt der Msg einen Zeitstempel hinzu, fuegt sie in HBQ ein, sendet ok {ServerPid,{request,pushHBQ,[NNr,Msg,TSclientout]}} -> TShbqin = werkzeug:timeMillliSecond(), NewMessage = {NNr,lists:concat(Msg,["HBQ in: ",TShbqin])}, Log = log(Config,["HBQ>>> Nachricht ",NNr, "in HBQ eingefügt.\n"]), NewHBQ = [HBQ|NewMessage], lists:sort(fun({A,_},{B,_}) -> A=<B end), checkTransfer(NewHBQ, CurrNumber, Config, DLQ,TSclientout,TShbqin), ServerPid ! {reply,ok}, loophbq(NewHBQ, DLQ ,Config, CurrNumber); %%DLQ soll über HBQ Nachricht an Client senden {ServerPid,{request,deliverMSG,NNr,ToClient}} -> {ok, HBQName} = werkzeug:get_config_value(hbqname, Config), Log = lists:concat(["HB-DLQ#", HBQName, ".log"]), Datei = erlang:list_to_atom(Log), log(Config, ["HBQ>>> dlq:delivermsg", NNr, pid_to_list(ToClient), "\n"]), NNrDLQ = dlq:deliverMSG(NNr, ToClient, DLQ, Datei), ServerPid ! {reply, NNrDLQ}, loophbq(HBQ, DLQ ,Config, CurrNumber); %%Terminiert Prozess der DLQ {ServerPid,{request,delHBQ}} -> ServerPid ! {reply,ok}, ok end. %%CheckTransfer checkTransfer(HBQ, Number, Config, [DLQ,Size],TSclientout,TShbqin) -> Datei = log(Config, ["HBQ>>> Nachricht Nr ", Number, " wird in DLQ uebertragen\n"]), FoundMatch = lists:keyfind(Number, 1, HBQ), if FoundMatch =:= false -> if(length(HBQ)>Size*0.667) -> [{MinNNr,_}|_] = HBQ, %wegen sort ist immer die kleinste NNr vorne in der Liste NewMessage = {MinNNr-1,lists:concat(["Weiß noch nicht was hier reinsoll: ",werkzeug:timeMilliSecond()])}, NewHBQ = lists:append([{MinNNr-1,NewMessage}], HBQ), log(Config,["HBQ>>> Fehlernachricht fuer Nachrichten ",Number," bis",MinNNr-1, " generiert.\n"]), NewNumber = MinNNr-1, checkTransfer(NewHBQ, NewNumber, Config,[DLQ,Size],TSclientout,TShbqin); true -> ok end; true -> {MatchNr,Msg} = FoundMatch, dlq:push2DLQ([MatchNr, Msg, TSclientout, TShbqin], DLQ, Datei), lists:delete(FoundMatch, HBQ), checkTransfer(HBQ, Number+1, Config,[DLQ,Size],TSclientout,TShbqin) end. log(Config,Message) -> {ok,HBQNode} = werkzeug:get_config_value(node,Config), DateiName = lists:concat(["HB-DLQ#", HBQNode,".log"]), Datei = erlang:list_to_atom(DateiName), werkzeug:logging(Datei, lists:concat(Message)), Datei. %%Dummy-Nachrichten schreiben um Lücken in der HBQ zu füllen wenn sie kritische Größe erreicht %%Methode um zu prüfen, ob Nachrichten in DLQ geschoben werden können, das dann auch machen loadConfig(Configfile) -> {ok, Config} = file:consult(Configfile), Config. DLQ: -module(dlq). -export([initDLQ/2, delDLQ/1, expectedNr/1, push2DLQ/3, deliverMSG/4]). %%Initialisiert DLQ mit Kapazitaet Size, Log in Datei initDLQ(Size, Datei) -> werkzeug:logging(Datei,lists:concat(["DLQ>>> intitialisiert worden mit Groesse ",Size,".\n"])), [[],Size]. %%Loescht DLQ delDLQ(_Queue) -> ok. %%Liefert NNr die als naechstes in DLQ gespeichert werden kann %%expectedNr(Queue) expectedNr([[], _Size]) -> 1; expectedNr([[[NNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] | _Rest], _Size]) -> NNr + 1. %%Speichert Nachricht in DLQ, fuegt Zeitstempel hinzu, Rueckgabe: Modifizierte DLQ %%push2DLQ([NNr, Msg, TSclientout, TShbqin], Queue, Datei) %%Fehlt noch: Abfrage, ob das die passende Nummer ist! push2DLQ([NNr, Msg, TSclientout, TShbqin], [DLQ,Size], Datei) -> if length(DLQ) < Size -> werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])), [[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | DLQ], Size]; length(DLQ) =:= Size -> [LastNNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] = lists:last(DLQ), werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", LastNNr, " aus DLQ entfernt.\n"])), werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])), [[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | lists:droplast(DLQ)], Size] end. %%Sendet Nachricht an Leser-Client deliverMSG(MSGNr, ClientPID, Queue, Datei) -> %%Aendern: MSGNer = -1, flag am Ende der Reply (siehe zeile 42) [{NewestNr,Msg}|Rest] = Queue, if MSGNr > NewestNr -> DummyMessage = {-1,lists:concat(["DLQ in: ",werkzeug:timeMilliSecond()])}, %% -1 Flag werkzeug:logging(Datei, lists:concat(["DLQ>>> DummyNachricht fuer ",MSGNr," an Client ",ClientPID, " ausgeliefert.\n"])), ClientPID ! {reply,Msg,true} end, %%%%%%Ab hier noch aendern bzgl Flag FoundMatch = lists:keyfind(MSGNr, 1, Queue), if FoundMatch =:= false -> deliverMSG(MSGNr+1, ClientPID, Queue, Datei), if MSGNr =:= NewestNr -> {Number,Msg} = FoundMatch, NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],-1)}, werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])), ClientPID ! {reply,Msg,false}; true -> {Number,Msg} = FoundMatch, NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],0)}, werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])), ClientPID ! {reply,Msg,false} end; true -> ok end. CMEM: -module(cmem). -export([initCMEM/2, delCMEM/1, updateClient/4, getClientNNr/2]). -import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2,getUTC/0]). %%Initialisiert CMEM initCMEM(RemTime, Datei) -> werkzeug:logging(Datei, lists:concat(["CMEM>>> initialisiert mit ", RemTime, " Sekunden\n"])), [[], RemTime]. %%Loescht CMEM delCMEM(_CMEM) -> ok. %%Speichert/aktualisiert Client und NNr im CMEM, updateClient([CMEM, RemTime], ClientID, NNr, Datei) -> ClientTS = getUTC(), logging(Datei, lists:concat(["CMEM>>> Client ", ClientID, " wird aktualisiert.\n"])), [lists:keystore(ClientID, 1, CMEM, {ClientID, NNr, ClientTS}), RemTime]. %%Gibt naechste vom Client erwartete NNr zurueck %%Es wird geprueft ob Client in der Liste steht und dann %%mit diesem Wissen eine Hilfsfunktion aufgerufen getClientNNr([CMEM, RemTime], ClientID) -> ClientBekannt = lists:keymember(ClientID, 1, CMEM), isClientKnown([CMEM, RemTime], ClientID, ClientBekannt). %%Client ist nicht bekannt: Naechste NNr = 1 isClientKnown(_CMEM, _ClientID, false) -> 1; %% Der Client ist bekannt. %%Zeit noch nicht abgelaufen: Gibt naechste Nummer aus %%Zeit abgelaufen: Naechste NNr = 1 isClientKnown([CMEM, RemTime], ClientID, true) -> {ClientID, NNr, ClientTS} = lists:keyfind(ClientID, 1, CMEM), RemainingTime = ClientTS + RemTime, Now = getUTC(), if RemainingTime >= Now -> NNr + 1; true -> 1 end. The client is supposed to contact the server sending it a message, the server puts it in data structures which send it back to the client under the right circumstances. The problem is, when I compile them, the start the HBQ, then the server and then the client, I get =ERROR REPORT==== 18-Apr-2017::10:25:46 === Error in process <0.104.0> with exit value: {distribution_not_started,[{auth,set_cookie,2,[{file,"auth.erl"},{line,119}]},{client,mitServerVerbinden,6,[{file,"client.erl"},{line,42}]}]} So apparently there is an issue with the client not connecting to the server. This is my first time working with Erlang and distributed systems, so I have no idea what is going on. Is it not enough to put the nodes and cookie into the configs and tell the components of the system to look there?
The error distribution_not_started is returned by the auth module when the erlang VM calling it does not have a name. Ensure that a -sname or -name flag is passed when starting erlang e.g.: erl -sname test
esp8266 RTOS blink example doesn't work
I have a problem with the RTOS firmware on the esp8266 (I have a esp12e), after flashing the firmware, reading from uart, it keeps stuck with those lines: ets Jan 8 2013,rst cause:2, boot mode:(3,0) load 0x40100000, len 31584, room 16 tail 0 chksum 0x24 load 0x3ffe8000, len 944, room 8 tail 8 chksum 0x9e load 0x3ffe83b0, len 1080, room 0 tail 8 chksum 0x60 csum 0x60 Now I will explain my HW setup: GPIO15 -> Gnd EN -> Vcc GPIO0 -> Gnd (when flashing) GPIO0 -> Vcc (normal mode) For the toolchain I've followed this tutorial and it works well: http://microcontrollerkits.blogspot.it/2015/12/esp8266-eclipse-development.html Then I started doing my RTOS blink example, I post my user_main.c code here: #include "esp_common.h" #include "gpio.h" void task2(void *pvParameters) { printf("Hello, welcome to client!\r\n"); while(1) { // Delay and turn on vTaskDelay (300/portTICK_RATE_MS); GPIO_OUTPUT_SET (5, 1); // Delay and LED off vTaskDelay (300/portTICK_RATE_MS); GPIO_OUTPUT_SET (5, 0); } } /****************************************************************************** * FunctionName : user_rf_cal_sector_set * Description : SDK just reversed 4 sectors, used for rf init data and paramters. * We add this function to force users to set rf cal sector, since * we don't know which sector is free in user's application. * sector map for last several sectors : ABCCC * A : rf cal * B : rf init data * C : sdk parameters * Parameters : none * Returns : rf cal sector *******************************************************************************/ uint32 user_rf_cal_sector_set(void) { flash_size_map size_map = system_get_flash_size_map(); uint32 rf_cal_sec = 0; switch (size_map) { case FLASH_SIZE_4M_MAP_256_256: rf_cal_sec = 128 - 5; break; case FLASH_SIZE_8M_MAP_512_512: rf_cal_sec = 256 - 5; break; case FLASH_SIZE_16M_MAP_512_512: case FLASH_SIZE_16M_MAP_1024_1024: rf_cal_sec = 512 - 5; break; case FLASH_SIZE_32M_MAP_512_512: case FLASH_SIZE_32M_MAP_1024_1024: rf_cal_sec = 1024 - 5; break; default: rf_cal_sec = 0; break; } return rf_cal_sec; } /****************************************************************************** * FunctionName : user_init * Description : entry of user application, init user function here * Parameters : none * Returns : none *******************************************************************************/ void user_init(void) { uart_init_new(); printf("SDK version:%s\n", system_get_sdk_version()); // Config pin as GPIO5 PIN_FUNC_SELECT (PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5); xTaskCreate(task2, "tsk2", 256, NULL, 2, NULL); } I also post the flash command, the first executed one time, the second every time I modify the code: c:/Espressif/utils/ESP8266/esptool.exe -p COM3 write_flash -ff 40m -fm qio -fs 32m 0x3FC000 c:/Espressif/ESP8266_RTOS_SDK/bin/esp_init_data_default.bin 0x3FE000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin 0x7E000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin c:/Espressif/utils/ESP8266/esptool.exe -p COM3 -b 256000 write_flash -ff 40m -fm qio -fs 32m 0x00000 firmware/eagle.flash.bin 0x40000 firmware/eagle.irom0text.bin There is something wrong? I really don't understand why it doesn't work. When I try the NON-OS example they works very well.
I had the same problem as you. This issue is caused by the incorrect address of the eagle.irom0text.bin . So I changed the address of the eagle.irom0text.bin from 0x40000 (0x10000) to 0x20000 and it worked well for me. [RTOS SDK version: 1.4.2(f57d61a)] The correct flash codes in the common_rtos.mk (ESP-12E) for flashinit flashinit: $(vecho) "Flash init data default and blank data." $(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fc000 $(SDK_BASE)/bin/esp_init_data_default.bin $(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fe000 $(SDK_BASE)/bin/blank.bin for flash: flash: all #ifeq ($(app), 0) $(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin else ifeq ($(boot), none) $(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin else $(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) $(addr) $(FW_BASE)/upgrade/$(BIN_NAME).bin endif endif
Message exchange between Paho java & javascript client not happening
How can I send a message from paho java client to paho javascript client. String topic = "chatWith/904"; String content = "Message from MqttPublishSample"; int qos = 0; String broker = "tcp://127.0.0.1:1883"; String clientId = "JavaSample"; MemoryPersistence persistence = new MemoryPersistence(); try { MqttClient sampleClient = new MqttClient(broker, clientId, persistence); MqttConnectOptions connOpts = new MqttConnectOptions(); connOpts.setCleanSession(true); System.out.println("Connecting to broker: "+broker); sampleClient.connect(connOpts); System.out.println("Connected"); System.out.println("Publishing message: "+content); MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(qos); sampleClient.publish(topic, message); System.out.println("Message published"); sampleClient.disconnect(); System.out.println("Disconnected"); System.exit(0); } catch(MqttException me) { me.printStackTrace(); } Message exchange between two JS client is happening. But between Javasript & java client, message exchange is not happening. Here is JS code client = new Messaging.Client(host, Number(port), clientId); client.onConnect = onConnect; client.onMessageArrived = onMessageArrived; client.onMessageDelivered = onMessageDelivered; client.onConnectionLost = onConnectionLost; var willMessage = createByteMessage({ id: '', 'msgType':'USER_STATUS', 'status': 'Offline', 'senderId': myUserId, 'senderName': myName }, statusTopic); willMessage.retained = true; client.connect({ userName:user, password:password, onSuccess:onConnect, onFailure:onFailure, 'willMessage': willMessage }); Here port is 8083 and mqtt broker is emqtt client.config testclientid0 testclientid1 127.0.0.1 testclientid2 192.168.0.1/24 emqttd.config % -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et [{kernel, [ {start_timer, true}, {start_pg2, true} ]}, {sasl, [ {sasl_error_logger, {file, "log/emqttd_sasl.log"}} ]}, {ssl, [ %{versions, ['tlsv1.2', 'tlsv1.1']} ]}, {lager, [ {colored, true}, {async_threshold, 5000}, {error_logger_redirect, false}, {crash_log, "log/emqttd_crash.log"}, {handlers, [ %%{lager_console_backend, info}, %%NOTICE: Level >= error %%{lager_emqtt_backend, error}, {lager_file_backend, [ {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]}, {file, "log/emqttd_error.log"}, {level, error}, {size, 104857600}, {date, "$D0"}, {count, 30} ]} ]} ]}, {esockd, [ {logger, {lager, error}} ]}, {emqttd, [ %% Authentication and Authorization {access, [ %% Authetication. Anonymous Default {auth, [ %% Authentication with username, password %{username, []}, %% Authentication with clientid %{clientid, [{password, no}, {file, "etc/clients.config"}]}, %% Authentication with LDAP % {ldap, [ % {servers, ["localhost"]}, % {port, 389}, % {timeout, 30}, % {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, % {ssl, fasle}, % {sslopts, [ % {"certfile", "ssl.crt"}, % {"keyfile", "ssl.key"}]} % ]}, %% Allow all {anonymous, []} ]}, %% ACL config {acl, [ %% Internal ACL module {internal, [{file, "etc/acl.config"}, {nomatch, allow}]} ]} ]}, %% MQTT Protocol Options {mqtt, [ %% Packet {packet, [ %% Max ClientId Length Allowed {max_clientid_len, 512}, %% Max Packet Size Allowed, 64K default {max_packet_size, 65536} ]}, %% Client {client, [ %% Socket is connected, but no 'CONNECT' packet received {idle_timeout, 30} %% seconds ]}, %% Session {session, [ %% Max number of QoS 1 and 2 messages that can be “in flight” at one time. %% 0 means no limit {max_inflight, 100}, %% Retry interval for redelivering QoS1/2 messages. {unack_retry_interval, 60}, %% Awaiting PUBREL Timeout {await_rel_timeout, 20}, %% Max Packets that Awaiting PUBREL, 0 means no limit {max_awaiting_rel, 0}, %% Statistics Collection Interval(seconds) {collect_interval, 0}, %% Expired after 2 day (unit: minute) {expired_after, 2880} ]}, %% Queue {queue, [ %% simple | priority {type, simple}, %% Topic Priority: 0~255, Default is 0 %% {priority, [{"topic/1", 10}, {"topic/2", 8}]}, %% Max queue length. Enqueued messages when persistent client disconnected, %% or inflight window is full. {max_length, infinity}, %% Low-water mark of queued messages {low_watermark, 0.2}, %% High-water mark of queued messages {high_watermark, 0.6}, %% Queue Qos0 messages? {queue_qos0, true} ]} ]}, %% Broker Options {broker, [ %% System interval of publishing broker $SYS messages {sys_interval, 60}, %% Retained messages {retained, [ %% Expired after seconds, never expired if 0 {expired_after, 0}, %% Max number of retained messages {max_message_num, 100000}, %% Max Payload Size of retained message {max_playload_size, 65536} ]}, %% PubSub and Router {pubsub, [ %% Default should be scheduler numbers {pool_size, 8}, %% Store Subscription: true | false {subscription, true}, %% Route aging time(seconds) {route_aging, 5} ]}, %% Bridge {bridge, [ %%TODO: bridge queue size {max_queue_len, 10000}, %% Ping Interval of bridge node {ping_down_interval, 1} %seconds ]} ]}, %% Modules {modules, [ %% Client presence management module. %% Publish messages when client connected or disconnected {presence, [{qos, 0}]}, %% Subscribe topics automatically when client connected {subscription, [ %% $c will be replaced by clientid %% {"$queue/clients/$c", 1}, %% Static subscriptions from backend backend ]} %% Rewrite rules %% {rewrite, [{file, "etc/rewrite.config"}]} ]}, %% Plugins {plugins, [ %% Plugin App Library Dir {plugins_dir, "./plugins"}, %% File to store loaded plugin names. {loaded_file, "./data/loaded_plugins"} ]}, %% Listeners {listeners, [ {mqtt, 1883, [ %% Size of acceptor pool {acceptors, 16}, %% Maximum number of concurrent clients {max_clients, 512}, %% Socket Access Control {access, [{allow, all}]}, %% Connection Options {connopts, [ %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec %% {rate_limit, "100,10"} %% 100K burst, 10K rate ]}, %% Socket Options {sockopts, [ %Set buffer if hight thoughtput %{recbuf, 4096}, %{sndbuf, 4096}, %{buffer, 4096}, %{nodelay, true}, {backlog, 1024} ]} ]}, {mqtts, 8883, [ %% Size of acceptor pool {acceptors, 4}, %% Maximum number of concurrent clients {max_clients, 512}, %% Socket Access Control {access, [{allow, all}]}, %% SSL certificate and key files {ssl, [{certfile, "etc/ssl/ssl.crt"}, {keyfile, "etc/ssl/ssl.key"}]}, %% Socket Options {sockopts, [ {backlog, 1024} %{buffer, 4096}, ]} ]}, %% WebSocket over HTTPS Listener %% {https, 8083, [ %% %% Size of acceptor pool %% {acceptors, 4}, %% %% Maximum number of concurrent clients %% {max_clients, 512}, %% %% Socket Access Control %% {access, [{allow, all}]}, %% %% SSL certificate and key files %% {ssl, [{certfile, "etc/ssl/ssl.crt"}, %% {keyfile, "etc/ssl/ssl.key"}]}, %% %% Socket Options %% {sockopts, [ %% %{buffer, 4096}, %% {backlog, 1024} %% ]} %%]}, %% HTTP and WebSocket Listener {http, 8083, [ %% Size of acceptor pool {acceptors, 4}, %% Maximum number of concurrent clients {max_clients, 64}, %% Socket Access Control {access, [{allow, all}]}, %% Socket Options {sockopts, [ {backlog, 1024} %{buffer, 4096}, ]} ]} ]}, %% Erlang System Monitor {sysmon, [ %% Long GC, don't monitor in production mode for: %% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421 {long_gc, false}, %% Long Schedule(ms) {long_schedule, 240}, %% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM. %% 8 * 1024 * 1024 {large_heap, 8388608}, %% Busy Port {busy_port, false}, %% Busy Dist Port {busy_dist_port, true} ]} ]} ].
OpenCV error when running make CentOS
I am trying to install OpenCV 2.4.2 on CentOS 5.8 but I get the following error [ 34%] Built target opencv_test_highgui [ 34%] Building CXX object modules/features2d/CMakeFiles/opencv_features2d.dir/src/freak.cpp.o /home/jtrinidad/Downloads/OpenCV-2.4.2/modules/core/include/opencv2/core/core.hpp:1286: warning: ‘class cv::_InputArray’ has virtual functions but non-virtual destructor /home/jtrinidad/Downloads/OpenCV-2.4.2/modules/core/include/opencv2/core/core.hpp:1365: warning: ‘class cv::_OutputArray’ has virtual functions but non-virtual destructor /home/jtrinidad/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp: In member function ‘virtual void cv::FREAK::computeImpl(const cv::Mat&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::Mat&) const’: /home/jtrinidad/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp:367: error: shift must be an immediate make[2]: *** [modules/features2d/CMakeFiles/opencv_features2d.dir/src/freak.cpp.o] Error 1 make[1]: *** [modules/features2d/CMakeFiles/opencv_features2d.dir/all] Error 2 make: *** [all] Error 2 I ran the following command on cmake cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_EXAMPLES=OFF WITH_CUDA=OFF .. Thank you.
The problem was resolved. I applied the following patch to ~/Downloads/OpenCV-2.4.2/modules/features2d/src/freak.cpp diff -crB OpenCV-2.4.2.orig/modules/features2d/src/freak.cpp OpenCV-2.4.2/modules/features2d/src/freak.cpp *** OpenCV-2.4.2.orig/modules/features2d/src/freak.cpp 2012-07-25 09:54:50.000000000 -0400 --- OpenCV-2.4.2/modules/features2d/src/freak.cpp 2012-07-24 10:34:57.000000000 -0400 *************** *** 364,370 **** __m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers workReg = _mm_cmpeq_epi8(workReg, operand2); // emulated "not less than" for 8-bit UNSIGNED integers ! workReg = _mm_and_si128(_mm_srli_epi16(binMask, m), workReg); // merge the last 16 bits with the 128bits std::vector until full result128 = _mm_or_si128(result128, workReg); } (*ptr) = result128; --- 364,404 ---- __m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers workReg = _mm_cmpeq_epi8(workReg, operand2); // emulated "not less than" for 8-bit UNSIGNED integers ! // merge the last 16 bits with the 128bits std::vector until full ! __m128i shiftedMask; ! switch(m) { ! case 8: ! shiftedMask = _mm_srli_epi16(binMask, 8); ! break; ! case 7: ! shiftedMask = _mm_srli_epi16(binMask, 7); ! break; ! case 6: ! shiftedMask = _mm_srli_epi16(binMask, 6); ! break; ! case 5: ! shiftedMask = _mm_srli_epi16(binMask, 5); ! break; ! case 4: ! shiftedMask = _mm_srli_epi16(binMask, 4); ! break; ! case 3: ! shiftedMask = _mm_srli_epi16(binMask, 3); ! break; ! case 2: ! shiftedMask = _mm_srli_epi16(binMask, 2); ! break; ! case 1: ! shiftedMask = _mm_srli_epi16(binMask, 1); ! break; ! case 0: ! shiftedMask = _mm_srli_epi16(binMask, 0); ! break; ! default: ! throw "shifting less than 0"; ! } ! workReg = _mm_and_si128(shiftedMask, workReg); ! result128 = _mm_or_si128(result128, workReg); } (*ptr) = result128;
This full patch file: http://code.opencv.org/projects/opencv/repository/revisions/65f85856306575e4d71164c8212e84d26424cf0f
After trying to use patches, I resorted to compile freak.cpp manually. My notes on the installation are available here: http://www.megalinux.net/compiling-opencv-2-4-on-rhelcentos-5/