微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AVPacket 到 Gstreamer 管道

如何解决AVPacket 到 Gstreamer 管道

我的目标是在 libav 中解复用视频流,然后在 GStreamer 中对其进行解码。

我的方法是从第一个线程中的视频流中获取 AVPacket,然后通过第二个线程中的 appsrc 元素将其发送到 GStreamer 管道线。代码的重要部分在这里

// -- THREAD 1 --    
// Take data from AVPacket
img_data = (guchar *)packet.data;
size = packet.size;
// Create GStreamer buffer
buffer = gst_buffer_new_allocate(NULL,size,NULL);
gst_buffer_map(buffer,&map,GST_MAP_WRITE);
memcpy((guchar *)map.data,img_data,gst_buffer_get_size(buffer));
map.size = size;
gst_buffer_unmap(buffer,&map);
// Send the buffer to appsrc element in the pipeline.
gstret = gst_app_src_push_buffer((GstAppSrc *)app_source,buffer);

// -- THREAD 2 --
// A video cap for appsrc element
const gchar *video_caps = "video/x-theora,width=1920,height=1080,framerate=30/1";
// GStreamer pipeline
string = g_strdup_printf("appsrc name=testsource caps=\"%s\" ! theoradec ! videoconvert ! autovideosink",video_caps);

但是,我收到以下错误

来自元素 theoradec0 的错误:无法解码流。 调试信息:gsttheoradec.c(812): theora_handle_data_packet (): /GstPipeline:pipeline0/GstTheoraDec:theoradec0: 还没有发送头

此外,gst_app_src_push_buffer 函数返回值为 -2 的 GstFlowReturn,这意味着“Pad 正在刷新”。根据{{​​3}}。但我不确定它是什么意思(我找不到)。

为了找到错误,我尝试了两个 GStreamer 管道,以确保我可以在第一个管道中解复用视频流并在第二个管道中对其进行解码。它有效:

const gchar *video_caps = "video/x-theora,framerate=30/1";
p1_str = g_strdup_printf("filesrc location=\"%s\" ! oggdemux ! appsink caps=\"%s\" name=testsink",filename,video_caps);
p2_str = g_strdup_printf("appsrc name=testsource caps=\"%s\" ! theoradec ! videoconvert ! autovideosink",video_caps);

然后,我还尝试通过 libav 将 AVPacket 解码为 AVFrame,然后发送到 GStreamer 管道以确保我可以从 AVFrame 创建 GStreamer 缓冲区。它也有效:

-- THREAD 1 --
// Decode.
avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);
img_data = (guchar *)pFrame->data;
// same way as before.

-- THREAD 2 --
const gchar *video_caps = "video/x-raw,format=BGR,framerate=30/1";
string = g_strdup_printf("appsrc name=testsource caps=\"%s\" ! videoconvert ! autovideosink",video_caps);

所有这些都在此视频文件上进行了测试:

container: ogg
codec: Theora
dim: 1920x1080
framerate: 30fps

导致错误的原因是什么?是否是由于向 GStreamer 管道发送格式错误的数据引起的?或者 theoradec 元素设置不正确?什么是“垫正在冲洗”。是什么意思?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。