Page 1 of 1

mjpg-streamer slow frame rate - how do I improve it

Posted: Thu Aug 27, 2015 6:54 am
by JonnyAlpha
Hi;

For a web controlled robot I am trying to use mjpg-streamer however the frame rate is very poor and I need to improve it.
I installed it using Jacom Salmela's guide here:
http://jacobsalmela.com/raspberry-pi-we ... -internet/

I am using a Logitech C270 USB WebCam

When researching how to improve the frame rate I found this guide by Wolf Paulus's guide, in the comments, towards the bottom, a user (Asif1924 on April 19, 2015 at 12:43 am) has commented that mjpg-stremer no longer works under later releases of Raspian without using the -y option (which invokes YUYV) , however using the -y option does not allow faster frame rates hence the unusable lag!!!

My latest command for running mjpeg-streamer is:

/usr/local/bin/mjpg_streamer -i "/usr/local/lib/input_uvc.so -y -f 15 -r 640x480 /dev/video0" -o "/usr/local/lib/output_http.so -w /usr/local/www"

Does anyone know of a fix to improve the frame rate to say 15fps or an alternative video low CPU usage streamer that can be streamed to a web page and used for real time control?



Many thanks

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Fri Aug 28, 2015 6:26 pm
by JonnyAlpha
No takers?

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Fri Aug 28, 2015 6:50 pm
by danjperron
The problem is maybe not the camera but the network link.

This is the link to fix mjpeg streamer
viewtopic.php?p=751735#p751735

I have my small robot with a c-270 and it is around 20fps at 1024x576 but on the internet it could drop down to 2.5 fps with a slow speed connection.

B.T.W. I put the rate at 10fps since I use the internet mostly.

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sat Aug 29, 2015 8:49 am
by JonnyAlpha
Dan;

You are absolute legend, I knew there would be a solution, just couldn't find it :-)

Many thanks

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sat Aug 29, 2015 12:26 pm
by danjperron
Well I'm not the guy who did it. I think I had the information on the same subject post but early on.

The guys on this February post should take the credit!
viewtopic.php?p=686670#p686670

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sat Aug 29, 2015 5:53 pm
by JonnyAlpha
No worries and thanks all the same.

Using the info in the link you supplied earlier I now have a very useable frame rate, couldn't view the web page at first but then I noticed in the streamer.sh script the port was changed to 10080.

Incidentally what does the '&' do at the end of the command?

I now need to change my WebIOPi .html page to reflect the new command.

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sat Aug 29, 2015 6:25 pm
by DougieLawson
JonnyAlpha wrote: Incidentally what does the '&' do at the end of the command?
It makes the shell put the new task into the background so it continues to run even when you start doing something else.

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sun Aug 30, 2015 1:49 am
by danjperron
This is my webpage to control my Robot. I'm using webiopi also.

I use a pololu servo instead of the Pi. I should change it but it is like that since 2013.

This is webpage using webioPI.
P.S. I changed my IP ! Just put yours.

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content = "height = device-height, width = 1280, user-scalable = no" /> 
	<title>WebRobot</title>
	<script type="text/javascript" src="/webiopi.js"></script>
	<script type="text/javascript">

        function init() {
        }


        function Stop() {
                webiopi().callMacro("Stop");
        }

        function Forward() {
                webiopi().callMacro("Forward");
        }


        function Reverse() {
               webiopi().callMacro("Reverse");
        }

        function TurnLeft() {
               webiopi().callMacro("TurnLeft");
        }

        function TurnRight() {
               webiopi().callMacro("TurnRight");
        }
     


        function Play1() {
                webiopi().callMacro("Play1");
        }

        function Play2() {
                webiopi().callMacro("Play2");
        }

        function Play3() {
                webiopi().callMacro("Play3");
        }

        function Play4() {
                webiopi().callMacro("Play4");
        }

        function Play5() {
                webiopi().callMacro("Play5");
        }

        function Play6() {
                webiopi().callMacro("Play6");
        }

        function Play7() {
                webiopi().callMacro("Play7");
        }

        function Play8() {
                webiopi().callMacro("Play8");
        }

        function Play9() {
                webiopi().callMacro("Play9");
        }

        function CloseJaw() {
                webiopi().callMacro("CloseJaw");
        }

        function OpenJaw() {
                webiopi().callMacro("OpenJaw");
        }
	
	function CameraUp() {
		webiopi().callMacro("CameraUp");
	}
		
	function CameraHome() {
		webiopi().callMacro("CameraHome");
	}
		
	function CameraDown() {
		webiopi().callMacro("CameraDown");
	}
		
	function CameraLeft() {
		webiopi().callMacro("CameraLeft");
	}
		
	function CameraRight() {
		webiopi().callMacro("CameraRight");
	}
	
       webiopi().ready(init);
		
	</script>
	<style  type="text/css">
		button.small {
			margin: 1px 1px 1px 1px;
			width: 24px;
			height: 24px;
			font-size: 12pt;
			font-weight: bold;
			color: black;
		}

		button   {
			margin: 1px 1px 1px 1px;
			width: 90px;
			height: 24px;
			font-size: 12pt;
			font-weight: bold;
			color: black;
		}
	</style>



</head>
<body>
	<div id="content" align="center">
		<img width="800" height="450" src="http://MyInternetIP:10088/?action=stream"><br/>
                <table width="800" border=2>
                <tr height="10px" margin=0><center><td><center> Moteur</center></td><td><center>Pince</center></td><td><center>Cam&eacute;ra</center></td><td><center>Son</center></td></tr>
                <tr><td>
                <center>
                <table>
                <tr><td colspan=3 align="center"><button class="long" type="button" onmousedown="Forward()" onmouseup="Stop()">Avancer</button></td></tr>
                <tr><td><button type="button" onmousedown="TurnLeft()" onmouseup="Stop()">Gauche</button></td>
                    <td><button type="button" onclick="Stop()">Stop</button></td>
                    <td><button type="button" onmousedown="TurnRight()" onmouseup="Stop()">Droite</button></td></tr>
                <tr><td colspan=3 align="center"><button type="button" onmousedown="Reverse()" onmouseup="Stop()">Reculer</button></td></tr>
                </table>
                </center>
                 </td>
                <td>
                <centre>
                <table><tr><td><button type="button" onmousedown="OpenJaw()">Ouvrir</button></td></tr>
                       <tr><td><button type="button" onmousedown="CloseJaw()">Fermer</button></td></tr>
                </table>
                <centre>
               </td>
                <td>
                <center>
                <table>
                <tr><td colspan=3 align="center"><button type="button" onmousedown="CameraUp()">Haut</button></td></tr>
                <tr><td><button type="button" onmousedown="CameraLeft()">Gauche</button></td> 
                    <td><button type="button" onmousedown="CameraHome()">Centre</button></td>          
                    <td><button type="button" onmousedown="CameraRight()">Droite</button></td></tr>
                <tr><td colspan=3 align="center"><button type="button" onmousedown="CameraDown()">Bas</button></td></tr>
                </table>
                </center>
                </td>
                <td>
                <centre>
                <table>
                <tr>
                <td><button class="small" type="button" onmousedown="Play1()">1</button></td>
                <td><button class="small" type="button" onmousedown="Play2()">2</button></td>
                <td><button class="small" type="button" onmousedown="Play3()">3</button></td>
                </tr>
                <tr>
                <td><button class="small" type="button" onmousedown="Play4()">4</button></td>
                <td><button class="small" type="button" onmousedown="Play5()">5</button></td>
                <td><button class="small" type="button" onmousedown="Play6()">6</button></td>
                </tr>
                <tr>
                <td><button class="small" type="button" onmousedown="Play7()">7</button></td>
                <td><button class="small" type="button" onmousedown="Play8()">8</button></td>
                <td><button class="small" type="button" onmousedown="Play9()">9</button></td>
                </tr>
                </table>
                </centre>
                </table>
	</div>
</body>
</html>
The python code

Code: Select all

#!/usr/bin/env python3
from time import sleep
import webiopi
import RPi.GPIO as GPIO
from select import select   
import serial
import ossaudiodev
import wave
from threading import Thread

out = serial.Serial('/dev/ttyAMA0',38400)


CamX = int(3000)
CamY = int(3000)

#set io pin

EnA = 11
EnB = 15
Out1 = 24
Out2 = 21
Out3 = 19
Out4 = 23

GPIO.setmode(GPIO.BOARD)




def Forward():
   GPIO.output(Out1,True)
   GPIO.output(Out3,True)
   GPIO.output(Out2,False)
   GPIO.output(Out4,False)
   GPIO.output(EnA,True)
   GPIO.output(EnB,True)

def Stop():
   GPIO.output(Out1,False)
   GPIO.output(Out3,False)
   GPIO.output(Out2,False)
   GPIO.output(Out4,False)
   GPIO.output(EnA,True)
   GPIO.output(EnB,True)

def Standby():
   GPIO.output(Out1,False)
   GPIO.output(Out3,False)
   GPIO.output(Out2,False)
   GPIO.output(Out4,False)
   GPIO.output(EnA,False)
   GPIO.output(EnB,False)

def Reverse():
   GPIO.output(Out2,True)
   GPIO.output(Out4,True)
   GPIO.output(Out1,False)
   GPIO.output(Out3,False)
   GPIO.output(EnA,True)
   GPIO.output(EnB,True)

def TurnRight():
   GPIO.output(Out1,True)
   GPIO.output(Out3,False)
   GPIO.output(Out2,False)
   GPIO.output(Out4,True)
   GPIO.output(EnA,True)
   GPIO.output(EnB,True)

def TurnLeft():
   GPIO.output(Out1,False)
   GPIO.output(Out3,True)
   GPIO.output(Out2,True)
   GPIO.output(Out4,False)
   GPIO.output(EnA,True)
   GPIO.output(EnB,True)


def ServoSpeed(id , speed):
 mystring ='\x80\x01\x01' + chr(id) + chr(speed)
 out.write(bytes(mystring,'iso-8859-1'))
 print("Servo ",id,"speed = ",id,speed)

def ServoSleep(id):
 mystring = '\x80\x01\x00' + chr(id) + chr(15)
 out.write(bytes(mystring,'iso-8859-1'))
 print("Servo ",id," to sleep")

def Servo( id , ServoPosition):
 mystring = '\x80\x01\x04' + chr(id) + chr(ServoPosition >>7) + chr(ServoPosition & 0x7f)
 out.write(bytes(mystring,'iso-8859-1'))
 print("Servo ",id," = ",ServoPosition)
def CloseJaw():
 Servo(2,4400)

def OpenJaw():
 Servo(2,1000)

def play(filename):
  sound_file = wave.open(filename,'rb')
  #print("getting parameters")
  (nc, sw, fr, nf, comptype, compname) = sound_file.getparams()

  #print("parameters were",  (nc, sw, fr, nf, comptype, compname))
  sound = ossaudiodev.open('w')

  sound.setparameters(ossaudiodev.AFMT_S16_NE, nc, fr)
  data = sound_file.readframes(nf)
  sound_file.close()
  sound.write(data)
  sound.close()




   
def Play1():
   thread = Thread(target = play, args=("ialert.wav",))
   thread.start()

def Play2():
   thread = Thread(target = play, args=("tos-redalert.wav",))
   thread.start()

def Play3():
   thread = Thread(target = play, args=("s3.wav",))
   thread.start()

def Play4():
   thread = Thread(target = play, args=("s4.wav",))
   thread.start()

def Play5():
   thread = Thread(target = play, args=("s5.wav",))
   thread.start()

def Play6():
   thread = Thread(target = play, args=("s6.wav",))
   thread.start()

def Play7():
   thread = Thread(target = play, args=("s7.wav",))
   thread.start()

def Play8():
   thread = Thread(target = play, args=("s8.wav",))
   thread.start()

def Play9():
   thread = Thread(target = play , args=("s9.wav",))
   thread.start()


#============ MAIN ==============
homeX = 2800
homeY = 3000
CamX = homeX
CamY = homeY

def CameraSet():
   global CamX
   global CamY
   Servo(0, CamX+70)
   Servo(1, CamY)

def CameraUp():
   global CamX
   global CamY
   CamY=CamY + 100
   if CamY > 3600:
      CamY = 3600
   CameraSet()

def CameraDown():
   global CamX
   global CamY
   CamY=CamY - 100
   if CamY < 2200:
      CamY = 2200
   CameraSet()

def CameraLeft():
   global CamX
   global CamY
   CamX = CamX - 200
   if CamX < 800:
      CamX = 800
   CameraSet()

def CameraRight():
   global CamX
   global CamY
   CamX = CamX + 200
   if CamX > 4800:
      CamX = 4800
   CameraSet()

def CameraHome():
   global CamX
   global CamY
   CamX = homeX
   CamY = homeY
   CameraSet()   

def CameraStop():
   CameraSet()


CameraSet()
ServoSpeed(0,32)
ServoSpeed(1,32)

GPIO.setmode(GPIO.BOARD)

# set enable a as output
GPIO.setup(EnA,GPIO.OUT)
GPIO.output(EnA, False)

#set enable b as output

GPIO.setup(EnB,GPIO.OUT)
GPIO.output(EnB, False)


#set enable out 1,2,3 and 4  as output

GPIO.setup(Out1,GPIO.OUT)
GPIO.setup(Out2,GPIO.OUT)
GPIO.setup(Out3,GPIO.OUT)
GPIO.setup(Out4,GPIO.OUT)


GPIO.output(Out1,False)
GPIO.output(Out2,False)
GPIO.output(Out3,False)
GPIO.output(Out4,False)


server = webiopi.Server(
            port=8000,
            login="robot",
            password="r2d2")


server.addMacro(Forward)
server.addMacro(Stop)
server.addMacro(Reverse)
server.addMacro(TurnRight)
server.addMacro(TurnLeft)
server.addMacro(OpenJaw)
server.addMacro(CloseJaw)
server.addMacro(CameraHome)
server.addMacro(CameraUp)
server.addMacro(CameraDown)
server.addMacro(CameraLeft)
server.addMacro(CameraRight)
server.addMacro(CameraStop)
server.addMacro(Play1)
server.addMacro(Play2)
server.addMacro(Play3)
server.addMacro(Play4)
server.addMacro(Play5)
server.addMacro(Play6)
server.addMacro(Play7)
server.addMacro(Play8)
server.addMacro(Play9)


webiopi.runLoop()
server.stop()
I change /etc/webiopi/config with the web folder directory and the script

Code: Select all

...
...
[SCRIPTS]
myscript = /usr/local/bin/webrobot/webrobot.py

...

[HTTP]

...
doc-root = /usr/local/bin/webrobot
and this is the webpage
Image

A small block diagram of my robot
Image

I do have a Pi A inside but I think I will redo the robot with a B+ and remove the USB hub, the Pololu servo. My usb battery pack has the battery cell inflated since it is always on for more than 2.5 years now . Also I will replace the L923 motor driver for some power mosfet driver to reduce power lost.

P.S. I do have a speaker on the robot if you wonder why is the keypad on the right. I just added snd_pcm_oss in /etc/modules.

Re: mjpg-streamer slow frame rate - how do I improve it

Posted: Sat Sep 12, 2015 8:16 pm
by JonnyAlpha
Dan;

Sorry for the late reply, this is all up and running now with an excellent frame rate.
Lots more to improve though :-)