在过去的两周里,我试图找到一种从 .mts 视频文件中读取帧并在 OpenCV 中处理它们的正确方法。当 .mts 文件为 25p(25 fps 逐行)格式时,OpenCV 的 VideoCapture 可以很好地寻找视频帧,但当它是 50i(25 fps 隔行扫描)格式时,OpenCV 的 VideoCapture 无法逐帧正确解码。(例如,在一个示例场景中,当我获得第 1 帧,然后读取第 300 帧,然后再读取第 1 帧时,它返回的损坏图像与我之前读取的第 1 帧不同)(我使用的是 OpenCV 2.4.6)
我决定替换程序的视频解码器部分。
我尝试了 FFmpegSource2,但没有解决为 .mts 正确寻找帧的问题(大多数时候 FFMS_GetFrame 函数为 50i .mts 文件的几个连续帧返回相同的输出)。
我也试过 DirectShow。但是 TIME_FORMAT_FRAME 的 IMediaSeeking 的 IsFormatSupported 方法对于 50i .mts 视频文件不返回 S_OK 并且它只支持这种视频文件的 TIME_FORMAT_MEDIA_TIME。我自己没有尝试过,但一位朋友说即使使用 TIME_FORMAT_MEDIA_TIME 进行寻帧也会导致与上述相同的问题,我可能无法前后跳转到各个帧并读取它们的数据。
现在我要试试 gstreamer。我在以下链接中找到了链接 gstreamer 和 openCV 的示例方法: 将 opencv 处理添加到 gstreamer 应用程序
当我尝试在 gstreamer 1.0 中编译它时,我收到以下错误:
错误 C3861:“gst_app_sink_pull_buffer”:找不到标识符
我已包含 gst/gst.h、gst/app/gstappsink.h、gst/app/gstappsrc.h
查看了以下帮助链接,那里也没有 gst_app_sink_pull_buffer 函数。 http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html
我正在使用来自 gstreamer.freedesktop.org 的 gstreamer 1.0 (v1.2.0)
可能是来自 www.gstreamer.com 的 gstreamer SDK(基于 gstreamer 0.1)为此工作,但我还没有尝试过,更喜欢使用来自 gstreamer.freedesktop.org 的 gstreamer
我不知道 gst_app_sink_pull_buffer 是在哪里定义的。任何人都知道如何在 为 gstreamer 1.0添加 opencv 处理到 gstreamer 应用程序中编译为 gstreamer 0.1 提供的示例方法?
先感谢您。
更新 1:我是 gstreamer 的新手。现在我知道必须将添加 opencv 处理到 gstreamer 应用程序的示例方法从 gstreamer 0.1 移植到 gstreamer 1.0。我用 gst_app_sink_pull_sample 和 gst_sample_get_buffer 替换了 gst_app_sink_pull_buffer 函数。必须在代码的其他部分上进行更多工作,看看是否可以从 50i .mts 视频文件中打开所需的帧并使用 OpenCV 处理它。
更新 2:我在http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-data-spoof.html#section-spoof-appsink找到了一个很好的例子 我很容易替换使用 GTk 保存快照的部分,该部分具有将帧数据缓冲区加载到 OpenCV Mat 的功能。该程序适用于许多视频文件类型,我可以在 OpenCV Mat 中抓取视频文件的帧。但是当输入视频文件是 50i .mts 视频文件时,它返回以下错误,我无法读取帧数据:
No accelerated IMDCT transform found
0:00:00.405110839 4632 0B775380 ERROR libav :0:: get_buffer() failed (-1 2 00000000)
0:00:00.405740899 4632 0B775380 ERROR libav :0:: decode_slice_header error
0:00:00.406401077 4632 0B7756A0 ERROR libav :0:: Missing reference picture
0:00:00.406705867 4632 0B7756A0 ERROR libav :0:: Missing reference picture
0:00:00.416044436 4632 0B7759C0 ERROR libav :0:: Cannot combine reference and non-reference fields in the same frame
0:00:00.416813339 4632 0B7759C0 ERROR libav :0:: decode_slice_header error
0:00:00.417725301 4632 0B775CE0 ERROR libav :0:: Missing reference picture
一步一步调试显示运行后出现“没有找到加速IMDCT变换”
ret = gst_element_get_state( pipeline, NULL, NULL, 5 * GST_SECOND );
谷歌搜索显示我可以忽略它作为警告。
所有其他错误都在运行后出现
g_signal_emit_by_name( sink, "pull-preroll", &sample, NULL );
我不知道如何解决这个问题?我已经在另一个示例中使用 playbin 播放了这个 .mts 文件,当我使用 playbin 时 gstreamer 可以很好地播放这个 .mts 视频文件。