- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 GStreamer 从 USB 网络摄像头 (Logitech C920) 捕获 H264 视频,并且我想在可能解码或将其流式传输到网络之前分析 h264 帧。
根据互联网上的不同来源,我构建了一个 python2.7 脚本,它允许我将帧输入 python,基本上使用原理图 gst-launch 命令:
gst-launch-1.0 v4l2src ! video/x-h264 ! h264parse ! appsink
但是,我一直试图解释接收到的缓冲区。我已经花了相当长的时间试图理解 python gstreamer 如何将元 api 附加到缓冲区,但现在是徒劳的。如果我理解正确的话,如果我以某种方式将元 api 附加到缓冲区,我将获得一个结构,该结构允许我访问不同的元素以及有关帧编码的信息。我怎样才能做到这一点? (无需为帧编写我自己的解码器)
下面是我当前的脚本,其中包含一些示例输出:
from __future__ import absolute_import, division, print_function
import sys, os, pdb
from datetime import datetime
import gi
gi.require_version("Gst","1.0")
from gi.repository import Gst
Gst.init(None)
def appsink_new_buffer(sink, data):
sample = sink.emit("pull-sample")
buf = sample.get_buffer()
caps = sample.get_caps()
print("\nGot new buffer: {} Sample Info: {}\n".format(datetime.now(),sample.get_info()))
print("Buffer size: {} ".format(buf.get_size()))
print("Buffer n_memory: {} Presentation TS (PTS): {:.3f} s Decoding DTS: {:.3f} s Duration: {:.1f} ms".format(
buf.n_memory(), buf.pts/1e9, buf.dts/1e9, buf.duration/1e6))
st = caps.get_structure(0)
field_names = [st.nth_field_name(i) for i in range(st.n_fields())]
print("Caps {} n_fields: {} name: {}, format: {}, height: {}, width: {}".format(
i,st.n_fields(),st.get_name(), st.get_value("format"), st.get_value("height"), st.get_value("width")))
print(" all fields: {}".format(" ".join(field_names)))
for fname in field_names:
if fname not in ['pixel-aspect-ratio','framerate']: # cause error because Gst.FractionType not known
print(" {:20}: ".format(fname), st.get_value(fname))
#
# somehow, here one nees to get the Meta API to understand the buffer content and to do further processing
# of the encoded h264 frames.
# Q: does one buffer after the h264parse represent exactly one frame?
#
return Gst.FlowReturn.OK
def appsink_webcam_h264():
# adapted from https://gist.github.com/willpatera/7984486
source = Gst.ElementFactory.make("v4l2src", "source")
source.set_property("device", "/dev/video2")
caps = Gst.caps_from_string("video/x-h264, width=640,height=480,framerate=10/1")
capsfilter = Gst.ElementFactory.make("capsfilter", None)
capsfilter.set_property("caps", caps)
parse = Gst.ElementFactory.make("h264parse","h264parse")
sink = Gst.ElementFactory.make("appsink", "sink")
pipeline_elements = [source, capsfilter, parse, sink]
sink.set_property("max-buffers",20) # prevent the app to consume huge part of memory
sink.set_property('emit-signals',True) #tell sink to emit signals
sink.set_property('sync',False) #no sync to make decoding as fast as possible
sink.connect("new-sample", appsink_new_buffer, sink)
# Create an empty pipeline & add/link elements
pipeline = Gst.Pipeline.new("test-pipeline")
for elem in pipeline_elements:
pipeline.add(elem)
for i in range(len(pipeline_elements[:-1])):
if not Gst.Element.link(pipeline_elements[i], pipeline_elements[i+1]):
raise Exception("Elements {} and {} could not be linked.".format(
pipeline_elements[i], pipeline_elements[i+1]))
ret = pipeline.set_state(Gst.State.PLAYING)
# Wait until error or EOS
bus = pipeline.get_bus()
# Parse message
while True:
message = bus.timed_pop_filtered(10000, Gst.MessageType.ANY)
if message:
if message.type == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print("Error received from element %s: %s" % (
message.src.get_name(), err))
print("Debugging information: %s" % debug)
break
elif message.type == Gst.MessageType.EOS:
print("End-Of-Stream reached.")
break
elif message.type == Gst.MessageType.STATE_CHANGED:
if isinstance(message.src, Gst.Pipeline):
old_state, new_state, pending_state = message.parse_state_changed()
print("Pipeline state changed from %s to %s." %
(old_state.value_nick, new_state.value_nick))
else:
print("Unexpected message received: ", message, message.type)
pipeline.set_state(Gst.State.NULL)
if __name__ == '__main__':
appsink_webcam_h264()
下面是该脚本的一些示例输出:
...
Got new buffer: 2016-01-09 01:41:52.091462 Sample Info: None
Buffer size: 9409
Buffer n_memory: 1 Presentation TS (PTS): 0.390 s Decoding DTS: 0.000 s Duration: 100.0 ms
Caps 8 n_fields: 9 name: video/x-h264, format: None, height: 480, width: 640
all fields: stream-format alignment width height pixel-aspect-ratio framerate parsed level profile
stream-format : byte-stream
alignment : au
width : 640
height : 480
parsed : True
level : 4
profile : constrained-baseline
Got new buffer: 2016-01-09 01:41:52.184990 Sample Info: None
Buffer size: 868
Buffer n_memory: 1 Presentation TS (PTS): 0.590 s Decoding DTS: 0.100 s Duration: 100.0 ms
Caps 8 n_fields: 9 name: video/x-h264, format: None, height: 480, width: 640
all fields: stream-format alignment width height pixel-aspect-ratio framerate parsed level profile
stream-format : byte-stream
alignment : au
width : 640
height : 480
parsed : True
level : 4
profile : constrained-baseline
Got new buffer: 2016-01-09 01:41:52.285425 Sample Info: None
Buffer size: 3202
...
我搜索了很多,但找不到一个示例如何将元 api 映射到包含 python 中编码视频帧的缓冲区,并且我认为这应该不会那么困难,因为似乎提供了该功能.
有什么建议吗?
最佳答案
您能否确认您没有尝试访问原始 h264 数据?那只会在缓冲区对象中。为了对其进行进一步分析,例如是否存在 I 帧、P 帧或 SEI 信息,您需要使用 gsth264parser.c 之类的工具来解析原始 h264 数据。
为了获取元数据,您必须知道您正在查找的元数据的类型。例如GstMetaXImage
。我不知道 GStreamer 中有任何 h264 元数据类型。
关于Python GStreamer : getting Meta Api for appsink buffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34688897/
我期望 new Buffer(buffer.toString()) 始终是逐字节相等的。但是,我遇到的情况并非如此。 首先,这是一个真实的案例: var buf1 = new Buffer(32);
我有用于记录数据的 Protocol Buffer 。 message Message { required double val1 = 1; optional int val2 =
请注意以下简单程序(基于 protobuf-net 项目 v1 wiki 中的示例): using System.Collections.Generic; using System.Diagnosti
在 Protocol Buffer 中,有没有办法让消息包含嵌套消息的集合?例如,消息主管可能有一个员工集合以及主管的姓名和部门。 最佳答案 是的。您使用 repeated领域; message Em
我想知道 Protocol Buffer 在解析流时如何处理损坏的数据。有没有办法知道数据是否已损坏。 Protocol Buffer 是否提供任何内置的数据完整性检查机制? 谢谢, 最佳答案 没有任
Protocol Buffer 如何处理类型版本控制? 例如,当我需要随时间更改类型定义时?就像添加和删除字段一样。 最佳答案 Google 设计的 protobuf 对版本控制非常宽容: 意外数据要
我尝试阅读 Protobuf 文档,但无法想象它可以用于许多用例。我想知道一些实际的 Protocol Buffer 性能改进用例。 谢谢 最佳答案 Protocol buffers 是一个序列化库,
给定 Protocol Buffer 模式和一些数据, Protocol Buffer 序列化是否跨库和语言具有确定性? 基本上,无论使用什么库,我是否可以保证相同的数据总是以相同的方式(直到字节)序
我正在使用一个示例 UWP C++/CX 程序,该程序创建两个 UDP 网络通信线程,它们使用 Windows::Storage::Streams::DataWriter 相互发送数据。和 Windo
我正在使用以下代码 int lenSend = odl->ByteSize(); char* buf = (char *)malloc(lenSend); odl->SerializeToArray(
Protocol Buffer 文档警告说...... You should never add behaviour to the generated classes by inheriting fr
我有一个定义如下的原型(prototype)模式, message User { int64 id = 1; bool email_subscribed = 2; bool sms_
我试图了解 Protocol Buffer 编码方法,将消息转换为二进制(或十六进制)格式时,我无法理解嵌入消息的编码方式。 我猜可能和内存地址有关,但我找不到准确的关系。 这是我所做的。 第 1 步
我需要序列化和反序列化一系列与字节流之间的 Protocol Buffer 消息。有一些预先确定的消息类型。编码类型信息的推荐方法是什么,以便我的应用程序可以知道它应该读取哪种类型? 最佳答案 最常见
与GSON相比, Protocol Buffer (protobuf)的优缺点是什么? 在什么情况下,protobuf比GSON更合适? 对于一个非常笼统的问题,我感到抱歉。 最佳答案 json(通过
message Person { required Empid = 1 [default = 100]; required string name = 2 [default = "Raju"]
我正在研究一个小型设备,该设备具有相当大的一组配置参数(~100 KB),这些参数是从 PC 软件生成的。过去,我们将参数存储在二进制文件中并将它们加载到数据结构中。维护有点烦人(不同的语言,确保结构
来自Encoding - Protocol Buffers - Google Code上的“签名类型”: ZigZag encoding maps signed integers to unsigne
我正在使用 Protocol Buffer ,一切正常。除了我不明白的事实 - 为什么我需要 proto 中的编号标签文件 : message SearchRequest { required s
Protocol Buffer 的吸引人的功能之一是它允许您扩展消息定义,而不会破坏使用较旧定义的代码。对于枚举according to the documentation: a field with
我是一名优秀的程序员,十分优秀!