2017-12-13 27 views
0

gstreamer의 appsrc 요소를 사용하여 이미지를 gstreamer의 파이프 라인으로 비디오 스트림으로 보내고 싶습니다. appsrc 예제에서 시간 기반 스트리밍 형식이 사용됩니다. 각 버퍼에는 0.5 초의 타임 스탬프 단계가 있고 'need-data'콜백은 0.5 초마다 호출합니다.사용 방법 gst_app_src_push_buffer()를 맞춤 이벤트와 함께 수동으로 사용하기

내 경우에는이 기능이 필요하지 않지만 이미지를 보낼 준비가되면 직접 gst_app_src_push_buffer()를 사용해야합니다.

나는 다음과 같은 초기화 코드 (간체, 의사)를 사용

:

void Foo::initializeGst() 
{ 
    // Init gstreamer. 
    ::gst_init(nullptr, nullptr); 

    // Configure appsrc element. 
    m_appsrc = ::gst_element_factory_make(
       "appsrc", "source"); 

    ::g_object_set(G_OBJECT(m_appsrc), 
        "stream-type", GST_APP_STREAM_TYPE_STREAM, 
        "is-live", true, 
        nullptr); 

    // Configure appsrc caps. 
    const auto caps = ::gst_caps_new_simple(
       "video/x-raw", 
       "format", G_TYPE_STRING, "BGRA", 
       "width", G_TYPE_INT, 800, 
       "height", G_TYPE_INT, 600, 
       "framerate", GST_TYPE_FRACTION, 0, 1, 
       nullptr); 

    ::g_object_set(G_OBJECT(m_appsrc), 
        "caps", caps, 
        nullptr); 

    // Configure video convertor element. 
    const auto conv = ::gst_element_factory_make(
       "videoconvert", "conv"); 

    // Configure video encoder element. 
    const auto videoenc = ::gst_element_factory_make(
       "x264enc", "video_encoder"); 

    // Configure payloader element. 
    const auto payloader = ::gst_element_factory_make(
       "rtph264pay", "payloader"); 

    ::g_object_set(G_OBJECT(payloader), 
        "config-interval", 60, 
        nullptr); 

    // Configure udpsink element. 
    const auto udpsink = ::gst_element_factory_make(
       "udpsink", "udpsink"); 

    ::g_object_set(G_OBJECT(udpsink), 
        "host", "127.0.0.1", 
        "port", 50666, 
        nullptr); 

    // Build pipeline. 
    m_pipeline = ::gst_pipeline_new("pipeline"); 

    ::gst_bin_add_many(GST_BIN(m_pipeline), 
         m_appsrc, 
         conv, 
         videoenc, 
         payloader, 
         udpsink, 
         nullptr); 

    const auto result = ::gst_element_link_many(
       m_appsrc, conv, videoenc, payloader, udpsink, nullptr); 

    if (!result) { 
     qDebug() << "Unable to initialize the GST"; 
    } else { 
     // Play. 
     const auto status = ::gst_element_set_state(m_pipeline, GST_STATE_PLAYING); 
     qDebug() << "Status:" << status; 
    } 
} 

그리고 다음 버퍼 액세스 코드 (간체, 의사) :

void Foo::setImage(const QImage &image) 
{ 
    GstBuffer *buffer = gst_buffer_new_and_alloc(m_image.byteCount()); 
    const auto bytesCopied = ::gst_buffer_fill(
       buffer, 0, m_image.constBits(), m_image.byteCount()); 

    const auto result = ::gst_app_src_push_buffer(
       GST_APP_SRC(m_appsrc), buffer); 

    qDebug() << "Push result" << result << "for copied bytes" 
      << bytesCopied; 
} 

하지만, 아무것도, 내가 한 일이 없습니다를 비디오 스트림을 보지 못한다. (SDP 파일과 함께) VLC 플레이어를 사용하고, 얼마 후에 응용 프로그램이 충돌합니다. 나는 "필요 데이터"신호 및 GST_FORMAT_TIME 옵션을 사용하는 경우

그러나 : 나는 전혀 이해하지 못했다

::g_object_set(G_OBJECT(appsrc), 
       "stream-type", 0, 
       "is-live", TRUE, 
       "format", GST_FORMAT_TIME, 
       nullptr); 

g_signal_connect(appsrc, "need-data", G_CALLBACK(need_data_cb), nullptr); 

static void need_data_cb(GstElement *appsrc, guint unused_size, gpointer user_data) 
{ 
    static gboolean white = FALSE; 
    static GstClockTime timestamp = 0; 

    const guint size = 800 * 600 * 4; 
    GstBuffer *buffer = ::gst_buffer_new_allocate(nullptr, size, nullptr); 

    // This makes the image black/white. 
    ::gst_buffer_memset(buffer, 0, white ? 0xff : 0x0, size); 

    white = !white; 

    GST_BUFFER_PTS(buffer) = timestamp; 
    GST_BUFFER_DURATION(buffer) = ::gst_util_uint64_scale_int (1, GST_SECOND, 20); 

    timestamp += GST_BUFFER_DURATION(buffer); 

    GstFlowReturn ret; 
    ::g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret); 

    ::gst_buffer_unref(buffer); 
} 

다음 작동을 ..., 나는에 필요한 타임 스탬프 및 GST_FORMAT_TIME 옵션없이 작동하도록 변경하십시오.

누군가 나를 도와 줄 수 있습니까?

BR, 데니스

답변

0

아 .. 내가 바보, 미안 해요.

이 셋업 enougth는 GST_FORMAT_TIME이다

::g_object_set(G_OBJECT(appsrc), 
       "stream-type", 0, 
       "is-live", TRUE, 
       "format", GST_FORMAT_TIME, 
       nullptr); 

단지 PTS 필드 현재 타임 스탬프 값, 예를 들어, 버퍼로 설정 버퍼 작성에서

QElapsedTimer 사용 .. yeehaa, 이제 모든 일을

void Foo::setImage(const QImage &image) 
{ 
    GstBuffer *buffer = gst_buffer_new_and_alloc(m_image.byteCount()); 
    const auto bytesCopied = ::gst_buffer_fill(
       buffer, 0, m_image.constBits(), m_image.byteCount()); 

    GST_BUFFER_PTS(buffer) = m_timer.nsecsElapsed(); 

    const auto result = ::gst_app_src_push_buffer(
       GST_APP_SRC(m_appsrc), buffer); 

    qDebug() << "Push result" << result << "for copied bytes" 
      << bytesCopied; 
} 

을 :)