2015-01-20 2 views
0

Я написал код для appsrc для приложений, и он работает. Я вижу фактический буфер. Он закодирован в H264 (vpuenc = avc). Теперь я хочу сохранить его в файле (filesink). Как я к нему подхожу?Gstreamer. Записывать приложения в filesink

приложение:

int main(int argc, char *argv[]) { 

gst_init (NULL, NULL); 

GstElement *pipeline, *sink; 
gchar *descr; 
GError *error = NULL; 
GstAppSink *appsink; 

descr = g_strdup_printf ( 
    "mfw_v4lsrc device=/dev/video1 capture_mode=0 ! " // grab from mipi camera 
    "ffmpegcolorspace ! vpuenc codec=avc ! " 
    "appsink name=sink" 
); 
pipeline = gst_parse_launch (descr, &error); 
if (error != NULL) { 
    g_print ("could not construct pipeline: %s\n", error->message); 
    g_error_free (error); 
    exit (-1); 
} 

gst_element_set_state(pipeline, GST_STATE_PAUSED); 
sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); 
appsink = (GstAppSink *) sink; 
gst_app_sink_set_max_buffers (appsink, 2); // limit number of buffers queued 
gst_app_sink_set_drop(appsink, true); // drop old buffers in queue when full 

gst_element_set_state (pipeline, GST_STATE_PLAYING); 


int i = 0; 
while(!gst_app_sink_is_eos(appsink)) 
{ 

    GstBuffer *buffer = gst_app_sink_pull_buffer(appsink); 
    uint8_t* data = (uint8_t*)GST_BUFFER_DATA(buffer); 
    uint32_t size = GST_BUFFER_SIZE(buffer); 

    gst_buffer_unref(buffer); 
} 
return 0; } 

ответ

1

Если, как упоминалось в комментариях, то, что вы на самом деле хотите знать, - это как сделать сетевой видеопоток в GStreamer, вероятно, вы должны закрыть этот вопрос, потому что вы ошибетесь. Для этого вам не нужно использовать appsink или filesink. То, что вы хотите исследовать, - это элементы GStreamer, связанные с RTP, RTSP, RTMP, MPEGTS или даже MJPEG (если ваш размер изображения достаточно мал).

Вот два основных отправить/получить видеопоток трубопроводы:

GST-ответно-0,10 v4l2src! ffmpegcolorspace! videocale! video/x-raw-yuv, width = 640, height = 480! vpuenc! h264parse! rtph264pay! udpsink host = localhost port = 5555

gst-launch-0.10 udpsrc port = 5555! application/x-rtp, encoding-name = H264, полезная нагрузка = 96! rtph264depay! h264parse! ffdec_h264! видеоконвертер! ximagesink

0

Simpler вариант будет записывать в файл непосредственно в самом appsink то есть, когда вы получаете обратный вызов, когда буфер делается запись в файл и убедитесь, что вы закроете его на ЭОС.

Надеюсь, что это поможет.

1

В этой ситуации вы не пишете свой собственный цикл while. Вы регистрируете обратные вызовы и ждете появления буферов (GStreamer 0.10). Если вы используете GStreamer 1.0, вы используете образцы вместо буферов. Образцы - огромная боль в заднице по сравнению с буферами, но хорошо.

Регистрация обратного вызова:

GstAppSinkCallbacks* appsink_callbacks = (GstAppSinkCallbacks*)malloc(sizeof(GstAppSinkCallbacks)); 
appsink_callbacks->eos = NULL; 
appsink_callbacks->new_preroll = NULL; 
appsink_callbacks->new_sample = app_sink_new_sample; 
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), appsink_callbacks, (gpointer)pointer_to_data_passed_to_the_callback, free); 

И ваш обратный вызов:

GstFlowReturn app_sink_new_sample(GstAppSink *sink, gpointer user_data) { 
    prog_data* pd = (prog_data*)user_data; 

    GstSample* sample = gst_app_sink_pull_sample(sink); 

    if(sample == NULL) { 
    return GST_FLOW_ERROR; 
    } 

    GstBuffer* buffer = gst_sample_get_buffer(src); 

    GstMemory* memory = gst_buffer_get_all_memory(buffer); 
    GstMapInfo map_info; 

    if(! gst_memory_map(memory, &map_info, GST_MAP_READ)) { 
    gst_memory_unref(memory); 
    gst_sample_unref(sample); 
    return GST_FLOW_ERROR; 
    } 

    //render using map_info.data 

    gst_memory_unmap(memory, &map_info); 
    gst_memory_unref(memory); 
    gst_sample_unref(sample); 

    return GST_FLOW_OK; 
} 

Вы можете сохранить время цикла, как это - с помощью gst_app_sink_is_eos() - но убедитесь, что поставить сон в этом. Большая часть времени я использую что-то вроде вместо следующего:

GMainLoop* loop = g_main_loop_new(NULL, FALSE); 
g_main_loop_run(loop); 
g_main_loop_unref(loop); 

Примечания: Если вам нужно сделать что-то особенное с данными, вы можете использовать элемент «filesink» непосредственно.

+0

Кроме того, если вы не знаете, что делаете, я бы не рекомендовал, чтобы appslink отбрасывали h264-буферы. Поместите элемент очереди дальше по конвейеру и удалите буферы необработанных видеокадров, но не данные .264 ... – mpr

+0

Моя цель - передавать данные в реальном времени в сети. –

+0

Если ваша цель - поток в сеть, вы полностью лаяете по неправильному дереву. Вы хотите посмотреть на сетевые приемники, связанные с RTP, RTMP, MPEGTS и т. Д. Какой стандарт передачи вы собираетесь использовать? – mpr

Смежные вопросы