工具/软件:
您好专家、
其中 可以找到将输出视频保存到文件位置的逻辑。 我的意思是、在配置文件中将 Sink 连接的代码在哪里?
我可以编辑代码,这将 重复产生3秒的视频片段直到应用停止,将一个接一个地保存到文件位置。
output1: #Video Output sink: /opt/edgeai-test-data/outputs/output_video.mkv #Output video file
此致、
Sajan
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:
您好专家、
其中 可以找到将输出视频保存到文件位置的逻辑。 我的意思是、在配置文件中将 Sink 连接的代码在哪里?
我可以编辑代码,这将 重复产生3秒的视频片段直到应用停止,将一个接一个地保存到文件位置。
output1: #Video Output sink: /opt/edgeai-test-data/outputs/output_video.mkv #Output video file
此致、
Sajan
您好、Sajan、
我们很高兴为您提供帮助。
在 edgeai-gst-apps 中、输出视频保存为文件由 GStreamer 处理。 应用程序代码中没有明确用于保存文件的逻辑。 在以下行中: https://github.com/TexasInstruments/edgeai-gst-apps/blob/main/apps_python/infer_pipe.py#L122 、经过后处理的帧会实时发送到输出 GStreamer 流水线。 代码本身不知道之后如何处理这些帧。 GStreamer 预配置为可能的输出之一(显示、保存到文件或远程流式传输)。
要执行您要求的操作、您可以在上述行插入逻辑以保存文件(在此处手动保存文件可能会花费很高)、也可以使用 GStreamer 插件自动将视频流保存到多个文件中 、例如"splitmuxsink"。 插入此插件需要更多的工作。 请参阅我在该主题中的回复: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1504970/sk-am62a-lp-loop-recording-on-running-model。
此致、
Qutaiba
您好、Qutaiba、
我尝试通过 splitmuxsink 修改文件链接、但似乎应用程序没有运行。
修改了下面的 gst_wrapper 代码片段
elif sink == "video": property = {} if (gst_element_map["h264enc"]["element"] == "v4l2h264enc"): property = {"extra-controls": Gst.Structure.from_string(enc_extra_ctrl)[0]} sink_elements += make_element(gst_element_map["h264enc"], property=property) for i in video_enc[sink_ext]: sink_elements += make_element(i[0], property=i[1]) property={ "location": output.sink.replace(".mp4", "_%03d.mp4"), "max-size-time": 5 * 1000000000, "name": sink_name} sink_elements += make_element("splitmuxsink", property=property)
此致、
Sajan
您好、Sajan、
我不确定我可以逐步完成更改 GST_Wrapper 代码的步骤。 我的建议是首先将"splitmuxsink"插件直接添加到 gstreamer 管道中。 当您有一个完全正常工作的流水线并且更好地了解这个新插件如何与其余插件交互时、请返回更改 GST_Wrapper。
您可以使用 OptiFlow 生成基本流水线、您可以将其用作添加"splitmuxsink"的起点。 OptiFlow 是 edgeai-gst-apps (https://github.com/TexasInstruments/edgeai-gst-apps/tree/main/optiflow)的一部分、它使用相同的 Yamil 文件作为可配置输入。 以下是一些流水线示例、您也可以使用这些示例作为起点: https://software-dl.ti.com/processor-sdk-linux/esd/AM62AX/latest/exports/edgeai-docs/common/edgeai_dataflows.html#optiflow。
在这 种方法中 、您可以首先关注添加"splitmuxsink"、然后根据需要更改 gst_wrapper。
此致、
Qutaiba
尊敬的 Qutaiba:
的起点OptiFlow 生成基本流水线、您可以将其用作添加"splitmuxsink"
sink_cmd += ( ' ! h264parse ! ' 'splitmuxsink muxer-factory=matroskamux ' 'max-size-time=3000000000 max-files=10 ' 'location=' + output.sink.replace('.mp4', '_%03d.mp4') )
通过在 gst_wrapper.py sink =="视频"条件中添加上述行、我得到了3秒文件的视频输出。 6 th 文件是52秒持续时间的视频。
我的问题是为什么我无法在 apps_python 中编写相同的代码。 如果我在 apps_python 中添加它、会抛出一些错误或应用程序会被击中。
此致、
Sajan
您好、Sajan、
我很高兴 OptiFlow 适用于您的用例。
我的问题是为什么我不能在 apps_python 中编写相同的代码。 如果我在 apps_python 中添加它、会抛出一些错误或应用程序会被击中。
[/报价]apps_python 使用更复杂的逻辑来生成最终 GST 流水线。 与 OptiFlow 不同、apps_python 不会直接为流水线生成最终字符串。 此处的代码用于演示目的、您正在进行一些修改。 对于此类特定用例、我建议您构建与此示例类似的自己 GST 包装器: https://github.com/TexasInstruments-Sandbox/edgeai-gst-apps-retail-checkout/blob/main/retail-shopping/gst_configs.py。 在这种情况下、考虑到所有其他输入和输出格式、您不必担心额外的逻辑。
如果您仍然有兴趣修改 apps_python、我的帮助将是 咨询能力。 我看到您在 apps_python 中对 gst_wrapper.py 所做的更改。 从第一个角度看、它们看起来很好。 由于我看不到它停止的确切位置、我无法提供任何建议。 您可以提供停止位置的日志。 我会很高兴看到它,看看我是否可以提供任何有益的建议。此致、
Qutaiba
尊敬的 Qutaiba:
提供其停止位置的日志
我将提供两个不同代码的日志。
第一个是
elif sink == "video": property = {} if (gst_element_map["h264enc"]["element"] == "v4l2h264enc"): property = {"extra-controls": Gst.Structure.from_string(enc_extra_ctrl)[0]} sink_elements += make_element(gst_element_map["h264enc"], property=property) for i in video_enc[sink_ext]: sink_elements += make_element(i[0], property=i[1]) mux = Gst.ElementFactory.make("mp4mux", f"{sink_name}-muxer") split = Gst.ElementFactory.make("splitmuxsink", sink_name) split.set_property( "location", output.sink.rstrip(".mp4") + "_%05d.mp4" ) split.set_property("max-size-time", 60 * Gst.SECOND) split.set_property("muxer", mux) sink_elements += [mux, split]
libtidl_onnxrt_EP loaded 0x30387660 Final number of subgraphs created are : 1, - Offloaded Nodes - 124, Total Nodes - 124 APP: Init ... !!! 247.479601 s: MEM: Init ... !!! 247.479671 s: MEM: Initialized DMA HEAP (fd=5) !!! 247.479924 s: MEM: Init ... Done !!! 247.479961 s: IPC: Init ... !!! 247.497610 s: IPC: Init ... Done !!! REMOTE_SERVICE: Init ... !!! REMOTE_SERVICE: Init ... Done !!! 247.504067 s: GTC Frequency = 200 MHz APP: Init ... Done !!! 247.508018 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_ERROR 247.508070 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_WARNING 247.508081 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_INFO 247.510685 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-0 247.510887 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-1 247.511000 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-2 247.511098 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-3 247.511114 s: VX_ZONE_INFO: [tivxInitLocal:126] Initialization Done !!! 247.511136 s: VX_ZONE_INFO: Globally Disabled VX_ZONE_INFO ** (python3:1626): WARNING **: 00:04:08.938: Could not add muxer element - splitmuxsink will not work ** (python3:1626): WARNING **: 00:04:08.945: Could not add muxer element - splitmuxsink will not work
2.
elif sink == "video": property = {} if (gst_element_map["h264enc"]["element"] == "v4l2h264enc"): property = {"extra-controls": Gst.Structure.from_string(enc_extra_ctrl)[0]} sink_elements += make_element(gst_element_map["h264enc"], property=property) for i in video_enc[sink_ext]: sink_elements += make_element(i[0], property=i[1]) muxer = Gst.ElementFactory.make("mp4mux", None) if not muxer: raise RuntimeError("Failed to create mp4mux") splitmuxsink = Gst.ElementFactory.make("splitmuxsink", sink_name) if not splitmuxsink: raise RuntimeError("Failed to create splitmuxsink") splitmuxsink.set_property("location", output.sink.replace(".mp4", "_%05d.mp4")) splitmuxsink.set_property("max-size-time", 3_000_000_000) # 3 seconds splitmuxsink.set_property("max-files", 10) splitmuxsink.set_property("muxer", muxer) sink_elements.append(splitmuxsink)
libtidl_onnxrt_EP loaded 0x3016a6a0 Final number of subgraphs created are : 1, - Offloaded Nodes - 124, Total Nodes - 124 APP: Init ... !!! 685.756972 s: MEM: Init ... !!! 685.757115 s: MEM: Initialized DMA HEAP (fd=5) !!! 685.757293 s: MEM: Init ... Done !!! 685.757325 s: IPC: Init ... !!! 685.775078 s: IPC: Init ... Done !!! REMOTE_SERVICE: Init ... !!! REMOTE_SERVICE: Init ... Done !!! 685.779531 s: GTC Frequency = 200 MHz APP: Init ... Done !!! 685.779689 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_ERROR 685.779710 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_WARNING 685.779722 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_INFO 685.781205 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-0 685.781513 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-1 685.781774 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-2 685.782046 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-3 685.782081 s: VX_ZONE_INFO: [tivxInitLocal:126] Initialization Done !!! 685.782121 s: VX_ZONE_INFO: Globally Disabled VX_ZONE_INFO ==========[INPUT PIPELINE(S)]========== [PIPE-0] v4l2src device=/dev/video-imx219-cam1 io-mode=5 pixel-aspect-ratio=None ! queue leaky=2 ! capsfilter caps="video/x-bayer, width=(int)1920, height=(int)1080, format=(string)rggb;" ! tiovxisp dcc-isp- file=/opt/imaging/imx219/linear/dcc_viss.bin sensor-name=SENSOR_SONY_IMX219_RPI ! capsfilter caps="video/x-raw, format=(string)NV12;" ! tiovxmultiscaler name=split_01 split_01. ! queue ! capsfilter caps="video/x-raw, width=(int)1920, height=(int)1080;" ! tiovxdlcolorconvert out-pool-size=4 ! capsfilter caps="video/x-raw, format=(string)RGB;" ! appsink max-buffers =2 drop=True name=sen_0 split_01. ! queue ! capsfilter caps="video/x-raw, width=(int)1188, height=(int)668;" ! tiovxmultiscaler target=1 ! capsfilter caps="video/x-raw, width=(int)454, height=(int)256;" ! tiovxdlcolorconve rt out-pool-size=4 ! capsfilter caps="video/x-raw, format=(string)RGB;" ! videobox qos=True left=115 right=115 top=16 bottom=16 ! tiovxdlpreproc out-pool-size=4 data-type=3 ! capsfilter caps="applic ation/x-tensor-tiovx;" ! appsink max-buffers=2 drop=True name=pre_0 ==========[OUTPUT PIPELINE]========== appsrc do-timestamp=True format=3 block=True is-live=True name=post_0 ! tiovxdlcolorconvert ! capsfilter caps="video/x-raw, format=(string)NV12, width=(int)1920, height=(int)1080;" ! v4l2h264enc ext ra-controls="controls, frame_level_rate_control_enable=(int)1, video_bitrate=(int)10000000, video_gop_size=(int)30;" ! h264parse ! mp4mux faststart-file=/tmp/qtmux1039052340 !
+--------------------------------------------------------------------------+ | Test Preview | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | Input Src: /dev/video-imx219-cam1 | | Model Name: TEST-CL-SAMPLE | | Model Type: classification | +--------------------------------------------------------------------------+ | dl-inference : 17.66 ms from 5 samples | | total time : 50.04 ms from 3 samples | | framerate : 19.98 fps from 3 samples | | Detected Class : | +--------------------------------------------------------------------------+
我还可以制作一个可用于类似目的的应用程序吗? 我的意思是它的难度级别如何。
谢谢。此致、
Sajan
您好、Sajan、
您使用 GST.ElementFactory.make 吗? 您是否尝试 使用类似的方式更新这两行 github.com/.../gst_wrapper.py
我还可以制作一个可用于类似目的的应用程序吗? 我的意思是它的难度级别如何。
[/报价]是的、这是我之前建议的。 只需创建您自己的专为此设计的应用程序。 通过浏览 edgeai-gst-apps 的逻辑来将其更新为不适合的内容可能会更简单。 请参阅零售 结账演示 作为示例。
此致、
Qutaiba
尊敬的 Qutaiba:
property={"location":output.sink.replace ('.mp4'、'_%03d.mp4')、"name":sink_name、"muxer-facture":"matroskamux "、"max-size-time":"3000000"[/quote:"10 "quote已尝试此代码但无法正常工作。
root@am62axx-evm:/opt/edgeai-gst-apps# ./apps_python/app_edgeai.py configs/my_config.yaml libtidl_onnxrt_EP loaded 0x31f79330 Final number of subgraphs created are : 1, - Offloaded Nodes - 124, Total Nodes - 124 APP: Init ... !!! 984.491832 s: MEM: Init ... !!! 984.491908 s: MEM: Initialized DMA HEAP (fd=5) !!! 984.492085 s: MEM: Init ... Done !!! 984.492116 s: IPC: Init ... !!! 984.509648 s: IPC: Init ... Done !!! REMOTE_SERVICE: Init ... !!! REMOTE_SERVICE: Init ... Done !!! 984.514150 s: GTC Frequency = 200 MHz APP: Init ... Done !!! 984.514299 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_ERROR 984.514317 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_WARNING 984.514328 s: VX_ZONE_INFO: Globally Enabled VX_ZONE_INFO 984.515345 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-0 984.515663 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-1 984.515951 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-2 984.516192 s: VX_ZONE_INFO: [tivxPlatformCreateTargetId:134] Added target MPU-3 984.516228 s: VX_ZONE_INFO: [tivxInitLocal:126] Initialization Done !!! 984.516259 s: VX_ZONE_INFO: Globally Disabled VX_ZONE_INFO [DEBUG] Adding elements: ['source0', 'queue0', 'capsfilter0', 'tiovxisp0', 'capsfilter1'] [DEBUG] Adding elements: ['queue2', 'capsfilter3', 'tiovxmultiscaler2', 'capsfilter4', 'tiovxdlcolorconvert1', 'capsfilter7', 'videobox0', 'tiovxdlpreproc0', 'capsfilter5'] [DEBUG] Adding elements: ['queue1', 'capsfilter2', 'tiovxdlcolorconvert2', 'capsfilter8', 'sen_0'] [DEBUG] Adding elements: ['split_01'] [DEBUG] Adding elements: ['post_0', 'tiovxdlcolorconvert0', 'capsfilter6'] [DEBUG] Adding elements: ['v4l2h264enc0', 'h264parse0', 'mp4mux0', 'sink0'] ==========[INPUT PIPELINE(S)]========== [PIPE-0] v4l2src device=/dev/video-imx219-cam1 io-mode=5 pixel-aspect-ratio=None ! queue leaky=2 ! capsfilter caps="video/x-bayer, width=(int)1920, height=(int)1080, format=(string)rggb;" ! tiovxisp dcc-isp- file=/opt/imaging/imx219/linear/dcc_viss.bin sensor-name=SENSOR_SONY_IMX219_RPI ! capsfilter caps="video/x-raw, format=(string)NV12;" ! tiovxmultiscaler name=split_01 split_01. ! queue ! capsfilter caps="video/x-raw, width=(int)1920, height=(int)1080;" ! tiovxdlcolorconvert out-pool-size=4 ! capsfilter caps="video/x-raw, format=(string)RGB;" ! appsink max-buffers =2 drop=True name=sen_0 split_01. ! queue ! capsfilter caps="video/x-raw, width=(int)1188, height=(int)668;" ! tiovxmultiscaler target=1 ! capsfilter caps="video/x-raw, width=(int)454, height=(int)256;" ! tiovxdlcolorconve rt out-pool-size=4 ! capsfilter caps="video/x-raw, format=(string)RGB;" ! videobox qos=True left=115 right=115 top=16 bottom=16 ! tiovxdlpreproc out-pool-size=4 data-type=3 ! capsfilter caps="applic ation/x-tensor-tiovx;" ! appsink max-buffers=2 drop=True name=pre_0 ==========[OUTPUT PIPELINE]==========
在该日志之后、它将生成终端报告 、并卡在第49毫秒。+--------------------------------------------------------------------------+ | Test Preview | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | Input Src: /dev/video-imx219-cam1 | | Model Name: TEST-CL-Sample | | Model Type: classification | +--------------------------------------------------------------------------+ | dl-inference : 20.33 ms from 5 samples | | total time : 49.76 ms from 3 samples | | framerate : 20.10 fps from 3 samples | +--------------------------------------------------------------------------+
注意:由于错误、我将 字符串中的"3000000000"和"10" 分别修改为整数3000000000、10。
删除了 matroskamux 后的空白空间、错误似乎 **(python3:1780):警告**:00:23:51.894:无法创建 muxer - splitmuxsink 将不起作用
此致、
Sajan
您好、Qutaiba、
我得到了所需的输出—非常感谢您的帮助! 非常感谢您的支持。
工作代码片段如下:
elif sink == "video": property = {} if (gst_element_map["h264enc"]["element"] == "v4l2h264enc"): property = {"extra-controls": Gst.Structure.from_string(enc_extra_ctrl)[0]} sink_elements += make_element(gst_element_map["h264enc"], property=property) sink_elements += make_element("h264parse") splitmuxsink_props = { "location": "/opt/edgeai-test-data/output/out_%02d.mp4", "max-files": 10, "max-size-time": 3 * Gst.SECOND, "async-finalize": True, "muxer": Gst.ElementFactory.make("mp4mux", None), "name": sink_name } sink_elements += make_element("splitmuxsink", property=splitmuxsink_props)