⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4dec.cpp

📁 一个使用 linux编写的mpeg4解码代码,包括mpeg4解码库和示例代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -