在连接到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;
}