I am trying to stream video feed from a USB webcam through a Jetson Orin device to an Android phone.
The camera is a standard UVC camera.
I am streaming the feed in python using gstreamer and opencv with the following pipeline:
self.launch_string = 'appsrc name=source is-live=true block=true format=GST_FORMAT_TIME ' \
'caps=video/x-raw, format=YUY2,width=320,height=240,framerate=30/1 ' \
'! videoconvert ! video/x-raw,format=I420,width=320,height=240 ' \
'! x264enc speed-preset=ultrafast tune=zerolatency ' \
'! rtph264pay config-interval=1 name=pay0 pt=96'
and it’s being pushed to the stream with the following code:
ret, frame = self.cap.read()
if ret:
data=frame.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = src.emit('push-buffer', buf)
This works…sort of. I can access the stream in VLC on windows by opening a network stream to “rtsp://:8554/uvcCam” although the image is shaped incorrectly. (see image below) If I change the encoding to h265 I can open the stream on the Jetson and it looks the same.
I have an Android device connected to the Jetson via USB at the USBc port next to the 40-pin header. I can ping the Android device from the Jetson and vice-versa. My Android app has Internet permissions turned on and I am using exoplayer with an RtspMediaSource. When I try to create the connection using the address “rtsp://:8554/uvcCam” Android throws a source error caused by ECONNREFUSED (Connection refused). The full stack trace is below.
E/ExoPlayerImplInternal: Playback error
com.google.android.exoplayer2.ExoPlaybackException: Source error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:644)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:620)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.net.ConnectException: failed to connect to /192.168.62.246 (port 8554) from /:: (port 39018): connect failed: ECONNREFUSED (Connection refused)
at libcore.io.IoBridge.connect(IoBridge.java:187)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:646)
at java.net.Socket.connect(Socket.java:595)
at java.net.Socket.<init>(Socket.java:475)
at java.net.Socket.<init>(Socket.java:243)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:279)
at com.google.android.exoplayer2.source.rtsp.RtspClient.getSocket(RtspClient.java:304)
at com.google.android.exoplayer2.source.rtsp.RtspClient.start(RtspClient.java:198)
at com.google.android.exoplayer2.source.rtsp.RtspMediaPeriod.prepare(RtspMediaPeriod.java:158)
at com.google.android.exoplayer2.source.MaskingMediaPeriod.prepare(MaskingMediaPeriod.java:145)
at com.google.android.exoplayer2.ExoPlayerImplInternal.maybeUpdateLoadingPeriod(ExoPlayerImplInternal.java:2002)
at com.google.android.exoplayer2.ExoPlayerImplInternal.updatePeriods(ExoPlayerImplInternal.java:1982)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:974)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:502)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
at libcore.io.Linux.connect(Native Method)
at libcore.io.ForwardingOs.connect(ForwardingOs.java:201)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:158)
at libcore.io.ForwardingOs.connect(ForwardingOs.java:201)
at libcore.io.IoBridge.connectErrno(IoBridge.java:201)
at libcore.io.IoBridge.connect(IoBridge.java:179)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:646)
at java.net.Socket.connect(Socket.java:595)
at java.net.Socket.<init>(Socket.java:475)
at java.net.Socket.<init>(Socket.java:243)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:279)
at com.google.android.exoplayer2.source.rtsp.RtspClient.getSocket(RtspClient.java:304)
at com.google.android.exoplayer2.source.rtsp.RtspClient.start(RtspClient.java:198)
at com.google.android.exoplayer2.source.rtsp.RtspMediaPeriod.prepare(RtspMediaPeriod.java:158)
at com.google.android.exoplayer2.source.MaskingMediaPeriod.prepare(MaskingMediaPeriod.java:145)
at com.google.android.exoplayer2.ExoPlayerImplInternal.maybeUpdateLoadingPeriod(ExoPlayerImplInternal.java:2002)
at com.google.android.exoplayer2.ExoPlayerImplInternal.updatePeriods(ExoPlayerImplInternal.java:1982)
at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:974)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:502)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.os.HandlerThread.run(HandlerThread.java:67)
I don’t expect to find any Android or exoplayer solutions here, although that would be awesome.
My question is two-fold:
- What am I doing wrong with my stream to cause the distortion in the posted image?
- Are there some permissions that need to be set on the Jetson in order to access the RTSP stream over USB from the USBc port?