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

📄 main.c

📁 palm编程
💻 C
📖 第 1 页 / 共 3 页
字号:
	imageParamP->width = 0; // Don't care
	imageParamP->height = 0; // Don't care
	imageParamP->rowByte = 0; // Don't care
	imageParamP->endianess = 0; // Don't care
	
	// Create the MPEG4 Decoding session
	//err = CodecMgrCreateSession(gMPEG4Info.codecMgrLibRefNum,  palmCodecVideoMPEG4, NULL, gMPEG4Info.imageFormat, imageParamP, &gMPEG4Info.session);	
	err = CodecMgrCreateSessionByID(gMPEG4Info.codecMgrLibRefNum, palmCodecVideoMPEG4, NULL, gMPEG4Info.imageFormat, imageParamP, 'mp4d', 0, &gMPEG4Info.session);
	if(err) {
		FrmCustomAlert(ErrorAlert, "Unable to create session", NULL, NULL);
		goto Done;
	}
	
	// Set the planar image
	planarImage.width = gMPEG4Info.width;
	planarImage.height = gMPEG4Info.height;
	planarImage.planeCount = 3;
	
	switch(gMPEG4Info.imageFormat)
	{
		case palmCodecImageYCbCr420Planar:
			planarImage.planeP[0] = Allocate( (3 * planarImage.width * planarImage.height) / 2);
			planarImage.planeP[1] = (UInt8*)planarImage.planeP[0] + planarImage.width * planarImage.height;
			planarImage.planeP[2] = (UInt8*)planarImage.planeP[1] + (planarImage.width * planarImage.height / 4);
			planarImage.planeWidth[0] = planarImage.width;
			planarImage.planeWidth[1] = planarImage.width / 2;
			planarImage.planeWidth[2] = planarImage.width / 2;
			break;
			
		default:
			FrmCustomAlert(ErrorAlert, "Bad image format", NULL, NULL);
			goto Done;
			break;
	}
	
	if(!planarImage.planeP[0]) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	
	// Use a byte-swapped copy for the CPM
	swapImageP->width = Swap32(planarImage.width);
	swapImageP->height = Swap32(planarImage.height);
	swapImageP->planeCount = Swap32(planarImage.planeCount);
	swapImageP->planeP[0] = (void*)Swap32(planarImage.planeP[0]);
	swapImageP->planeP[1] = (void*)Swap32(planarImage.planeP[1]);
	swapImageP->planeP[2] = (void*)Swap32(planarImage.planeP[2]);	
	swapImageP->planeWidth[0] = Swap32(planarImage.planeWidth[0]);
	swapImageP->planeWidth[1] = Swap32(planarImage.planeWidth[1]);
	swapImageP->planeWidth[2] = Swap32(planarImage.planeWidth[2]);
	
	// Running from file
	if(gMPEG4Info.loadFileInMemory)
	{	
		// Get the file size
		err = VFSFileSize(gMPEG4Info.inputFileRef, &inputBufferSize);	
		if(err || !inputBufferSize)
			goto Done;
				
		currentBufferP = inputBufferP = (UInt8*)Allocate(inputBufferSize);
		if(!inputBufferP) {
			// Try with FtrPtr
			err = FtrPtrNew(appFileCreator, 0, inputBufferSize, (void*)&inputBufferP);
			if(err) {
				err = memErrNotEnoughSpace;
				FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
				goto Done;
			}
			
			currentBufferP = inputBufferP;
			useFtr = true;
		}
		
		// Load the file
		if(!PrvLoadFileInMemory(gMPEG4Info.inputFileRef, inputBufferSize, inputBufferP, useFtr))
			goto Done;
	}
	else
	{
		// Allocate buffer for VFS
		inputBufferP = (UInt8*)Allocate(DATA_BUFFER_SIZE);
		
		// Load first input buffer
		currentBufferP = inputBufferP;
		err = VFSFileRead(gMPEG4Info.inputFileRef, DATA_BUFFER_SIZE, inputBufferP, &inputBufferSize);
		if(err)
			goto Done;
	}
	
	// Get the bounds for the Go button
	FrmGetObjectBounds(FrmGetActiveForm(), FrmGetObjectIndex(FrmGetActiveForm(),MainGoButton), &goButtonBounds);
	
		
	// LCD Overlay
	if( gUseOverlay)
	{
		LcdOverlayLibSettingType overlaySetting;
		RectangleType rect = { { 0, 0 }, { 0, 0 } };
		
		rect.extent.x = planarImage.width / 2;
		rect.extent.y = planarImage.height / 2;
		
		overlaySetting.type = kLcdOverlayLibDataFormatYCbCr420Planar;
		err = LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlFormatSet, (void*)&overlaySetting);
		err |= LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlRectSet, &rect);
		err |= LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlStart, NULL);
		
		if(err) {
			FrmCustomAlert(ErrorAlert, "LCD Overlay Init failed!!!", NULL, NULL);
			goto Done;
		}
	}

	
	// Get the current time here we we go!
	gFrameCount = 0;
	gRateControl = sysTicksPerSecond / 15; // Rate control: 15 FPS
	gStartTicks = gLastTick = TimGetTicks();

	// Decode Frames
	while(true)
	{
		// Set input params		
		inSize = inputBufferSize;
		outSize = sizeof(PalmImagePlanarType);
		
		// Check the event queue
		EvtGetEvent(&event, 0);
		if(event.eType == penDownEvent && RctPtInRectangle(event.screenX, event.screenY, &goButtonBounds))
			goto Done;
		
		// Decode a frame
		err = CodecMgrEncodeDecode(gMPEG4Info.codecMgrLibRefNum, gMPEG4Info.session, currentBufferP, &inSize, swapImageP, &outSize);
		switch(err)
		{	
			UInt32 read = 0;
			
			case kCodecSyncNotFound:
				if(gMPEG4Info.loadFileInMemory) {
					if(gMPEG4Info.loop)
					{
						VFSFileSize(gMPEG4Info.inputFileRef, &inputBufferSize);	
						currentBufferP = inputBufferP;
						err = CodecMgrResetSession(gMPEG4Info.codecMgrLibRefNum, gMPEG4Info.session);
					}
					else
					{
						FrmCustomAlert(InfoAlert, "Decoding done!", NULL, NULL);
						goto Done;
					}
				} else {
					// Reload the buffer
					MemMove(inputBufferP, currentBufferP, inputBufferSize);
					err = VFSFileRead(gMPEG4Info.inputFileRef, DATA_BUFFER_SIZE - inputBufferSize, inputBufferP + inputBufferSize, &read);
					if(!read) {
						if(gMPEG4Info.loop)
						{
							VFSFileSeek(gMPEG4Info.inputFileRef, vfsOriginBeginning, 0);	
							currentBufferP = inputBufferP;
							VFSFileRead(gMPEG4Info.inputFileRef, DATA_BUFFER_SIZE, inputBufferP, &inputBufferSize);
							err = CodecMgrResetSession(gMPEG4Info.codecMgrLibRefNum, gMPEG4Info.session);
						}
						else
						{
							if(gUseOverlay)
								err = LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlStop, NULL);
							FrmCustomAlert(InfoAlert, "Decoding done!", NULL, NULL);
							goto Done;
						}
					}
					// Set current buffer
					inputBufferSize += read;
					currentBufferP = inputBufferP;
				}				
				
				break;
				
			// Real error
			case kCodecMgrLibNotSupported:
			case kCodecErrBadParam:
				if(gUseOverlay)
					err = LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlStop, NULL);
				FrmCustomAlert(InfoAlert, "Decoding done!", NULL, NULL);
				goto Done;
				
			default:
				break;
		}
				
		// Update the input buffer size
		inputBufferSize -= inSize;
		currentBufferP += inSize;
		
		// Update the Frame counter
		if(outSize)
		{
			gFrameCount++;
			
			if(gUseOverlay)
			{
				err = LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlDraw, planarImage.planeP[0]);
			}
			
			if(gMPEG4Info.outputToSD)
			{
				UInt32 written = 0;
				UInt32 YSize = planarImage.width * planarImage.height;
				UInt32 CSize = planarImage.width * planarImage.height / 4;
				
				// Write the Y components
				err = VFSFileWrite(gMPEG4Info.outputFileRef, YSize, planarImage.planeP[0], &written);
				if(err || written != YSize) {
					FrmCustomAlert(ErrorAlert, "Error during file write!", NULL, NULL);
					goto Done;
				}
				// Write the Cb components
				err = VFSFileWrite(gMPEG4Info.outputFileRef, CSize, planarImage.planeP[1], &written);
				if(err || written != CSize) {
					FrmCustomAlert(ErrorAlert, "Error during file write!", NULL, NULL);
					goto Done;
				}
				// Write the Cr components
				err = VFSFileWrite(gMPEG4Info.outputFileRef, CSize, planarImage.planeP[2], &written);
				if(err || written != CSize) {
					FrmCustomAlert(ErrorAlert, "Error during file write!", NULL, NULL);
					goto Done;
				}
			}
		}
	
#if USE_RATE_CONTROL == 1
		if((TimGetTicks() - gLastTick) < gRateControl)
			SysTaskDelay(gRateControl - TimGetTicks() + gLastTick);
#endif
		
		// Update the UI frame count
		PrvUpdateUI(gFrameCount);
	}
			
Done:
	if(offScreenH)
		WinDeleteWindow(offScreenH, false);
	if(inputBufferP)
		if(useFtr)	
			FtrPtrFree(appFileCreator, 0);
		else
			MemPtrFree(inputBufferP);
	if(planarImage.planeP[0])
		MemPtrFree(planarImage.planeP[0]);

	if(imageParamP)
		MemPtrFree(imageParamP);

	if(swapImageP)
		MemPtrFree(swapImageP);
		
	// Close overlay
	if( gUseOverlay)
		err = LcdOverlayLibControl(gLCDOverlayRefNum, kLcdOverlayLibCtrlStop, NULL);
				
	// Delete the session
	if(gMPEG4Info.session)
		CodecMgrDeleteSession(gMPEG4Info.codecMgrLibRefNum, &gMPEG4Info.session);
	
	// Close files
	if(gMPEG4Info.inputFileRef) {
		VFSFileClose(gMPEG4Info.inputFileRef);
		gMPEG4Info.inputFileRef = NULL;
	}
	
    if(gMPEG4Info.outputFileRef) {
    	VFSFileClose(gMPEG4Info.outputFileRef);
    	gMPEG4Info.outputFileRef = NULL;
    }
    
    // Quick refresh
    if(gUseOverlay)
	    FrmDrawForm(FrmGetActiveForm());
    		
	return err;
}

/**
 * Run the MPEG4 Encoder
 *
 * The loop option is done by simply rewinding the file or stream.
 */
static Err PrvStartEncoder()
{
	Err err = errNone;
	EventType event;
	Boolean useFtr = false;
	UInt32 inSize = 0;
	UInt32 outSize = 0;
	UInt32 inputBufferSize = 0;
	UInt32 fileOffset = 0;
	UInt8 *inputBufferP = NULL;
	UInt8 *outputBufferP = NULL;
	UInt8 *savedPlaneP[3] = { NULL, NULL, NULL };
	RectangleType goButtonBounds;
	PalmImagePlanarType planarImage;
	PalmImagePlanarType *swapImageP = NULL;
	PalmImageParamType *imageParamP = NULL;
	PalmVideoMPEG4EncodeParamType *mpeg4ParamP = 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);
	
	// Allocate MPEG4 param	
	mpeg4ParamP = (PalmVideoMPEG4EncodeParamType*)MemPtrNew(sizeof(PalmVideoMPEG4EncodeParamType));
	if(!mpeg4ParamP) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	MemSet(mpeg4ParamP, sizeof(PalmVideoMPEG4EncodeParamType), 0);
	
	// Set Image Params
	imageParamP->width = Swap32(gMPEG4Info.width);
	imageParamP->height = Swap32(gMPEG4Info.height);
	imageParamP->rowByte = 0; // Don't care
	imageParamP->endianess = 0; // Don't care
	
	// Set MPEG4 Params 
	mpeg4ParamP->profile = 0; // Don't care for now
	mpeg4ParamP->volWidth = Swap32(gMPEG4Info.width);
	mpeg4ParamP->volHeight = Swap32(gMPEG4Info.height);
	mpeg4ParamP->keyFrame =  Swap32(gMPEG4Info.keyFrame);
	mpeg4ParamP->frameRate = Swap32(gMPEG4Info.frameRate);
	mpeg4ParamP->bitRate = Swap32(gMPEG4Info.bitRate);
	mpeg4ParamP->algorithm = Swap32(palmCodecMPEG4MVFAST);
	mpeg4ParamP->IVOPQuantization = Swap32(gMPEG4Info.IQuantization);
	mpeg4ParamP->VOVOLVersionID = Swap32(2);
	
	// Set the planar image
	planarImage.width = gMPEG4Info.width;
	planarImage.height = gMPEG4Info.height;
	switch(gMPEG4Info.imageFormat)
	{
		case palmCodecImageYCbCr420Planar:
			planarImage.planeP[0] = Allocate(planarImage.width * planarImage.height);
			planarImage.planeP[1] = Allocate(planarImage.width * planarImage.height / 4);
			planarImage.planeP[2] = Allocate(planarImage.width * planarImage.height / 4);
			planarImage.planeWidth[0] = planarImage.width;
			planarImage.planeWidth[1] = planarImage.width / 2;
			planarImage.planeWidth[2] = planarImage.width / 2;
			break;
			
		case palmCodecImageYCbCr422Planar:
			planarImage.planeP[0] = Allocate(planarImage.width * planarImage.height);
			planarImage.planeP[1] = Allocate(planarImage.width * planarImage.height / 2);
			planarImage.planeP[2] = Allocate(planarImage.width * planarImage.height / 2);
			planarImage.planeWidth[0] = planarImage.width;
			planarImage.planeWidth[1] = planarImage.width / 2;
			planarImage.planeWidth[2] = planarImage.width / 2;
			break;
			
		default:
			FrmCustomAlert(ErrorAlert, "Bad image format", NULL, NULL);
			goto Done;
			break;
	}
	
	// Check for memory 
	if(!planarImage.planeP[0] || !planarImage.planeP[1] || !planarImage.planeP[2]) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	
	// Save plane pointers since they can be modified
	savedPlaneP[0] = planarImage.planeP[0];
	savedPlaneP[1] = planarImage.planeP[1];
	savedPlaneP[2] = planarImage.planeP[2];
	
	// Create a copy for the CPM
	swapImageP->width = Swap32(planarImage.width);
	swapImageP->height = Swap32(planarImage.height);
	swapImageP->planeP[0] = (void*)Swap32(planarImage.planeP[0]);
	swapImageP->planeP[1] = (void*)Swap32(planarImage.planeP[1]);
	swapImageP->planeP[2] = (void*)Swap32(planarImage.planeP[2]);
	swapImageP->planeWidth[0] = Swap32(planarImage.planeWidth[0]);
	swapImageP->planeWidth[1] = Swap32(planarImage.planeWidth[1]);
	swapImageP->planeWidth[2] = Swap32(planarImage.planeWidth[2]);
		
	// Create the MPEG4 Encoding session
	err = CodecMgrCreateSession(gMPEG4Info.codecMgrLibRefNum, gMPEG4Info.imageFormat, imageParamP, palmCodecVideoMPEG4, mpeg4ParamP, &gMPEG4Info.session);
	if(err) {
		FrmCustomAlert(ErrorAlert, "Unable to create session", NULL, NULL);
		goto Done;
	}
	
	// Allocate output buffer	
	outputBufferP = (UInt8*)Allocate(planarImage.width * planarImage.height * 2);
	if(!outputBufferP) {
		err = memErrNotEnoughSpace;
		FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
		goto Done;
	}
	MemSet(mpeg4ParamP, sizeof(PalmVideoMPEG4EncodeParamType), 0);
	
	// Running from file
	if(gMPEG4Info.loadFileInMemory)
	{	
		// Get the file size
		err = VFSFileSize(gMPEG4Info.inputFileRef, &inputBufferSize);	
		if(err || !inputBufferSize)
			goto Done;
		
		// Might work....	
		inputBufferP = (UInt8*)Allocate(inputBufferSize);
		if(!inputBufferP) {
		
			// Try with FtrPtr
			err = FtrPtrNew(appFileCreator, 0, inputBufferSize, (void*)&inputBufferP);
			if(err) {
				err = memErrNotEnoughSpace;
				FrmCustomAlert(ErrorAlert, "Not enough memory", NULL, NULL);
				goto Done;
			}
			
			useFtr = true;
		}
		
		
		// Load the file
		if(!PrvLoadFileInMemory(gMPEG4Info.inputFileRef, inputBufferSize, inputBufferP, useFtr))
			goto Done;
	}
	
	// Get the bounds for the Go button
	FrmGetObjectBounds(FrmGetActiveForm(), FrmGetObjectIndex(FrmGetActiveForm(),MainGoButton), &goButtonBounds);
	
	// Get the current time here we we go!
	gFrameCount = 0;
	gStartTicks = gLastTick = TimGetTicks();

	// Decode Frames
	while(true)
	{
		// Load raw data from input file
		if(gMPEG4Info.loadFileInMemory)
		{
			if( gMPEG4Info.loop && fileOffset < inputBufferSize)
				fileOffset = 0;
			
			if( fileOffset < inputBufferSize )
			{
				PrvLoadFrameFromMemory(inputBufferP + fileOffset, &planarImage, gMPEG4Info.imageFormat);
				swapImageP->planeP[0] = (void*)Swap32(planarImage.planeP[0]);
				swapImageP->planeP[1] = (void*)Swap32(planarImage.planeP[1]);
				swapImageP->planeP[2] = (void*)Swap32(planarImage.planeP[2]);
				switch(gMPEG4Info.imageFormat)
				{
					case palmCodecImageYCbCr420Planar:
						fileOffset += ( 3 * planarImage.width * planarImage.height ) / 2;
						break;
						
					case palmCodecImageYCbCr422Planar:
						fileOffset += ( 2 * planarImage.width * planarImage.height );
						break;
				}
			}
			else
			{
				FrmCustomAlert(InfoAlert, "Encoding done!", NULL, NULL);
				goto Done;
			}
		}
		else
		{
			// Load from file
			err = PrvLoadFrameFromFile(gMPEG4Info.inputFileRef, &planarImage, gMPEG4Info.imageFormat);
			if(err) {
				if(gMPEG4Info.loop) {
					VFSFileSeek(gMPEG4Info.inputFileRef, vfsOriginBeginning, 0);	
					err = PrvLoadFrameFromFile(gMPEG4Info.inputFileRef, &planarImage, gMPEG4Info.imageFormat);
				} else {
					FrmCustomAlert(InfoAlert, "Encoding done!", NULL, NULL);
					goto Done;
				}
			}

⌨️ 快捷键说明

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