ffdec_mpeg4: ошибка декодирования с помощью gst_pad_push() = несвязано при использовании gstreamer-java с конвейером decodebin2! ffmpegcolorspace! видео / х-сырец-RGB
Я пытаюсь заставить следующий конвейер работать в gstreamer-java (используя gstreamer-0.10):
"gst-launch-0.10 filesrc location = big_buck_bunny_480p_surround-fix.avi! decodebin2! ffmpegcolorspace! autovideosink"
Этот конвейер работает в командной строке. Машина vbox vm работает под управлением убунту 14.04 LTS
Может ли кто-нибудь помочь мне определить, что моя проблема может быть с конвейером в коде Java?
Java-код выглядит следующим образом:
public static void main (String [] args) {
args = Gst.init("AppSrcTest", args);
/* setup pipeline */
pipeline = new Pipeline("pipeline");
final AppSrc appsrc = (AppSrc) ElementFactory.make("appsrc", "appsrc");
final Element decodebin = ElementFactory.make("decodebin2", null);
final Element ffmpegcolorspace = ElementFactory.make("ffmpegcolorspace", "formatConverter");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("FakeSrcTest");
VideoComponent panel = new VideoComponent();
panel.setPreferredSize(new Dimension(width, height));
frame.add(panel, BorderLayout.CENTER);
Element videosink = panel.getElement();
pipeline.addMany(appsrc, decodebin,ffmpegcolorspace, videosink);
Element.linkMany(appsrc, decodebin,ffmpegcolorspace, videosink);
appsrc.setTimestamp(true);
appsrc.set("emit-signals", true);
appsrc.connect(new AppSrc.NEED_DATA() {
public void needData(AppSrc elem, int size) {
try {
//other code
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
}
System.out.println("Data collected..");
Buffer buffer = new Buffer(outputStream.toByteArray().length);
buffer.getByteBuffer().put(outputStream.toByteArray());
appsrc.pushBuffer(buffer);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Отладочная информация выглядит следующим образом, когда я начинаю получать ошибку:
0:00:06.194558872 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00;01;37;41m GST_ELEMENT_PADS gstelement.c:728:gst_element_add_pad:<decodebin20>[00m adding pad 'src0'
0:00:06.194682253 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00;01;37;41m GST_ELEMENT_PADS gstelement.c:728:gst_element_add_pad:<decodebin20>[00m adding pad 'src1'
0:00:06.194765369 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00;01;31m GST_STATES gstbin.c:2942:bin_handle_async_done:<decodebin20>[00m committing state from READY to PAUSED, old pending PAUSED
0:00:06.194824176 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00;01;31m GST_STATES gstbin.c:2962:bin_handle_async_done:<decodebin20>[00m completed state change, pending VOID
0:00:06.194877892 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00;01;31m GST_STATES gstelement.c:2365:_priv_gst_element_state_changed:<decodebin20>[00m notifying about state-changed READY to PAUSED (VOID_PENDING pending)
Got TAG event
Tag audio-codec = Dolby Digital (AC-3)
Tag bitrate = 448000
0:00:06.212171413 [332m14803[00m 0x7f24dc038680 [32;01mINFO [00m [00m a52dec gsta52dec.c:439:gst_a52dec_reneg:<a52dec0>[00m reneg channels:6 rate:48000
0:00:06.258920113 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.259312652 [332m14803[00m 0x7f24dc043450 [32;01mINFO [00m [00m basesrc gstbasesrc.c:2562:gst_base_src_loop:<appsrc>[00m pausing after gst_pad_push() = not-linked
0:00:06.259366067 [332m14803[00m 0x7f24dc043450 [33;01mWARN [00m [00m basesrc gstbasesrc.c:2625:gst_base_src_loop:<appsrc>[00m error: Internal data flow error.
0:00:06.259383885 [332m14803[00m 0x7f24dc043450 [33;01mWARN [00m [00m basesrc gstbasesrc.c:2625:gst_base_src_loop:<appsrc>[00m error: streaming task paused, reason not-linked (-1)
0:00:06.259418691 [332m14803[00m 0x7f24dc043450 [32;01mINFO [00m [00;01;31;47m GST_ERROR_SYSTEM gstelement.c:1964:gst_element_message_full:<appsrc>[00m posting message: Internal data flow error.
0:00:06.268446147 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.273770933 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.274603418 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.275939105 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.277303268 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
Error: code=1 message=Internal data flow error.
0:00:06.291740181 [332m14803[00m 0x7f24dc043450 [32;01mINFO [00m [00;01;31;47m GST_ERROR_SYSTEM gstelement.c:1987:gst_element_message_full:<appsrc>[00m posted error message: Internal data flow error.
0:00:06.292844435 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
Got TAG event
Tag minimum-bitrate = -1
Tag bitrate = 0
Tag maximum-bitrate = 0
0:00:06.297233217 [332m14803[00m 0x7f24dc043400 [33;01mWARN [00m [00m ffmpeg gstffmpegdec.c:2299:gst_ffmpegdec_frame:<ffdec_mpeg40>[00m ffdec_mpeg4: decoding error (len: -1, have_data: 0)
0:00:06.297382004 [332m14803[00m 0x7f24dc043400 [32;01mINFO [00m [00;01;31;41m GST_PADS gstpad.c:3554:gst_pad_event_default_dispatch:<mpeg4vparse0:sink>[00m Sending event 0x7f24dc148c60 (eos) to all internally linked pads
1 ответ
Отвечая на мой вопрос
Лучший совет, который я прочитал в Интернете относительно gstreamer: протестируйте свой конвейер в командной строке, прежде чем внедрять в код. Следовательно, если он работает в командной строке, он должен работать в коде.
Следующий вопрос и ответь на мой вопрос в c коде. т.е. он предлагает решение для ошибки "пауза после gst_pad_push() = несвязанная " gStreamer-Sharp Динамические площадки не связываются
Однако я не знал, как это сделать в коде Java. Итак, я немного больше познакомился с динамическими конвейерами в gstreamer, используя следующий учебник: Динамические конвейеры: http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+3%3A+Dynamic+pipelines
Два замечания, которые следует отметить из приведенного выше руководства по решению этой проблемы:
GSignals является критической точкой в GStreamer. Они позволяют вам получать уведомления (посредством обратного вызова), когда происходит что-то интересное. Сигналы идентифицируются по имени, и каждый GObject имеет свои собственные сигналы.
Демуксеры начинаются с исходных площадок, с которыми могут связываться другие элементы, и поэтому конвейер должен обязательно заканчиваться на них. Решение состоит в том, чтобы построить конвейер от источника до демультиплексора и настроить его на запуск (воспроизведение). Когда демультиплексор получит достаточно информации, чтобы узнать о количестве и типе потоков в контейнере, он начнет создавать исходные площадки. Это подходящее время для нас, чтобы закончить сборку конвейера и присоединить его к недавно добавленным площадкам демультиплексора.
Следовательно, мой код Java выглядит следующим образом:
public void run() {
JFrame frame = new JFrame("FakeSrcTest");
VideoComponent panel = new VideoComponent();
panel.setPreferredSize(new Dimension(width, height));
frame.add(panel, BorderLayout.CENTER);
final Element videosink = panel.getElement();
pipeline.addMany(appsrc, decodebin2, ffmpegcolorspace, videosink);
Element.linkMany(appsrc, decodebin2);
//we need to finish linking the pipeline later...
appsrc.set("emit-signals", true);
appsrc.connect(new AppSrc.NEED_DATA() { ...
Кроме того, вам нужно добавить прослушиватель для случаев, когда в decodebin2 создаются пэды, после чего вам нужно закончить связывание конвейера.
/* listen for newly created pads */
decodebin2.connect(new Element.PAD_ADDED() {
public void padAdded(Element element, Pad pad) {
System.out.println("New Pad " + pad.getName() + " was created");
Element.linkMany(decodebin2, ffmpegcolorspace, videosink);
}
});
Вот и все.
Я надеюсь, что это помогает кому-то еще.