嵌入式项目_嵌入式Linux项目分享_linux系统编程

分享一个适合入门嵌入式linux系统编程的项目,其他项目见:https://www.nowcoder.com/discuss/1018842

项目一:基于Linux6818开发版的视频播放器(可提供源码)

1、 项目描述

本项目基于嵌入式linux6818开发板,制作一个音视频播放器。开发板移植安装好mplayer,我提前下载了5个mv,使用mplayer命令分别在5个视频里截取某一秒的画面,共得到5张图片,也就是所谓的视频缩略图,将5个缩略图显示在显示屏的右边,当作是播放列表,支持上下滑动浏览播放列表,点击其中某个图片,即可播放对应视频,并实现播放器常见的开始、停止、上下首、音量调节、进度调节、全屏、静音等功能。

2、使用到的技术

● 多进程通讯:有名管道、消息队列、信号量;

● 多线程通讯:互斥锁、条件变量;

● 其他知识:C语言、链表、嵌入式开发;

● mplayer:mplayer移植(自行百度,很多资料,跟着敲指令即可),语法(可参考:https://blog.csdn.net/weixin_43288201/article/details/105847664);

3、推荐人群

该项目适合正在学习嵌入式Linux系统编程的同学,可以让你更高效了解多进程、多线程通讯,如消息队列,信号量,互斥锁、条件变量等知识点。

4、 项目源码讲解

4.1 运行

在命令行输入:./app video 即可。

其中app是源码通过makefile编译出来的可执行文件,video是你自己去创建的一个目录,里面放着各种mp4视频,我这边没有提供这个目录。

4.2 文件目录

4.2.1 src目录

main.c:主文件

secondary.c:副文件

pthread.c:子线程文件

lcd.c:对lcd显示屏的操作文件

freetype.c:字符操作文件

file_list.c:对照片的操作的文件,如如何打印,打印下一张或者上一张

display_jpeg.c:存放对jpeg图片的打印函数,包括特效打印

4.2.2 include目录

src目录中的c文件对应的头文件,以及jpeg图像和freetype2字符库相关的头文件。

4.2.3 lib目录

jpeg图片库和freetype2字符库(本项目需要在显示屏显示图片和显示字符)。

4.2.4 data目录

simsun.ttc :宋体库,为了在屏幕上显示中文。

4.2.5 material目录

我在百度找到的一些图片,比如开始播放,停止播放的jpg图片。

4.3 源码逻辑

1、在main.c文件的主函数先初始化各种互斥锁,条件变量,FIFO管道,并且遍历material目录下的图片信息,主要是获取图片的像素信息,如图片高度/宽度。接着遍历video视频目录里的视频,获取视频信息,以及获取每个视频的一帧截图,遍历的结果都是放在链表里面;

2、 初始化显示屏,并在显示屏上面:如right_display_picture()是在显示屏右边将视频截图显示出来,然后就可以点击每个截图来播放对应的视频;display_main_material()把material目录下的图片显示在屏幕上,

3、 创建一个子进程,并使用mplayer播放视频;

4、 创建3个子线程,这三个子线程的代码在pthread.c :

1)查询触屏指令的get_main_instrcution()

2)写指令来获取视频播放进度的write_command():该子线程一直写{"get_percent_pos\n","get_time_length\n"}来查询播放进度,为何是写这个指令,是mplayer工具规定的。可见上述参考链接;

3)获取视频播放进度信息的get_video_info():通过write_command和get_video_info两个子线程,就能实时获取播放进度,实时更新进度条啦。

5、 最后就是在主函数的while循环里,等待get_main_instrcution子线程有触摸事件后,主函数再去执行对应操作,如“下一首”,“静音”等。

可提供源码和技术交流,以下是main函数,其他源码有偿提供:

#include <file_list.h>
#include <lcd.h>
#include <display_jpeg.h>
#include <pthread.h>
   

int main(int argc, const char *argv[])
{
	int lcd_fd; //打开lcd设备
	
	int retval; 
	
	int first_video_pid;//打开播放第一个视频的pid
	g_wWrite_command_flg = 1;
	g_wPrint_type = 0;
	/***************初始化互斥锁和条件变量***********/
	pthread_mutex_init(&g_write_command_m,NULL);
	pthread_cond_init(&g_write_command_v,NULL);

	pthread_mutex_init(&g_main_instruction_m,NULL);
	pthread_cond_init(&g_main_instruction_v,NULL);

	/**********创建保存文件信息的链表并初始化*********/
    g_video_head_node = create_file_link_init();

    /**********遍历整个目录,将视频文件保存下来********/
	retval = list_for_all_file(argv[1],g_video_head_node); 
	PrintError(retval,"list for all file failed");

	/**********创建保存jpeg信息的链表并初始化*********/
    g_jpeg_head_node = create_jpeg_link_init();

    /**********遍历整个目录,将jepg文件保存下来*******/
	retval = list_for_all_jpeg_file("material",g_jpeg_head_node); 
	PrintError(retval,"list for all jpeg file failed");

	/**********打开lcd设备,获得地址映射地址**********/
	lcd_fd = open_lcd_device(&p_wLcd_fb_ptr);
	PrintError(lcd_fd,"open lcd failed");
    
	/****************创建有名管道*******************/
	OpenFifo(PATH_COMMAND);
	OpenFifo(PATH_INFORMATION);
	/*************打开写命令的FIFO******************/
	int fifo_command_fd = open(PATH_COMMAND, O_RDWR);
	PrintError(fifo_command_fd,"open fifo error");
  
   
	/***************打开获得触屏指令的POSIX有名信号量********************/
	sem_t *g_main_instruction_sem;
	g_main_instruction_sem = sem_open(MAIN_SEMNAME, O_CREAT, 0777, 0);
	/**************逐一显示一帧图片 检验遍历目录是否正确***************
	display_all_jpeg(p_wLcd_fb_ptr, g_video_head_node); */
 	
	/**************在lcd右边打印预览界面,获得指向当前图像的指针**********/
	g_now_jpeg_pos = (&(g_video_head_node->list))->next;
	right_display_picture(p_wLcd_fb_ptr,g_now_jpeg_pos,g_video_head_node);

	/******************创建子进程,播放第一个视频*******************/
 	g_now_play_pos = g_now_jpeg_pos;
	first_video_pid = fork();
	if(first_video_pid == 0)
	{   
		int fifo_fd2;
		fifo_fd2 = open(PATH_INFORMATION, O_RDWR);
		dup2(fifo_fd2,STDOUT_FILENO);
		
		linklist_t ptr;
		ptr = list_entry(g_now_play_pos, linknode_t, list);
		execlp("mplayer","mplayer","-slave","-quiet","-input","file=/tmp/videoplayer/myfifo","-geometry",\
							"0:0","-zoom","-x","610","-y","370",ptr->info.file_name,NULL);
		exit(0);
	}
	waitpid(first_video_pid,NULL,WNOHANG); //非阻塞等待

	/***************打开查询触屏、写指令、读视频信息的3个线程*****************/
	pthread_t get_main_instrcution_tid;
	pthread_create(&get_main_instrcution_tid, NULL, get_main_instrcution, NULL);

	pthread_t write_command_tid;
	pthread_create(&write_command_tid, NULL, write_command, NULL);

	pthread_t get_video_info_tid;
	pthread_create(&get_video_info_tid, NULL, get_video_info, (void*)p_wLcd_fb_ptr);

	
	/********打印素材图片*******/
	display_main_material(p_wLcd_fb_ptr,g_jpeg_head_node);
	/********将进度条、声音控制条的背景纯色化******************/
	clean_main_rate_frame_buf(p_wLcd_fb_ptr);
	clean_main_sound_frame_buf(p_wLcd_fb_ptr);
	void *ret;

	/***********开始操作触摸屏*************/
	int continue_flg = 1;
	while(continue_flg&&1)
	{
		/*****等待有触屏操作,防止重复执行上一个命令,进入死循环********/
		sem_wait(g_main_instruction_sem);
		/************按触屏指令进行操作****************/
		main_interface_control(g_main_instruction);
	}

	/******************回收线程******************/
	pthread_join(get_main_instrcution_tid,NULL);
	pthread_join(write_command_tid,NULL);   
	pthread_join(get_video_info_tid,NULL);
	
	/*************关闭lcd,删除视频文件链表***********/
	close_lcd_device(lcd_fd, p_wLcd_fb_ptr,g_video_head_node);

	return 0;
}     



牛客高级系列专栏:

#嵌入式##嵌入式招聘嵌入式面经CVTE##嵌入式面经##嵌入式工程师##项目#
全部评论
源码多少钱😁
点赞 回复 分享
发布于 2022-10-07 15:54 广东

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
19
172
分享
牛客网
牛客企业服务