2017-03-09 14 views
0

ARM 프로세서와 Wayland + Qt를 윈도우 하위 시스템으로 사용하는 자체 커스터마이징 용 gstreamer 프레임 워크를 기반으로 간단한 비디오 레코더를 작성하려고합니다. 내가 rec_start 슬롯 클래스 RecordBin을 만들어 공공 방법 rec_stop 한 :이 플레이 MainWindow를 내 슬롯이 버튼을 클릭하면 정지/gstreamer-1.0 GUI를 통한 녹화 파이프 라인 중지 및 시작

void RecordBin::rec_start() 
{ 
    /* Set pipeline to the PLAYING state */ 
    gst_element_set_state (record_pipeline, GST_STATE_PLAYING); 
    g_print ("setting playing state\n"); 

    /* Start main loop context */ 
    g_main_loop_run (rec_loop); 
} 

void RecordBin::rec_stop() 
{ 
    /* Set pipeline to the NULL state */ 
    change_ret = gst_element_set_state (record_pipeline, GST_STATE_NULL); 

    /* Quit from main loop context */ 
    g_main_loop_quit (rec_loop); 
} 

입니다 :

void MainWindow::on_recordButton_clicked() 
{ 
    if (!is_recording) { 
    if (window_is_opened == false) { 
     cout << "start recording" << endl; 

     /* Start recording */ 
     window_is_opened = true; 
     emit start_recording(); 
    } else { 
     cout << "playing window already opened" << endl; 
    } 
    } else { 
    cout << "recording reset" << endl; 

    /* Stop recording */ 
    record_bin->rec_stop(); 
    window_is_opened = false; 
    } 
} 

RecordBin 클래스 것은 별도의 스레드에서 일하고 (이것은 QThread를 통해 실현됩니다) glib mainloop 컨텍스트가 Qt 메인 윈도우를 차단하지 않도록합니다. rec_stop 메서드를 슬롯으로 사용할 수 없습니다. rec_loop은 메시지 처리를 차단하고 녹음이 시작되면 신호를 통해 중지 될 수 없기 때문입니다. 그러나 직접 호출 rec_stop은 스레드가 안전하지 않습니다.

두 사람이 두 가지 질문으로 나를 도울 수 있습니까? 1. 다른 스레드에서 파이프 라인 상태를 어떻게 변경해야합니까? 2. 파이프 라인 상태를 NULL로 변경하여 기록을 중지해야합니까? 버스에서 EOS 신호를 보내고 처리해야 할 것 같습니까?

답변

0

gst_element_set_state()은 MT 안전으로 표시되어 있으므로 모든 스레드에서 중지 할 수 있습니다. gst_element_set_state()을 NULL로 설정하는 데 문제가있었습니다. 파이프 라인 끝에있는 filesink이 출력 파일을 올바르게 완료하지 못했습니다 (EOS를 사용해야하고 filesink에 해당 EOS가 있음을 확인하는 다른 이벤트를 잡아야 함). 하지만 NULL은 플레이어에게 잘 작동합니다.

전반적으로 glib 메인 루프를 없앨 수 있습니다. gst_bus_set_sync_handler()을 사용하여 콜백을 설정할 수 있습니다. 콜백에서 Qt 신호를 RecordBin으로 내 보냅니다. RecordBin은 기본 Qt 스레드에있는 QObject입니다. 도착 슬롯 GstMessage*을 처리하십시오.