📄 mjpeg_decode.c
字号:
/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc. All Rights Reserved. This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************
$RCSfile: mjpeg_decode.c,v $
$Revision: 1.6 $
$Date: 2006/11/10 07:18:58 $
Project: BlackfinSDK (JPEG-MJPEG)
Title: MJPEG decode
Author(s): ku, bmk
Revised by:
Description:
High level MJPEG decoding functions
References:
None
******************************************************************************
Tab Setting: 4
Target Processor: ADSP-BF5xx
Target Tools Revision: ADSP VisualDSP++ v4.5
******************************************************************************
Modification History:
====================
$Log: mjpeg_decode.c,v $
Revision 1.6 2006/11/10 07:18:58 bmk
merged BF533 & BF561 apps
Fixed BF561 caches issue
Revision 1.5 2006/11/03 07:12:07 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 <MJPEG_AVI_FileReader.h>
#include <jpeg_mjpeg_err.h>
// MJPEG file parameter info prototype
extern int32 MJPEG_AVI_GetImageInfo(int8 *lInputFileName,tJpegParam *limageParam,uint32* lBufLength,FILE *TestReportFile);
extern void *mcu_ex;
// local prototype
int MJPEG_decode(char* input_file);
/*********************************************************************
Function: do_MJPEG_Decode
Description: File Handling for MJPEG decoding
*********************************************************************/
section("sdram0_bank1_nocache")
int do_MJPEG_Decode(void)
{
char current_input_file_name[MAX_FILE_NAME_LEN];
//char file_name[MAX_FILE_NAME_LEN];
static char current_path[MAX_PATH_NAME_LEN];
static char temp_path[MAX_PATH_NAME_LEN];
FILE *fp_mjpg_dir; // file pointer to list file
int next_file = 1; // let next file value not be a null
char key;
bool replay = FALSE; // clear replay flag initially
int return_code = CODEC_SUCCESS;
printf("Blackfin(r) Multimedia Starter Kit - MJPEG 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 MJPEG file(s): ");
fflush(stdout);
scanf ("%s", current_path); // get file path
strcat(current_path,"\\");
printf("Enter MJPEG (.avi) 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 MJPEG list file
strcpy(current_path, SPEC_DIR);
fp_mjpg_dir = fopen( strcat(current_path, MJPEG_LIST_FILE), "r" );
if (fp_mjpg_dir == NULL)
{
fprintf( fperr, "Error: could not read directory file\n" );
return CODEC_FILE_ERROR;
}
printf("Reading list of MJPEG files from %s\n", MJPEG_LIST_FILE);
// Get first File name from directory file
next_file = fscanf(fp_mjpg_dir, "%s", current_input_file_name);
}
// Install Video Encoder (ADV717x)
InstallVideoEncoder();
// Format a JPEG image buffers as ITU656 frame (2 frames for MJPEG)
if (VideoMode == ITU656_PAL)
{
// Format as PAL frame
adi_video_FrameFormat ((char *)pITU656Frames[0],PAL_IL);
// Format as PAL frame
adi_video_FrameFormat ((char *)pITU656Frames[1],PAL_IL);
}
else // VideoMode must be ITU656_NTSC
{
// Format as NTSC frame
adi_video_FrameFormat ((char *)pITU656Frames[0],NTSC_IL);
// Format as NTSC frame
adi_video_FrameFormat ((char *)pITU656Frames[1],NTSC_IL);
}
// Submit Video Output buffers for MJPEG
SubmitVideoOutBufs();
// Setup MDMA for YUV to ITU656 conversion
SetupMDMA_YUV_ITU656();
while((next_file != EOF) && (next_file != (int)NULL))
{
// clear out video frames (black screen)
if (VideoMode == ITU656_PAL)
{
// Fill the Video out frame with background color
adi_video_FrameFill ((char *)pITU656Frames[0],PAL_IL,JPEGImageBackground);
// Fill the Video out frame with background color
adi_video_FrameFill ((char *)pITU656Frames[1],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);
// Fill the Video out frame with background color
adi_video_FrameFill ((char *)pITU656Frames[1],NTSC_IL,JPEGImageBackground);
}
// generate next file path only if replay is not selected
if (!replay)
{
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, ".avi") == NULL) &&
(strstr(current_input_file_name, ".AVI") == NULL))
strcat(current_input_file_name,".avi"); // 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_MJPEG), current_input_file_name);
}
}
// decode the MJPEG file
if ((return_code = MJPEG_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
}
replay = FALSE; // clear replay flag
// Fixes frame jitter at end of file by copying last frame to other output buffer
if(pDestDescStartAddr == pITU656Frames[0])
memcpy(pITU656Frames[1], pITU656Frames[0], (DataPerLine * FrameLines));
else
memcpy(pITU656Frames[0], pITU656Frames[1], (DataPerLine * FrameLines));
// Wait for Key stroke
printf("\nHit 'Return' to go to next file, 'r' to replay this file or 'q' to quit: ");
fflush(stdout);
while (key = getchar())
{
if ((key == 'q') || (key == 'Q'))
next_file = EOF;
else if ((key == 'r') || (key == 'R'))
replay = TRUE; // set replay flag
else if (key == '\n')
break;
}
// read next file only when replay or quit not selected by the user
if ((next_file != EOF) && (!replay))
{
if (File_Settings == PROMPT_FOR_FILE_SETTINGS)
{
printf("\nEnter next MJPEG (.avi) 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_mjpg_dir, "%s", current_input_file_name);
}
}
if(return_code)
fprintf(fperr, "\n!!! MJPEG Decoding Failed !!!\n");
if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
// close the list file
fclose( fp_mjpg_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 CODEC_SUCCESS;
}
/*********************************************************************
Function: MJPEG_decode
Description: Decodes a selected MJPEG file
(by interacting with MJPEG Decode library)
*********************************************************************/
section("App_Code_L1")
int MJPEG_decode(char* input_file_name)
{
tJpegParam lImageParam;
uint32 lMinStreamBufLength = 0;
uint32 lStreamBufferLength = 0;
uint32 lStreamFileInHandle = 0;
uint32 lStreamHandle = 0;
MemObjHandle *StreamBuffer_Obj;
uint8 *lStreamBuffer = NULL;
tIMG_BufferInfo lStreamBufferInfo;
tJpegDecoder *JpegDecHandle = 0;
uint8 *lOutputBuffer;
unsigned int lNumFrames = 0;
int32 lResult = 0;
// Parameters returned from CONFIG
unsigned int CodingType = 0;
unsigned int JPEGWidth = 0;
unsigned int JPEGHeight = 0;
#ifdef ADI_MMSK_EXTRA_INFO // macro to enable extra debug information
// cycle counting
static cycle_t start_count;
static cycle_t final_count;
static cycle_t min_frame_cycles; // decode time
static cycle_t max_frame_cycles;
static cycle_t min_usb_cycles; // usb read time / frame
static cycle_t max_usb_cycles;
static unsigned int min_usb_bytes; // bytes / frame read
static unsigned int max_usb_bytes;
float cycle_sum;
#endif
// Setup MJPEG Decoder
// Read the JPEG information from the first frame of the input file
lResult = JPEG_Param_INIT(&lImageParam);
if(lResult != E_SUCCESS)
{
JPEG_ProcessErrorCode(lResult, "JPEG_Param_INIT");
return CODEC_FILE_ERROR;
}
// Open the AVI file
lResult = MJPEG_AVI_OpenFileRead(&lStreamFileInHandle, (int8 *)input_file_name);
if(lResult != MJPEG_AVI_RETURN_OK)
{
MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_OpenFileRead");
fprintf(fperr, "Error while opening the Input file: %s \n", input_file_name);
return CODEC_FILE_ERROR;
}
// Get the handle for AVI stream
lResult = MJPEG_AVI_OpenStreamRead(lStreamFileInHandle, &lStreamHandle, MJPEG_AVI_StreamTypeVIDEO, 0);
if(lResult != MJPEG_AVI_RETURN_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -