#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <ui.h>
#include <stdlib.h>
#include <stdint.h>
#include “lvgl.h”
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
static int g_indev_rotation = 0;
static int g_disp_rotation = LV_DISP_ROT_NONE;
static int quit = 0;
// static GstMapInfo map;
static lv_img_dsc_t img_dsc;
static lv_obj_t *img = NULL;
static int frame_index = 0;
static void sigterm_handler(int sig)
{
fprintf(stderr, “signal %d\n”, sig);
quit = 1;
}
int app_disp_rotation(void)
{
return g_disp_rotation;
}
typedef struct
{
// 这里可以添加你需要的任何变量或函数指针
// …
GstElement *pipeline;
GstElement *sink;
} GStreamerApp;
GstFlowReturn on_new_sample(GstAppSink appsink)
{
/ 获取样本和缓冲区 */
GstSample *sample = gst_app_sink_pull_sample(appsink);
GstBuffer *buffer = gst_sample_get_buffer(sample);
GstCaps *caps;
GstStructure *structure;
gboolean ret;
int width, height;
GstMapInfo map;
/* 映射缓冲区以便读取 */
if (!gst_buffer_map(buffer, &map, GST_MAP_READ))
{
printf(“Error: Unable to map buffer\n”);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
caps = gst_sample_get_caps(sample);
if (!caps)
{
printf(“Error: No caps available\n”);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
/* 获取 caps 中的第一个结构(对于视频,这通常是唯一的) */
structure = gst_caps_get_structure(caps, 0);
if (structure == NULL)
{
// 没有结构,这是错误的
gst_caps_unref(caps);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
/* 获取样本的caps信息、宽度和高度 */
ret = gst_structure_get_int(structure, “width”, &width);
if (!ret)
{
printf(“Error: Unable to get width\n”);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
ret = gst_structure_get_int(structure, “height”, &height);
if (!ret)
{
printf(“Error: Unable to get height\n”);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
printf(“Video Width: %d, Video Height: %d\n”, width, height);
/* 检查缓冲区是否为空 */
if (map.data == NULL)
{
printf(“Error: Buffer data is NULL\n”);
gst_buffer_unmap(buffer, &map);
gst_sample_unref(sample);
return GST_FLOW_ERROR;
}
/* 设置lvgl图像描述符 */
img_dsc.header.always_zero = 0;
img_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
img_dsc.header.w = width;
img_dsc.header.h = height;
img_dsc.data_size = map.size;
img_dsc.data = map.data; // 使用GStreamer映射的数据
// memset(&img_dsc, 0, sizeof(lv_img_dsc_t));
lv_img_set_src(img, &img_dsc);
/* 清理释放资源 */
gst_buffer_unmap(buffer, &map);
gst_sample_unref(sample);
gst_caps_unref(caps);
frame_index++;
printf(“Frame %d updated at %ld\n”, frame_index, (long)time(NULL));
return GST_FLOW_OK;
}
GstFlowReturn onNewSampleCallback(GstAppSink *appsink, gpointer user_data)
{
GStreamerApp *gstreamerApp = (GStreamerApp *)user_data;
printf(“appsink 接受到新样本\n”);
return on_new_sample(appsink);
}
void init_gstreamer(GStreamerApp gstreamerApp)
{
gst_init(NULL, NULL);
/创建并解析 GStreamer 管道,该管道从文件读取视频,解码,转换格式为 RGB,并发送到 appsink/
gstreamerApp->pipeline = gst_parse_launch("filesrc location=/media/test_movie.avi ! decodebin name=decoder "
"decoder. ! videoconvert ! appsink name=sink "
“decoder. ! autoaudiosink”,
NULL);
if (!gstreamerApp->pipeline)
{
printf(“Failed to create GStreamer pipeline\n”);
return;
}
/// 获取 appsink 元素*/
gstreamerApp->sink = gst_bin_get_by_name(GST_BIN(gstreamerApp->pipeline), “sink”);
g_object_set(gstreamerApp->sink, “caps”, gst_caps_new_simple(“video/x-raw”, “format”, G_TYPE_STRING, “RGB”, NULL), NULL);
g_object_set(gstreamerApp->sink, “emit-signals”, TRUE, NULL);
/* // 连接信号处理函数*/
g_signal_connect(gstreamerApp->sink, “new-sample”, G_CALLBACK(onNewSampleCallback), gstreamerApp);
/// 设置管道状态为 READY/
gst_element_set_state(gstreamerApp->pipeline, GST_STATE_READY);
GstStateChangeReturn ret = gst_element_get_state(gstreamerApp->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
if (ret != GST_STATE_CHANGE_SUCCESS)
{
printf(“Error: GStreamer pipeline failed to enter READY state\n”);
return;
}
/// 设置管道状态为 PLAYING/
gst_element_set_state(gstreamerApp->pipeline, GST_STATE_PLAYING);
}
// 主程序
int main(int argc, char *argv)
{
setbuf(stdout, NULL);
UI_Init();
signal(SIGINT, sigterm_handler);
GStreamerApp gstreamerApp;
init_gstreamer(&gstreamerApp);
img = lv_img_create(lv_scr_act());
lv_obj_set_size(img, 1024, 600); / 设置图像对象大小为屏幕分辨率 */
lv_obj_center(img);
while (!quit)
{
lv_timer_handler();
usleep(5000);
}
// 清理 GStreamer 资源
if (gstreamerApp.pipeline)
{
gst_element_set_state(gstreamerApp.pipeline, GST_STATE_NULL);
gst_object_unref(gstreamerApp.sink);
gst_object_unref(gstreamerApp.pipeline);
}
return 0;
}