📄 spvejpeg.c
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////// spvejpeg.c (JPEG Encoder Functions 'C' File)//// Notice: COPYRIGHT (C) STREAM PROCESSORS, INC. 2005-2007// THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE SPI// END-USER LICENSE AGREEMENT (EULA). THE PROGRAM MAY ONLY// BE USED IN A MANNER EXPLICITLY SPECIFIED IN THE EULA,// WHICH INCLUDES LIMITATIONS ON COPYING, MODIFYING,// REDISTRIBUTION AND WARANTIES. UNAUTHORIZED USE OF THIS// PROGRAM IS STRICTLY PROHIBITED. YOU MAY OBTAIN A COPY OF// THE EULA FROM WWW.STREAMPROCESSORS.COM. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #includes ////////////////////////////////////////////////////////////////////////////////#include "spi_common.h"#include "spvejpeg.h"#include "jpege_context.h"//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_open(void **p_handle)// This function must be called exactly once per encoder//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_open(void **p_handle){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT (p_handle != NULL); p_jenc = (JPEGE_CONTEXT *) spi_malloc (sizeof (JPEGE_CONTEXT)); if (p_jenc == NULL) { spi_printf ("\n Malloc for context failed.\n"); return SPVEJPEG_ERR_MEM; } memset (p_jenc, 0, sizeof(JPEGE_CONTEXT)); *p_handle = p_jenc; // By default, use tables for quant factor of 1 and allocate context and do settings for 320x240 420planar image if ((jpege_set_default (p_jenc)) == STATUS_SUCCESS) { return SPVEJPEG_ERR_SUCCESS; } else { return SPVEJPEG_ERR_FAILED; }}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_close(void *p_handle)// This function must be called exactly once per encoder//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_close(void *p_handle){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT (p_handle != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_free_component_input_buffers (p_jenc); jpege_free_component_tables (p_jenc); jpege_free_component_bit_buffers (p_jenc); spi_free(p_jenc); p_jenc = NULL; return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_prep_encode_frame(// void *p_handle,// SPVEJPEG_IMAGE_SPECS *p_input_image // );// This function should be called once for each image to be encoded//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_prep_encode_frame( void *p_handle, SPVEJPEG_IMAGE_SPECS *p_input_image ){ int i; JPEGE_CONTEXT *p_jenc; IMAGE_FORMAT in_format; unsigned char *p_buffers[MAX_NUM_COMPONENTS]; int padded_width, padded_height; int prev_encode_width, prev_encode_height; SPI_ASSERT (p_handle != NULL); SPI_ASSERT (p_input_image != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; switch (p_input_image->format) { case SPVEJPEG_YUV444_PLANAR: in_format = YUV444_PLANAR; break; case SPVEJPEG_YUV422_PLANAR: in_format = YUV422_PLANAR; break; case SPVEJPEG_YUV420_PLANAR: in_format = YUV420_PLANAR; break; default: spi_printf ("\n Error: Image format %d is not supported\n", p_input_image->format); return SPVEJPEG_ERR_ARG; } padded_width = (p_input_image->width + 7) & ~7; padded_height = (p_input_image->height + 7) & ~7; prev_encode_width = p_jenc->encode_width; prev_encode_height = p_jenc->encode_height; // Figure out whether the yuv frame is bugger than actual encoding size if ((p_input_image->width != p_input_image->buffer.frame_width) || (p_input_image->height != p_input_image->buffer.frame_height) \ || (p_input_image->x_offset != 0) || (p_input_image->y_offset != 0)) { /* TBD: Support taking a portion of the yuv frame as input * Allocate input buffers, extract the input, pad/copy the input to the allocated buffers */ spi_printf ("\n Error: Does not support taking a portion of the yuv frame as input.\n"); return SPVEJPEG_ERR_ARG; } p_buffers[0] = p_input_image->buffer.p_y_buffer; p_buffers[1] = p_input_image->buffer.p_u_buffer; p_buffers[2] = p_input_image->buffer.p_v_buffer; // When Input image height is not a multiple of 8 : // Buffers need not be re-allocated and padded. The index stream will take care of the padding. // // When Input image width is not a multiple of 8 : // Condition is not handled. Seven (7) extra bytes (worst case) will be accessed // outside the buffer boundaries of all the 3 components. Buffer can be over-allocated if reqd. jpege_set_input_image (p_jenc, p_buffers); p_jenc->image_width = p_input_image->width; p_jenc->image_height = p_input_image->height; p_jenc->encode_width = padded_width; p_jenc->encode_height = padded_height; /* If input format or sizes are changed, do realloc of buffers and change context parameters */ if (in_format != p_jenc->input_format) { jpege_set_component_formats(p_jenc, in_format); jpege_free_component_bit_buffers(p_jenc); if (jpege_set_component_sizes(p_jenc) != STATUS_SUCCESS) { spi_printf ("\n Realloc bitstream buffer failed.\n"); return SPVEJPEG_ERR_MEM; } } else if ((padded_width != prev_encode_width) || (padded_height != prev_encode_height)) { jpege_free_component_bit_buffers(p_jenc); if (jpege_set_component_sizes(p_jenc) != STATUS_SUCCESS) { spi_printf ("\n Realloc bitstream buffer failed.\n"); return SPVEJPEG_ERR_MEM; } } /* Mask the following function if tables need to be put only in first frame and when quality/huffman table changes */ jpege_put_all_tables(p_jenc); return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_encode_frame(// void *p_handle,// SPVEJPEG_BITSTREAM_BUFFER *p_output_buffer// );// This function should be called once for each image to be encoded//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_encode_frame( void *p_handle, SPVEJPEG_BITSTREAM_BUFFER *p_output_buffer ){ JPEGE_CONTEXT *p_jenc;#if (defined(ONE_FRAME_PERF) && (defined(SPI_TARGET_DEVICE))) SPI_PERF_T timer ; spi_perf_init (&timer , "timer") ;#endif SPI_ASSERT (p_handle != NULL); SPI_ASSERT (p_output_buffer != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_set_output_buffer (p_jenc, p_output_buffer->p_buffer, p_output_buffer->total_num_bytes);#if (defined(ONE_FRAME_PERF) && (defined(SPI_TARGET_DEVICE))) spi_printf("Perf Start \n "); spi_perf_start (&timer) ;#endif jpege_encode (p_jenc);#if (defined(ONE_FRAME_PERF) && (defined(SPI_TARGET_DEVICE))) spi_perf_stop (&timer) ; spi_perf_print(&timer, 1); spi_printf("Perf Stop \n ");#endif p_output_buffer->used_num_bytes = p_jenc->output_buffer.byte_pos; jpege_free_component_input_buffers (p_jenc); return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_set_quality(// void *p_handle,// int quality // 0 .. 100. 100 being the best quality.// );// Following functions can be called (or not) between frames. If not called, default value will be used//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_set_quality ( void *p_handle, int quality // 0 .. 100. 100 being the best quality. 75 is the default. ){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT(p_handle != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_set_quality (p_jenc, quality); return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_set_qp(// void *p_handle,// int qp// );// Following functions can be called (or not) between frames. If not called, default value will be used//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_set_qp ( void *p_handle, int qp ){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT(p_handle != NULL); SPI_ASSERT(qp != 0); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_set_qp (p_jenc, qp); return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_get_qp(// void *p_handle,// int qp// );// Following functions can be called (or not) between frames. If not called, default value will be used//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_get_qp ( void *p_handle, int *p_qp ){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT(p_handle != NULL); SPI_ASSERT(p_qp != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; *p_qp = p_jenc->quant_scale_factor; return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_add_quant_table (// void *p_handle,// SPVEJPEG_QUANT_TABLE *p_table// );// Following functions can be called (or not) between frames. If not called, default value will be used//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_add_quant_table ( void *p_handle, SPVEJPEG_QUANT_TABLE *p_table ){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT(p_handle != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_add_quant_table (p_jenc, p_table->table_index, p_table->p_basic_table); return SPVEJPEG_ERR_SUCCESS;}//--------------------------------------------------------------------// SPVEJPEG_ERROR spvejpeg_add_huffman_table (// void *p_handle,// SPVEJPEG_HUFFMAN_TABLE *p_table// );// Following functions can be called (or not) between frames. If not called, default value will be used//--------------------------------------------------------------------SPVEJPEG_ERROR spvejpeg_add_huffman_table ( void *p_handle, SPVEJPEG_HUFFMAN_TABLE *p_table ){ JPEGE_CONTEXT *p_jenc; SPI_ASSERT(p_handle != NULL); p_jenc = (JPEGE_CONTEXT *) p_handle; jpege_add_huff_table (p_jenc, p_table->table_type, p_table->table_index, p_table->p_code_length, p_table->p_value); return SPVEJPEG_ERR_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -