📄 mjpeg_encode.c
字号:
#endif
// Configure JPEG encoder
// set the desired input image width
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_FRAME_WIDTH, JPEGImageWidth);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// set the desired input image height
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_FRAME_HEIGHT, JPEGImageHeight);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// set the desired Quality factor
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_QUALITYFACTOR, QualityFactor);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// set the desired encoding mode
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_ENCODINGMODE, EncodingMode);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// set the desired threshold
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_THRESHOLD, Threshold);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// set the desired image frame format
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_IMAGEFORMAT, JPEGFrameFormat);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// allocate the output streambuffer
StreamBuffer_Obj = JPEG_MemAlloc_NEW(3 * JPEGImageWidth * JPEGImageHeight,1,MEM_TYPE_DATA);
if(StreamBuffer_Obj == NULL)
{
fprintf(fperr, "Memory allocation for StreamBuffer failed.\n");
exit(1);
}
// Dynamically allocate memory to store compressed image
StreamBuffer = (uint8*)JPEG_MemAlloc_ADDRESS(StreamBuffer_Obj);
// JPEG image storage buffer
lResult = JPEG_Param_CONFIG(&lImageEncParam, JPEG_POINTER_OUTPUT, (int)StreamBuffer);
if(lResult != E_SUCCESS) JPEG_ProcessErrorCode(lResult, "JPEG_Param_CONFIG");
// Create Instance of JPEG Encoder
lJpegEnc = JPEG_Encoder_NEW(&lImageEncParam);
if(NULL == lJpegEnc)
{
fprintf(fperr, "Encoder creation failed\n");
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_MEMORY_ALLOCATION_ERROR;
}
/****************************
Setup MJPEG Encoder
****************************/
// Create the AVI output file, with the required file
// write result to output file
// check for file extension. add file extension if user didn't provide it
if ((strstr(input_file, ".avi") == NULL) && (strstr(input_file, ".AVI") == NULL))
strcat(input_file,".avi"); // add file extension
printf("\nWriting result to Output file: %s\n", input_file);
// wait for user action
printf("\npress and release button %s on EZ-kit to start recording\n",JPEG_MJPEG_REC_BUTTON_ID);
// wait for button to be pressed
while(!ezIsButtonPushed(JPEG_MJPEG_RECORD_BUTTON));
// wait for button to be released
while(ezIsButtonPushed(JPEG_MJPEG_RECORD_BUTTON));
// Get the input video mode & update the video parameters
UpdateInputVideoMode();
// Frame rate
if (VideoMode == ITU656_NTSC)
// NTSC frame rate (30fps)
FrameRate = ITU656_NTSC_FRAME_RATE;
else if (VideoMode == ITU656_PAL)
// PAL frame rate (25fps)
FrameRate = ITU656_PAL_FRAME_RATE;
// Open input file to write encoded video
lResult = MJPEG_AVI_OpenFileWrite(&lStreamFileOutHandle, (uint8*)input_file,&lImageEncParam, FrameRate);
if(lResult != MJPEG_AVI_RETURN_OK)
{
MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_OpenFileWrite");
fprintf(fperr, "Error while opening the output file: %s \n", input_file);
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_FILE_ERROR;
}
// Set stream parameters from the JPEG parameters
lResult = MJPEG_AVI_SetStreamParams (&lStreamInfo, &lImageEncParam, FrameRate);
if (MJPEG_AVI_RETURN_ERROR == lResult)
{
fprintf(fperr, "Cannot set MJPEG AVI encoder stream parameters\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
// Create the stream
lResult = MJPEG_AVI_OpenStreamWrite(lStreamFileOutHandle, &lStreamHandle, &lStreamInfo);
if(lResult == MJPEG_AVI_RETURN_ERROR)
{
fprintf(fperr, "Cannot create MJPEG AVI encoder stream\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
// Copy the frame format from the JPEG parameters
lResult = MJPEG_AVI_CopyParams (&lBitMapInfo, &lImageEncParam);
if(lResult == MJPEG_AVI_RETURN_ERROR)
{
fprintf(fperr, "Cannot copy MJPEG AVI encoder frame format from JPEG parameters\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
// Set the stream format from the JPEG parameters
lFormatLength = sizeof(tMJPEG_AVI_BITMAPINFO);
lResult = MJPEG_AVI_SetFormat(lStreamHandle, 0, (uint8 *)&lBitMapInfo, lFormatLength);
if(lResult == MJPEG_AVI_RETURN_ERROR)
{
fprintf(fperr, "Cannot set the MJPEG AVI encoder stream format\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
/****************************
Encode video frames
****************************/
lNumFrames = 0;
isMJEInputDataAvailable = E_TRUE;
BufferLevel = NUM_YUV_BUFS;
FrameReady = TRUE;
MJPEG_YUV_BufID = 0;
YUV_MDMA_BufID = 0;
StartMDMA = TRUE;
#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
// Initialise ITU656 to YUV conversion parameters
// Source Descriptor start address - Video (ITU656) buffer(s)
pSrcDescStartAddr = pITU656Frames[0];
// Destination Descriptor start buffer - YUV buffer(s)
pDestDescStartAddr = pYUVBufs[0];
// check interleave format
if (JPEGFrameFormat == 1)
{
// Image will be encoded in YUV420 format
// initialise MDMA descriptors for ITU656 to YUV420 conversion
SetupMDMA_ITU656toYUV420 ();
}
// Check input video mode
if (VideoMode == ITU656_PAL)
printf ("\nRecording from ITU656 PAL Video source...\n");
else if (VideoMode == ITU656_NTSC)
printf ("\nRecording from ITU656 NTSC Video source...\n");
printf("\npress and release button %s AGAIN to stop recording...\n",JPEG_MJPEG_REC_BUTTON_ID);
// Submit Video Input buffers for MJPEG encoding (two ITU656 frame buffers will be used)
SubmitVideoInBufs ();
// wait until a video frame is captured
VideoFrameCompletedFlag = false;
while(VideoFrameCompletedFlag != true)
asm("nop;");
VideoFrameCompletedFlag = false;
// Reset counters
VideoFrameCounter = 1;
FrameDroppedCounter = 0;
// Main loop for each frame
do
{
// Wait for a filled buffer to encode
while (BufferLevel >= NUM_YUV_BUFS);
// Get address of next YUV buffer
lInputBuffer = (uint8*)(pYUVBufs[MJPEG_YUV_BufID]);
// Set input YUV buffer pointer
JPEG_McuBuffer_CONFIG(mcu_ex, MCU_POINTER_C1, (unsigned int)lInputBuffer);
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
START_CYCLE_COUNT(start_count) // begin counting time
#endif
// Encode this frame
lResult = JPEG_EncodeSequentialImage(lJpegEnc, &NumBytes);
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
STOP_CYCLE_COUNT(final_count,start_count) // stop counting
cycle_sum += (float)final_count;
min_frame_cycles = min(min_frame_cycles, final_count);
max_frame_cycles = max(max_frame_cycles, final_count);
#endif
// Process Encoder result
if (lResult != E_SUCCESS)
{
MJPEG_ProcessErrorCode(lResult, "JPEG_EncodeSequentialImage");
fprintf(fperr, "Failed to Encode this file!\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
// Update the count (next YUV buffer to be used by MJPEG encoder)
MJPEG_YUV_BufID++;
if (MJPEG_YUV_BufID >= NUM_YUV_BUFS)
MJPEG_YUV_BufID = 0;
// increment buffer level
BufferLevel++;
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
START_CYCLE_COUNT(start_count) // begin counting time
#endif
// Write encoded frame to the file
lResult = MJPEG_AVI_WriteStream(lStreamHandle, StreamBuffer, NumBytes, 0);
#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, NumBytes);
max_usb_bytes = max(max_usb_bytes, NumBytes);
#endif
// Process Write encoded frame result
if (lResult != MJPEG_AVI_RETURN_OK)
{
MJPEG_ProcessErrorCode(lResult, "MJPEG_AVI_WriteStream");
fprintf(fperr, "\nCan not write MJPEG AVI encoder frame to stream\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_FILE_ERROR;
}
else
{
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
if ((lNumFrames % FrameRate) == 0) printf("\nRecorded %8.8d frames: ", lNumFrames);
printf(".");
#endif
lNumFrames++;
}
} while ((!ezIsButtonPushed(JPEG_MJPEG_RECORD_BUTTON)));
// Disable MDMA
StartMDMA = false;
// some statistics
printf("\nRecorded %d Frames", lNumFrames);
#ifdef ADI_MMSK_EXTRA_INFO // Extra debug information
printf(", Dropped %d Frame(s)\n\n", FrameDroppedCounter);
printf("Average Frame Rate of %d Frames/sec\n", FrameRate * lNumFrames/VideoFrameCounter);
printf("Slowest Frame encoded in %llu cycles, equivalent to %lu cyles/pixel\n", max_frame_cycles,max_frame_cycles/(JPEGImageWidth * JPEGImageHeight));
printf("Fastest Frame encoded in %llu cycles, equivalent to %lu cyles/pixel\n", min_frame_cycles,min_frame_cycles/(JPEGImageWidth * JPEGImageHeight));
printf("Encoding with an average of %.0f cycles, equivalent to %.2f cycles/pixel\n",cycle_sum/lNumFrames,cycle_sum/lNumFrames/(JPEGImageWidth * JPEGImageHeight));
printf("Slowest Frame written %d bytes over USB in %llu cycles\n", max_usb_bytes, max_usb_cycles);
printf("Fastest Frame written %d bytes over USB in %llu cycles\n", min_usb_bytes, min_usb_cycles);
#endif //#ifdef ADI_MMSK_EXTRA_INFO
/************************************
Finalise & Destroy Encoder
************************************/
printf("\nPlease wait while closing this file stream...\n");
// Close the AVI stream
lResult = MJPEG_AVI_CloseStreamWrite(lStreamHandle);
if(lResult == MJPEG_AVI_RETURN_ERROR)
{
fprintf(fperr, "Cannot close MJPEG AVI encoder stream\n");
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
return CODEC_ALGORITHM_ERROR;
}
// Close the output file
lResult = MJPEG_AVI_CloseFileWrite(lStreamFileOutHandle);
if(lResult == MJPEG_AVI_RETURN_ERROR)
fprintf(fperr, "Cannot close MJPEG AVI encoder file\n");
// Free and destroy used resources
JPEG_Encoder_DELETE(lJpegEnc);
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
printf("\n*** MJPEG Conversion successful ***\n");
return CODEC_SUCCESS;
}
/*****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -