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

📄 jpeg_decode.c

📁 这个是balckfin533/561的MPEG和Mjpeg的源代码
💻 C
字号:
/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc.  All Rights Reserved. This software is 
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************

$RCSfile: jpeg_decode.c,v $
$Revision: 1.6 $
$Date: 2006/11/20 05:54:44 $

Project:	BlackfinSDK (JPEG-MJPEG)
Title:		JPEG decode
Author(s):	ku, bmk
Revised by: 

Description:
			High level JPEG decoding functions

References:
			None

******************************************************************************
Tab Setting:			4

Target Processor:		ADSP-BF5xx
Target Tools Revision:	ADSP VisualDSP++ v4.5
******************************************************************************

Modification History:
====================
$Log: jpeg_decode.c,v $
Revision 1.6  2006/11/20 05:54:44  bmk
Enabled streaming for video output

Revision 1.5  2006/11/10 07:18:59  bmk
merged BF533 & BF561 apps
Fixed BF561 cache issue

Revision 1.4  2006/11/03 07:12:16  bmk
SDK 2.0  files - Initial Entry

*****************************************************************************/

#include <jpeg_mjpeg_system.h>		// JPEG-MJPEG System includes

#include <adi_usbio_blackfin.h>		// USB I/O functions for Blackfin
#include <string.h>					// string header
#include <math.h>
#include <cycle_count.h> 			// for basic cycle counting

// codec APIs
#include <JPEG_api_decoder.h>
#include <JPEG_BitsBuffer.h>
#include <IMG_common.h>
#include <JPEG_memalloc.h>
#include <jpeg_mjpeg_err.h>

// local function prototype
int JPEG_decode(char* input_file);

/*********************************************************************

    Function:       do_JPEG_Decode

    Description:    File Handling for JPEG decoding

*********************************************************************/	
section("sdram0_bank1_nocache")
int do_JPEG_Decode (void)
{
	char  current_input_file_name[MAX_FILE_NAME_LEN];
	static char current_path[MAX_PATH_NAME_LEN];
	static char temp_path[MAX_PATH_NAME_LEN];

	FILE *fp_jpg_dir;			// file pointer to list file

	int next_file = 1;	// let next file value not be a null
	char key;
	int return_code = CODEC_SUCCESS;
	int i;
	
	printf("Blackfin(r) Multimedia Starter Kit - JPEG Decoder\n");
	printf("(c) 2006 Analog Devices Inc.\n\n");

	// Reset Video codecs
	ResetVideoCodecs();
	
	// Display output video mode
	if (OutputVideoMode == ITU656_NTSC)
		// NTSC video out
		printf ("ITU656 NTSC Interlaced Video Out\n\n");
	else if (OutputVideoMode == ITU656_PAL)
		// PAL video out
		printf ("ITU656 PAL Interlaced Video Out\n\n");

	// prompt for file name & location?
	if (File_Settings == PROMPT_FOR_FILE_SETTINGS) 
	{
	    printf("Enter directory path holding JPEG file(s): ");
	    fflush(stdout);
	    scanf ("%s", current_path);	// get file path
	    strcat(current_path,"\\");
	    printf("Enter JPEG file name to decode: ");
	    fflush(stdout);
	    scanf ("%s", current_input_file_name);	// get file name
	    key = getchar();	// clear the final character (\n) in the input buffer
	}   
	else if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE) 
	{
  		// Open JPEG list file from .txt file in spec directory
  		strcpy(current_path, SPEC_DIR);  	
		fp_jpg_dir = fopen( strcat(current_path, JPEG_LIST_FILE), "r" );
 		if (fp_jpg_dir == NULL)
		{
			fprintf( fperr, "Error: could not read directory file\n" );
			return CODEC_FILE_ERROR;
		}
		
		// start decoding
		printf("Reading list of JPEG files from %s\n", JPEG_LIST_FILE);
		// Get first File name from directory file
		next_file = fscanf(fp_jpg_dir, "%s", current_input_file_name);
	}
	
	// clear Frame ready flag to start JPEG Decoding
	FrameReady 	= FALSE;
	// Install Video Encoder (ADV717x)
	InstallVideoEncoder();	
  	// Setup MDMA for YUV to ITU656 conversion
 	SetupMDMA_YUV_ITU656();
 			 			
	// Format a JPEG image buffer as ITU656 frame
	if (VideoMode == ITU656_PAL)
		// Format as PAL frame
		adi_video_FrameFormat ((char *)pITU656Frames[0],PAL_IL);
	else // VideoMode must be ITU656_NTSC
		// Format as NTSC frame
		adi_video_FrameFormat ((char *)pITU656Frames[0],NTSC_IL);

	while((next_file != EOF) && (next_file != (int)NULL))
	{	
		// clear out video frame (black screen)
		if (VideoMode == ITU656_PAL)
			// Fill the Video out frame with background color
			adi_video_FrameFill ((char *)pITU656Frames[0],PAL_IL,JPEGImageBackground);
		else // VideoMode must be ITU656_NTSC
			// Fill the Video out frame with background color
			adi_video_FrameFill ((char *)pITU656Frames[0],NTSC_IL,JPEGImageBackground);

		if (File_Settings == PROMPT_FOR_FILE_SETTINGS) 
		{
	    	// check for file extension. add file extension if user didn't provide it	    	
	    	if ((strstr(current_input_file_name, ".jpg") == NULL) &&
	    		(strstr(current_input_file_name, ".JPG") == NULL))
	    		strcat(current_input_file_name,".jpg");	// add file extension	    				    
			// build the next input file name in tempstring
	    	strcpy (temp_path,current_path);
			strcat(temp_path, current_input_file_name);			
		}   
		else if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE) 
		{
			printf("\nInput file: %s\n", current_input_file_name);

			// build the next input file name in tempstring
			strcpy(temp_path, ROOT_DIR);
			strcat(strcat(temp_path, IMAGE_DIR_JPEG), current_input_file_name);
		}
								
		// decode the JPEG file
		if ((return_code = JPEG_decode(temp_path)) != CODEC_SUCCESS)
		{
			// if it was a file error, try next file in the list
			if (return_code != CODEC_FILE_ERROR)
				break;			// error! Abort loop
			else
				FrameReady = TRUE;	// File error. go to next file
		}
		
		// wait until JPEG to ITU656 frame conversion is done
		while(!FrameReady)
			asm("nop;");

		// Submit Video Output buffer for JPEG (only one ITU656 frame buffer will be used)
		SubmitVideoOutBufs();
		
		// Wait for Key stroke to go to next file
		printf("\nHit 'Return' key to go to next file or 'q' to quit: ");
		fflush(stdout);
		
		while (key = getchar())
		{
			if ((key == 'q') || (key == 'Q'))
				next_file = EOF;
			else if (key == '\n')								    
				break;
		}

		// check for end of file
		if((next_file != EOF) && (next_file != 0))
		{
			if (File_Settings == PROMPT_FOR_FILE_SETTINGS) 
			{
				printf("\nEnter next JPEG file name to decode: ");
	    		fflush(stdout);
	    		scanf ("%s", current_input_file_name);
	    		key = getchar();	// clear the final character (\n) in the input buffer
			}
			else if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
	        	// Get Next File name from directory file
				next_file = fscanf(fp_jpg_dir, "%s", current_input_file_name);		
		}
		
		FrameReady = FALSE;	// clear flag for next JPEG frame
	}

	if(return_code)
		fprintf(fperr, "\n!!! JPEG Decoding Failed !!!\n");

	if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
		// close the list file
		fclose( fp_jpg_dir );

	// free up Video and DMA resources	
	// Free MDMA stream used for YUV to ITU656 conversion
	FreeMDMA_YUV_ITU656 ();	
	// Close Video Encoder (ADV717x)
	ezErrorCheck(adi_dev_Close(ADV717xDeviceHandle));	
	
  	return return_code;
}

/*********************************************************************

    Function:       JPEG_decode

    Description:    Decodes a JPEG image (by interacting with JPEG Decode library)
    				Initiates YUV to ITU656 conversion

*********************************************************************/	
section("sdram0_bank1_cache")
int JPEG_decode(char* input_file_name)
{
	tJpegParam   				lParam;
    tJpegDecoder    			*JpegDecHandle = 0;
    FILE            			*inPtr = NULL;
	tIMG_BufferInfo 			lInputBufferInfo;
    MemObjHandle    			*StreamBuffer_Obj;
	uint8	        			*lOutputBuffer;
	// Parameters returned from CONFIG
    unsigned int    			JPEGWidth = 0;
    unsigned int    			JPEGHeight = 0;

	int32 				    	lResult = 0;

#ifdef ADI_MMSK_EXTRA_INFO		// macto to enable extra debug information
	// cycle counting
	static cycle_t              start_count;
	static cycle_t              final_count;
#endif
	
	// Start a new image
	if (JPEG_Param_INIT (&lParam) != E_SUCCESS)
	{
		fprintf(fperr, "Could not initialize JPEG parameters.\n");
		return CODEC_ALGORITHM_ERROR;
	}

	// Configure the input buffer (get size from input file)
	inPtr = fopen(input_file_name, "rb");
	if(inPtr == NULL)
	{
		fprintf(fperr, "Error opening Input File %s\n",input_file_name);
		return CODEC_FILE_ERROR;;
	}
	
	// Get the size of JPEG file to be decoded
	fseek(inPtr, 0, SEEK_END);
	lInputBufferInfo.Length  = ftell (inPtr);			// size of input file
	
	// Dynamically allocate memory to copy the JPEG file for decoding
    StreamBuffer_Obj = JPEG_MemAlloc_NEW(lInputBufferInfo.Length,sizeof (uint8),MEM_TYPE_DATA);
	if(StreamBuffer_Obj == NULL)
	{
		fprintf(fperr,"Memory allocation for StreamBuffer failed.\n");
	    fprintf(fperr, "Could not allocate %d bytes for input buffer\n", lInputBufferInfo.Length);
	    fclose(inPtr);
		return CODEC_MEMORY_ALLOCATION_ERROR;
	}
	// Get the address of dynamically allocated buffer
	lInputBufferInfo.Pointer = (uint8*)JPEG_MemAlloc_ADDRESS(StreamBuffer_Obj);

	// Read the input file
	fseek(inPtr, 0, SEEK_SET);

	// Copy the JPEG file to dynamically allocated memory for decoding
	if (fread(lInputBufferInfo.Pointer, sizeof (uint8), lInputBufferInfo.Length, inPtr) != lInputBufferInfo.Length)
	{
		fprintf(fperr, "Could not read input image\n");
	    fclose(inPtr);
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_FILE_ERROR;
	}

#ifdef ADI_MMSK_EXTRA_INFO		// macto to enable extra debug information
	printf("Input buffer size    = %d bytes\n", lInputBufferInfo.Length);
	printf("Input buffer address = 0x%x\n\n", lInputBufferInfo.Pointer);
#endif

	// Done with input file: close it
	fclose(inPtr);

	// Configure JPEG library to decode the copied JPEG image
	lResult = JPEG_Param_CONFIG(&lParam, JPEG_POINTER_INPUT, (int)&lInputBufferInfo);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    
    // Create a new JPEG Decoder instance   	
	JpegDecHandle = JPEG_Decoder_NEW(&lParam);
	if (JpegDecHandle == NULL)
	{
	    fprintf(fperr, "Could not create JPEG decoder instance\n");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_ALGORITHM_ERROR;
	}

	// Process the JPEG header and extract image parameters
	lResult = JPEG_ProcessHeader(JpegDecHandle, &lParam);
	if (lResult != E_SUCCESS)
	{
		JPEG_ProcessErrorCode(lResult, "JPEG_ProcessHeader");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		JPEG_Decoder_DELETE(JpegDecHandle);
		return CODEC_FILE_ERROR;
	}
	
	// Get the JPEG image width
	lResult = JPEG_Param_STATUS(&lParam, JPEG_FRAME_WIDTH, &JPEGWidth);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
    // Get the JPEG image height
    lResult = JPEG_Param_STATUS(&lParam, JPEG_FRAME_HEIGHT, &JPEGHeight);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
    // Get the JPEG image frame format (YUV4xx/RGG)
	lResult = JPEG_Param_STATUS(&lParam, JPEG_IMAGEFORMAT, &JPEGFrameFormat);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");

    // Check the decoded JPEG image Frame Format
	if (JPEGFrameFormat != 1)
	{
	    // image format not supported by this app
		fprintf(fperr,"Input image format not supported, \n");
		fprintf(fperr,"this version of developer kit only supports YUV420 format\n");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		JPEG_Decoder_DELETE(JpegDecHandle);
		return CODEC_SUCCESS;
	}
	
	// Pointer to (JPEG decoded) output buffer
	lOutputBuffer = (uint8*)pYUVBufs[0];
		
	// check if the image is bigger than YUV buffer	size
	if ((JPEGWidth * JPEGHeight) > (MAX_JPEG_IMAGE_WIDTH * MAX_JPEG_IMAGE_HEIGHT))
	{
	    // This image can't be decoded as its bigger than available buffer size
		fprintf(fperr, "Image size larger than YUV buffer size\n");
		fprintf(fperr, "Image size - %d x %d pixels (includes padding), YUV size - %d x %d pixels\n",\
						JPEGWidth,JPEGHeight,MAX_JPEG_IMAGE_WIDTH,MAX_JPEG_IMAGE_HEIGHT);
		fprintf(fperr, "This file will be skipped!");
		printf("\n");
		JPEG_Decoder_DELETE(JpegDecHandle);
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_FILE_ERROR;
	}
		    
	// Give the output buffer pointer to JPEG Decoder library
	lResult = JPEG_Param_CONFIG(&lParam, JPEG_POINTER_OUTPUT, (int)lOutputBuffer);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
    
#ifdef ADI_MMSK_EXTRA_INFO		// macro to enable extra debug information    	
	// check if the image is bigger than output display resolution size
	if ((JPEGWidth * JPEGHeight) > (ITU_PIXEL_PER_LINE * ActiveFrameLines))
	    // This image will be clipped
		printf("Image size larger than Display resolution. This image will be clipped!\n\n");

	printf("Actual  Image Size = %d x %d pixels\n", JPEGWidth, JPEGHeight);
	printf("Display Image Size = %d x %d pixels\n", ITU_PIXEL_PER_LINE, ActiveFrameLines);
	
	START_CYCLE_COUNT(start_count)	// begin counting time
#endif

	// Decode the JPEG image
	lResult = JPEG_DecodeImage(JpegDecHandle, &lParam);
	
#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information
	STOP_CYCLE_COUNT(final_count,start_count)	// stop counting
	printf("Took %lu cycles to decode this image, ",final_count);
	printf("Equivalent to %lu cyles/pixel\n\n", final_count/((JPEGWidth) * (JPEGHeight)));
#endif // ADI_MMSK_EXTRA_INFO

	if (lResult != E_SUCCESS)
	{
	    JPEG_ProcessErrorCode(lResult, "JPEG_DecodeImage");
	    fprintf(fperr, "Failed to Decode this image!\n");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		JPEG_Decoder_DELETE(JpegDecHandle);
		return CODEC_ALGORITHM_ERROR;
	}
	
	// Clean up
	JPEG_Decoder_DELETE(JpegDecHandle);
	JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
	
 	// initialise YUV to ITU656 conversion parameters 			
 	JPEGImageWidth 	= JPEGWidth;
 	JPEGImageHeight	= JPEGHeight;
 	// Source Descriptor start address - YUV buffer(s)
 	pSrcDescStartAddr	= pYUVBufs[0];
 	// Destination Descriptor start buffer - Video (ITU656) buffer(s)
 	pDestDescStartAddr	= pITU656Frames[0];
 		  					
 	// switch to JPEG image Frame format
 	switch (JPEGFrameFormat)
 	{
 	    // case (JPEG image is in YUV420 format)
 		case 1:
			// setup YUV420 to ITU656 frame conversion
			SetupMDMA_YUV420toITU656 ();

		// this would never happen as we've already validated JPEG image format
		default:	
			break;
 	}

	// Disable Video out dataflow before updating Video out buffer
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)FALSE));	

	// Kicks off MDMA for YUV to ITU656 frame conversion
	KickOffMDMA_YUV_ITU656();
	
	printf("***  JPEG Playback successful ***\n");
	
  	return CODEC_SUCCESS;
}

/*****/

⌨️ 快捷键说明

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