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

📄 video_player.cpp

📁 嵌入式linux系统的网络编程(C++) 在ARM上实现视频会议 此程序获得全国研究生电子大赛一等奖 压缩包内为全部源码
💻 CPP
字号:
///////////////////////////////////////////////////////// FileName:	video_player.cpp// Author:		b1gm0use// Project:		myvideo#include <qpainter.h>#include <iostream>#include <qdatetime.h>#include <qimage.h>#include "video_player.h"#include "capture_event.h"#include "video_cap_thread.h"#include "video.h"#include "avi.h"using namespace std;extern int jpeg_decompress(unsigned char *dst, unsigned char *src, int size, int *w, int *h);extern void dump_image ( const BUFF * image, size_t size, const char * filename );///////////////////////////////////////////////////////// Public Functions///////////////////////////////////////////////////////// 构造函数// sfr 为是否显示帧数, zoom_in 为是否放大// 其余三个为widget的子类要求的参数VideoPlayer::VideoPlayer( avi * avi_ptr_in, bool sfr, bool zoom_in, QWidget *parent, 		const char *name, int wFlags ) 		: QWidget( parent, name, wFlags ), 		conversion_flags( PreferDither ) // {{{{	verbose_output( 2, "create VideoPlayer." );    alloc_context = 0;	image = NULL;	ct = NULL;	repaint_timer = new QTime();	repaint_interval = 0;	painter = new QPainter( this );	show_frame_rate = sfr;		zoom_image[0] = zoom_image[1] = NULL;	recv_image = NULL; 	jpeg_temp = NULL;	frame = 0;	zoom = zoom_in;	image_mutex = NULL;	avi_ptr = avi_ptr_in;	is_running = false;} // }}}// 析构函数VideoPlayer::~VideoPlayer( void ) // {{{{	verbose_output( 2, "delete VideoPlayer." );	if ( NULL != ct )	{		if ( ct->running() )		{			ct->terminate();		}		delete ct;	}		if ( NULL != repaint_timer )	{		delete repaint_timer;	}    if ( alloc_context )	{		QColor::destroyAllocContext( alloc_context );	}	delete image;	delete repaint_timer;	delete painter;	delete [] zoom_image[0];	delete [] zoom_image[1];	delete image_mutex;	delete [] jpeg_temp;	delete [] recv_image; 	delete image_mutex;} // }}}// 初始化函数int VideoPlayer::init ( void ) // {{{{	verbose_output( 2, "init VideoPlayer." );	zoom_image[0] = new BUFF[ avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 4 ];	zoom_image[1] = new BUFF[ avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 4 ];			recv_image = new BUFF[ avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 3 ]; 	if ( NULL == zoom_image[0] || NULL == zoom_image[1] )	{		cerr << "No enough memory, exit..." << endl;		exit( 1 );	}	jpeg_temp = new BUFF[ avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 4 ];	if ( NULL == jpeg_temp )	{		cerr << "Not enough memory, exit..." << endl;		exit( 1 );	}	image_mutex = new QMutex();	return 0;} // }}}void VideoPlayer::begin_running ( void ) // {{{{	verbose_output( 2, "VideoPlayer begin running." );	if ( avi_ptr->net_mode != CONNECT )	{		ct = new video_cap_thread ( avi_ptr, this );		ct->start();	}	repaint_timer->start();	is_running = true;	return;} // }}}bool VideoPlayer::running ( void ) // {{{{	return is_running;} // }}}///////////////////////////////////////////////////////// Protected Functions///////////////////////////////////////////////////////// 内部方法,当发生重绘事件时被调用void VideoPlayer::paintEvent( QPaintEvent *e ) // {{{{	verbose_output( 4, "VideoPlayer repaint." );	// 如果当前的图像可用,则用当前图像绘制	if ( NULL != image && !image->isNull() )	{		//计算上次重绘到现在经历了多长时间		repaint_interval += repaint_timer->elapsed();		repaint_timer->restart();				if ( repaint_interval < 60 )		{			return;		}		painter->setClipRect(e->rect());			//image_mutex->lock();		painter->drawImage( 0, 0, *image );		//image_mutex->unlock();		if ( show_frame_rate )		{			char tmp[5];			snprintf( tmp, 5, "%2.1f", 1000/static_cast < double > ( repaint_interval ) );			tmp[4] = '\0';			painter->setPen( green );			painter->setFont( QFont::QFont( "Times", 20 ) );			painter->drawText( 0, 15, QString::QString( tmp ) );			repaint_interval = 0;		}		return;	}	else	{		//painter->setClipRect(e->rect());		//painter->setPen( black );		//painter->setFont( QFont::QFont( "Times", 15, QFont::Bold ) );		//painter->drawText( 20, 20, QString::QString( "No Image Avaliable" ) );		//painter->drawText( 20, 70, QString::QString( "Please Waiting" ) );	}		repaint_timer->restart();} // }}}// 内部函数,用于接收自定义的事件// 在本事件中,对接收的原始图像进行放大处理void VideoPlayer::customEvent ( QCustomEvent * e ) // {{{{	verbose_output( 4, "VideoPlayer change image event." );	// 判断事件类型,是否正确	if ( e->type() == VIDEO_EVENT )	{		capture_event * ce = ( capture_event * ) e;		BUFF * temp = ce->get_buff();		int size = ce->get_size();		QImage * img = NULL;		QImage * img_temp = NULL;		(*(avi_ptr->video_send_semaphore))++;		memcpy( recv_image, temp, size );		(*(avi_ptr->video_send_semaphore))--;		//判断是否要放大		int w, h;		unsigned short int * header = (unsigned short*) recv_image;				if ( (*header) != JPEG_HEAD_MAGIC )		{			cerr << "Warning! Bad JPEG file" << endl;			return;		}		// JPEG解压缩		int result = jpeg_decompress( jpeg_temp, recv_image, size, &w, &h);		if ( result == -1 )		{			cerr << "Warning! decompress too few data" << endl;		}		if ( w != avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor || h!= avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor )		{			cerr << "Warning! the size of picture is not expected!" << endl;		}		temp = jpeg_temp;		//能识别的大小,由3byte 转为4byte		//复制		for ( register int i=0; i< avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor; i++ )		{			for ( register int j=0; j<4; j++ )			{				zoom_image[frame][i*4+j] = temp[i*3+j];			}		}		img_temp = new QImage( zoom_image[frame], avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor, 			avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor, 32, 0, 65535, QImage::BigEndian );				if( zoom )		{			img = new QImage( img_temp->smoothScale( avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * 2, 					avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 2, QImage::ScaleMax ) );		}		else		{			img = img_temp;		}		if ( NULL == img || img->isNull()  )		{			cerr << "Can't load image" << endl;			return;		}		setImage( img );				frame ^= 1;		if ( zoom )		{			// 非放大时,指会指向相同对象,不可删除。			delete img_temp;		}	}} // }}}///////////////////////////////////////////////////////// Private Functions///////////////////////////////////////////////////////// 设置当前图像,并重绘屏幕void VideoPlayer::setImage(const QImage * newimage) // {{{{	//delete image;    image = newimage;    reconvertImage();    repaint( image->hasAlphaBuffer() );} // }}}// 目的不明bool VideoPlayer::reconvertImage() // {{{{		verbose_output( 3, "reconvert image" );	     if ( alloc_context ) 	{		QColor::destroyAllocContext( alloc_context );		alloc_context = 0;    }	if ( zoom )	{		resize( avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * 2, avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 2 );	}	else	{		resize( avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor, avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor );	}    return true;} // }}}

⌨️ 快捷键说明

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