GStreamer 1.0 кодирует raw в H.264 в C - PullRequest
0 голосов
/ 02 июля 2018

Я работаю с GStreamer-1.0 версия: 1.10.4

У меня есть необработанный видеофайл, который я хочу кодировать с помощью h.264, используя GStreamer в C.

Мой конвейер выглядит следующим образом:

gst-launch-1.0 filesrc location = myVideo.yuv blocksize = 2073600! ширина видеопарс = 1920 высота = 1080! расшифровка! видеоконвертер! x264enc! очередь ! mp4mux name = mux! расположение файловой папки = myFile.mp4

Этот конвейер работает нормально, когда я выполняю его в терминале. Но я хочу сделать это с C-API, поэтому мой исходный код выглядит следующим образом:

GstElement* pipeline;

GstElement* src;
GstElement* videoparse;
GstElement* decodebin;
GstElement* videoconvert;
GstElement* x264enc;
GstElement* queue;
GstElement* mp4mux;
GstElement* filesink;

pipeline = gst_pipeline_new("pipeline");

src = gst_element_factory_make("filesrc", NULL);
if(!src) {
    GST_WARNING("Error in: src");
}

g_object_set(G_OBJECT(src),"location","myVideo.yuv",NULL);
g_object_set(G_OBJECT(src),2073600,NULL);

videoparse = gst_element_factory_make("videoparse", NULL);
if(!videoparse) {
    GST_WARNING("Error in: videoparse");
}

g_object_set(G_OBJECT(videoparse),"width",1920,NULL);
g_object_set(G_OBJECT(videoparse),"height",1080,NULL);

decodebin = gst_element_factory_make("decodebin", NULL);
if(!decodebin) {
    GST_WARNING("Error in: decodebin");
}

videoconvert = gst_element_factory_make("videoconvert", NULL);
if(!videoconvert) {
    GST_WARNING("Error in: videoconvert");
}   

x264enc = gst_element_factory_make("x264enc", NULL);
if(!x264enc) {
    GST_WARNING("Error in: x264enc");
}    

queue = gst_element_factory_make("queue", NULL);
if(!queue) {
    GST_WARNING("Error in: queue");
}     

mp4mux = gst_element_factory_make("mp4mux", NULL);
if(!mp4mux) {
    GST_WARNING("Error in: mp4mux");
}     

g_object_set(G_OBJECT(mp4mux),"name","mux",NULL);

filesink = gst_element_factory_make("filesink", NULL);
if(!filesink) {
    GST_WARNING("Error in: filesink");
}     

g_object_set(G_OBJECT(filesink),"location","myFile.mp4",NULL);

gst_bin_add_many(GST_BIN(pipeline),src,videoparse,decodebin,videoconvert,x264enc,queue,mp4mux,filesink, NULL);

gst_element_link(src, videoparse);
gst_element_link(videoparse, decodebin);
gst_element_link(decodebin, videoconvert);
gst_element_link(videoconvert, x264enc);
gst_element_link(x264enc, queue);
gst_element_link(queue, mp4mux);
gst_element_link(mp4mux, filesink);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

sleep(40);

Как я уже сказал, конвейер в терминале работает нормально, но реализация C создает только пустой файл mp4. И я не понимаю почему.

В случае, если это может быть полезно: запись необработанного видеофайла также была сделана с помощью GStreamer. Для этого используется конвейер:

gst-launch-1.0 -e устройство v4l2src = / dev / video0 num-buffers = 300! очередь ! изображение / JPEG, ширина = 1920, высота = 1080, частота кадров = 30/1! jpegdec! видео / x-raw, формат = I420, ширина = 1920, высота = 1080, частота кадров = 30/1! местоположение файла file = myVideo.yuv

Я хотел бы знать, может ли кто-нибудь увидеть ошибку, которую я сделал, или кто-то сталкивался с подобными проблемами.

1 Ответ

0 голосов
/ 05 октября 2018

Вы не проверяете возвращаемые значения каких-либо функций. Связывание элементов может привести к сбою, например, или установка состояния.

В вашем случае проблема заключается в том, чтобы: а) связать декодер с видеоконвертером (у него иногда есть пэды, вам нужно подключиться к сигналу «добавление пэдов» и оттуда ссылку, проверьте документы GStreamer), б) связать очередь с mp4mux (у него есть пэды запроса, вы должны использовать gst_element_get_request_pad () для получения правильного пэда).

В качестве альтернативы вы можете использовать gst_parse_launch () из C и передать строку конвейера. Он даст вам конвейер, эквивалентный тому, который создан инструментом gst-launch-1.0, и он будет выполнять две вещи, которые я упомянул выше, без необходимости об этом беспокоиться.

...