GNOME Bugzilla – Bug 783354
Alternative RTMP implementation
Last modified: 2018-11-03 14:09:06 UTC
Make.TV has been working on an alternative RTMP implementation in gst-plugins-bad, based on David Schleef's gst-rtmp. It still feels like a pile of hacks (with some pretty parts sticking out of it), but we think it's already pretty usable. It features: rtmp2sink/src as drop-in replacements for the existing rtmpsink/src, no segfaults when stopping (bug 729099), handling ping and stats messages, adobe-style auth. Major things that are known to be missing are: Automated tests, documentation, support for rtmpt/rtmps/rtmpe, a server implementation, post-start command handling, not depending on flvmux and flvdemux. The code is available at https://github.com/heftig/gst-plugins-bad/tree/rtmp2/gst/rtmp2 . It's branched off 1.12.0; as of today 1.12 and master still merge in fine.
Created attachment 354508 [details] [review] rtmp2: New elements rtmp2sink, rtmp2src With an internal implementation of RTMP using GIO. Squashed from https://github.com/heftig/gst-plugins-bad/commits/rtmp20.
Review of attachment 354508 [details] [review]: ::: gst/rtmp2/gstrtmp2src.c @@ +131,3 @@ + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-flv") May be here,we should not to limit specific mimetype, as gstrtmpsrc.c,just let it be ANY, otherwise playbin may fail when play some rtmp streams.
Created attachment 358225 [details] rtmp2src will be blocked in code execution In addition, rtmp2 used in terminal, everything is ok, like this: gst-launch-1.0 playbin uri=rtmp://xxx or gst-launch-1.0 rtmp2src location=rtmp://xx ! decodebin ! autovideosink Once in gst-sdk-tutorial's sample code(in attachment), it will block, seems that connect_task_done can't be executed for some reason.
A bit of progress: rtmp2src.c gst_rtmp2_src_task_func() L565 ---- ... context = self->context = g_main_context_new (); ... ---- If I replace g_main_context_new() with g_main_context_default(),above results are completely reversed --): * Use gst_parse_launch() to load pipeline,it's OK,such as, pipeline = gst_parse_launch ("rtmp2src location=rtmp://v1.one- tv.com/live/mpegts.stream ! decodebin ! autovideosink", NULL); * Use gst-lauch-1.0 to load pipeline with terminal,it's NG,such as, gst-launch-1.0 rtmp2src location=rtmp://v1.one-tv.com/live/mpegts.stream ! decodebin ! autovideosink , Also, terminal output the following assertion error: ----- ** GStreamer:ERROR:gstbus.c:1349:gst_bus_add_signal_watch_full: assertion failed: (!bus->priv->signal_watch) ----- I debugged rtmp2src's codes, which was normal until '<=' mark line, ---- static void start_play_done (GObject * source, GAsyncResult * result, gpointer user_data) { GTask *task = G_TASK (user_data); .... if (gst_rtmp_client_start_play_finish (connection, result, &self->stream_id, &error)) { g_task_return_pointer (task, g_object_ref (connection), <= gst_rtmp_connection_close_and_unref); .... The task is marked as completed, in theory should call GAsyncReadyCallback (connect_task_done)... GIO Reference Manual tell us: ---- void g_task_return_pointer (GTask *task, gpointer result, GDestroyNotify result_destroy); Sets task 's result to result and completes the task. If result is not NULL, then result_destroy will be used to free result if the caller does not take ownership of it with g_task_propagate_pointer(). "Completes the task" means that for an ordinary asynchronous task it will either invoke the task's callback, or else queue that callback to be invoked in the proper GMainContext, or in the next iteration of the current GMainContext ---- So,it seems to be related to gtask/GMainContext, but where exactly is it? a little confused -( ----
I'm still on vacation at the moment, but I'll take a look at your problem as soon as I can.
Thank you for taking time to pay attention during the enjoyable vacation.
Created attachment 362001 [details] [review] rtmp2: New elements rtmp2sink, rtmp2src Here's a patch based on the current HEAD, which should also fix your problem.
Thanks for your patience,it works. Maybe GStreamer developer should pay more attention and give advice, it's worth merging into upstream. -)
just retested rtmp2src with a stream generated by wowza, still doesn't work, here is the error: (gst-launch-1.0:6729): GLib-CRITICAL **: g_checksum_update: assertion 'length == 0 || data != NULL' failed (gst-launch-1.0:6729): GLib-CRITICAL **: g_checksum_update: assertion 'length == 0 || data != NULL' failed 0:00:00.878524371 6729 0x55cc4a55aa30 ERROR rtmp2src gstrtmp2src.c:781:send_connect_error:<rtmp2src0> Failed to connect (g-io-error-quark:14): authentication failed! wrong credentials? ERROR: from element /GstPipeline:pipeline0/GstRtmp2Src:rtmp2src0: Not authorized to connect Additional debug info: gstrtmp2src.c(785): send_connect_error (): /GstPipeline:pipeline0/GstRtmp2Src:rtmp2src0: authentication failed! wrong credentials? the stream does not require credentials I'll continue to use this rtmpsrc plugin based on libav for now https://bugzilla.gnome.org/show_bug.cgi?id=788583
We sent a "Live Encoder" Flash version for playback too, so Wowza asks for publishing credentials. I've fixed this and some more problems that prevented playback from Wowza; the fixes are available in my branch at https://github.com/heftig/gst-plugins-bad/tree/rtmp2/gst/rtmp2 . If reviewers request I can squash the current series into a new patch, again.
Yes, please. Wowza are also widely used. -)
Created attachment 362799 [details] [review] rtmp2: New elements rtmp2sink, rtmp2src New patch with fixed Wowza playback.
Dear heftig, Thanks. Wowza playback work now. -).
Created attachment 362983 [details] [review] fix some leaks the patch fixs these leaks 6 bytes in 1 blocks are definitely lost in loss record 82 of 4,275 ==5520== at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5520== by 0x60102F9: g_malloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FEF3B0: g_strdup (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97B9163: send_connect (rtmpclient.c:506) ==5520== by 0x97B9163: handshake_done (rtmpclient.c:387) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x97BB8E3: client_handshake3_done (rtmphandshake.c:260) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x97BD299: write_all_bytes_done (rtmputils.c:144) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9C80C3A: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9C7FD7B: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305E8: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x5FFF0BD: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6000F68: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) 4 bytes in 1 blocks are definitely lost in loss record 29 of 4,275 ==5520== at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5520== by 0x60102F9: g_malloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FEF3B0: g_strdup (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97B9142: send_connect (rtmpclient.c:505) ==5520== by 0x97B9142: handshake_done (rtmpclient.c:387) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x97BB8E3: client_handshake3_done (rtmphandshake.c:260) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x97BD299: write_all_bytes_done (rtmputils.c:144) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9C80C3A: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9C7FD7B: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305E8: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x5FFF0BD: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6000F68: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) 2,088 (40 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 4,226 of 4,275 ==5520== at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5520== by 0x60102F9: g_malloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FF1706: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FD8ECA: g_bytes_new_with_free_func (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97BC0BE: gst_rtmp_client_handshake (rtmphandshake.c:142) ==5520== by 0x97B7727: socket_connect_done (rtmpclient.c:359) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CACD8B: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CB3657: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D380CD: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CAB402: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x5FFF0BD: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6000F68: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6001F41: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97B0FFA: gst_rtmp2_src_task_func (gstrtmp2src.c:611) ==5520== by 0x4EE4138: gst_task_func (gsttask.c:332) ==5520== by 0x5FEFF5A: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== ==5520== 2,088 (40 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 4,227 of 4,275 ==5520== at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5520== by 0x60102F9: g_malloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FF1706: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x5FD8ECA: g_bytes_new_with_free_func (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97BBCDD: client_handshake2_done (rtmphandshake.c:233) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x97BD1F0: read_all_bytes_done (rtmputils.c:93) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CF95F1: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CF2168: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D305AB: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9D30BC6: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CF8A64: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x9CF8AE8: ??? (in /usr/lib/libgio-2.0.so.0.5400.0) ==5520== by 0x5FFF0BD: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6000F68: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x6001F41: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5400.0) ==5520== by 0x97B0FFA: gst_rtmp2_src_task_func (gstrtmp2src.c:611)
valgrind reports this leaks in error case, but rtmp2 code seems good here ==14287== 41 (16 direct, 25 indirect) bytes in 1 blocks are definitely lost in loss record 2,866 of 4,557 ==14287== at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14287== by 0x60102F9: g_malloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x5FF1706: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x5FE656E: g_error_new_valist (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x9CA7C15: g_task_return_new_error (in /usr/lib/libgio-2.0.so.0.5400.0) ==14287== by 0x97B7437: on_publish_or_play_status (rtmpclient.c:1089) ==14287== by 0x97B9697: cancel_all_commands (rtmpconnection.c:314) ==14287== by 0x97B9756: gst_rtmp_connection_emit_error.part.0 (rtmpconnection.c:470) ==14287== by 0x97BB17C: gst_rtmp_connection_emit_error (rtmpconnection.c:463) ==14287== by 0x97BB17C: gst_rtmp_connection_input_ready (rtmpconnection.c:417) ==14287== by 0x131FE313: ??? (in /usr/lib/gio/modules/libgiognutls.so) ==14287== by 0x5FFF0BD: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x6000F68: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x6001F41: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x97B0FFA: gst_rtmp2_src_task_func (gstrtmp2src.c:611) ==14287== by 0x4EE4138: gst_task_func (gsttask.c:332) ==14287== by 0x5FEFF5A: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x5FF51EA: ??? (in /usr/lib/libglib-2.0.so.0.5400.0) ==14287== by 0x66C6089: start_thread (in /usr/lib/libpthread-2.26.so) ==14287== by 0x69D324E: clone (in /usr/lib/libc-2.26.so) the leaks is probably in glib itself
Thanks for your patch. I've applied it and afterwards refactored the handshake code a bit. I believe I've also found the leak for the error case.
(In reply to Jan Alexander Steffens (heftig) from comment #16) > Thanks for your patch. I've applied it and afterwards refactored the > handshake code a bit. > > I believe I've also found the leak for the error case. I see, thanks! In the next weeks I'll do some more tests aiming to replace my implementation based on ffmpeg
Created attachment 371665 [details] [review] rtmp2: New elements rtmp2sink, rtmp2src With an internal implementation of RTMP using GIO. Squashed from: https://github.com/heftig/gst-plugins-bad/commits/rtmp2 commit dab97a41eba516d35980318942eb7557f581d62f "rtmp2: Let connection continue despite handshake verification failure"
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/562.