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

📄 mjpeg_decode.c

📁 这个是balckfin533/561的MPEG和Mjpeg的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_OpenStreamRead");
        return CODEC_FILE_ERROR;
    }
	
    // go to start of the frame
    lResult = MJPEG_AVI_RewindToFirstFrame(lStreamHandle, &lStreamBufferLength);
    
	if(lResult == MJPEG_AVI_RETURN_NOMORESAMPLES)
    	fprintf(fperr, "Not enough samples to read the first JPEG image from stream\n");    	
    else if(lResult != MJPEG_AVI_RETURN_OK)
    {
        MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_RewindToFirstFrame");
        return CODEC_FILE_ERROR;
    }
    
    // Dynamically allocate memory to read a MJPEG frame
    StreamBuffer_Obj = JPEG_MemAlloc_NEW(lStreamBufferLength, 1, 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", lStreamBufferLength); return CODEC_FILE_ERROR;
	}

	// get the address of memory location where the MJPEG frame will be read to
	lStreamBuffer = (uint8*)JPEG_MemAlloc_ADDRESS(StreamBuffer_Obj);

	// check if there is any MJPEG frame available for decoding
	lResult = MJPEG_AVI_ReadNextFrame(lStreamHandle, lStreamBuffer, &lMinStreamBufLength);
	if(lResult != MJPEG_AVI_RETURN_OK)
    {
        MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_ReadNextFrame");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
        return CODEC_FILE_ERROR;
    }
	
    // setup JPEG Decoder
	lStreamBufferInfo.Length   = lStreamBufferLength;	// frame size
	lStreamBufferInfo.Pointer  = lStreamBuffer;			// pointer to MJPEG frame in Blackfin memory
	
	// set the input buffer address to JPEG library
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_POINTER_INPUT, (int)&lStreamBufferInfo);
	if(lResult != E_SUCCESS)    
	{
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
        return CODEC_ALGORITHM_ERROR;
    }
    
    // YUV output buffer address
	lOutputBuffer = (uint8*)pYUVBufs[0];
	
	// set the output buffer address to JPEG library
	lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_POINTER_OUTPUT, (int)lOutputBuffer);
	if(lResult != E_SUCCESS)    
	{
        JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
        JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
        return CODEC_ALGORITHM_ERROR;
    }
    
	// create a JPEG Decoder instance
	JpegDecHandle= JPEG_Decoder_NEW(&lImageParam);

	if(JpegDecHandle == NULL)
	{
		fprintf(fperr, "Could not create JPEG decoder instance\n");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_FILE_ERROR;
	}

	// Process JPEG file header info
	lResult = JPEG_ProcessHeader(JpegDecHandle, &lImageParam);
	if(lResult != E_SUCCESS)
    {
        JPEG_ProcessErrorCode(lResult, "JPEG_ProcessHeader");
        JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
        JPEG_Decoder_DELETE(JpegDecHandle);
        return CODEC_FILE_ERROR;
    }
	
    // Get frame width	
	lResult = JPEG_Param_STATUS(&lImageParam, JPEG_FRAME_WIDTH, &JPEGWidth);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
	// Get frame height
	lResult = JPEG_Param_STATUS(&lImageParam, JPEG_FRAME_HEIGHT, &JPEGHeight);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
	// Get frame format
	lResult = JPEG_Param_STATUS(&lImageParam, JPEG_IMAGEFORMAT, &JPEGFrameFormat);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
	// Get coding type
	lResult = JPEG_Param_STATUS(&lImageParam, JPEG_ENCODINGMODE, &CodingType);
	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_STATUS");
	
	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_MemAlloc_DELETE(StreamBuffer_Obj);
		JPEG_Decoder_DELETE(JpegDecHandle);
		return CODEC_FILE_ERROR;
	}

    // Check the decoded MJPEG 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 support YUV420 format files\n");
		JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		JPEG_Decoder_DELETE(JpegDecHandle);
		return CODEC_FILE_ERROR;
	}

    // go to start of the frame
	lResult = MJPEG_AVI_RewindToFirstFrame(lStreamHandle, &lStreamBufferLength);
	if(lResult != MJPEG_AVI_RETURN_OK)	MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_RewindToFirstFrame");

 	// initialise YUV to video (ITU656) frame 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 occur as we've already validated JPEG image format
		default:	
			break;
 	}

#ifdef ADI_MMSK_EXTRA_INFO		// macro to enable extra debug information    	
	// check if the image frame is bigger than output display resolution size
	if ((JPEGWidth * JPEGHeight) > (ITU_PIXEL_PER_LINE * ActiveFrameLines))
	    // This image will be clipped
		printf("Frame size larger than Display resolution. This file will be clipped!\n\n");

	printf("Actual  Frame Size = %d x %d pixels\n", JPEGWidth, JPEGHeight);
	printf("Display Frame Size = %d x %d pixels\n", ITU_PIXEL_PER_LINE, ActiveFrameLines);
#endif

	printf("\nPlaying MJPEG file.Do not press any keys until prompted...\n");

/****************************
Start Decoding MJPEG file
****************************/

	// Initialise counters/flags
	BufferLevel 	= 0;
  	StartMDMA 		= FALSE;
    FrameReady 		= TRUE;
	MJPEG_YUV_BufID = 0;
	YUV_MDMA_BufID	= 0;	
	lNumFrames 		= 0;	// # of frames played
	isMJDInputDataAvailable = E_TRUE;
	FrameDroppedCounter = 0;					// # of frames dropped

#ifdef ADI_MMSK_EXTRA_INFO		// macro to enable extra debug information    	
	// initialise statistics
	max_frame_cycles = 0;
	min_frame_cycles = (cycle_t)10*600*1000000;		// set to time approx equivalent to 10Seconds at 600MHz - no frame should take longer than that to decode :)

	max_usb_cycles = 0;
	min_usb_cycles = (cycle_t)10*600*1000000;		// set to time approx equivalent to 10Seconds at 600MHz - no frame should take longer than that to be read :)
	max_usb_bytes = 0;
	min_usb_bytes = (unsigned int)0x0fffffff;		// big value for min calculation
	cycle_sum = 0;
#endif

	// Continue decoding till reaching end of file
	while(E_TRUE == isMJDInputDataAvailable)
	{
		// Enable MDMA only when half of YUV buffers is filled with MJPEG frame (YUV) data
		if( (!StartMDMA) && (BufferLevel >= NUM_YUV_BUFS) )
			StartMDMA = TRUE;

#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information
	START_CYCLE_COUNT(start_count)	// begin counting time
#endif

		// Read next JPEG frame
		lResult = MJPEG_AVI_ReadNextFrame(lStreamHandle, lStreamBuffer, &lMinStreamBufLength);
		
		MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_ReadNextFrame");
		
        switch (lResult)
		{
			case MJPEG_AVI_RETURN_OK:
				break;

			case MJPEG_AVI_RETURN_NOMORESAMPLES:
#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information	
				printf("Reached end of MJPEG stream\n");
#endif				
				isMJDInputDataAvailable = E_FALSE;
				continue;

			case MJPEG_AVI_RETURN_EVALUATIONLIMITREACHED:
				fprintf(fperr, "*** Reached limit of evaluation library ***\n");
				isMJDInputDataAvailable = E_FALSE;
				continue;

			default:
				printf("Cannot read to next frame of the MJPEG stream.  Error code = %d\n", lResult);
				return CODEC_FILE_ERROR;
		}

#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information
		STOP_CYCLE_COUNT(final_count,start_count)	// stop counting
		// update cycle measurements
		min_usb_cycles = min(min_usb_cycles, final_count);
		max_usb_cycles = max(max_usb_cycles, final_count);
		min_usb_bytes = min(min_usb_bytes, lMinStreamBufLength);
		max_usb_bytes = max(max_usb_bytes, lMinStreamBufLength);	
#endif

		// Next YUV buffer to hold decoded MJPEG frame data
		lOutputBuffer = (uint8*)(pYUVBufs[MJPEG_YUV_BufID]);
		// update the output buffer address to store the decoded image
		lResult = JPEG_Param_CONFIG(&lImageParam, JPEG_POINTER_OUTPUT, (int)lOutputBuffer);
		JPEG_McuBuffer_CONFIG(mcu_ex, MCU_POINTER_C1, (unsigned int)lOutputBuffer);		
    	if(lResult != E_SUCCESS)	JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");        

		// Wait for free buffers for decoding
		while ( (BufferLevel >= NUM_YUV_BUFS) );

#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information
		START_CYCLE_COUNT(start_count)	// begin counting time
#endif
		
		// Decode this frame
		lResult = JPEG_DecodeSequentialImage(JpegDecHandle, &lImageParam);

#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information
		STOP_CYCLE_COUNT(final_count,start_count)	// stop counting
		cycle_sum += (float)final_count;
		// update cycle measurements
		min_frame_cycles = min(min_frame_cycles, final_count);
		max_frame_cycles = max(max_frame_cycles, final_count);
#endif
		
		if (lResult != E_SUCCESS)
		{
	    	MJPEG_ProcessErrorCode(lResult, "JPEG_DecodeSequentialImage");			
	    	fprintf(fperr, "Failed to Decode this file!\n");
			JPEG_Decoder_DELETE(JpegDecHandle);
	    	JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
			return CODEC_ALGORITHM_ERROR;
		}

		// Update the count (next YUV buffer to be used by MJPEG decoder)
		++MJPEG_YUV_BufID;
		if (MJPEG_YUV_BufID >= NUM_YUV_BUFS)
			MJPEG_YUV_BufID = 0;
		
		// increment buffer level
		++BufferLevel;
		// increment frame counter
		lNumFrames++;
	}		// while (E_TRUE == isMJDInputDataAvailable)

	// Wait for all remaining frames to be played
	while (BufferLevel > 0);
	
	// Disable MDMA
	StartMDMA = false;

	// some statistics
	printf("\nPlayed %d Frames", lNumFrames);

#ifdef ADI_MMSK_EXTRA_INFO		// Extra debug information	
	printf(", Dropped %d Frame(s)\n\n", FrameDroppedCounter);
	printf("Slowest Frame decoded in %llu cycles, equivalent to %lu cyles/pixel\n", max_frame_cycles,max_frame_cycles/(JPEGWidth * JPEGHeight));
	printf("Fastest Frame decoded in %llu cycles, equivalent to %lu cyles/pixel\n", min_frame_cycles,min_frame_cycles/(JPEGWidth * JPEGHeight));	
	printf("Average decoding in %.0f cycles, equivalent to %.2f cycles/pixel\n",cycle_sum/lNumFrames,cycle_sum/lNumFrames/(JPEGWidth*JPEGHeight));
	printf("Slowest Frame read %d bytes over USB in %llu cycles\n", max_usb_bytes, max_usb_cycles);
	printf("Fastest Frame read %d bytes over USB in %llu cycles\n", min_usb_bytes, min_usb_cycles);
#endif 

	// clean up and close streams
	if (MJPEG_AVI_CloseStreamRead(lStreamHandle) == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot close MJPEG Decoder AVI stream\n");
		JPEG_Decoder_DELETE(JpegDecHandle);
	    JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_FILE_ERROR;
	}

	if (MJPEG_AVI_CloseFileRead(lStreamFileInHandle) == MJPEG_AVI_RETURN_ERROR)
	{
		fprintf(fperr, "Cannot close MJPEG Decoder input file\n");
		JPEG_Decoder_DELETE(JpegDecHandle);
	    JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
		return CODEC_FILE_ERROR;
	}

	// Free and destroy used resources
	JPEG_Decoder_DELETE(JpegDecHandle);
    JPEG_MemAlloc_DELETE(StreamBuffer_Obj);

	printf("\n***  MJPEG Playback successful ***\n");
  	return CODEC_SUCCESS;
}

/*****/

⌨️ 快捷键说明

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