GNOME Bugzilla – Bug 478244
rtpamrdepay make no playable stream
Last modified: 2007-09-24 02:56:53 UTC
I got problem in rtpamrdepay element. The jill.3gp is encoded in amrnb and h263 as a testing video file gst-launch -v ffmux_3gp name=mux ! filesink location=/home/video/jill3.3gp \ {filesrc location=/home/video/jill.3gp ! qtdemux name=demuxer2 ! rtpamrpay ! rtpamrdepay !queue }! mux.audio_0 \ {filesrc location=/home/video/jill.3gp ! qtdemux name=demuxer ! ffdec_h263 ! ffenc_h263 bitrate=45000 rtp-payload-size=500 gop-size=3 me-method=4 ! queue }! mux.video_0 In the above pipeline, after I converted the file into jill3.3gp(it runs without error), it cannot be played through the following pipeline gst-launch -v filesrc location=/home/video/jill3.3gp ! qtdemux name=demuxer \ demuxer.!queue! rtpamrpay ! udpsink host=172.20.122.9 port=11002 \ demuxer.!queue! rtph263pay ! udpsink host=172.20.122.9 port=11000 It gives out error like this: Setting pipeline to PAUSED ... Pipeline is PREROLLING ... ERROR: from element /pipeline0/demuxer: This file contains no playable streams. Additional debug info: qtdemux.c(1444): gst_qtdemux_loop (): /pipeline0/demuxer: no known streams found ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... FREEING pipeline ... However, if i remove the rtpamrpay and rtpamrdepay in the converting pipeline, the second pipeline runs smoothly without any problem, I can even see the movie in the remote end I suspect there is a problem within the rtpamrdepay(As I can use rtpamrpay without problem in streaming the original file)
rtpamrpay ! rtpamrdepay does not preserve the duration of a packet, which the ffmpeg muxers need to estimate the length of the track.
Two patches are needed: to -base: * gst-libs/gst/rtp/gstbasertpdepayload.c: (gst_base_rtp_depayload_chain), (gst_base_rtp_depayload_set_gst_timestamp): Only copy timestamp on outgoing packets if the depayloader did not set one. Also copy duration on outgoing packets. to -good: * gst/rtp/gstrtpamrpay.c: (gst_rtp_amr_pay_handle_buffer): * gst/rtp/gstrtpgsmpay.c: (gst_rtp_gsm_pay_handle_buffer): * gst/rtp/gstrtpmp2tpay.c: (gst_rtp_mp2t_pay_handle_buffer): * gst/rtp/gstrtpspeexpay.c: (gst_rtp_speex_pay_handle_buffer): * gst/rtp/gstrtptheorapay.c: (gst_rtp_theora_pay_init_packet), (gst_rtp_theora_pay_flush_packet): * gst/rtp/gstrtpvorbispay.c: (gst_rtp_vorbis_pay_flush_packet): Try to preserve the incomming buffer duration on the outgoing packets. Fixes #478244.
Hi, can you give some more hints to fix this problem? what do you mean by the duration? The time between sending two outgoing buffer?
Terry, the bug is marked FIXED and in Comment #2 you can find the CVS patches that fixed it.
Thx, now I come up with another problem and I guess it should be similar bug gst-launch -m ffmux_3gp name=mux ! filesink location=/home/video/receive.3gp \ { udpsrc num-buffers=500 port=11002 name=audioudp caps="application/x-rtp, media=(string)audio, payload=(int)98, clock-rate=(int)8000, encoding-name=(string)AMR, encoding-params=(string)1, octet-align=(string)1" ! rtpamrdepay queue-delay=0 ! queue } ! mux.audio_0 This time, I use udpsrc instead of rtpamrpay After the buffer in udpsrc got full and a eos raised, the receive.3gp cannot be played From my understanding, as it is impossible for the udpsrc to know the duration of incoming buffer(packet), now the rtpamrdepay cannot copy the duration from incoming buffer to outgoing buffer which may cause the similar problem like before, isnt it? Therefore, we should have a rtpamrdepay sending out correct outgoing buffer duration if the incoming buffer doesnt have it?
Yes, good point. Here's the fix: * gst/rtp/gstrtpamrdepay.c: (gst_rtp_amr_depay_process): Set outgoing packet duration because we can. Fixes #478244 some more. Also note that reconstructing a valid quicktime stream from RTP packets is not trivial. The default gstreamer setup will try to mux the stream as close to the original streamed files as possible, preserving timestamps etc. You also might want to insert a gstjitterbuffer right after the udpsrc to compensate for packet loss, reordering and jitter to get a somewhat higher quality input for the muxer.
I got another problem and also seems related to the duration The pipeline i use this time: gst-launch -m ffmux_3gp name=mux ! filesink location=/home/video/receive.3gp \ { udpsrc num-buffers=500 port=11002 name=audioudp caps="application/x-rtp, media=(string)audio, payload=(int)98, clock-rate=(int)8000, encoding-name=(string)AMR, encoding-params=(string)1, octet-align=(string)1" ! rtpamrdepay queue-delay=0 ! queue } ! mux.audio_0 \ { udpsrc num-buffers=500 port=11000 name=videoudp caps="application/x-rtp, media=(string)video, payload=(int)34, clock-rate=(int)90000, encoding-name=(string)H263" ! rtph263depay queue-delay=0 ! queue } ! mux.video_0 With the above pipeline, once it receive the stream, error occurs: Setting pipeline to PLAYING ... Got Message from element "pipeline0" (new-clock): GstMessageNewClock, clock=(GstClock)GstSystemClock New clock: GstSystemClock Got Message from element "mux" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "queue0" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "queue1" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "rtpamrdepay0" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "rtph263depay0" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "audioudp" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "videoudp" (state-changed): GstMessageState, old-state=(GstState)GST_STATE_PAUSED, new-state=(GstState)GST_STATE_PLAYING, pending-state=(GstState)GST_STATE_VOID_PENDING Got Message from element "mux" (error): GstMessageError, gerror=(GstGError)(NULL), debug=(string)"gstffmpegmux.c\(475\):\ gst_ffmpegmux_collected\ \(\):\ /pipeline0/mux:\012Failed\ to\ write\ file\ header\ -\ check\ codec\ settings" ERROR: from element /pipeline0/mux: Could not configure supporting library. Additional debug info: gstffmpegmux.c(475): gst_ffmpegmux_collected (): /pipeline0/mux: Failed to write file header - check codec settings Execution ended after 3618236000 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... FREEING pipeline ... I think that this is because the h263depayloader did not set the duration of a packet which the mux need as you mentioned before Then I tried another pipeline with a h263 deconder and encoder inserted after the h263depayloader gst-launch -m ffmux_3gp name=mux ! filesink location=/home/video/receive.3gp \ { udpsrc num-buffers=500 port=11002 name=audioudp caps="application/x-rtp, media=(string)audio, payload=(int)98, clock-rate=(int)8000, encoding-name=(string)AMR, encoding-params=(string)1, octet-align=(string)1" ! rtpamrdepay queue-delay=0 ! queue } ! mux.audio_0 \ { udpsrc num-buffers=500 port=11000 name=videoudp caps="application/x-rtp, media=(string)video, payload=(int)34, clock-rate=(int)90000, encoding-name=(string)H263" ! rtph263depay queue-delay=0 ! ffdec_h263 ! ffenc_h263 bitrate=45000 rtp-payload-size=500 gop-size=3 me-method=4 !queue } ! mux.video_0 This time, the pipeline runs sucessfully and I obtain the file. However, the video is much faster than it should be I do think that this is related to the duration is not set in the h263depayloader and then the encoder calculate an incorrect duration(seems base on arrival time). I've read rfc2190, From my understanding, the only way to calculate the duration is based on the timestamp, marker bit and the 90kHz clock. I am not very sure about this but still I hope this information will save you time.