我无法播放以前由gstreamer 1.9录制的视频文件。
目前我有这条管道:
视频
appsrc! video / x-raw format = RGB,width = 800,height = 400,framerate = 24/1! jpegenc! matroskamux! filesink location = c:\ gstreamer \ test.mkv
用于字幕(2首曲目)
appsrc! text / x-raw format = utf8! matroskamux! filesink location = c:\ gstreamer \ test.mkv
使用 gst_element_factory_make 逐个元素构建Pipeline,并使用 gst_element_link 进行链接。
当我需要停止录制时,我会调用 gst_element_send_event(_pipeline,gst_event_new_eos()); 。
只有在总线上发生 GST_MESSAGE_EOS 事件后才能通过 gst_element_set_state(_pipeline,GST_STATE_NULL); 停止管道。
但是,当我想通过 gst-validate-1.0 测试结果文件时,我有这个:
C:\gstreamer\1.0\x86\bin>gst-validate-1.0 filesrc location=C:\\Video\\test.mkv ! matroskademux name=mux mux.video_0! jpegdec ! autovideosink
WARNING: no real random source present!
Starting pipeline
Pipeline started
warning : EOS received without segment event before
Detected on <jpegdec0:src>
Description : A segment event should always be sent before data flow EOS being some kind of data flow, there is no exception in that regard
issue : EOS events that are part of the same pipeline 'operation' should have the same seqnum
Detected on <mux:video_0>
Detected on <jpegdec0:sink>
Description : when events/messages are created from another event/message, they should have their seqnums set to the original event/message seqnum
critical : We got an ERROR message on the bus
Detected on <pipeline0>
==== Got criticals, Return value set to 18 ====
Critical error Got error: Internal data stream error. -- Debug message: matroska-demux.c(4759): gst_matroska_demux_loop (): /GstPipeline:pipeline0/GstMatro
skaDemux:mux:
streaming stopped, reason not-negotiated (-4)
Issues found: 3
Returning 18 as error where found
=======> Test FAILED (Return value: 18)
我也试图发送结束段事件,但没有运气。我不会在公共汽车上看到它。
录制或播放时我做错了什么?
请帮我解决一下我的问题。
我的录制源代码。它是提取。可能是一些小错误。抱歉。 你还需要播放代码吗?它根本不起作用。
class GStreamerRecorder
{
GstElement* _pipeline = nullptr;
GstElement* _videoSource = nullptr;
GstElement* _videoFilter = nullptr;
GstCaps* _videoFormat = nullptr;
GstElement* _container = nullptr;
GstElement* _recorder = nullptr;
void init()
{
//init gstreamer library
gst_init(nullptr, nullptr);
//init papeline
_pipeline = gst_pipeline_new("VideoRecorder");
if (!_pipeline){throw 1;}
//init video source
_videoSource = gst_element_factory_make("videotestsrc", "VideoFrame");//appsrc videotestsrc
if (!_videoSource){throw 2;}
//init video filter
_videoFilter = gst_element_factory_make("capsfilter", "VideoFilter");
if (!_videoFilter){throw 2;}
_videoFormat = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "RGB",
"width", G_TYPE_INT, 800,
"height", G_TYPE_INT, 400,
"framerate", GST_TYPE_FRACTION, 24, 1,
NULL);
g_object_set(G_OBJECT(_videoFilter), "caps", _videoFormat, NULL);
//init video container
_container = gst_element_factory_make("matroskamux", "Container"); //matroskamux avimux
if (!_container){throw 3;}
//init file recording
_recorder = gst_element_factory_make("filesink", "Recorder");
if (!_recorder){throw 4;}
//set file name
g_object_set(_recorder, "location","c:\\videoid\\gstreamer\\test.mkv", NULL);
//build the pipeline
gst_bin_add_many(GST_BIN(_pipeline), _videoSource, _videoFilter, _container, _recorder, NULL);
//link elemets
if ((bool)gst_element_link(_videoSource, _videoFilter) != true) { throw 5; }
if ((bool)gst_element_link(_videoFilter, _container) != true) { throw 5; }
if ((bool)gst_element_link(_container, _recorder) != true) { throw 5; }
//start recording
GstStateChangeReturn status;
status = gst_element_set_state(_pipeline, GST_STATE_PLAYING);
if (status == GST_STATE_CHANGE_FAILURE){throw 1;}
}
void AddFrame(GstElement* destination, unsigned char* data, int size, int offset, int duration)
{
GstBuffer* buffer= gst_buffer_new_allocate(NULL, size, NULL);
GST_BUFFER_PTS(result) = offset;
GST_BUFFER_DURATION(result) = duration;
//fill buffer with data
gst_buffer_fill(buffer, 0, data, size);
//push video buffer to file
GstFlowReturn ret;
g_signal_emit_by_name(destination, "push-buffer", buffer, &ret);
}
void StopVideoFile()
{
//register call back function for soft stop
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline));
gst_bus_add_watch(bus, BusCallback, _loop);
//gst_bus_add_signal_watch(bus);
//send soft stop signal
gst_element_send_event(_pipeline, gst_event_new_eos());
//activate main loop
g_main_loop_run(_loop);
//stop recording
gst_element_set_state(_pipeline, GST_STATE_NULL);
_pipeline = nullptr;
}
int GStreamerRecorder::BusCallback(GstBus* bus, GstMessage* message, void* loop)
{
switch (GST_MESSAGE_TYPE(message))
{
case GST_MESSAGE_ERROR:
break;
case GST_MESSAGE_EOS:
g_main_loop_quit((GMainLoop *)loop);
return false;
break;
}
return TRUE;
}
};
gst-discoverer-1.0 -v C的结果:\ Video \ test.mkv
Analyzing file:///C://video//test.mkv
Done discovering file:///C://video//test.mkv
Topology:
container: video/x-matroska
subtitles: text/x-raw, format=(string)pango-markup
Tags:
container format: Matroska
language code: en
Codec:
text/x-raw, format=(string)pango-markup
Additional info:
None
Stream ID: b4368b8a0fa3b45cffd297ed75944d7e99b0c7abc7e93a406c4ee970c8d97ac5/003:16476197871654839755
Language: en
subtitles: text/x-raw, format=(string)pango-markup
Tags:
container format: Matroska
language code: en
Codec:
text/x-raw, format=(string)pango-markup
Additional info:
None
Stream ID: b4368b8a0fa3b45cffd297ed75944d7e99b0c7abc7e93a406c4ee970c8d97ac5/002:17212272217086422368
Language: en
video: image/jpeg, framerate=(fraction)4/1, width=(int)900, height=(int)800
Tags:
container format: Matroska
video codec: Motion JPEG
Codec:
image/jpeg, framerate=(fraction)4/1, width=(int)900, height=(int)800
Additional info:
None
Stream ID: b4368b8a0fa3b45cffd297ed75944d7e99b0c7abc7e93a406c4ee970c8d97ac5/001:380798365750797811
Width: 900
Height: 800
Depth: 24
Frame rate: 4/1
Pixel aspect ratio: 1/1
Interlaced: false
Bitrate: 0
Max bitrate: 0
Properties:
Duration: 0:00:38.250000000
Seekable: yes
Tags:
container format: Matroska
language code: en
video codec: Motion JPEG