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

📄 radeonaddon.cpp

📁 ati driver
💻 CPP
字号:
/******************************************************************************//	File:			RadeonAddOn.cpp//	Description:	ATI Radeon Video Capture Media AddOn for BeOS.//	Copyright 2001, Carlos Hasan/*******************************************************************************/#include <support/Autolock.h>#include <media/MediaFormats.h>#include <Directory.h>#include <Entry.h>#include <Debug.h>#include <File.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <storage/FindDirectory.h>#include <String.h>#include "RadeonAddOn.h"#include "RadeonProducer.h"#define DPRINT(args) { PRINT(("\x1b[0;30;35m")); PRINT(args); PRINT(("\x1b[0;30;47m")); }CRadeonPlug::CRadeonPlug( CRadeonAddOn *aaddon, const BPath &adev_path, int aid )  : addon( aaddon ), dev_path( adev_path ), id( aid ), node( NULL ){	fFlavorInfo.name = const_cast<char *>("Radeon In");	fFlavorInfo.info = const_cast<char *>("Radeon Video In Media Node");	fFlavorInfo.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;	fFlavorInfo.flavor_flags = 0;	fFlavorInfo.internal_id = aid;	fFlavorInfo.possible_count = 1;		fFlavorInfo.in_format_count = 0;	fFlavorInfo.in_format_flags = 0;	fFlavorInfo.in_formats = NULL;		fFlavorInfo.out_format_count = 4;	//fFlavorInfo.out_format_count = 1;	fFlavorInfo.out_format_flags = 0;		fMediaFormat[0].type = B_MEDIA_RAW_VIDEO;	fMediaFormat[0].u.raw_video = media_raw_video_format::wildcard;	fMediaFormat[0].u.raw_video.interlace = 1;	fMediaFormat[0].u.raw_video.display.format = B_RGB32;		fMediaFormat[1].type = B_MEDIA_RAW_VIDEO;	fMediaFormat[1].u.raw_video = media_raw_video_format::wildcard;	fMediaFormat[1].u.raw_video.interlace = 1;	fMediaFormat[1].u.raw_video.display.format = B_RGB16;		fMediaFormat[2].type = B_MEDIA_RAW_VIDEO;	fMediaFormat[2].u.raw_video = media_raw_video_format::wildcard;	fMediaFormat[2].u.raw_video.interlace = 1;	fMediaFormat[2].u.raw_video.display.format = B_RGB15;	fMediaFormat[3].type = B_MEDIA_RAW_VIDEO;	fMediaFormat[3].u.raw_video = media_raw_video_format::wildcard;	fMediaFormat[3].u.raw_video.interlace = 1;	fMediaFormat[3].u.raw_video.display.format = B_YCbCr422;		/*fMediaFormat[0].type = B_MEDIA_RAW_VIDEO;	fMediaFormat[0].u.raw_video = media_raw_video_format::wildcard;	fMediaFormat[0].u.raw_video.interlace = 1;	fMediaFormat[0].u.raw_video.display.format = B_YCbCr422;*/		fFlavorInfo.out_formats = fMediaFormat;		readSettings();}BPath CRadeonPlug::getSettingsPath(){	BPath path;		if( find_directory( B_USER_CONFIG_DIRECTORY, &path ) != B_OK )		return BPath();			path.Append( "settings/Media/RadeonIn" );		create_directory( path.Path(), 755 );			BString id_string;		id_string << "settings" << id;		path.Append( id_string.String() );		return path;}void CRadeonPlug::writeSettings( BMessage *new_settings ){	BMessage cur_settings;	// if new_settings are provided, use them; else, ask node for settings	// (needed during shutdown where node cannot reply anymore)	if( new_settings != NULL ) {		cur_settings = *new_settings;			} else {		if( node == NULL )			return;						if( addon->GetConfigurationFor( node, &cur_settings ) != B_OK )			return;	}				BMallocIO old_settings_flat, new_settings_flat;		settings.Flatten( &old_settings_flat );	cur_settings.Flatten( &new_settings_flat );		if( old_settings_flat.BufferLength() == new_settings_flat.BufferLength() &&		memcmp( old_settings_flat.Buffer(), new_settings_flat.Buffer(), old_settings_flat.BufferLength() ) == 0 )		return;		settings = cur_settings;	BPath settings_path = getSettingsPath();		BFile file( settings_path.Path(), B_WRITE_ONLY | B_CREATE_FILE );		settings.Flatten( &file );}voidCRadeonPlug::readSettings(){	BPath settings_path = getSettingsPath();		BFile file( settings_path.Path(), B_READ_ONLY );			settings.Unflatten( &file );}CRadeonAddOn::CRadeonAddOn(image_id imid)	: BMediaAddOn(imid),	settings_thread( -1 ), settings_thread_sem( -1 ){	DPRINT(("CRadeonAddOn::CRadeonAddOn()\n"));				fInitStatus = B_NO_INIT;	if( RecursiveScan( "/dev/video/radeon" ) != B_OK )		return;			if( (settings_thread_sem = create_sem( 0, "Radeon In settings" )) < 0 )		return;			if( INIT_BEN( plug_lock, "Radeon device list" ) < 0 )		return;			if( (settings_thread = spawn_thread( 		settings_writer, "Radeon In settings", B_LOW_PRIORITY, this )) < 0 )		return;			resume_thread( settings_thread );	fInitStatus = B_OK;}CRadeonAddOn::~CRadeonAddOn(){	status_t dummy;		DPRINT(("CRadeonAddOn::~CRadeonAddOn()\n"));		release_sem( settings_thread_sem );	wait_for_thread( settings_thread, &dummy );		delete_sem( settings_thread_sem );		for( int32 i = 0; i < fDevices.CountItems(); ++i ) {		CRadeonPlug *plug = (CRadeonPlug *)fDevices.ItemAt(i);				delete plug;	}		DELETE_BEN( plug_lock );}status_t CRadeonAddOn::InitCheck(const char **out_failure_text){	DPRINT(("CRadeonAddOn::InitCheck()\n"));		if (fInitStatus < B_OK) {		*out_failure_text = "Unknown error";		return fInitStatus;	}	return B_OK;}int32 CRadeonAddOn::settings_writer( void *param ){	((CRadeonAddOn *)param)->settingsWriter();	return B_OK;}void CRadeonAddOn::writeSettings(){	ACQUIRE_BEN( plug_lock );		for( int32 i = 0; i < fDevices.CountItems(); ++i ) {		CRadeonPlug *plug = (CRadeonPlug *)fDevices.ItemAt(i);		plug->writeSettings( NULL );	}		RELEASE_BEN( plug_lock );}voidCRadeonAddOn::settingsWriter(){	while( acquire_sem_etc( settings_thread_sem, 1, B_RELATIVE_TIMEOUT, 10000000 ) == B_TIMED_OUT ) {		writeSettings();	}}voidCRadeonAddOn::UnregisterNode( BMediaNode *node, BMessage *settings ){	ACQUIRE_BEN( plug_lock );		for( int32 i = 0; i < fDevices.CountItems(); ++i ) {		CRadeonPlug *plug = (CRadeonPlug *)fDevices.ItemAt(i);				if( plug->getNode() == node ) {			// write last settings, so they don't get lost			plug->writeSettings( settings );			plug->setNode( NULL );			break;		}	}		RELEASE_BEN( plug_lock );}int32 CRadeonAddOn::CountFlavors(){	DPRINT(("CRadeonAddOn::CountFlavors()\n"));		if (fInitStatus < B_OK)		return fInitStatus;	return fDevices.CountItems();}/* * The pointer to the flavor received only needs to be valid between  * successive calls to BCRadeonAddOn::GetFlavorAt(). */status_t CRadeonAddOn::GetFlavorAt(int32 n, const flavor_info **out_info){	DPRINT(("CRadeonAddOn::GetFlavorAt()\n"));		if (fInitStatus < B_OK)		return fInitStatus;	if (n < 0 || n >= fDevices.CountItems() )		return B_BAD_INDEX;	/* Return the flavor defined in the constructor */	*out_info = ((CRadeonPlug *)fDevices.ItemAt(n))->getFlavorInfo();	return B_OK;}BMediaNode *CRadeonAddOn::InstantiateNodeFor(		const flavor_info *info, BMessage *config, status_t *out_error){	DPRINT(("CRadeonAddOn::InstantiateNodeFor()\n"));		CRadeonProducer *node;	if (fInitStatus < B_OK)		return NULL;	if (info->internal_id < 0 || info->internal_id >= fDevices.CountItems())		return NULL;	CRadeonPlug *plug = (CRadeonPlug *)fDevices.ItemAt( info->internal_id );		ACQUIRE_BEN( plug_lock );		if( plug->getNode() != NULL ) {		*out_error = B_BUSY;		node = NULL;			} else {		BMessage single_settings;				// under R5, configuration is always an empty message, so we need to		// get our own configuration		if( config == NULL || 1 )			config = plug->getSettings();				node = new CRadeonProducer( this, plug->getName(), 			plug->getDeviceName(), info->internal_id, config );					if (node && (node->InitCheck() < B_OK)) {			*out_error = node->InitCheck();			delete node;			node = NULL;		}	}		plug->setNode( node );			RELEASE_BEN( plug_lock );	return node;}status_t CRadeonAddOn::GetConfigurationFor(	BMediaNode *your_node,	BMessage *into_message ){	port_id reply_port;	CRadeonProducer::configuration_msg msg;	status_t res;		reply_port = create_port( 1, "GetConfiguration Reply" );	if( reply_port < 0 )		return reply_port;			msg.reply_port = reply_port;		res = write_port_etc( your_node->ControlPort(), CRadeonProducer::C_GET_CONFIGURATION, 		&msg, sizeof( msg ), B_TIMEOUT, 10000000 );	if( res == B_OK ) {		ssize_t reply_size;		CRadeonProducer::configuration_msg_reply *reply;		int32 code;				reply_size = port_buffer_size_etc( reply_port, B_TIMEOUT, 10000000 );		if( reply_size < 0 )			res = reply_size;		else {			reply = (CRadeonProducer::configuration_msg_reply *)malloc( reply_size );					res = read_port( reply_port, &code, reply, reply_size );			if( res == reply_size ) {				if( code != CRadeonProducer::C_GET_CONFIGURATION_REPLY )					res = B_ERROR;				else {					res = reply->res;										if( res == B_OK )						res = into_message->Unflatten( &reply->config );				}			}						free( reply );		}	}		delete_port( reply_port );		return res;}status_tCRadeonAddOn::RecursiveScan(const char* rootPath, BEntry *rootEntry = NULL){		BDirectory root;		if( rootEntry != NULL )		root.SetTo( rootEntry );	else if( rootPath != NULL ) {		root.SetTo( rootPath );	} else {		PRINT(("Error in MultiAudioAddOn::RecursiveScan null params\n"));		return B_ERROR;	}		BEntry entry;	int cur_id = 0;		while( root.GetNextEntry( &entry ) > B_ERROR ) {		if(entry.IsDirectory()) {			RecursiveScan( rootPath, &entry );					} else {			BPath path;						entry.GetPath(&path);						CRadeon device( path.Path() );						if( device.InitCheck() != B_OK)				continue;							CVIPPort vip_port( device );					// if there is a Rage Theatre, then there should be Video-In				if( vip_port.InitCheck() == B_OK &&				vip_port.FindVIPDevice( 				(C_THEATER_VIP_VENDOR_ID << 0) |				(C_THEATER_VIP_DEVICE_ID << 16)) >= 0 )			{				fDevices.AddItem( new CRadeonPlug( this, path, cur_id++ ));			}		}	}		return B_OK;}BMediaAddOn *make_media_addon(image_id imid){	return new CRadeonAddOn(imid);}

⌨️ 快捷键说明

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