📄 mjpeg_encode.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_encode.c,v $
$Revision: 1.7 $
$Date: 2006/11/10 07:18:58 $
Project: BlackfinSDK (JPEG-MJPEG)
Title: MJPEG encode
Author(s): ku, bmk
Revised by:
Description:
High level MJPEG encoding functions
References:
None
******************************************************************************
Tab Setting: 4
Target Processor: ADSP-BF5xx
Target Tools Revision: ADSP VisualDSP++ v4.5
******************************************************************************
Modification History:
====================
$Log: mjpeg_encode.c,v $
Revision 1.7 2006/11/10 07:18:58 bmk
merged BF533 & BF561 apps
Fixed BF561 caches issue
Revision 1.6 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_encoder.h>
#include <JPEG_BitsBuffer.h>
#include <IMG_common.h>
#include <JPEG_memalloc.h>
#include <MJPEG_AVI_FileWriter.h>
#include <jpeg_mjpeg_err.h>
// encoder settings (valid only for the JPEG encoder in this file)
// Width, Heigth and Quality Factor can be set through the specification file
static unsigned int QualityFactor = 40; // Input Desired Quality Factor
static unsigned int Threshold = 0;
static unsigned int EncodingMode = SEQUENTIAL;
// local prototype
int MJPEG_encode(char* input_file);
/*********************************************************************
Function: do_MJPEG_Encode
Description: File Handling for MJPEG encoding
*********************************************************************/
section("sdram0_bank1_nocache")
int do_MJPEG_Encode(void)
{
char current_input_file_name[MAX_FILE_NAME_LEN+4];
static char current_path[MAX_PATH_NAME_LEN];
static char temp_path[MAX_PATH_NAME_LEN];
FILE *fp_mjpg_dir; // file pointer to spec file
int next_file = 1; // let next file value not be a null
char key;
int return_code = CODEC_SUCCESS;
printf("Blackfin(r) Multimedia Starter Kit - MJPEG Encoder\n");
printf("(c) 2006 Analog Devices Inc.\n\n");
// Reset Video codecs
ResetVideoCodecs();
if (File_Settings == PROMPT_FOR_FILE_SETTINGS)
{
printf("Enter directory path to store MJPEG (.avi) file(s): ");
fflush(stdout);
scanf ("%s", current_path);
strcat(current_path,"\\");
printf("Name this MJPEG file as: ");
fflush(stdout);
scanf ("%s", current_input_file_name);
}
else if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
{
// Open MJPEG list-and-specification file
strcpy(current_path, SPEC_DIR);
fp_mjpg_dir = fopen( strcat(current_path, MJPEG_SPEC_FILE), "r" );
if (fp_mjpg_dir == NULL)
{
fprintf( fperr, "Error: could not read specification file\n" );
return CODEC_FILE_ERROR;
}
printf("\nReading list of MJPEG files and parameters from '%s'\n", MJPEG_SPEC_FILE);
// loop through all the files in the list-file
// Get first File name from directory file
next_file = fscanf(fp_mjpg_dir, "%s %d %d %d", current_input_file_name, &JPEGImageWidth, &JPEGImageHeight, &QualityFactor);
}
// Format a JPEG image buffer as ITU656 frame
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);
}
// continue till end of list or user selects to quit
while((next_file != EOF) && (next_file != (int)NULL))
{
if (File_Settings == PROMPT_FOR_FILE_SETTINGS)
{
printf("\n");
printf("Desired Frame Size (Width) : ");
fflush(stdout);
scanf ("%d", &JPEGImageWidth);
printf("Desired Frame Size (Height): ");
fflush(stdout);
scanf ("%d", &JPEGImageHeight);
printf("Desired Quality factor : ");
fflush(stdout);
scanf ("%d", &QualityFactor);
key = getchar(); // clear the final character (\n) in the input buffer
}
// delimit image sizes to valid values
// minimum image size must be 16 x 16 pixels
// maximum can be size of input resolution (720 x 486 for NTSC, 720 x 576 for PAL)
if (JPEGImageWidth < 0x10)
JPEGImageWidth = 0x10;
else if (JPEGImageWidth > ITU_PIXEL_PER_LINE)
JPEGImageWidth = ITU_PIXEL_PER_LINE;
if (JPEGImageHeight < 0x10)
JPEGImageHeight = 0x10;
else if (JPEGImageHeight > ActiveFrameLines)
JPEGImageHeight = ActiveFrameLines;
// Sizes should be in multiples of 16
JPEGImageWidth &= ~0x0F;
JPEGImageHeight &= ~0x0F;
// Quality factor should be between 1 and 100
if (QualityFactor < 1)
QualityFactor = 1;
else if (QualityFactor > 100)
QualityFactor = 100;
// 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);
// 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);
}
// Install video decoder (ADV7183)
InstallVideoDecoder();
// Setup MDMA for ITU656 to YUV conversion
SetupMDMA_YUV_ITU656();
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
{
// print actual parameters
printf("\nImage size to capture = %d x %d pixels\n", JPEGImageWidth, JPEGImageHeight);
printf("Encoding Quality Factor = %d \n", QualityFactor);
}
#endif
if (File_Settings == PROMPT_FOR_FILE_SETTINGS)
{
// 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)
{
// build the next input file name in tempstring
strcpy(temp_path, ROOT_DIR);
strcat(strcat(temp_path, IMAGE_DIR_MJPEG), current_input_file_name);
}
// start MJPEG encoding
if ((return_code = MJPEG_encode(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
}
// 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 != (int)NULL))
{
if (File_Settings == PROMPT_FOR_FILE_SETTINGS)
{
printf("\nName this MJPEG file as: ");
fflush(stdout);
scanf ("%s", current_input_file_name);
}
else if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
{
// Get Next File name from directory file
next_file = fscanf(fp_mjpg_dir, "%s %d %d %d", current_input_file_name, &JPEGImageWidth, &JPEGImageHeight, &QualityFactor);
}
}
// free up Video and DMA resources
// Free MDMA stream used for ITU656 to YUV conversion
FreeMDMA_YUV_ITU656 ();
// Close Video Decoder (ADV7183)
ezErrorCheck(adi_dev_Close(ADV7183DeviceHandle));
}
if(return_code)
fprintf(fperr, "!!! MJPEG Encoding Failed !!!\n");
if (File_Settings == GET_FILE_SETTINGS_FROM_TXT_FILE)
{
printf("Reached end of list\n");
// close the list file
fclose( fp_mjpg_dir );
}
return CODEC_SUCCESS;
}
/*********************************************************************
Function: MJPEG_encode
Description: Encodes ITU656 video frames to MJPEG file
(by interacting with MJPEG Encode library)
*********************************************************************/
section("App_Code_L1")
int MJPEG_encode(char* input_file)
{
tJpegParam lImageEncParam = { 0 };
MemObjHandle *StreamBuffer_Obj;
uint8 *StreamBuffer = NULL;
uint32 lStreamFileOutHandle = 0;
uint32 lFormatLength = 0;
tJpegEncoder *lJpegEnc = 0;
tMJPEG_AVI_STREAMINFO lStreamInfo;
tMJPEG_AVI_BITMAPINFO lBitMapInfo;
uint32 lStreamHandle = 0;
uint8 *lInputBuffer;
int32 lResult = 0;
uint32 NumBytes = 0;
static unsigned int FrameRate;
unsigned int lNumFrames = 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -