Конвейер GStreamer записывает кадры потока UDP в изображения JPEG, но в некоторых кадрах разбросаны пиксели.C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Конвейер GStreamer записывает кадры потока UDP в изображения JPEG, но в некоторых кадрах разбросаны пиксели.

Сообщение Anonymous »

Я написал код на C++, используя конвейер GStreamer, который принимает поток UDP в качестве входных данных и записывает кадры в изображения JPEG. Однако некоторые выходные изображения имеют разбросанные пиксели и размытость, и я не уверен, что вызывает эту проблему. Входное видео, которое используется в потоке udp, представляет собой четкое и высококачественное видео со скоростью 1 кадр в секунду и форматом H264 (базовый уровень). Мы используем Ubuntu 20.04 в Virtual Box.
Первый код — это серверный код, который создает поток udp из входного видео.

Код: Выделить всё

#include 
#include 

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

// path to your video file
const char *video_path = "./data/test_video.mp4";
// the host address
const char *host_address = "224.1.1.1";
//the port
int port = 5000;

GstElement *pipeline = gst_parse_launch(
g_strdup_printf("filesrc location=%s ! qtdemux ! rtph264pay config-interval=1 ! udpsink host=%s port=%d auto-multicast=true", video_path, host_address, port), NULL);

if (!pipeline) {
g_printerr("Pipeline could not be created.\n");
return -1;
}

GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(pipeline);
return -1;
}

g_print("Streaming video from %s to %s:%d...\n", video_path, host_address, port);
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);

gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
g_main_loop_unref(loop);

return 0;
}
затем второй код использует этот поток и записывает кадры в изображения JPEG.

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 

// Bus message handler
static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
GMainLoop *loop = (GMainLoop *)data;

switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS:
g_print("End of stream\n");
g_main_loop_quit(loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;

gst_message_parse_error(msg, &error, &debug);
g_free(debug);

g_printerr("Error: %s\n", error->message);
g_error_free(error);

g_main_loop_quit(loop);
break;
}
default:
break;
}
return TRUE;
}

// New sample handler for appsink
static GstFlowReturn new_sample(GstElement *sink, gpointer user_data) {
static int frame_count = 1;
GstSample *sample;
GstBuffer *buffer;
GstMapInfo map;

g_signal_emit_by_name(sink, "pull-sample", &sample);
if (sample) {
buffer = gst_sample_get_buffer(sample);
gst_buffer_map(buffer, &map, GST_MAP_READ);

std::string directory = "output/";
std::string filename = directory + "frame_" + std::to_string(frame_count) + ".jpg";
std::ofstream file(filename, std::ios::binary);
file.write(reinterpret_cast(map.data), map.size);
file.close();

gst_buffer_unmap(buffer, &map);
gst_sample_unref(sample);
frame_count++;
return GST_FLOW_OK;
}
return GST_FLOW_ERROR;
}

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

GMainLoop *loop = g_main_loop_new(NULL, FALSE);

const gchar *pipeline_str =
"udpsrc multicast-group=224.1.1.1 auto-multicast=true port=5000 "
"caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264\" "
"! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! videorate ! video/x-raw, framerate=1/1 ! jpegenc ! appsink name=sink sync=false";

GstElement *pipeline = gst_parse_launch(pipeline_str, NULL);

if (!pipeline) {
g_printerr("Pipeline could not be created.  Exiting.\n");
return -1;
}

GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
if (!sink) {
g_printerr("Appsink element could not be found. Exiting.\n");
return -1;
}

g_object_set(G_OBJECT(sink), "emit-signals", TRUE, NULL);
g_signal_connect(sink, "new-sample", G_CALLBACK(new_sample), NULL);

GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

g_print("Running...\n");
g_main_loop_run(loop);

g_print("Returned, stopping playback\n");
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print("Deleting pipeline\n");
gst_object_unref(GST_OBJECT(pipeline));
g_main_loop_unref(loop);

return 0;
}
Код правильно записывает кадры по указанному пути. Однако некоторые выходные изображения JPEG содержат разбросанные пиксели и артефакты.
[img]https://i.sstatic .net/KnP2SgHG.jpg[/img]
Будем очень признательны за любую информацию о том, что может быть причиной этих проблем и как их решить.

Подробнее здесь: https://stackoverflow.com/questions/787 ... frames-hav
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»