Created
May 15, 2023 15:24
-
-
Save msilvestre/a0232d2552d0173b3495626163d8444f to your computer and use it in GitHub Desktop.
gstreamer with SDL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <gst/gst.h> | |
#include <thread> | |
#include <iostream> | |
#include <gst/app/gstappsink.h> | |
#include <SDL.h> | |
// SDL window dimensions | |
#define SCREEN_WIDTH 640 | |
#define SCREEN_HEIGHT 480 | |
bool quit = false; | |
#define VERIFY_GST_NULL(ELEMENT) if (!ELEMENT) {std::cout << ">>>>>>>" << #ELEMENT " is null!" << std::endl; return 0;} | |
int main(int argc, char *argv[]) { | |
// Initialize GStreamer | |
gst_init(0, NULL); | |
// Create the pipeline | |
GstElement *pipeline = gst_pipeline_new("video-player"); | |
GstElement* videoSrc = gst_element_factory_make("videotestsrc", "video_src"); | |
GstElement *videoConvert = gst_element_factory_make("videoconvert", "video_decoder"); | |
GstAppSink *sink = GST_APP_SINK(gst_element_factory_make("appsink", "sink")); | |
VERIFY_GST_NULL(pipeline) | |
VERIFY_GST_NULL(videoConvert) | |
VERIFY_GST_NULL(sink) | |
auto videoConvert_src_pad = gst_element_get_static_pad(videoConvert, "src"); | |
auto videoConvert_src_caps = gst_caps_new_simple("video/x-raw", | |
"format", G_TYPE_STRING, "BGRA", | |
"width", G_TYPE_INT, SCREEN_WIDTH, | |
"height", G_TYPE_INT, SCREEN_HEIGHT, | |
NULL); | |
gst_pad_set_caps(videoConvert_src_pad, videoConvert_src_caps); | |
// Set the sink element to push data to the app | |
gst_app_sink_set_emit_signals(sink, true); | |
gst_app_sink_set_drop(sink, true); | |
gst_app_sink_set_max_buffers(sink, 1); | |
gst_app_sink_set_caps(sink, gst_caps_new_simple("video/x-raw", | |
"format", G_TYPE_STRING, "BGRA", | |
"width", G_TYPE_INT, SCREEN_WIDTH, | |
"height", G_TYPE_INT, SCREEN_HEIGHT, | |
NULL)); | |
gst_bin_add_many(GST_BIN (pipeline), | |
videoSrc, | |
videoConvert, | |
sink, | |
NULL); | |
gst_element_link_many(videoSrc, videoConvert, sink, NULL); | |
// Start the pipeline | |
gst_element_set_state(pipeline, GST_STATE_PLAYING); | |
// Create the SDL window | |
SDL_Init(SDL_INIT_VIDEO); | |
SDL_Window *window = SDL_CreateWindow("GStreamer + SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); | |
// Create the SDL renderer | |
auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | |
// Create the SDL surface | |
auto surface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0); | |
SDL_Event e; | |
while (!quit) { | |
// Get the buffer from the appsink | |
GstSample *sample = gst_app_sink_pull_sample(sink); | |
if (!sample) | |
{ | |
std::cout << ">>>>> No Sample from appsink!\n"; | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
continue; | |
} | |
GstBuffer *buffer = gst_sample_get_buffer(sample); | |
// Get the buffer data | |
GstMapInfo info; | |
gst_buffer_map(buffer, &info, GST_MAP_READ); | |
SDL_LockSurface(surface); | |
memcpy(surface->pixels, info.data, surface->pitch * surface->h); | |
SDL_UnlockSurface(surface); | |
// Unmap the buffer | |
gst_buffer_unmap(buffer, &info); | |
// Release the sample | |
gst_sample_unref(sample); | |
auto texture = SDL_CreateTextureFromSurface(renderer, surface); | |
SDL_RenderCopy(renderer, texture, NULL, NULL); | |
SDL_DestroyTexture(texture); | |
SDL_RenderPresent(renderer); | |
while (SDL_PollEvent(&e)) { | |
if (e.type == SDL_QUIT) { | |
quit = 1; | |
break; | |
} | |
} | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
} | |
// Stop the pipeline | |
gst_element_set_state(pipeline, GST_STATE_NULL); | |
// Release the GStreamer elements | |
//gst_object_unref(sink); | |
//gst_object_unref(videoConvert); | |
//gst_object_unref(videoSrc); | |
//gst_object_unref(pipeline); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment