GStreamer 03: Basic tutorial 1

Hello world

Posted by NAB on December 13, 2022

Goal

Không gì có thể tốt hơn để có ấn tượng đầu tiên về thư viện phần mềm hơn là in “Hello World” trên màn hình

Nhưng do chúng ta đang đối mặt với multimedia frameworks, chúng ta sẽ chạy một video thay vì in dòng chữ.

Hello world

Copy đoạn code này vào trong file tên basic_tutorial_1.c

basic_tutorial_1.c

#include <gst/gst.h>

int main(int argc, char *argv[])
{
    GstElement *pipeline;
    GstBus *bus;
    GstMessage *msg;

    /* Initialize GStreamer */
    gst_init(&argc, &argv);

    /* Build the pipeline */
    pipeline = gst_parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);

    /* Start playing */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    /* Wait until error or EOS */
    bus = gst_element_get_bus(pipeline);
    msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

    /* See next tutorial for proper error message handling/parsing */
    if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
    {
        g_error("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
                "variable set for more details.");
    }

    /* Free resources */
    gst_message_unref(msg);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

Complie nó như đã mô tả trong phần cài cài đặt. Nếu bạn gặp lỗi khi complie, kiểm tra lại lần nữa hướng dẫn trong phần đó.

Để complie trên Linux di chuyển vào thư mục chứa code và chạy lệnh để complie sau:

gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`

Run

./basic_tutorial_2

Walkthrough

Hãy xem lại các dòng code này và xem chúng làm gì:

gst_init (&argc, &argv);

Đây luôn phải là câu lệnh GStreamer đầu tiên của bạn trong số những thứ khác gst_init():

  • Khởi tạo tất cả các cấu trúc bên trong
  • Kiểm tra các plug-ins nào có sẵn
  • Thực thi bất kỳ tùy chọn dòng lệnh nào dành cho GStreamer các tham số dòng lệnh argcargv cho gst_init() thì ứng dụng của bạn sẽ tự động được hưởng lợi từ các tùy chọn dòng lệnh tiêu chuẩn của GStreamer (biết thêm về điều này trong Basic tutorial 10: GStream tools)
pipeline = gst_parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);

Dòng này là trọng tâm của hướng dẫn này, và minh họa hai điểm chính: gst_parse_launch()playbin.

gst_parse_launch

GStreamer là một framework được thiết kế để xử lý các luồng đa phương tiện. Truyền thông di chuyển từ các phần tử “nguồn - source” (nhà sản xuất) xuống các phần tử “sink” (người dùng), thông qua một loạt các phần tử trung gian và thực hiện tất cả các loại nhiệm vụ. Tập hợp các phần tử liên kết với nhau gọi là “pipeline”.

Trong GStreamer bạn sẽ thường xuyên xây dựng pipeline bằng cách lắp ráp các phần tử riêng lẻ theo cách thủ công, tuy nhiên, khi pipeline đủ dễ dàng, vầ bạn không cần bất kỳ tính năng nâng cao nào, bạn có thể sử dụng cách nhanh hơn là gst_parse_launch().

Hàm này lấy một một biểu diễn dạng văn bản của một pipeline và biến nó thành một một pipeline thực tế, rất tiện dụng. Trong thực tế, chức năng này rất tiện dụng, có một công cụ được xây dựng hoàn toàn xung quanh nó mà bạn rất quen thuộc (xem Basic tutorial 10: GStream tools để học về gst-launch-1.0 và cú pháp của gst-launch-1.0).

playbin

Vậy, loại pipeline nào mà chúng ta yêu cầu gst_parse_launch() xây dựng cho chúng ta? Ở đây đi vào điểm quan trọng thứ hai: Chúng ta xây dựng một pipeline bao gồm một phần tử duy nhất được gọi là playbin.

playbin là một phần tử đặc biệt đóng vai trò là source và sink, đồng thời là toàn bộ pipeline. Bên trong, nó tạo ra và kết nối tất cả các phần tử cần thiết để phát media của bạn, vì vậy bạn không phải lo lắng về điều đó.

Nó không cho phép kiểm soát mức độ chi tiết mà một pipeline thủ công có được, tuy nhiên, nó vẫn cho phép tùy chỉnh đủ để đáp ứng cho nhiều ứng dụng. Bao gồm cả hướng dẫn này.

Trong ví du này, chúng ta chỉ truyền một tham số vào playbin, đó là URI - Uniform Resource Identify (khác với URL - Uniform Resource Locator) của media chúng ta muốn phát. Hãy thử thay đổi nó thành một cái gì khác! Cho dù là một http:// hoặc file:// URI, playbin sẽ khởi tạo GStreamer source một cách minh bạch!

Nếu bạn nhập sai URI hoặc tệp không tồn tại hoặc bạn đang thiếu một plug-in, GStreamer cung cấp một số cơ chế thông báo, nhưng điều duy nhất, đang thực hiện trong ví dụ này là thoát do lỗi, vì vậy đừng mong chờ nhiều phản hồi.

gst_element_set_state (pipeline, GST_STATE_PLAYING);

Dòng này nhắc đến một khái niệm thú vị khác: “state - trạng thái”. Mỗi một phần tử trong GStreamer đều có trạng thái liên quan, mà bạn có thể nghĩ nó là nút Phát/Dừng trong đầu DVD thông thường của bạn. Hiện tại, đủ để nói rằng playback sẽ không bắt đầu trừ khi bạn đặt pipeline cho PLAYING trạng thái.

Trong dòng này, gst_element_set_state() đang set cho pipeline (chỉ có một phần tử - playbin) cho trạng thái PLAYING, do đó bắt đầu playback

bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

Các dòng này sẽ đợi đến khi một lỗi xảy hoặc tìm thấy phần kết thúc của luồng stream. gst_element_set_bus() truy xuất bus của pipeline, và gst_bus_time_pop_filtered() sẽ chặn đến khi bạn nhận được một ERROR hawojc một EOS(End-Of-Stream) qua bus đó. Đừng lo lắng nhiều về dòng này, GStreamer bus được giải thích trong Basic tutorial 2: GStreamer concept.

Từ thời điểm này trở đi, GStreamer sẽ lo mọi thứ. Quá tình thực hiện sẽ kết thức khi luồng stream kết thúc (EOS) hoặc gặp lỗi (ERROR) (thử đóng cửa sổ video hoặc rút cáp mạng). Luôn có thể dừng ứng dụng bằng cách nhất Ctrl + C trong console

Cleanup

Tuy nhiên, trước khi kết thúc ứng dụng, có một số điều chúng ta cần làm để tự dọn dẹp chính xác.

if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
        "variable set for more details.");
}

Hãy luôn đọc tài liệu của các hàm bạn dùng, để biết liệu bạn có nên giải phóng cá đối tượng (objects) chúng trả lại sau khi sử dụng chúng.

Trong trường hợp này, gst_bus_timed_pop_filterd() trả về một thông báo cần được giải phóng bằng gst_message_unref() (chi tiết hơn về các thông báo trong Basic tutorial 2: GStreamer concepts).

gst_element_get_bus() đã thêm một tham số đến bus cần được giải phóng bằng gst_object_unref(). Đặt pipeline thành trạng thái NULL sẽ đảm bảo rằng nó giải phóng mọi tài nguyên mà nó đã phân bố (chi tiết hơn về các trạng thái - states trong Basic tutorial 3: Dynamic pipelines). Cuối cùng, hủy tham chiếu pipeline sẽ phá hủy nó và tất cả nội dung của nó.

Conclusion

Vậy là kết thúc hướng dẫn đầu tiên của bạn với GStreamer.

Hãy tóm tắt lại một số nội dung đã học được:

  • Cách để khởi tạo GStreamer sử dụng gst_init().
  • Cách để xây dựng nhanh một pipeline từ mô tả dạng văn bản sử dụng gst_parse_launch()
  • Cách để tạo một pipeline playback tự động sử dụng playbin.
  • Cách để báo hiệu GStreamer bắt đầu playback sử dụng gst_element_set_state().
  • Cách để ngồi xuống và thư giãn, trong khi GStreamer lo mọi thứ, sử dụng gst_element_get_bus()gst_bus_timed_pop_filtered().

Hướng dẫn tiếp theo sẽ giới thiệu các phần tử cơ bản hơn của GStreamer và chỉ cho bạn các xây dựng pipeline theo cách thủ công.


References