📄 mp4dec.cpp
字号:
else {
stream_buf->bs_cur_bitoffset = 0;
}
return code;
}
/***************************************************************************
// Name: release_input_video_buffer
// Description: Release the input video bitstream buffer
//
// Input Arguments:
// stream_buf Pointer to input video bitstream buffer
//
// Output Arguments:
// stream_buf Pointer to released video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
*****************************************************************************/
sample_status release_input_video_buffer (sample_bitstream *stream_buf)
{
if (stream_buf->bs_buffer) {
free(stream_buf->bs_buffer);
stream_buf->bs_buffer = NULL;
}
return SAMPLE_STATUS_NOERR;
}
/***************************************************************************
// Name: init_input_video_buffer
// Description: Initialize the input video bitstream buffer
//
// Input Arguments:
// stream_buf Pointer to input video bitstream buffer
//
// Output Arguments:
// stream_buf Pointer to initialized video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_NOMEM_ERR If memory allocation fails
*****************************************************************************/
sample_status init_input_video_buffer (sample_bitstream *stream_buf)
{
/* reset the struct to zeroes */
memset((void*)stream_buf, 0, sizeof(sample_bitstream));
/* initialize the input video bitstream buffer which is large enough
// to store two frames of raw data at least to reduce reload times,
// note to allocate extra 3 bytes for the final sync code insertion */
stream_buf->bs_buffer = (Ipp8u*)malloc(SAMPLE_VIDEO_STREAM_BUF_SIZE
+ MPEG4_SC_LEN);
if (NULL == stream_buf->bs_buffer) {
/* memory allocation fails */
return SAMPLE_STATUS_NOMEM_ERR;
}
else {
/* reset the newly allocated buffer to zeroes */
memset (stream_buf->bs_buffer, 0, SAMPLE_VIDEO_STREAM_BUF_SIZE
+ MPEG4_SC_LEN);
}
/* set current pointer to the end of buffer for there's no data loaded
// at beginning */
stream_buf->bs_cur_byte = stream_buf->bs_buffer
+ SAMPLE_VIDEO_STREAM_BUF_SIZE;
stream_buf->bs_cur_bitoffset = 0;
stream_buf->bs_bytelen = 0;
return SAMPLE_STATUS_NOERR;
}
/***************************************************************************
// Name: load_video_buffer
// Description: Load input video bitstream into buffer
//
// Input Arguments:
// stream_buf Pointer to the video bitstream buffer
// fpin Pointer to the input file stream
//
// Output Arguments:
// stream_buf Pointer to updated video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If no data read from the file stream
*****************************************************************************/
sample_status load_video_buffer(sample_bitstream *stream_buf, FILE *fpin)
{
int offset;
int remain_len;
offset = stream_buf->bs_cur_byte - stream_buf->bs_buffer; remain_len = SAMPLE_VIDEO_STREAM_BUF_SIZE - offset;
/* round the buffer */
if (0 != remain_len) {
memcpy (stream_buf->bs_buffer, stream_buf->bs_cur_byte, remain_len);
}
/* fill up the buffer by loading new data into the buffer */
stream_buf->bs_bytelen = remain_len + fread(stream_buf->bs_buffer
+ remain_len, 1, offset, fpin);
/* no new data loaded */
if (stream_buf->bs_bytelen == remain_len) {
return SAMPLE_STATUS_ERR;
}
stream_buf->bs_cur_byte = stream_buf->bs_buffer;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: free_align_mem_mpeg4
// Description: Free aligned memory blocks
//
// Input Arguments:
// buf_addr_ptr Pointer to the void pointer to the allocated space
// with alignment offset.
//
// Output Arguments:
// buf_addr_ptr Pointer to a NULL void pointer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
******************************************************************************/
sample_status free_align_mem_mpeg4(void **buf_addr_ptr)
{
Ipp8u offset = 0;
Ipp8u *addr = NULL;
addr = (Ipp8u*)(*buf_addr_ptr);
offset = *(addr - 1);
addr -= offset;
free((void*)addr);
*buf_addr_ptr = NULL;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: alloc_align_mem_mpeg4
// Description: Allocate aligned memory blocks
//
// Input Arguments:
// buf_addr_ptr Pointer to the void pointer to the allocated space
// size Number of bytes to be allocated
// alignstatus Number of bytes to be aligned, e.g., 2 for half
// word aligned, 4 for word aligned, 8 for double word
// aligned
//
// Output Arguments:
// buf_addr_ptr Pointer to the void pointer to the allocated space
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_NOMEM_ERR If memory allocation fails
******************************************************************************/
sample_status alloc_align_mem_mpeg4(void **buf_addr_ptr,
int size,
int alignstatus)
{
Ipp8u *addr = NULL;
Ipp8u tmp = 0;
size += alignstatus;
addr = (Ipp8u*)malloc(size);
if (!addr) {
*buf_addr_ptr = NULL;
return SAMPLE_STATUS_NOMEM_ERR;
}
tmp = (Ipp8u)((Ipp32u)(addr) & (alignstatus - 1));
tmp = (Ipp8u)(alignstatus - tmp);
addr += tmp;
*(addr - 1) = tmp;
*buf_addr_ptr = (void*)addr;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: get_working_buffer_mpeg4
// Description: Allocate working buffer for MPEG4 decoder
//
// Input Arguments:
// dec_state Pointer to the general state structure of MPEG-4 decoder
//
// Output Arguments:
// dec_state Pointer to the updated general state structure of MPEG-4
// decoder
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_NOMEM_ERR If memory allocation fails
******************************************************************************/
sample_status get_working_buffer_mpeg4 (mp4_dec_state *dec_state)
{
int size = 0, align = 0;
/* cur_frame.y_ptr */
align = 8;
size = (dec_state->frame_dimension.width + SAMPLE_VIDEO_MB_SIZE * 2)
* (dec_state->frame_dimension.height + SAMPLE_VIDEO_MB_SIZE * 2);
if (alloc_align_mem_mpeg4((void**)&dec_state->cur_frame.y_ptr, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->cur_frame.y_ptr += dec_state->frame_step_set.y_step
* SAMPLE_VIDEO_MB_SIZE + SAMPLE_VIDEO_MB_SIZE;
/* fwd_ref_frame.y_ptr */
if (alloc_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.y_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->fwd_ref_frame.y_ptr += dec_state->frame_step_set.y_step
* SAMPLE_VIDEO_MB_SIZE + SAMPLE_VIDEO_MB_SIZE;
/* cur_frame.cb_ptr */
size = size / 4;
if (alloc_align_mem_mpeg4((void**)&dec_state->cur_frame.cb_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->cur_frame.cb_ptr += dec_state->frame_step_set.cb_step
* SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
/* fwd_ref_frame.cb_ptr */
if (alloc_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.cb_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->fwd_ref_frame.cb_ptr += dec_state->frame_step_set.cb_step
* SAMPLE_VIDEO_MB_SIZE / 2 +SAMPLE_VIDEO_MB_SIZE / 2;
/* cur_frame.cr_ptr */
if (alloc_align_mem_mpeg4((void**)&dec_state->cur_frame.cr_ptr, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->cur_frame.cr_ptr += dec_state->frame_step_set.cr_step
* SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
/* fwd_ref_frame.cr_ptr */
if (alloc_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.cr_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
dec_state->fwd_ref_frame.cr_ptr += dec_state->frame_step_set.cr_step
* SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
/* coef_buf_row.y_ptr */
align = 4;
size = (dec_state->mb_per_row + 1) * sizeof(short) * SAMPLE_VIDEO_MB_SIZE;
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_row.y_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* coef_buf_col.y_ptr */
size = SAMPLE_VIDEO_MB_SIZE * sizeof(short);
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_col.y_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* coef_buf_row.cb_ptr */
size = (dec_state->mb_per_row + 1) * sizeof(short) * SAMPLE_VIDEO_MB_SIZE
/ 2;
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_row.cb_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* coef_buf_col.cb_ptr */
size = (SAMPLE_VIDEO_BLOCK_SIZE) * sizeof(short);
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_col.cb_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* coef_buf_row.cr_ptr */
size = (dec_state->mb_per_row + 1) * sizeof(short) * SAMPLE_VIDEO_MB_SIZE
/ 2;
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_row.cr_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* coef_buf_col.cr_ptr */
size = (SAMPLE_VIDEO_BLOCK_SIZE) * sizeof(short);
if (alloc_align_mem_mpeg4((void**)&dec_state->coef_buf_col.cr_ptr, size,
align) != SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* mv_buf */
align = 4;
size = (dec_state->mb_per_row + 2) * 4 * sizeof(IppMotionVector);
if (alloc_align_mem_mpeg4((void**)&dec_state->mv_buf, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* tranp_buf */
size = (dec_state->mb_per_row + 2) * 4;
if (alloc_align_mem_mpeg4((void**)&dec_state->tranp_buf, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* qp_buf */
align = 8;
size = dec_state->mb_per_row + 1;
if (alloc_align_mem_mpeg4((void**)&dec_state->qp_buf, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
/* info_pic */
size = sizeof(sample_picture);
if (alloc_align_mem_mpeg4((void**)&dec_state->info_pic, size, align)
!= SAMPLE_STATUS_NOERR) {
return SAMPLE_STATUS_NOMEM_ERR;
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: decoder_init_alloc_mpeg4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -