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

📄 main.c

📁 palm编程
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * MiniMPEG4.c
 *
 * Main file for MPEG4
 *
 * This wizard-generated code is based on code adapted from the
 * stationery files distributed as part of the Palm OS SDK 4.0.
 *
 * Copyright (c) 1999-2004 PalmOne, Inc. or its subsidiaries.
 * All rights reserved.
 */
 
#include <PalmOS.h>
#include <VFSMgr.h>
#include <MemGlue.h>
#include "Common.h"
#include "MiniMPEG4.h"
#include "MiniMPEG4Rsc.h"
#include "FileBrowserForm.h"
#include "FileBrowserFormRsrc.h"
#include "PalmOneCodecPluginMgr.h"
#include "PalmOneCodecFormat.h"
#include "ColorButtonGadget.h"
#include "PalmLcdOverlay.h"
#include "PalmOneCamera.h"

#define ourMinVersion    sysMakeROMVersion(3,0,0,sysROMStageDevelopment,0)
#define kPalmOS20Version sysMakeROMVersion(2,0,0,sysROMStageDevelopment,0)

#define Allocate(n)	MemPtrNew(n)

#define DATA_BUFFER_SIZE	16384
#define USE_RATE_CONTROL	1

/** Holds basic encoder/decoder info. */
typedef struct {
	Char	inputFileName[256];
	Char	outputFileName[256];
	
	FileRef inputFileRef;
	FileRef outputFileRef;
	
	UInt32 	width;
	UInt32 	height;
	UInt32 	frameRate;
	UInt32 	bitRate;
	UInt32 	keyFrame;
	UInt32 	IQuantization;
	UInt32	searchRange;
	
	UInt16 	codecMgrLibRefNum;
	PalmCodecSession session;
	UInt32 imageFormat;

	Boolean loadFileInMemory;
	Boolean outputToSD;
	Boolean encoding;
	Boolean	loop;
	
} MPEG4Info;

#if 0
#pragma mark Globals
#endif

/** Internal Globals. */
static MPEG4Info 	gMPEG4Info;
static UInt32		gFrameCount	= 0;
static UInt32		gStartTicks	= 0;
static UInt32		gLastTick	= 0;
static UInt32		gRateControl= 0;

static Char			*gGOButtonLabel[] = { "Go", "Stop" };
static Char			gLoadingText[] = "Loading";

static UInt32	gScreenDepth = 16;
static UInt32	gPreviousScreenDepth = 0;

RGBColorType	gStartColor = { 0, 255, 255, 255 };
RGBColorType	gEndColor = { 0, 0, 0, 255 };

static const RGBColorType	gWhite = { 0, 255, 255, 255 };
static const RGBColorType	gBlack = { 0, 0, 0, 0 };

// Extra
static UInt16	gLCDOverlayRefNum = sysInvalidRefNum;
static Boolean	gUseOverlay = true;
static UInt16	gCameraRefNum = sysInvalidRefNum;

#if 0
#pragma mark -
#endif

/**
 * Read and Encode the parameters
 */
static Err PrvReadParameters(Boolean encoding)
{
	Err err = errNone;
	FieldType *fldP = NULL;
	FormType *frmP = FrmGetActiveForm();
	
	// Get the width & height
	fldP = FrmGetPtr(frmP, MainWidthField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.width = StrAToI(FldGetTextPtr(fldP));
	fldP = FrmGetPtr(frmP, MainHeightField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.height = StrAToI(FldGetTextPtr(fldP));
		
	// Read the file names
	fldP = FrmGetPtr(frmP, MainInputField);
	StrCopy(gMPEG4Info.inputFileName, FldGetTextPtr(fldP));
	fldP = FrmGetPtr(frmP, MainOutputField);
	StrCopy(gMPEG4Info.outputFileName, FldGetTextPtr(fldP));
	
	// Get the SearchRange & BitRate
	fldP = FrmGetPtr(frmP, MainSearchRangeField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.searchRange = StrAToI(FldGetTextPtr(fldP));
	fldP = FrmGetPtr(frmP, MainBitRateField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.bitRate = StrAToI(FldGetTextPtr(fldP));
		
	// Get the KeyFrame & IQuantization
	fldP = FrmGetPtr(frmP, MainKeyFrameField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.keyFrame = StrAToI(FldGetTextPtr(fldP));
	fldP = FrmGetPtr(frmP, MainIQuantizationField);
	if(FldGetTextPtr(fldP))
		gMPEG4Info.IQuantization = StrAToI(FldGetTextPtr(fldP));
	
Done:	
	return err;
}

/**
 * Open input file
 */
static Err PrvFileOpenInput()
{
	Err err = errNone;
	UInt32 volumeIterator = 0;
	UInt16 firstVolume = 0;
	
	// Get first card
	volumeIterator = vfsIteratorStart;
	err = VFSVolumeEnumerate(&firstVolume, &volumeIterator);
	if( err == expErrEnumerationEmpty ) {
		goto Done;
	}
	
	// If we have a file path, open the file
	if(gMPEG4Info.inputFileName)
	{
		err = VFSFileOpen(firstVolume, gMPEG4Info.inputFileName, vfsModeRead, &gMPEG4Info.inputFileRef);
		if( err ) goto Done;
	}

Done:	
	return err;
}

/**
 * Open output file
 */
static Err PrvFileOpenOutput()
{
	Err err = errNone;
	UInt32 volumeIterator = 0;
	UInt16 firstVolume = 0;
	
	// Get first card
	volumeIterator = vfsIteratorStart;
	err = VFSVolumeEnumerate(&firstVolume, &volumeIterator);
	if( err == expErrEnumerationEmpty ) {
		goto Done;
	}
	
	// If we have a file path, open the file
	if(gMPEG4Info.outputFileName)
	{
		err = VFSFileOpen(firstVolume, gMPEG4Info.outputFileName, vfsModeWrite|vfsModeCreate|vfsModeTruncate, &gMPEG4Info.outputFileRef);
		if( err ) goto Done;
	}

Done:	
	return err;
}

/**
 * File info callback.
 * This function is called by the file browser
 */
static void PrvGetInputFileInfoCallback(UInt16 volume, const Char* path, const Char* file)
{
	// Create the full path name
	StrCopy(gMPEG4Info.inputFileName, path);

	// Internally, we expect full path
	StrCat(gMPEG4Info.inputFileName, file);
}

/**
 * Load a file in memory.
 * Draws a fill rectangle with specified colors.
 *
 */
static UInt32 PrvLoadFileInMemory(FileRef srcFile, UInt32 inputBufferSize, UInt8 *fileBufferP, Boolean useFtr)
{
	UInt32 read = 0;
	UInt32 total = 0;
	UInt32 current = 0;
	UInt32 xPosition = 80 - FntCharsWidth(gLoadingText, StrLen(gLoadingText)) / 2;
	RGBColorType oldColor;
	EventType event;
	UInt8 *tempBufferP = NULL;
	RectangleType goButtonBounds;
	WinDrawOperation oldOperation;
	UInt32 toRead = inputBufferSize / 100;
	RectangleType rect = { { 30, 147 }, { 1, 10 } };
	RGBColorType color = { 0, 0, 0, 0 };
	Int32 R, G, B;
	Int32 sR, sG, sB;
	
	// FtrPtrNew - Allocate temporary buffer
	if(useFtr) {
		tempBufferP = MemPtrNew(4096);
	}
	
	// Save old color
	WinSetBackColorRGB(&color, &oldColor);
	
	R = (UInt32)gStartColor.r << 8; G = (UInt32)gStartColor.g << 8; B = (UInt32)gStartColor.b << 8;
	
	// Color steps
	sR = (((Int32)gEndColor.r - (Int32)gStartColor.r) << 8) / 101;
	sG = (((Int32)gEndColor.g - (Int32)gStartColor.g) << 8) / 101;
	sB = (((Int32)gEndColor.b - (Int32)gStartColor.b) << 8) / 101;
	
	// Get the bounds for the Go button
	FrmGetObjectBounds(FrmGetActiveForm(), FrmGetObjectIndex(FrmGetActiveForm(),MainGoButton), &goButtonBounds);
	
	while(1)
	{
		EvtGetEvent(&event, 0);
		if(event.eType == penDownEvent && RctPtInRectangle(event.screenX, event.screenY, &goButtonBounds)) {
			total = 0;
			goto Done;
		}
			
		if(useFtr) {
			VFSFileRead(srcFile, 4096, tempBufferP, &read);
			DmWrite(fileBufferP, total, tempBufferP, read);
		} else {
			VFSFileRead(srcFile, toRead, fileBufferP, &read);
			fileBufferP += read;
		}
			
		if(!read)
			break;
		
		total += read;
	
		current = (total * 100) / inputBufferSize + 31;
		
		if( current > rect.topLeft.x)
		{
			R += sR; G += sG; B += sB;
			if(R < 0) R = 0; if(R > 65536) R = 65536;
			if(G < 0) G = 0; if(G > 65536) G = 65536;
			if(B < 0) B = 0; if(B > 65536) B = 65536;
			color.r = R >> 8;
			color.g = G >> 8;
			color.b = B >> 8;
					
			WinSetBackColorRGB(&color, NULL);
			WinFillRectangle(&rect, 0);
			oldOperation = WinSetDrawMode(winOverlay);
			WinPaintChars(gLoadingText, StrLen(gLoadingText), xPosition, 146);
			WinSetDrawMode(oldOperation);		
			rect.topLeft.x = current;
		}
	}

Done:
	if(tempBufferP)
		MemPtrFree(tempBufferP);
	WinSetBackColorRGB(&oldColor, NULL);
	return total;
}

/**
 * Update the current UI
 * Displays the frmae count, the average FPS and the current FPS
 */
static void PrvUpdateUI()
{
	Char text[32];
	FieldType *fldP = NULL;
	UInt32 curTicks =  TimGetTicks();
	UInt32 fps = curTicks - gStartTicks;
	
	if(fps)
		fps = (sysTicksPerSecond * gFrameCount) / fps;
	
	// Average FPS
	StrIToA(text, fps);
	fldP = FrmGetPtr(FrmGetActiveForm(), MainAverageFPSField);
	SetFieldTextFromStr(fldP, text, true);
	
	// Current FPS
	fps = ( curTicks - gLastTick );
	if(fps)
		fps = sysTicksPerSecond / fps;
	
	StrIToA(text, fps);
	fldP = FrmGetPtr(FrmGetActiveForm(), MainCurrentFPSField);
	SetFieldTextFromStr(fldP, text, true);
	
	gLastTick = curTicks;
	
	// Current Frame Count
	StrPrintF(text, "%04ld", gFrameCount);
	fldP = FrmGetPtr(FrmGetActiveForm(), MainFramesField);
	SetFieldTextFromStr(fldP, text, true);
}

/**
 * DrawLaoding rectangle
 */
static void PrvDrawLoadingRect()
{
	RGBColorType oldColor;
	RectangleType rect = { { 30, 147 }, { 101, 10 } };
	
	// Draw the progress bar
	WinSetForeColorRGB(&gWhite, &oldColor);
	WinDrawRectangle(&rect, 0);
	WinSetForeColorRGB(&gBlack, NULL);
	WinDrawRectangleFrame(rectangleFrame, &rect);
	
	// Restore
	WinSetForeColorRGB(&oldColor, NULL);
}

#if 0
#pragma mark -
#endif

/**
 * Load a frame from memory.
 */
static void PrvLoadFrameFromMemory(UInt8 *bufferP, PalmImagePlanarType *planarImage, UInt32 imageFormat)
{
	switch(imageFormat)
	{
		case palmCodecImageYCbCr420Planar:
			planarImage->planeP[0] = bufferP;
			bufferP += planarImage->width * planarImage->height;
			planarImage->planeP[1] = bufferP;
			bufferP += planarImage->width * planarImage->height / 4;
			planarImage->planeP[2] = bufferP;
			break;
			
		case palmCodecImageYCbCr422Planar:
			planarImage->planeP[0] = bufferP;
			bufferP += planarImage->width * planarImage->height;
			planarImage->planeP[1] = bufferP;
			bufferP += planarImage->width * planarImage->height / 2;
			planarImage->planeP[2] = bufferP;
			break;
	}	
}

/**
 * Laos a frame from file
 */
static Err PrvLoadFrameFromFile(FileRef fileRef, PalmImagePlanarType *planarImage, UInt32 imageFormat)
{
	Err 	err = errNone;
	UInt32	read = 0;
	UInt32 	width = 0;
	UInt32 	height = 0;
	UInt32	YHeight = 0;
	UInt32	YWidth = 0;
	UInt32	CHeight = 0;
	UInt32	CWidth = 0;
	UInt8	*planeP = NULL;	
	
	switch(imageFormat)
	{
		case palmCodecImageYCbCr420Planar:
			YWidth 	= planarImage->width;
			YHeight = planarImage->height;
			CWidth 	= planarImage->width / 2;
			CHeight = planarImage->height / 2;
			break;
			
		case palmCodecImageYCbCr422Planar:
			YWidth 	= planarImage->width;
			YHeight = planarImage->height;
			CWidth	= planarImage->width / 2;
			CHeight	= planarImage->height;
			break;
		
		default:
			err = appErrorClass;
			goto Done;
	}
	
	// Load the Y components
	planeP = planarImage->planeP[0];
	for(height = 0; height < YHeight; height++)
	{
		err = VFSFileRead(fileRef, YWidth, planeP, &read);
		if(err || read != YWidth) {
			err = vfsErrFileEOF; 
			goto Done;
		}	
		planeP += YWidth;
	}
	
	// Load the Cb components
	planeP = planarImage->planeP[1];
	for(height = 0; height < CHeight; height++)
	{
		err = VFSFileRead(fileRef,CWidth, planeP, &read);
		if(err || read != CWidth) {
			err = vfsErrFileEOF;
			goto Done;
		}
		planeP += CWidth;
	}
	
	// Load the Cr components
	planeP = planarImage->planeP[2];
	for(height = 0; height < CHeight; height++)
	{
		err = VFSFileRead(fileRef, CWidth, planeP, &read);
		if(err || read != CWidth) {
			err = vfsErrFileEOF;
			goto Done;
		}
		planeP += CWidth;
	}
	
Done:
	return err;
}

#if 0
#pragma mark -
#endif


/**
 * Run the MPEG4 Decoder
 *
 * The loop option is done by resetting the decoder since the
 * next loop will have to read again the VO & VOL header.
 */
static Err PrvStartDecoder()
{
	Err err = errNone;
	EventType event;
	UInt32 inSize = 0;
	UInt32 outSize = 0;
	Boolean useFtr = false;
	UInt32 inputBufferSize = 0;
	UInt8 *inputBufferP = NULL;
	UInt8 *currentBufferP = NULL;
	UInt8 *offScreenP = NULL;
	WinHandle offScreenH = NULL;
	RectangleType goButtonBounds;
	PalmImagePlanarType planarImage;
	PalmImagePlanarType *swapImageP = NULL;
	PalmImageParamType *imageParamP = NULL;
	
	// Make sure atack data is clean
	MemSet(&planarImage, sizeof(PalmImagePlanarType), 0);
	
	// Read parameters and check
	err = PrvReadParameters(false);
	if(err)
		goto Done;
		
	// Open the input and output files
	err = PrvFileOpenInput();
	if(err)
		goto Done;
	
	if(gMPEG4Info.outputToSD) {	
		err = PrvFileOpenOutput();
		if(err)
			goto Done;
	}
	
	// Allocate image structure	
	imageParamP = (PalmImageParamType*)MemPtrNew(sizeof(PalmImageParamType));
	if(!imageParamP) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	MemSet(imageParamP, sizeof(PalmImageParamType), 0);
	
	// Allocate swap image	
	swapImageP = (PalmImagePlanarType*)MemPtrNew(sizeof(PalmImagePlanarType));
	if(!swapImageP) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	MemSet(swapImageP, sizeof(PalmImagePlanarType), 0);
	
	// Set Image Params

⌨️ 快捷键说明

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