GStreamer iOS - 返回相应的 UITabBarController 选项卡时可能出现流媒体和 glimagesink 阻塞问题
GStreamer iOS - possible streaming & glimagesink blocking issue when returning to corresponding UITabBarController tab
运行 XCode Mac Catalina 10.15.6 上的 12.0 beta 6 连接到 iPhone 8+ 13.5.1
消费税版本:1.16.1
我创建了一个应用程序,其中 rtsp 视频流作为功能之一,通过 GStreamer 管道在动态创建的选项卡视图上显示流 UI。
当切换到流选项卡并第一次启动流时,它会启动,gstreamer 和 ios 正常并且可以查看流。
在切换到 UI 视图和 window 句柄失去焦点的另一个选项卡后,我将来自解码器的样本丢弃到管道中的 appsink 元素(下面详细描述)。
切换回流式传输选项卡,我恢复流式传输,我可以看出有视频数据传入(如下所述),但没有显示。
整个流有 2 个管道,由 appsink 和 appsrc 分隔。
我可以告诉视频数据在切换回选项卡后进入,因为我注册的 appsink“new-sample”回调被调用。
此外,在回调中,将带有 gst_app_src_push_sample(...) 的样本无误地推送到 appsrc 元素 returns。
下面是管道的示例:
rtspsrc 名称=rtspsrc01 位置=rtsp://192.168.0.25:7768/流延迟=25! rtph264depay ! h264解析!解码箱!视频转换! videobox left=0 right=0 top=0 bottom=0 !球座名称=t2_01 !队列 !视频比例! glimagesink 名称=thumb_sink01 t2_01。 ! appsink 名称=appsink01 sync=false
appsrc 名称=appsrc01 最大延迟=10!视频比例! glimagesink 名称=viewer_sink01 sync=false
名为“thumb_sink01”的 glimagesink 元素是选项卡上显示的流的缩略图视图,“appsink01”转到“new-sample”回调。
第二个管道上的“appsrc01”元素正在接收来自 gst_app_src_push_sample(...) 调用的示例,并转到同一选项卡上更大的 UIImageView window。
我也可以看到在切换回流式传输选项卡后内存消耗也在增加,因此看起来第二个管道上的元素之一由于某种原因正在阻塞。我已验证两条管道也都处于 GST_STATE_PLAYING 状态。
我已经尝试了很多其他的事情,例如验证 GStreamer 正在渲染的视图是否有效,甚至在切换回流媒体选项卡并恢复流媒体时验证这段代码:
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(self->video_sink), (guintptr) (id) self->ui_video_view);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(self->thumb_sinks[0]), (guintptr) (id) self->ui_thumb_views[0]);
gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(self->thumb_sinks[0]));
gst_video_overlay_expose(GST_VIDEO_OVERLAY(self->thumb_sinks[0]));
gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(self->video_sink));
gst_video_overlay_expose(GST_VIDEO_OVERLAY(self->video_sink));
我一直假设问题出在 glimagesink 元素中,因为推送样本 returns,这向我表明 appsrc 接受了它并且没有迹象表明 运行 超出缓冲区或丢弃样品。我觉得 videoscale 也不太可能是罪魁祸首,但我以前就错了。
也许 glimagesink name=thumb_sink01 元素发生了一些愚蠢的事情。?。?我还没有真正看过。
感谢任何人的反馈。
- 道格
我关于删除 glimagesink 并直接写入 window 句柄的最后一条评论看起来是可行的方法,而且似乎整体效果更好。
从“new-sample”回调中收到的 appsink 示例内存缓冲区中获取原始 RGB 解码帧,并从中创建一个 UIImage 并将 UIImageView.image 设置为 UIImage 有效。
如果对其他人有用,一些伪代码示例可以进行转换(尽管在线提供了大量示例):
// Create this once before passing any image frames.
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
data->img_ctx = CGBitmapContextCreate(img_buff, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
// Use this for converting decoded RGB image frames to UIImage's
dispatch_async(dispatch_get_main_queue(), ^{
CGImageRef imgRef = CGBitmapContextCreateImage(data->img_ctx);
data->the_img = [[UIImage alloc] initWithCGImage: imgRef];
CGImageRelease(imgRef);
[data->ui_video_view setMyImage: (UIImage *)data->the_img];
[data->ui_video_view setNeedsDisplay];
});
// Edit: had problems with subclassing between Objective-C & Swift, so had to create this setter function to work around it.
-(void) setMyImage: (UIImage *) img {
super.image = img;
}
运行 XCode Mac Catalina 10.15.6 上的 12.0 beta 6 连接到 iPhone 8+ 13.5.1 消费税版本:1.16.1
我创建了一个应用程序,其中 rtsp 视频流作为功能之一,通过 GStreamer 管道在动态创建的选项卡视图上显示流 UI。 当切换到流选项卡并第一次启动流时,它会启动,gstreamer 和 ios 正常并且可以查看流。 在切换到 UI 视图和 window 句柄失去焦点的另一个选项卡后,我将来自解码器的样本丢弃到管道中的 appsink 元素(下面详细描述)。
切换回流式传输选项卡,我恢复流式传输,我可以看出有视频数据传入(如下所述),但没有显示。
整个流有 2 个管道,由 appsink 和 appsrc 分隔。 我可以告诉视频数据在切换回选项卡后进入,因为我注册的 appsink“new-sample”回调被调用。 此外,在回调中,将带有 gst_app_src_push_sample(...) 的样本无误地推送到 appsrc 元素 returns。
下面是管道的示例:
rtspsrc 名称=rtspsrc01 位置=rtsp://192.168.0.25:7768/流延迟=25! rtph264depay ! h264解析!解码箱!视频转换! videobox left=0 right=0 top=0 bottom=0 !球座名称=t2_01 !队列 !视频比例! glimagesink 名称=thumb_sink01 t2_01。 ! appsink 名称=appsink01 sync=false
appsrc 名称=appsrc01 最大延迟=10!视频比例! glimagesink 名称=viewer_sink01 sync=false
名为“thumb_sink01”的 glimagesink 元素是选项卡上显示的流的缩略图视图,“appsink01”转到“new-sample”回调。
第二个管道上的“appsrc01”元素正在接收来自 gst_app_src_push_sample(...) 调用的示例,并转到同一选项卡上更大的 UIImageView window。
我也可以看到在切换回流式传输选项卡后内存消耗也在增加,因此看起来第二个管道上的元素之一由于某种原因正在阻塞。我已验证两条管道也都处于 GST_STATE_PLAYING 状态。
我已经尝试了很多其他的事情,例如验证 GStreamer 正在渲染的视图是否有效,甚至在切换回流媒体选项卡并恢复流媒体时验证这段代码:
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(self->video_sink), (guintptr) (id) self->ui_video_view);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(self->thumb_sinks[0]), (guintptr) (id) self->ui_thumb_views[0]);
gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(self->thumb_sinks[0]));
gst_video_overlay_expose(GST_VIDEO_OVERLAY(self->thumb_sinks[0]));
gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(self->video_sink));
gst_video_overlay_expose(GST_VIDEO_OVERLAY(self->video_sink));
我一直假设问题出在 glimagesink 元素中,因为推送样本 returns,这向我表明 appsrc 接受了它并且没有迹象表明 运行 超出缓冲区或丢弃样品。我觉得 videoscale 也不太可能是罪魁祸首,但我以前就错了。
也许 glimagesink name=thumb_sink01 元素发生了一些愚蠢的事情。?。?我还没有真正看过。
感谢任何人的反馈。
- 道格
我关于删除 glimagesink 并直接写入 window 句柄的最后一条评论看起来是可行的方法,而且似乎整体效果更好。
从“new-sample”回调中收到的 appsink 示例内存缓冲区中获取原始 RGB 解码帧,并从中创建一个 UIImage 并将 UIImageView.image 设置为 UIImage 有效。
如果对其他人有用,一些伪代码示例可以进行转换(尽管在线提供了大量示例):
// Create this once before passing any image frames.
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
data->img_ctx = CGBitmapContextCreate(img_buff, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
// Use this for converting decoded RGB image frames to UIImage's
dispatch_async(dispatch_get_main_queue(), ^{
CGImageRef imgRef = CGBitmapContextCreateImage(data->img_ctx);
data->the_img = [[UIImage alloc] initWithCGImage: imgRef];
CGImageRelease(imgRef);
[data->ui_video_view setMyImage: (UIImage *)data->the_img];
[data->ui_video_view setNeedsDisplay];
});
// Edit: had problems with subclassing between Objective-C & Swift, so had to create this setter function to work around it.
-(void) setMyImage: (UIImage *) img {
super.image = img;
}