User avatar
JonnyAlpha
Raspberry Pi Certified Educator
Raspberry Pi Certified Educator
Posts: 572
Joined: Sat Nov 02, 2013 2:06 pm

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

Thu Aug 27, 2015 6:54 am

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
Raspberry Pi Certified Educator. Main Hardware - Raspberry Pi 1 model B revision 2, Raspberry Pi 2 model B, Pi Camera

User avatar
JonnyAlpha
Raspberry Pi Certified Educator
Raspberry Pi Certified Educator
Posts: 572
Joined: Sat Nov 02, 2013 2:06 pm

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

Fri Aug 28, 2015 6:26 pm

No takers?
Raspberry Pi Certified Educator. Main Hardware - Raspberry Pi 1 model B revision 2, Raspberry Pi 2 model B, Pi Camera

danjperron
Posts: 3508
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

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

Fri Aug 28, 2015 6:50 pm

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.

User avatar
JonnyAlpha
Raspberry Pi Certified Educator
Raspberry Pi Certified Educator
Posts: 572
Joined: Sat Nov 02, 2013 2:06 pm

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

Sat Aug 29, 2015 8:49 am

Dan;

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

Many thanks
Raspberry Pi Certified Educator. Main Hardware - Raspberry Pi 1 model B revision 2, Raspberry Pi 2 model B, Pi Camera

danjperron
Posts: 3508
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

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

Sat Aug 29, 2015 12:26 pm

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

User avatar
JonnyAlpha
Raspberry Pi Certified Educator
Raspberry Pi Certified Educator
Posts: 572
Joined: Sat Nov 02, 2013 2:06 pm

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

Sat Aug 29, 2015 5:53 pm

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.
Raspberry Pi Certified Educator. Main Hardware - Raspberry Pi 1 model B revision 2, Raspberry Pi 2 model B, Pi Camera

User avatar
DougieLawson
Posts: 39297
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

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

Sat Aug 29, 2015 6:25 pm

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.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

danjperron
Posts: 3508
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

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

Sun Aug 30, 2015 1:49 am

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.

User avatar
JonnyAlpha
Raspberry Pi Certified Educator
Raspberry Pi Certified Educator
Posts: 572
Joined: Sat Nov 02, 2013 2:06 pm

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

Sat Sep 12, 2015 8:16 pm

Dan;

Sorry for the late reply, this is all up and running now with an excellent frame rate.
Lots more to improve though :-)
Raspberry Pi Certified Educator. Main Hardware - Raspberry Pi 1 model B revision 2, Raspberry Pi 2 model B, Pi Camera

Return to “HATs and other add-ons”