⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avoutput.c

📁 DawnLightPlayer,一个新的基于ffmpeg的全功能播放器
💻 C
字号:
/********************************************** * Dawn Light Player * *   avoutput.c * * Created by kf701 * 21:39:45 02/25/08 CST * * $Id: avoutput.c 174 2008-03-22 06:30:04Z kf701 $ **********************************************/#include "avcodec.h"#include "swscale.h"#include "avutil.h"#include "avformat.h"#include "avdecode.h"#include "avoutput.h"#include "avinput.h"#include "global.h"static AVPicture	*logo_picture = NULL;static int			init_logo_picture(void);static vo_t	*gl_vo = NULL;static vo_t	*first_vo = NULL;static ao_t	*gl_ao = NULL;static ao_t	*first_ao = NULL;#define REGISTER_VO(X, x)  		\	if( ENABLE_VO_##X )			\	{ 							\		extern vo_t vo_##x; 	\		register_vo(&vo_##x);	\	}#define REGISTER_AO(X, x)	 	\	if( ENABLE_AO_##X ) 		\	{							\		extern ao_t ao_##x; 	\		register_ao(&ao_##x); 	\	}static void register_vo(vo_t *vo){	vo_t **p;	p = &first_vo;	while (*p != NULL) p = &(*p)->next;	*p = vo;	vo->next = NULL;}static void register_ao(ao_t *ao){	ao_t **p;	p = &first_ao;	while (*p != NULL) p = &(*p)->next;	*p = ao;	ao->next = NULL;}vo_t *get_vo_by_name(const char *name){	vo_t *p;	p = first_vo;	while (p)	{		if (strcmp(name,p->name) == 0)			return p;		p = p->next;	}	return NULL;}ao_t *get_ao_by_name(const char *name){	ao_t *p;	p = first_ao;	while (p)	{		if (strcmp(name,p->name) == 0)			return p;		p = p->next;	}	return NULL;}void output_register_all(void){	REGISTER_VO(NULL, null);	REGISTER_VO(SDL, sdl);	REGISTER_VO(X11, x11);	REGISTER_VO(FB, fb);	REGISTER_VO(GL, gl);	REGISTER_VO(DIRECTX, directx);	REGISTER_AO(NULL, null);	REGISTER_AO(ALSA, alsa);	REGISTER_AO(OSS, oss);	REGISTER_AO(SDL, sdl);	REGISTER_AO(DSOUND, dsound);}queue_t *picture_queue = NULL;queue_t *samples_queue = NULL;int av_output_init(void){	av_log(NULL, AV_LOG_INFO, "*************INIT OUTPUT*************\n");	/*-----------------------------------------------------------------------------	 *  audio and video queue new	 *-----------------------------------------------------------------------------*/	picture_queue = dlp_queue_new();	if ( NULL == picture_queue)	{		av_log(NULL,AV_LOG_ERROR,"video output picture queue init ERROR\n");		dlp_exit(-1);	}	av_log(NULL,AV_LOG_INFO,"video output picture queue init OK\n");	samples_queue = dlp_queue_new();	if ( NULL == samples_queue)	{		av_log(NULL,AV_LOG_ERROR,"audio output samples queue init ERROR\n");		dlp_exit(-1);	}	av_log(NULL,AV_LOG_INFO,"audio output samples queue init OK\n");	/*-----------------------------------------------------------------------------	 *-----------------------------------------------------------------------------*/	output_register_all();	/*-----------------------------------------------------------------------------	 *  select audio and video output	 *-----------------------------------------------------------------------------*/	gl_vo = get_vo_by_name(dlpctxp->vo);	if ( NULL == gl_vo )	{		av_log(NULL, AV_LOG_ERROR, "%s output NOT FOUND\n", dlpctxp->vo);		dlp_exit(-1);	}	av_log(NULL, AV_LOG_INFO, "call %s vo_init now\n", gl_vo->name);	if ( gl_vo->vo_init() < 0 )		dlp_exit(-1);	if ( gl_vo->vo_event_loop )		dlp_main_loop = gl_vo->vo_event_loop;	gl_ao = get_ao_by_name(dlpctxp->ao);	if ( NULL == gl_ao )	{		av_log(NULL, AV_LOG_ERROR, "%s output NOT FOUND\n", dlpctxp->ao);		dlp_exit(-1);	}	av_log(NULL, AV_LOG_INFO, "call %s ao_init now\n", gl_ao->name);	if ( gl_ao->ao_init() < 0 )	{		av_log(NULL, AV_LOG_ERROR, "call %s ao_init error\n", gl_ao->name);		dlp_exit(-1);	}	/*-----------------------------------------------------------------------------	 *-----------------------------------------------------------------------------*/	if ( init_logo_picture() < 0 )		av_log(NULL, AV_LOG_ERROR, "init logo picture error\n");	av_log(NULL, AV_LOG_INFO, "*************INIT OUTPUT*************\n");	return 0;}int av_output_uninit(void){	if ( samples_queue )	{		dlp_queue_free(samples_queue, (free_func)av_free_sample);		samples_queue = NULL;	}	if ( picture_queue )	{		dlp_queue_free(picture_queue, (free_func)avpicture_free);		picture_queue = NULL;	}	if ( gl_vo )	{		av_log(NULL, AV_LOG_INFO, "call %s vo_uninit now\n", gl_vo->name);		gl_vo->vo_uninit();	}	if ( gl_ao )	{		av_log(NULL, AV_LOG_INFO, "call %s ao_uninit now\n", gl_ao->name);		gl_ao->ao_uninit();	}	return 0;}static int init_logo_picture(void){	int ret;	AVPicture *pict;	static struct SwsContext *img_convert_ctx;	FILE *fp = fopen( "logo.yuv", "rb" );	if ( NULL == fp )		return -1;	pict = av_mallocz(sizeof(AVPicture));	ret = avpicture_alloc(pict, 0, 320, 240);	if ( -1 == ret )	{		av_log(NULL, AV_LOG_ERROR, "av picture alloc err\n");		av_free(pict);		return -1;	}	fread(pict->data[0], 1, 115200, fp);	fclose(fp);	logo_picture = av_mallocz(sizeof(AVPicture));	ret = avpicture_alloc(logo_picture, 0, dlpctxp->pwidth, dlpctxp->pheight);	if ( -1 == ret )	{		av_log(NULL, AV_LOG_ERROR, "av picture alloc err\n");		av_free(logo_picture);		logo_picture = NULL;		avpicture_free(pict);		av_free(pict);		return -1;	}	img_convert_ctx = sws_getCachedContext(img_convert_ctx,	                                       320, 240,	                                       0,	                                       dlpctxp->pwidth, dlpctxp->pheight,	                                       0, SWS_BICUBIC, NULL, NULL, NULL);	if (img_convert_ctx == NULL)	{		av_log(NULL, AV_LOG_ERROR, "Cannot initialize the conversion context\n");		avpicture_free(pict);		av_free(pict);		avpicture_free(logo_picture);		av_free(logo_picture);		logo_picture = NULL;		return -1;	}	sws_scale(img_convert_ctx, pict->data, pict->linesize,	          0, 240, logo_picture->data, logo_picture->linesize);	avpicture_free(pict);	av_free(pict);	return 0;}/*----------------------------------------------------------------------------- *  audio and video output thread *-----------------------------------------------------------------------------*/static void *audio_output_thread(void *arg){	AVSample *s;	while (1)	{		if ( dlpctxp->paused )		{			usleep(50*1000);			continue;		}		s = dlp_queue_pop_head(samples_queue);		if ( s )		{			gl_ao->ao_play(s);			/* MUST FREE sample here */			av_free_sample(s);			av_free(s);			dlpctxp->last_audio_pts = s->pts;		}		else			dlp_wait_on_queue(samples_queue);	}	return 0;}static void *video_output_thread(void *arg){	AVPicture_t *picture;	AVPicture *pic;	int64_t pre_time, after_time; /* Control FPS */	int rest_time;	int need_show_logo = 0;	while (1)	{		if ( dlpctxp->paused )		{			usleep(50*1000);			continue;		}		pre_time = av_gettime();		picture = dlp_queue_pop_head(picture_queue);		if ( picture )		{			need_show_logo = 0;			pic = (AVPicture*)picture;			gl_vo->vo_display(pic);			after_time = av_gettime();			rest_time = 1000*1000/dlpctxp->fps - (after_time - pre_time);			if ( dlpctxp->last_audio_pts <= 0 ||			        NULL == dlp_actxp ||			        AO_ID_EXAMPLE == gl_ao->id )			{				/* only video, need not sync AV */				goto not_sync_p;			}			if ( dlpctxp->last_audio_pts > picture->pts )			{				rest_time = rest_time / 2;			}			else if ( dlpctxp->last_audio_pts < picture->pts )			{				rest_time = rest_time * 2;			}not_sync_p:			if ( rest_time > 0 )				usleep(rest_time);			/* MUST FREE picture here */			avpicture_free(pic);			av_free(picture);		}		else		{			if ( need_show_logo > 5 && logo_picture )				gl_vo->vo_display(logo_picture);			need_show_logo++;			dlp_wait_on_queue_timeout(picture_queue, 500);		}	}	return 0;}void create_avoutput_thread(void *arg){	pthread_t threadid;	if ( pthread_create(&threadid, NULL, video_output_thread, NULL) )	{		av_log(NULL, AV_LOG_ERROR, "video output thread start error\n");	}	if ( pthread_create(&threadid, NULL, audio_output_thread, NULL) )	{		av_log(NULL, AV_LOG_ERROR, "audio output thread start error\n");	}	av_log(NULL, AV_LOG_INFO, "video output thread start\n");	av_log(NULL, AV_LOG_INFO, "audio output thread start\n");}/*----------------------------------------------------------------------------- *  AV Sample functions *-----------------------------------------------------------------------------*/int av_new_sample(AVSample *s, int size){	s->data = av_malloc(size);	s->size = size;	return 0;}void av_free_sample(AVSample *s){	av_free(s->data);	s->data = NULL;	s->size = 0;}AVSample *av_dup_sample(AVSample *s){	AVSample *new;	new = av_malloc( sizeof(AVSample) );	av_new_sample( new, s->size );	memcpy( new->data, s->data, s->size );	return new;}/*----------------------------------------------------------------------------- *  User Interface functions *-----------------------------------------------------------------------------*/int dlp_add_volume(void){	return gl_ao->ao_control( AO_ADD_VOLUME, NULL );}int dlp_sub_volume(void){	return gl_ao->ao_control( AO_SUB_VOLUME, NULL );}int dlp_pause_ao(void){	return gl_ao->ao_control( AO_PAUSE, NULL );}int dlp_resume_ao(void){	return gl_ao->ao_control( AO_RESUME, NULL );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -