【问题标题】:In Gstreamer while playing the pipeline in iOS 8, and after entering background and returning foreground pipeline doesnt work :(?在 iOS 8 中播放管道时在 Gstreamer 中,进入后台并返回前台管道后不起作用:(?
【发布时间】:2015-06-17 16:37:00
【问题描述】:

-实际上我从链接下载了 gstreamer 的示例教程,

http://cgit.freedesktop.org/~slomo/gst-sdk-tutorials/

git://people.freedesktop.org/~slomo/gst-sdk-tutorials

  • 现在我在教程 3 中修改了以下代码,

    -(void) app_function
     {
    GstBus *bus;
    GSource *bus_source;
    GError *error = NULL;
    
    GST_DEBUG ("Creating pipeline");
    
    pipeline = gst_pipeline_new ("e-pipeline");
    
    
    /* Create our own GLib Main Context and make it the default one */
    context = g_main_context_new ();
    g_main_context_push_thread_default(context);
    
    /* Build pipeline */
    // pipeline = gst_parse_launch("videotestsrc ! warptv ! videoconvert ! autovideosink", &error);
    
    
    source = gst_element_factory_make("udpsrc", "source");
    
    g_object_set( G_OBJECT ( source),   "port", 8001, NULL );
    
    GstCaps *caps;
    
    caps = gst_caps_new_simple ("application/x-rtp",
                                "encoding-name", G_TYPE_STRING, "H264",
                                "payload", G_TYPE_INT, 96,
                                "clock-rate", G_TYPE_INT, 90000,
                                NULL);
    
    g_object_set (source, "caps", caps, NULL);
    
    
    
    
    rtp264depay = gst_element_factory_make ("rtph264depay", "rtph264depay");
    h264parse = gst_element_factory_make ("h264parse", "h264parse");
    vtdec = gst_element_factory_make ("vtdec", "vtdec");
    glimagesink  = gst_element_factory_make ("glimagesink", "glimagesink");
    
    gst_bin_add_many (GST_BIN(pipeline), source,  rtp264depay, h264parse, vtdec, glimagesink, NULL);
    
    
    
    
    if (error) {
        gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
        g_clear_error (&error);
        [self setUIMessage:message];
        g_free (message);
        return;
    }
    
    /* Set the pipeline to READY, so it can already accept a window handle */
    gst_element_set_state(pipeline, GST_STATE_READY);
    
    video_sink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY);
    if (!video_sink) {
        GST_ERROR ("Could not retrieve video sink");
        return;
    }
    gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), (guintptr) (id) ui_video_view);
    
    /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
    bus = gst_element_get_bus (pipeline);
    bus_source = gst_bus_create_watch (bus);
    g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
    g_source_attach (bus_source, context);
    g_source_unref (bus_source);
    g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, (__bridge void *)self);
    g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, (__bridge void *)self);
    gst_object_unref (bus);
    
    /* Create a GLib Main Loop and set it to run */
    GST_DEBUG ("Entering main loop...");
    main_loop = g_main_loop_new (context, FALSE);
    [self check_initialization_complete];
    g_main_loop_run (main_loop);
    GST_DEBUG ("Exited main loop");
    g_main_loop_unref (main_loop);
    main_loop = NULL;
    
    /* Free resources */
    g_main_context_pop_thread_default(context);
    g_main_context_unref (context);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
    
    return;
    

    }

-现在我在 ipad 上运行应用程序,应用程序开始播放。

  • 现在正在进入后台并返回前台 Gstreamer 流式更新在 UI 中不可见,但在 xcode 的网络使用情况下,我可以看到数据包正在接收....:(

提前致谢....iOS GEEKS....

【问题讨论】:

  • 我在 iPhone 的 Gstreamer 中也面临同样的问题。如果您找到解决方案,请发布。 :(
  • pipeline = gst_parse_launch("udpsrc host=192.168.7.45 port=5000 !application/x-rtp, payload=96 !rtpjitterbuffer !rtph264depay !avdec_h264 !auto​​videosink sync=false text-overlay=false", &错误);错误管道错误无法构建管道:没有元素“udpsrc”
  • 请解释您使用了哪些额外的变量以及类型,例如,来源,rtp264depay 等
  • 嗨,我是 Gstremer 的新手,我正在运行一个演示 // pipeline = gst_parse_launch("videotestsrc !warptv !videoconvert !auto​​videosink", &error);上面的行在我这边没有注释,我得到了错误 - “没有为 warptv 找到元素”?你有什么解决办法请帮帮我谢谢

标签: ios gstreamer ios8-extension


【解决方案1】:

更新:让 UDP 工作。

经过进一步调查,我让 UDP h264 流在 linux (PC x86) 上工作,但在 IOS 上的原理应该是相同的(特别是 avdec_h264(在 PC 上使用)必须替换为 vtdec)。

TCP 和 UDP 管道的主要区别:

服务器端:

  • IP:让我在 UDP 和 TCP 服务器端混淆的第一个元素:在 UDP 服务器 上,udpsink 元素上指定的 IP 地址是 客户端侧IP,即 gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000

TCP 服务器 端,IP 是 服务器端 之一(tcpserversink 上的主机参数),即 gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$SERVERIP port=5000

  • 视频流负载/格式:为了让客户端能够检测帧的格式和大小,TCP服务器端使用gdppaypayloader 元素,在其管道中。在客户端相反的元素上,使用了一个de-payloader gdpdepay,以便能够读取接收到的帧。 即

gst-launch-1.0 -v fdsrc ! h264解析! rtph264pay 配置间隔=1 pt=96 ! gdppay ! tcpserversink 主机=$SERVERIP 端口=5000

UDP 服务器端使用 gdpay 元素,它让客户端在其 udpsink 上使用 CAPS,请参阅下面的客户端差异。 p>

客户端

  • IP:UDP 客户端确实 需要指定任何 IP。 而 TCP 客户端需要 服务器 IP(tcpclientsrc 上的主机参数),即 gst-launch-1.0 -v tcpclientsrc host=$SERVERIP port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false
  • 视频流payload/format:如上一段所述,TCP服务器端使用payloader gdppay,而客户端使用de-payloader来识别帧的格式和大小。

相反,UDP 客户端必须在其 udpsrc 元素上使用 caps 明确指定它,即 CAPS='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96'

gst-launch-1.0 -v udpsrc 端口=5000 大写=$CAPS ! rtph264depay! avdec_h264 !视频转换! autovideosink sync=false enable-last-buffer=false`

如何指定大写字母:这有点老套,但它有效: 使用详细选项 -v 运行您的 UDP 服务器,即 gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000

您将获得以下日志:

Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, width=(int)1280, height=(int)720, parsed=(boolean)true, stream-format=(string)avc, alignment=(string)au, codec_data=(buffer)01640028ffe1000e27640028ac2b402802dd00f1226a01000428ee1f2c /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQCgC3QDxImo\=\,KO4fLA\=\=", payload=(int)96, ssrc=(uint)3473549335, timestamp-offset=(uint)257034921, seqnum-offset=(uint)12956 /GstPipeline:pipeline0/GstUDPSink:udpsink0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)"J2QAKKwrQCgC3QDxImo\=\,KO4fLA\=\=", payload=(int)96, ssrc=(uint)3473549335, timestamp-offset=(uint)257034921, seqnum-offset=(uint)12956 /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:sink: caps = video/x-h264, width=(int)1280, height=(int)720, parsed=(boolean)true, stream-format=(string)avc, alignment=(string)au, codec_data=(buffer)01640028ffe1000e27640028ac2b402802dd00f1226a01000428ee1f2c /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: timestamp = 257034921 /GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: seqnum = 12956 Pipeline is PREROLLED ... Setting pipeline to PLAYING ...

现在复制以 caps = application/x-rtp 开头的大写字母 这是指定 rtp 流格式的一种。据我所知,真正必须让 UDP 客户端识别 rtp 流内容然后初始化播放。

为了避免混淆,请在下面找到完整的命令行示例,使用 raspivid 和 Raspberry pi。如果你想试试(在 linux 上)

UDP

  • 服务器:raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=$CLIENTIP port=5000
  • 客户: CAPS='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96' gst-launch-1.0 -v udpsrc port=5000 caps=$CAPS ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false

TCP

  • 服务器:raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -o - | gst-launch-0.10 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=$SERVERIP port=5000

  • 客户:gst-launch-1.0 -v tcpclientsrc host=$SERVERIP port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false enable-last-buffer=false

注意:Raspivid 可以使用 cat 轻松替换为简单的 h264 文件,即cat myfile.h264 | gst-launch...

【讨论】:

  • 在 Gstreamer 管道中创建管道时遇到一些错误管道错误无法构建管道:没有元素“udpsrc”请指定正确的语法
【解决方案2】:

我最近尝试通过“vtdec”gstreamer 插件使用 Apple VideoToolBox API,使用硬件 h264 解码从 RaspberryPi 到 IOS8 进行实时流式传输。

我看了很多教程,来自 Braincorp (https://github.com/braincorp/gstreamer_ios_tutorial)

和 塞巴斯蒂安·德罗格: http://cgit.freedesktop.org/~slomo/gst-sdk-tutorials/

我让后一个工作,修改了教程 3:

  • 服务器管道RaspberryPi 上使用 pi 摄像头和 Raspivid + gstreamer:
    raspivid -t 0 -w 1280 -h 720 -fps 25 -b 2500000 -p 0,0,640,480 -o - | gst-launch-0.10 -v fdsrc ! h264解析! rtph264pay 配置间隔=1 pt=96 !支付宝! tcpserversink host=ServerIPRaspberryPi 端口=any_port_on_Rpi

  • 客户端侧管道一个 IOS 8 设备:
    tcpclientsrc host=ServerIPRaspberryPi port=any_port_on_Rpi ! gdpdepay! rtph264depay! h264解析!视频解码器! glimagesink

或相同,而不是 glimagesink autovideosink

此解决方案有效,可以同时使用多个客户端。我尝试让 udpsink 代替 tcpserversink 工作,但运气不好,到目前为止它从来没有工作过。

===重要===
此外,使用 gst_element_factory_make() + gst_bin_add_many (GST_BIN(pipeline), ...) 的工厂方式从未奏效。 相反,我使用了 pipeline = gst_parse_launch(...) 方法。

所以在我们的例子中,在 IOS 客户端:
pipeline = gst_parse_launch("tcpclientsrc host=172.19.20.82 port=5000 !gdpdepay !rtph264depay !h264parse !vtdec !auto​​videosink", &error);

可能的原因:有一个页面记录了差异,以及如何从 gstreamer 0.101.0 移植代码: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-porting-1.0.html

我们注意到,在使用 “工厂方法” 时,管道的各种元素缺失,具体取决于我们使用的是 gstreamer 1.0 还是 0.1trph264depayavdec_h264(用于其他平台,即 linux 客户端)解码 h264 而不是 IOS 特定的 vtdec强>)。

我们几乎无法使用 Factory 方法将所有元素组合在一起,但我们使用 "gst_parse_launch()" 函数在 IOS 和 linux 上毫无问题地进行了管理。 p>

因此,总而言之,虽然我们尚未测试并让 UDP 接收器工作,但请尝试使用 tcpclientsrc 元素的 TCP 方式相反,让它工作,然后只有在它工作后,尝试找到 udp 的方法,如果你结束了,请告诉我们。

最好的问候,希望这对你们中的许多人有所帮助。

罗曼·S

【讨论】:

    猜你喜欢
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2015-10-03
    相关资源
    最近更新 更多