QUYẾT
tôi tìm thấy giải pháp của tôi, và những gì sau là một bài dài nhưng làm ơn, trần với tôi, tôi phải chia sẻ sự thất vọng của tôi với một ai đó.
Sau nhiều lần thử nhiều lần, tôi quyết định quay trở lại để thử nghiệm một số thiết lập bằng gst-launch. Điều này đã giúp tôi tìm ra rằng sau khi phần tử xếp hàng đệm phần mà đi đến các tập tin tôi cần một yếu tố ffmpegcolorspace để thiết lập các định dạng video chính xác tôi nghĩ. Tại thời điểm này tôi đã không trở lại để cố gắng điều này ra nó Haskell một lần nữa, tôi nghĩ rằng tôi cần thiết để có được 'gần gũi hơn' vì vậy tôi quyết định thử nó trong C. Như một mặt lưu ý, tôi không biết C, tôi có thể hiểu cú pháp nhưng đó là về nó ... và vì sự tốt lành vì tôi chỉ đang cố học Haskell. Để tiếp tục, tôi quyết định thử sử dụng 'GS.elementGetCompatiblePad' trên phần tử tee để tôi có thể chắc chắn rằng các miếng đệm sẽ liên kết với hàng đợi.
Mã C i khâu lại với nhau là thế này:
#include <gst/gst.h>
#include <glib.h>
int
main (int argc,char *argv[])
{
GstElement *pipeline, *source, *color, *color2 , *color3, *tee, *rQ, *vQ, *encoder, *fSink , *sink;
GMainLoop *loop;
loop = g_main_loop_new (NULL,FALSE);
/* initialize gstreamer */
gst_init(&argc,&argv);
/* creating elements */
pipeline = gst_pipeline_new("stream-pipeline");
source = gst_element_factory_make ("v4l2src","stream-source");
color = gst_element_factory_make ("ffmpegcolorspace","video-color");
tee = gst_element_factory_make ("tee","stream-tee");
rQ = gst_element_factory_make ("queue","record-queue");
vQ = gst_element_factory_make ("queue","video-queue");
encoder = gst_element_factory_make ("theoraenc","video-encoder");
fSink = gst_element_factory_make ("filesink","record-sink");
sink = gst_element_factory_make ("ximagesink","video-sink");
color2 = gst_element_factory_make ("ffmpegcolorspace","video-color2");
color3 = gst_element_factory_make ("ffmpegcolorspace","video-color3");
/*check that the elements were created */
if (!source || !color || !tee || !rQ || !vQ || !encoder || !fSink || !sink){
g_printerr("One element could not be created!");
return -1;
}
/*set file output location */
g_object_set(G_OBJECT (fSink),"location","rec",NULL);
gst_bin_add_many (GST_BIN(pipeline),
source,color,color2,color3,tee,rQ,vQ,encoder,fSink,sink,NULL);
/* get request pads */
GstPad *dPad, *rPad, *sDPad, *sRPad;
sDPad = gst_element_get_static_pad(vQ,"sink");
sRPad = gst_element_get_static_pad(rQ,"sink");
dPad = gst_element_get_compatible_pad(tee,sDPad,GST_CAPS_ANY);
rPad = gst_element_get_compatible_pad(tee,sRPad,GST_CAPS_ANY);
/*link pads*/
gst_pad_link(dPad,sDPad);
gst_pad_link(rPad,sRPad);
/*unref pads */
gst_object_unref(GST_OBJECT(dPad));
gst_object_unref(GST_OBJECT(rPad));
gst_object_unref(GST_OBJECT(sDPad));
gst_object_unref(GST_OBJECT(sRPad));
/*link elements */
gst_element_link(source,tee);
gst_element_link_many(rQ,color2,encoder,fSink,NULL);
gst_element_link_many(vQ,color3,sink),NULL;
/*set the pipeline state to playing */
gst_element_set_state(pipeline,GST_STATE_PLAYING);
g_main_loop_run (loop);
gst_element_set_state(pipeline,GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));
return 0;
}
Để sử dụng 'gst_element_get_compatible_pad' tôi đã phải đầu tiên có được miếng đệm tĩnh từ các yếu tố hàng đợi vì vậy tôi tay để chuyển những bốn dây chuyền liên quan. Tôi dùng thử, và Abracadabra ... ồ không, chờ ... camera bắt đầu, tập tin được tạo và một cửa sổ có cửa sổ 'video', nhưng một cửa sổ đen vẫn còn đen!
Không có vấn đề gì tôi nói, hãy chạy chương trình với gst-debug-level = 5 (=))) yea, phải, thử đọc toàn bộ output.I bỏ cuộc và tôi nghĩ có lẽ nó có thứ gì đó làm với các yếu tố trong đường ống của tôi không làm việc ngay với nhau vì vậy tôi mã một đường ống trong C nhưng lần này một cái gì đó đơn giản hơn chỉ với các tập tin âm thanh.
Tôi đã có kết quả tương tự vì vậy tôi quyết định tu gỡ lỗi một lần nữa, lần này với runlevel 3 và tôi bắt đầu đọc toàn bộ điều, từng dòng một.
Một nơi nào đó ở đó tôi thấy điều này:
cố gắng liên kết dòng chữ I: src0 và kỷ lục đợi: chìm
cố gắng liên kết dòng chữ I: src0 và video đợi: chìm
một cái gì đó khó chịu đang xảy ra ở đây
liên kết luồng-tee: src0 và video-queue: sink, thành công
cố gắng liên kết stream-tee: src0 và record-queue: sink
src stream-tee: src0 đã được liên kết với video-queue: sink
Và nó bỏ cuộc!
Tôi đoán tôi phải quay trở lại bằng cách sử dụng gst_element_get_request_pad, nhưng tôi chưa thử điều đó chưa? Vì vậy, tôi chuyển về vim và thay thế tất cả các lần xuất hiện của 'gst_element_get_compatible_pad với các đối tác yêu cầu như vậy:
sDPad = gst_element_get_static_pad(vQ,"sink");
sRPad = gst_element_get_static_pad(rQ,"sink");
dPad = gst_element_get_request_pad(tee,"src%d");
rPad = gst_element_get_request_pad(tee,"src%d");
Tôi nhìn vào mã này và tôi nói với bản thân mình 'bạn twit', đây là nơi mà tất cả bắt đầu ; hít một hơi thật sâu; sau khi tất cả điều này là những gì trình gỡ lỗi phàn nàn về vì vậy tôi biên dịch, tôi chạy, và Voila. Tôi tìm thấy giải pháp của tôi.
Bốn dòng này phải được đảo ngược, trước tiên tôi phải có tham chiếu đến các miếng đệm tĩnh và sau đó yêu cầu tham chiếu đến miếng đệm 'yêu cầu' trên phần tử tee.
Tôi quay trở lại haskell một người đàn ông hạnh phúc.Tôi thực hiện giải pháp của tôi, biên dịch, cháy lên, máy ảnh bắt đầu, các tập tin được tạo ra và ... chỉ cần như vậy..nothing, thậm chí không màn hình màu đen.
Đầy giận dữ tôi chỉ bình luận ra những dòng mà tôi phát hành các miếng đệm yêu cầu và quyết định biên dịch và chạy một lần nữa, cổ của tôi bắt đầu bị tổn thương một thời gian trước đây.
Một lần nữa, bằng phép thuật, tất cả đều hoạt động, tôi có video trên màn hình và trong tệp.
Tôi đoán Haskell chỉ thích giữ chặt hơn và đôi khi bạn phải chỉ cần đi với một cái gì đó mà không có ý nghĩa. Các tài liệu gstreamer tuyên bố rõ ràng phát hành, phát hành, phát hành.
Mã Haskell thức:
module Main(main) where
import qualified Media.Streaming.GStreamer as GS
import Data.Maybe
import System.Exit
import System.Glib.MainLoop as Glib
import System.Glib.Signals as Glib
import System.Glib.Properties as Glib
makeElement:: String → String → IO GS.Element
makeElement elementType elementName = do
element ← GS.elementFactoryMake elementType (Just elementName)
case element of
Just element' → return element'
Nothing → do
putStrLn "Cannot create element!"
exitFailure
linkSPadToStaticSink::(GS.ElementClass object, GS.ElementClass elementT) ⇒ object → elementT → IO (Glib.ConnectId object)
linkSPadToStaticSink elSrc elSink = do
Glib.on elSrc GS.elementPadAdded (λpad → do
sinkPad ← GS.elementGetStaticPad elSink "sink"
GS.padLink pad (fromJust sinkPad)
return ∅)
player = do
GS.init
pipeline ← GS.pipelineNew "video-stream"
source ← makeElement "v4l2src" "video-source"
color ← makeElement "ffmpegcolorspace" "video-color"
color2 ← makeElement "ffmpegcolorspace" "video-color2"
tee ← makeElement "tee" "stream-tee"
rQ ← makeElement "queue" "record-queue"
vQ ← makeElement "queue" "video-queue"
encoder ← makeElement "y4menc" "video-encoder"
rSink ← makeElement "filesink" "record-sink"
sink ← makeElement "ximagesink" "video-sink"
let elements = [source,color,color2,encoder,rSink,vQ,rQ,sink,tee]
Glib.objectSetPropertyString "location" rSink "rec"
mapM_ (GS.binAdd (GS.castToBin pipeline)) elements
-- Get static pads from queue elements
sDPad ← GS.elementGetStaticPad vQ "sink"
sRPad ← GS.elementGetStaticPad rQ "sink"
-- Request pads from tee element
dPad ← GS.elementGetRequestPad tee "src%d"
rPad ← GS.elementGetRequestPad tee "src%d"
-- Link tee source to queue sink
GS.padLink (fromJust dPad) (fromJust sDPad)
GS.padLink (fromJust rPad) (fromJust sRPad)
GS.elementLink source color
GS.elementLink color tee
GS.elementLink vQ sink
GS.elementLink rQ color2
GS.elementLink color2 encoder
GS.elementLink encoder rSink
GS.elementSetState pipeline GS.StatePlaying
main = do
loop ← Glib.mainLoopNew Nothing False
player
Glib.mainLoopRun loop
Bây giờ tôi hỏi bạn, nên/có thể tôi đã thấy điều này?
Điều đó có hiển nhiên không?
Tôi rất vui vì điều này sẽ làm cho tôi cẩn thận hơn và nhìn vào những nơi không rõ ràng nhưng ... eww.
Tóm lại để tất cả điều này, tôi đã học được về các tùy chọn GStreamer gỡ lỗi, tôi đã học được rằng nó thì thầm với tôi và tôi phải lắng nghe. Tôi đã học được về GDB bị buộc phải sử dụng bởi vì khi tôi bắt đầu khâu C mã tất cả tôi đã nhận được là một 'seg lỗi'.
Tôi đã học cách yêu mã lười biếng-eval và Haskell thuần túy.
Một chút Haskell, có thể là một chút xíu của C và nhiều kinh nghiệm hơn. 'Lost' khoảng nửa ngày, ba lớp và một số giờ ngủ nhưng sau khi tất cả ... Vì vậy, nó đi ...
Bạn nên thêm những khám phá của bạn như là một câu trả lời và chấp nhận câu trả lời đó. Nó không được coi là thô lỗ để trả lời câu hỏi của riêng bạn ở đây - nếu bạn đã xảy ra là người đầu tiên khám phá những gì đã sai, nhiều quyền lực hơn cho bạn! –