📄 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.4 $
$Date: 2005/10/28 05:46:22 $
Project: Developer Kit
Title: MJPEG encode
Author(s): ku
Revised by:
Description:
High level MJPEG encoding functions
References:
None
******************************************************************************
Tab Setting: 4
Target Processor: ADSP-BF5xx
Target Tools Revision: ADSP VisualDSP++ v4.0
******************************************************************************
Modification History:
====================
$Log: MJPEG_encode.c,v $
Revision 1.4 2005/10/28 05:46:22 dwu
Moved the location of the start_frame counter to give a more accurate count.
Revision 1.3 2005/10/28 02:49:13 dwu
Added error checking code for JPEG/MJPEG routines, and added ADI
legal headers.
*****************************************************************************/
#include "system.h"
#include "codec.h"
#include "video_656.h"
#include "YUV.h"
#include "semaphores.h"
#include "ezkitutilities.h"
#include "cache_services.h"
#include <stdio.h> // stdio header
#include <string.h> // string header
#include <math.h>
#include <cycle_count.h> // for basic cycle counting
// codec APIs
#include "IMG_common.h"
#include "JPEG_BitsBuffer.h"
#include "JPEG_memalloc.h"
#include "JPEG_api_encoder.h"
#include "MJPEG_AVI_filewriter.h"
#include "usr_routines.h"
// encoder settings (valid only for the MJPEG 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 InterLeaveFormat = 1; // 1 = YUV420
static unsigned int Threshhold = 0;
static unsigned int EncodingMode = SEQUENTIAL;
static unsigned int FrameRate = 30;
static bool Capture_from_Video = false;
// local prototype
int MJPEG_encode(char* input_file, bool capture_video);
// Encoder main function
// does all the file handling
section("sdram0_bank1_cache")
int do_MJPEG_encode(void)
{
int Number_Frames;
ADI_DEV_DEVICE_HANDLE PPI_DevHandle;
char current_input_file_name[MAX_FILE_NAME_LEN+4];
static char current_path[MAX_PATH_NAME_LEN];
FILE *fp_mjpg_dir; // file pointer to spec file
int next_file;
char key;
int return_code = CODEC_SUCCESS;
printf("Blackfin(r) JPEG/MJPEG Kit\n");
printf("(c) 2005 Analog Devices Inc.\n");
printf("\n");
Number_Frames = 2; // double buffer video for MJPEG
// Open JPEG list-and-specification file
strcpy(current_path, ROOT_DIR);
fp_mjpg_dir = fopen( strcat(strcat(current_path, SPEC_DIR), MJPG_SPEC_FILE), "r" );
if (fp_mjpg_dir == NULL)
{
fprintf( fperr, "Error: could not read specification file\n" );
return CODEC_FILE_ERROR;
}
// start decoding
printf("Reading list of JPEG files and parameters from %s\n\n", MJPG_SPEC_FILE);
// loop through all the files in the list-file
next_file = !EOF;
while(next_file != EOF)
{
// Get Next File name from directory file
next_file = fscanf(fp_mjpg_dir, "%s %d %d %d", current_input_file_name, &Input_Width, &Input_Height, &QualityFactor);
if( (next_file == EOF) | (next_file == (int)NULL) )
{
break;
}
if ( strstr(current_input_file_name, "DISPLAY") != NULL) // capture from Video Display
{
printf("Capturing from Video Input\n");
// delimit image sizes to valid values
Input_Width =max(Input_Width, 0x10);
Input_Width =min(Input_Width, CCIR656_ACTIVEWIDTH);
Input_Height =max(Input_Height, 0x10);
Input_Height =min(Input_Height, CCIR656_ACTIVEHEIGHT);
Capture_from_Video = true;
}
else // does this make sense for MJPEG? What file format should be used?
{
strcat(current_input_file_name, ".bmp");
// delimit image sizes to valid values
Input_Width =max(Input_Width, 0x10);
Input_Width =min(Input_Width, CCIR656_ACTIVEWIDTH);
Input_Height =max(Input_Height, 0x10);
Input_Height =min(Input_Height, CCIR656_ACTIVEHEIGHT);
Capture_from_Video = false;
}
// Sizes should be multiples of 16
Input_Width &= ~0xf;
Input_Height &= ~0xf;
// delimit quality factor to valid values
QualityFactor =max(QualityFactor, 1);
QualityFactor =min(QualityFactor, 100);
// print actual parameters
printf("Input file: %s\n", current_input_file_name);
printf("Image Size = %d x %d pixels\n", Input_Width, Input_Height);
printf("Encoding Quality Factor = %d \n", QualityFactor);
printf("Writing result to Output file: %s.avi\n", current_input_file_name);
// build the next input file name in tempstring
strcpy(current_path, ROOT_DIR);
strcat(strcat(current_path, IMAGE_DIR_MJPEG), current_input_file_name);
// set up the Video Output driver
Setup_Video_Driver(Number_Frames, 0, &PPI_DevHandle); // 0 == PPI in
// set up DMA services and constant part of descriptors
Setup_YUV_to_VideoFrame_DMA(0); // 0 == VideoFrame -> YUVbuffer
// encode the JPEG file
if ((return_code = MJPEG_encode(current_path, Capture_from_Video)) != CODEC_SUCCESS) {
if (return_code != CODEC_FILE_ERROR) { // if it was a file error, try next file in the list
break; // error! Abort loop
}
}
// Wait for Key stroke to go to next file
printf("\nHit 'Return' key to go to next file...\n");
printf("'s' to skip next file or 'q' to quit: ");
fflush(stdout);
while (key = getchar())
{
if ( (key == 'q') || (key == 'Q') )
next_file = EOF;
else
if (key == '\n')
break;
else
if ( (key == 's') || (key == 'S') )
next_file = fscanf(fp_mjpg_dir, "%s %d %d %d", current_input_file_name, &Input_Width, &Input_Height, &QualityFactor);
}
// clear out video frames (blue screen)
CCIR656_FillFrame(Video_Frames[0], BACKGROUND_COLOR);
CCIR656_FillFrame(Video_Frames[1], BACKGROUND_COLOR);
// free up Video and DMA resources
Free_MEMDMA1_Channel();
Free_Video_Resource(0, &PPI_DevHandle); // 0 == PPI in
}
if(!return_code) printf("Success: Reached end of list\n");
// close the list file
fclose( fp_mjpg_dir );
return CODEC_SUCCESS;
}
//section("sdram0_bank1_cache")
int MJPEG_encode(char* input_file, bool capture_video)
{
tJpegParam lImageParam;
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; /* Image output buffer */
uint32 MaxBytesPerFrame=0;
int32 lResult = 0;
uint32 NumBytes = 0;
// 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;
// frame counting
unsigned int lNumFrames = 0;
unsigned int start_frame = 0;
unsigned int end_frame = 0;
float cycle_sum = 0;
// Disable MDMA
Start_MDMA = false;
// Initialize buffer and variables
InitBufferQueue();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -