How to save incoming h264 stream without re-encoding?
W.A. Garrett Weaver
weaverg at email.arizona.edu
Thu May 24 20:54:09 PDT 2012
I found the solution to the intermittent delay problem. What you have to do
is reduce the latency on gstrtpjitterbuffer to 10ms instead of being 500ms.
gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
port=5010 caps='application/x-rtp, media=(string)video,
clock-rate=(int)90000, encoding-name=(string)H264,
sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
latency=10 ! rtph264depay ! ffdec_h264 ! x264enc ! matroskamux ! filesink
location=movie.mkv
The result is this:
http://www.youtube.com/watch?v=br--9h3-g4U
This works good if the computer on the receiving end is sufficiently fast
enough to compress video, since mine is, this is an adequate solution.
Still, it would be nice to record the h264 stream directly to a file
instead of having to re compress.
On Wed, May 16, 2012 at 2:01 PM, W.A. Garrett Weaver <
weaverg at email.arizona.edu> wrote:
> So here's an update.
>
> All the scripts I ran, and gave results to, in the previous email, were
> all run locally, on one machine.
>
> I tried to use my imperfect, but functional, solution in my real
> application: wireless video streaming from one device to another. It didn't
> work as well as it did when both transmit and receive scripts were running
> on the same machine. The recorded video looked like this:
> http://youtu.be/YfsFI7PlStw
>
> Note: At the edges of reception, when I'm outside my yard, video starts
> getting very pixlated and the framerates drop. That's not really GStreamers
> fault, many of the packets are just getting dropped. I'm most concerned
> with the frame rates when I'm close to my router.
>
> I will say that my display script showed video perfectly smooth on the
> screen, responsively and with a high frame rate, so I don't think there's
> any problems with the network (at close enough range).
>
> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
> port=5010 caps='application/x-rtp, media=(string)video,
> clock-rate=(int)90000, encoding-name=(string)H264,
> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
> seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
> latency=500 ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! coglogoinsert
> location="equisightoverlay.png" ! ffmpegcolorspace ! ximagesink sync=false
>
> But as you can see with the video recording above the video isn't recorded
> linearly. It pushes some frames through quickly, pauses, and then quickly
> pushes frames through again. It seems like all the frames are getting
> recorded, but they're not moving at a consistent pace.
>
> I decided to make some adjustments to the record script to try and reduce
> this effect by increasing the latency of gstrtpjitterbuffer, adding a queue
> before x264enc and setting latency on the x264enc to zero.
>
> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
> port=5010 caps='application/x-rtp, media=(string)video,
> clock-rate=(int)90000, encoding-name=(string)H264,
> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
> seqnum-base=(uint)45576' ! queue ! gstrtpjitterbuffer drop-on-latency=true
> latency=2000 ! rtph264depay ! ffdec_h264 ! queue max-size-buffers=0
> max-size-bytes=0 max-size-time=0 ! x264enc tune=zerolatency ! matroskamux !
> filesink location=video.mkv
>
> The result was this:
> http://youtu.be/x2QbLaImkt0
>
> It looks like it helped make the frame rate a bit more consistent, but not
> by much. Does anyone have any ideas on how to improve the inconsistent
> frame rate problem? I have a hunch it's caused by the x264enc element (or
> lack of using it correctly). Of course if I could sidestep having to
> re-compress the video, this problem would be alleviated. But I'm sure I'm
> missing a major setting somewhere that would solve this problem.
>
> On Wed, May 16, 2012 at 11:28 AM, W.A. Garrett Weaver <
> weaverg at email.arizona.edu> wrote:
>
>> Thank you for the suggestions Rufael and Tiago.
>>
>> I tried writing the H264 stream to an mp4 file with mp4mux. My strategy
>> for developing this receive and write script is to write a single test
>> script is to see if a particular mux can write a file directly from the
>> output of rtph264depay and then, if it works, integrate the mux into the
>> network receive and write script.
>>
>> My test script for writing to an mp4 file was:
>> gst-launch-0.10 v4l2src ! queue ! 'video/x-raw-yuv,width=640,height=480'
>> ! x264enc bitrate=500 speed-preset=superfast tune=zerolatency ! rtph264pay
>> ! rtph264depay ! mp4mux ! filesink location=video.mp4
>>
>> This wrote a file but the file was 0 bytes in size.
>>
>> If you were to take out the "rtph264pay ! rtph264depay" part:
>> gst-launch-0.10 v4l2src ! queue ! 'video/x-raw-yuv,width=640,height=480'
>> ! x264enc bitrate=500 speed-preset=superfast tune=zerolatency ! mp4mux !
>> filesink location=video.mp4
>>
>> It writes a file that takes up space, but when playing the file my media
>> player says it doesn't contain playable streams (I'm closing the script
>> with ctrl + c by the way).
>>
>> When I test the matroskamux element:
>> gst-launch-0.10 v4l2src ! queue ! 'video/x-raw-yuv,width=640,height=480'
>> ! x264enc bitrate=500 speed-preset=superfast tune=zerolatency ! rtph264pay
>> ! rtph264depay ! matroskamux ! filesink location=video.mkv
>>
>> I get a file that is 0 bytes in size.
>>
>> Removing the "rtph264pay ! rtph264depay" part of the script produces a
>> playable file (although the playhead progress is not liner, it starts in
>> the middle and slows down increasingly as it approaches the end of the
>> movie).
>>
>> Adding in "ffdec_h264 ! ffmpegcolorspace" to the script:
>>
>> gst-launch-0.10 v4l2src ! queue ! 'video/x-raw-yuv,width=640,height=480'
>> ! x264enc bitrate=500 speed-preset=superfast tune=zerolatency ! rtph264pay
>> ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! matroskamux ! filesink
>> location=video.mkv
>>
>> Produces a playable (but very large file).
>>
>> Extending this to the network receive script:
>> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
>> port=5010 caps='application/x-rtp, media=(string)video,
>> clock-rate=(int)90000, encoding-name=(string)H264,
>> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
>> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
>> seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
>> latency=500 ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! matroskamux !
>> filesink location=video.mkv
>>
>> Produces a playable, but large file. This "works" but is an ineffective
>> solution because uncompressed video is too large.
>>
>> If I try to add in a x264 encode before the matroskamux, to compress the
>> video, after it has been received:
>> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
>> port=5010 caps='application/x-rtp, media=(string)video,
>> clock-rate=(int)90000, encoding-name=(string)H264,
>> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
>> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
>> seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
>> latency=500 ! rtph264depay ! ffdec_h264 ! x264enc ! matroskamux ! filesink
>> location=video.mkv
>>
>> This produces a playable, compressed video file (although the playhead
>> progress is not liner, it starts in the middle and slows down increasingly
>> as it approaches the end of the movie). But this is an inelegant solution
>> because I needed to decompress, then re compress the video as it comes in.
>>
>> There must be a way to take the incoming H264 stream and write it
>> directly to a file.
>>
>> On Tue, May 15, 2012 at 10:02 AM, Tiago Katcipis <katcipis at inf.ufsc.br>wrote:
>>
>>> Hi,
>>>
>>> On Tue, May 15, 2012 at 8:43 AM, Rufael Mekuria <R.N.Mekuria at cwi.nl>wrote:
>>>
>>>> I don't think its such a good idea to save H.264 to avi, I would
>>>> recommend trying mp4mux and save to mp4 instead,
>>>>
>>>
>>> There is also Matroska:
>>>
>>>
>>> http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-matroskamux.html
>>>
>>> Best regards,
>>> Tiago Katcipis
>>>
>>>
>>>>
>>>> hope it helps, with me this works fine.
>>>>
>>>> best,
>>>>
>>>> Rufael
>>>>
>>>> ----- Oorspronkelijk bericht -----
>>>> Van: "garrett" <weaverg at email.arizona.edu>
>>>> Aan: gstreamer-devel at lists.freedesktop.org
>>>> Verzonden: Dinsdag 15 mei 2012 04:00:28
>>>> Onderwerp: Re: How to save incoming h264 stream without re-encoding?
>>>>
>>>> I'm trying to do the exact same thing. I stumbled upon a heap of
>>>> unanswered
>>>> threads like these on my search, so I'll bump this one because it's most
>>>> similar to what I want to do.
>>>>
>>>> I'm trying to transmit H264 video in RTP packets, over UDP and then on
>>>> the
>>>> receiving end reconvert the packets into an H264 stream and both output
>>>> the
>>>> stream with ximagesink and save the h264 stream into a file.
>>>>
>>>> I can output the live stream to ximagesink just fine. Saving the stream
>>>> is a
>>>> whole different ordeal. No matter what I do, I cannot save a stream to a
>>>> file.
>>>>
>>>> I'll start by posting my transmit script.
>>>> gst-launch-0.10 v4l2src ! queue !
>>>> 'video/x-raw-yuv,width=640,height=480' !
>>>> x264enc bitrate=500 speed-preset=superfast tune=zerolatency ! queue !
>>>> rtph264pay ! udpsink host=224.1.1.1 port=5010 auto-multicast=true
>>>>
>>>> This is my most desired receiving script (it's supposed to both show the
>>>> video in a window and write the video to an avi file):
>>>> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
>>>> port=5010 caps='application/x-rtp, media=(string)video,
>>>> clock-rate=(int)90000, encoding-name=(string)H264,
>>>>
>>>> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
>>>> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
>>>> seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
>>>> latency=500 ! rtph264depay ! tee name=videosrc \
>>>> videosrc. ! queue ! ffdec_h264 ! ffmpegcolorspace ! ximagesink
>>>> sync=false \
>>>> videosrc. ! queue ! avimux ! filesink location=video.avi
>>>>
>>>> Unfortunately that doesn't work, doesn't throw any errors, but it
>>>> doesn't
>>>> bring up the video window nor does it try to write a file. If I take
>>>> out the
>>>> last line (the tee for printing out the file), it does bring up the
>>>> video
>>>> window. If I take out the second to last line (the tee for displaying
>>>> the
>>>> window) it creates the file, but it's zero bytes in size.
>>>>
>>>> My scripts do depend on the elements rtph264pay and rtph264depay which
>>>> are
>>>> poorly documented. I thought that perhaps the output of rtph264depay
>>>> doesn't
>>>> output an h264 format avimux likes. So I ran this script:
>>>> gst-launch-0.10 v4l2src ! queue !
>>>> 'video/x-raw-yuv,width=640,height=480' !
>>>> x264enc bitrate=500 speed-preset=superfast tune=zerolatency !
>>>> rtph264pay !
>>>> rtph264depay ! avimux ! filesink location=video.avi
>>>>
>>>> Which doesn't work, it only writes a file of zero bytes large, but if I
>>>> took
>>>> out the "rtph264pay ! rtph264depay !" part, it works fine. But what's
>>>> more?
>>>> If I add "ffdec_h264 ! ffmpegcolorspace !" between rtph264depay and
>>>> avimux
>>>> it does write a file (albeit a very large file).
>>>>
>>>> But then if I try to run this script as the receive script (just to try
>>>> to
>>>> write a file):
>>>> gst-launch-0.10 udpsrc multicast-group=224.1.1.1 auto-multicast=true
>>>> port=5010 caps='application/x-rtp, media=(string)video,
>>>> clock-rate=(int)90000, encoding-name=(string)H264,
>>>>
>>>> sprop-parameter-sets=(string)\"Z0KAHukBQHpCAAAH0AAB1MAIAA\\=\\=\\,aM48gAA\\=\",
>>>> payload=(int)96, ssrc=(uint)3315029550, clock-base=(uint)3926529534,
>>>> seqnum-base=(uint)45576' ! gstrtpjitterbuffer drop-on-latency=true
>>>> latency=500 ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! tee
>>>> name=videosrc \
>>>> videosrc. ! queue ! avimux ! filesink location=video.avi
>>>>
>>>> It does not work. So what is the deal here? Is there any way to write
>>>> video
>>>> from a h264 stream?
>>>>
>>>> --
>>>> View this message in context:
>>>> http://gstreamer-devel.966125.n4.nabble.com/How-to-save-incoming-h264-stream-without-re-encoding-tp1559487p4633660.html
>>>> Sent from the GStreamer-devel mailing list archive at Nabble.com.
>>>> _______________________________________________
>>>> gstreamer-devel mailing list
>>>> gstreamer-devel at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>>>> _______________________________________________
>>>> gstreamer-devel mailing list
>>>> gstreamer-devel at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>>>>
>>>
>>>
>>> _______________________________________________
>>> gstreamer-devel mailing list
>>> gstreamer-devel at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>>>
>>>
>>
>>
>> --
>> *W.A. Garrett Weaver *
>> weaverg at email.arizona.edu
>>
>>
>
>
> --
> *W.A. Garrett Weaver *
> weaverg at email.arizona.edu
>
>
--
*W.A. Garrett Weaver *
weaverg at email.arizona.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20120524/ee413a0d/attachment-0001.html>
More information about the gstreamer-devel
mailing list