GStreamer iOS - 返回相应的 UITabBarController 选项卡时可能存在的流媒体和 glimagesink 阻塞问题



在连接到iPhone 8+13.5.1的Mac Catalina 10.15.6上运行XCode 12.0测试版6GST版本:1.16.1

我创建了一个带有rtsp视频流的应用程序,作为流由GStreamer管道在动态创建的UI的选项卡视图上显示的功能之一。当切换到流选项卡并第一次启动流时,它启动,gstreamer&ios很好&流是可见的。在切换到另一个UI视图和窗口句柄失焦的选项卡后,我将解码器中的样本丢弃到管道中的appsink元素中(下面将详细描述(。

切换回流媒体选项卡,我恢复流媒体,我可以判断有视频数据进入(如下所述(,但它没有显示。

整个流有2条管道,由appsink和appsrc分隔。我可以判断视频数据是在切换回选项卡后进入的;新样本";我注册的回调正在被调用。此外,在回调中,将带有gst_app_src_push_sample(…(的示例推送到appsrc元素不会返回错误。

下面是一个管道的例子:

rtsprc名称=rtsprc01位置=rtsp://192.168.0.25:7768/stream延迟=25!rtph264天!h264解析!decodebin!视频转换!视频框左=0右=0上=0下=0!发球台名称=t2_01!队列视频秤!glimagesink name=thumb_sink01 t2_01!appsink name=appsink01 sync=false

appsrc名称=appsrc01最大延迟=10!视频秤!glimagesink name=viewer_sink01 sync=false

glimagesink元素被命名为";thumb_sink01";是显示在选项卡上的流的缩略图;appsink01";转到";新样本";回调
;appsrc01";第二个管道上的元素正在从gst_app_src_push_sample(…(调用接收样本,并转到同一选项卡上的一个更大的UIImageView窗口

我可以看到,在切换回流式处理选项卡后,内存消耗也在增加,所以第二个管道上的一个元素似乎由于某种原因被阻塞了。我已经验证了这两个管道也处于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元素中,因为推送样本返回,这向我表明appsrc接受了它,并且没有指示缓冲区用完或丢弃样本。我觉得视频秤也不太可能是罪魁祸首,但我以前错了。

也许glimagesink name=thumb_sink01元素有什么愚蠢的地方。?。?我还没有真正看过。

感谢任何人的反馈。

  • 道格

我最后一条关于删除glimagesink并直接写入窗口句柄的评论看起来是可行的,而且总体上效果更好。

从在"接收帧"中接收的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;
}

最新更新