Project

General

Profile

Actions

Bug #829

closed

Hi-res is not working

Added by Hammel about 3 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Immediate
Assignee:
Start date:
26 Mar 2021
Due date:
% Done:

100%

Estimated time:
Severity:
01 - Critical

Description

The following command works for low res:
mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 256x144 -f 4" -o "output_http.so -p 9090"

The following command works for high res:
mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 640x480 -f 33" -o "output_http.so -p 9090"

This is the current config for high res:
mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 640x480 -f 10" -o "output_http.so -p 9090"

It should work. But it will fail if the old mjpeg_streamer is running. So the problem may be that the low-res is still running when we try to switch to the high-res.

Actions #1

Updated by Hammel about 3 years ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 10

Need to add some programmatic upkeep here.
See https://gist.github.com/tugstugi/2627647

This will allow me to query the device and do some setup before creating the hi-res/low-res instance of mjpeg-streamer.

Actions #2

Updated by Hammel about 3 years ago

This may be a more general problem. I can't get the webcam to work at all with pisentry.

I need to retest a full media system build and check that the webcam is really working (on the web interface).
I need to add more debug - is the php message getting to piboxd? Is it the right message? Is piboxd not adding inbound to the queue? Is the message getting lost on the queue?

Actions #3

Updated by Hammel about 3 years ago

  • % Done changed from 10 to 20

It seems that the init script now starts piboxd with -I and -S. The latter disables streams. Taking that out (manually) seemed to let the video stream just fine.

The question is: why did that get added? And why?

Actions #4

Updated by Hammel about 3 years ago

  • % Done changed from 20 to 80

It was a mistake, based on tests for piplayer. This has been fixed now.
Changes committed, tested and pushed.
Still needs to be tested with pisentry just to be sure.

Actions #5

Updated by Hammel about 3 years ago

  • % Done changed from 80 to 60

Hi-Res is still not working in the webui. It starts in low-res mode but switching to hi-res fails.

Actions #6

Updated by Hammel about 3 years ago

The problem is that sometimes mjpg_streamer doesn't start. I don't know why. Nor do I know how to get any additional information as to why it doesn't start.

Actions #7

Updated by Hammel almost 3 years ago

Just thought of this, but maybe I should switch from mjpg_streamer to ffmpeg. That might provide better results.

I need to experiment with using ffmpeg to stream a webcam. Some references:
  1. https://trac.ffmpeg.org/wiki/StreamingGuide
  2. https://www.rickmakes.com/streaming-an-ip-camera-to-a-web-browser-using-ffmpeg/
    1. https://www.youtube.com/watch?v=ztjT2YqQ2Hc
  3. http://4youngpadawans.com/stream-camera-video-and-audio-with-ffmpeg/
  4. https://yushulx.medium.com/raspberry-pi-live-streaming-with-usb-webcam-bbc5f2380b3f
  5. https://quincyhuang.io/2019/11/21/ffmpeg-hls/
  6. http://trac.gateworks.com/wiki/linux/v4l2

Question: Can we control the stream on the fly using v4l2-ctrl? A quick experiment shows this:

Set resolution and format

v4l2-ctl -d /dev/video2 -vwidth=1920,height=1080,pixelformat=YUYV

Play the video

ffplay -i /dev/video2

The pixelformat may not be needed as I can set it with ffmpeg directly. In other words, instead of adjusting the ffmpeg command I can simply adjust resolution with v4l2-ctl and then use the same ffmpeg command every time. Not sure if that's cleaner than what I have now, though by using v4l2-ctl I can use popen to run the command and find out if it works before starting the stream.

Actions #8

Updated by Hammel almost 3 years ago

This works with VLC, but only because it can play from a UDP stream.

ffmpeg -f v4l2 -i /dev/video2 -profile:v high -pix_fmt yuvj420p -level:v 4.1 -preset ultrafast -tune zerolatency -vcodec libx264 -r 10 -b:v 512k -s 640x360 -f mpegts -flush_packets 0 udp://192.168.101.4:5000?pkt_size=1316

The IP address has to be the local hosts address where ffmpeg is run.

Actions #9

Updated by Hammel almost 3 years ago

I've experimented with both mjpeg_streamer and ffmpeg. The latter doesn't stream as easily as mjpeg-streamer but does handle input and output formats managed via v4l2-ctl better. mjpeg-streamer doesn't honor v4l2 changes to the device. So the only choice is to relaunch mjpeg-streamer with different resolution settings.

That means a better understanding of why relaunching the process doesn't always work.

Actions #10

Updated by Hammel almost 3 years ago

I have an update to piboxd/stream.c that waits for the process to really start by stat'ing it's /proc/<pid> directory. If that doesn't work it returns an error.

This should be extended in queueProcessor.c to put the request back on the queue to be tried again, with a max-tries option added. Right now there are other assumptions on what to do if the process doesn't start, like just updating the timestamp.

Actions #11

Updated by Hammel almost 3 years ago

  • Severity changed from 03 - Medium to 01 - Critical
Actions #12

Updated by Hammel almost 3 years ago

Code has been updated and is ready for testing. Build a media system and test the webcam via piboxwww.

Actions #13

Updated by Hammel almost 3 years ago

Doesnt work. A mjpg-streamer process is launched but never killed.

There has to be a better way.

Actions #14

Updated by Hammel over 2 years ago

I lost the changes I was experimenting with when my desktop fried. However, it doesn't look like they worked anyway.

This problem may have been more related to the apps, specifically the picam app. It wasn't exiting cleanly, but that's now been fixed.
However, the problem with the webui still needs to be addressed. I need to test this on the media system so I can more easily watch what is happening with webui requests.

Actions #15

Updated by Hammel over 2 years ago

I've tested the webui on pisentry. Low res starts the first time just fine. Switching to high res didn't work the first time. So I swapped back and forth a few times. Sometimes high res started and played. Sometimes it started and froze. Low-res didn't always work either: sometimes it played and sometimes it doesn't.

So, while it can work, it doesn't work consistently.

There is also a white bar flashed at the bottom of the webui video window that doesn't show on the console webcam. This is likely something to do with the way I setup the video playback in the browser. But that's not related to this so I'm not going to worry about it for now (just write up another issue for it).

Actions #16

Updated by Hammel over 2 years ago

  • Severity changed from 01 - Critical to 05 - Very Low
Actions #17

Updated by Hammel over 2 years ago

I'm wondering if the problem might actually be on the front end, in the javascript for the video page. In lowres(), for example, we might do this instead to stop the first video instance and then start a new one.

lowres() {
    jQuery.get("/php/pibox.php?function=teardown&tag=[TAG]");
    setTimeout( function() {
            window.location.href = '/php/pibox.php?function=webcam&res=low&tag=[TAG]';
        }, 3000);
    }

This would teardown the video stream, which tells piboxd to stop mjpeg-streamer, then waits 3 seconds before it tries to restart in lowres mode. The hires variation would be just like this.

The benefit of this is that the front end can request stopping the stream before requesting restarting it, which saves piboxd from having to kill and wait for mjpeg-streamer to stop before it starts again.

Actions #18

Updated by Hammel about 2 years ago

  • Severity changed from 05 - Very Low to 01 - Critical
Actions #19

Updated by Hammel about 2 years ago

  • % Done changed from 60 to 80

Yup - that seems to have fixed it. I first retested without the fix on my desktop with the Pi connected over ethernet and ran into the original problem - dropped video stream when switching between hi and low resolutions. With the fix, I can now switch between the two with never a failed video display. I increased the delay to 5 seconds to be completely safe. It would be better if there was a synchronization that could happen here but short of using websockets I think this method is just fine.

I've tested on my desktop with the webcam connected over ethernet. I need to test it over wifi on the Pi to be certain that covers it too.

Actions #20

Updated by Hammel about 2 years ago

Ugh. I tried to reach the server from my wifi laptop to the eth-connected Pi and it's not working well. The initial stream plays. But switching to the alternative resolution doesn't complete.

So I increased the artificial delay to 10 seconds. That works most of the time (only 1 failure so far).

Actions #21

Updated by Hammel about 2 years ago

Left it running in hires for awhile. Switched to lowres and got the broken file icon. Tried to switch back to hires, same thing. Exited, restarted, got the same thing.

So while this method helps, it's not a complete solution.

Next, I'm going to try ustreamer.

Actions #22

Updated by Hammel about 2 years ago

  • Status changed from In Progress to Closed
  • % Done changed from 80 to 100

Ustreamer doesn't work. It has bugs. Googling around there really isn't a better solution than mjpeg-streamer for this use case. Some people use gstreamer but that doesn't quite stream like mjpeg-streamer does.

So I dug around the code a bit and found that I can set numerous display resolutions by name. I've added those to libpibox and piboxd. I've change the default lowres to CGA and made SXGA for high res. Medium res is VGA and Full res is now FHD (full HD). The UI is updated to provide for all four resolutions. Picam will just use the default Hi res.

I've also tested streaming on multiple browsers and via mplayer using the following command:

mplayer -fps 30 -demuxer lavf "http://192.168.101.73:9090/?action=stream&ignored.mjpg"

On all browsers there is data loss at different rates that cause the bottom line(s) of the video to go black (on Chrome) or white (on Firefox). Playing the same stream on mplayer there is no data loss and no black/white lines at the bottom of the video. So the problem seems to be the browsers. I'm not going to try and fix that, though I did try most of the options for the input_uvc plugin for mjpeg_streamer.

All changes tested, committed and pushed.

Closing issue.

Actions

Also available in: Atom PDF