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

📄 mp4dec.cpp

📁 一个使用 linux编写的mpeg4解码代码,包括mpeg4解码库和示例代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Description:     Init function for MPEG-4 simple profile decoder, it parses
//                  the stream vo and vol header information, initialize the 
//                  decoder state structure and its working buffer, it also
//                  locates the position of first vop synchronization code
// Input Arguments: 
//      stream_buf  Pointer to the source compressed video bitstream
//      dec_state   Pointer to the general state structure of MPEG-4 decoder.
//
//  Output Arguments:
//      stream_buf  Pointer to the updated video stream
//      dec_state   Pointer to the updated state structure of MPEG-4 decoder.
//
//  Returns:    
//      SAMPLE_STATUS_NOERR             If succeeds
//      SAMPLE_STATUS_NOMEM_ERR         If memory allocation fails
//      SAMPLE_STATUS_ERR               If stream parsing error occurs
//      SAMPLE_STATUS_SYNCNOTFOUND_ERR  If cannot find sync code
//      SAMPLE_STATUS_NOTSUPPORTED_ERR  If stream syntax is not supported by
//                                      current sample decoder
******************************************************************************/
sample_status decoder_init_alloc_mpeg4(sample_bitstream *stream_buf,
                                       mp4_dec_state    *dec_state)
{
    Ipp8u*        next_sc_pos = NULL;
    sample_status ret_code;
    
    /* reset all the state members to zero */
    memset((void*)dec_state, 0, sizeof(mp4_dec_state));

    /* parse vo and vol information from bitstream */    //    printf("stream_buf offset: %d\n", stream_buf->bs_cur_byte-stream_buf->bs_buffer);
    ret_code = parse_voandvol_header_mpeg4(stream_buf, dec_state);//     printf("stream_buf offset: %d\n", stream_buf->bs_cur_byte-stream_buf->bs_buffer);
    if (ret_code != SAMPLE_STATUS_NOERR) {
        return ret_code;
    }
    
    /* determine the vop size */
    dec_state->mb_per_row  = (dec_state->vol_display_width  + 15)
        / SAMPLE_VIDEO_MB_SIZE;
    dec_state->mb_per_col  = (dec_state->vol_display_height + 15)
        / SAMPLE_VIDEO_MB_SIZE;
    
    dec_state->frame_dimension.width  = dec_state->mb_per_row
        * SAMPLE_VIDEO_MB_SIZE;
    dec_state->frame_dimension.height = dec_state->mb_per_col
        * SAMPLE_VIDEO_MB_SIZE;

    dec_state->frame_step_set.y_step  = dec_state->frame_dimension.width
        + SAMPLE_VIDEO_MB_SIZE * 2;
    dec_state->frame_step_set.cb_step = dec_state->frame_dimension.width / 2
        + SAMPLE_VIDEO_MB_SIZE;
    dec_state->frame_step_set.cr_step = dec_state->frame_dimension.width / 2
        + SAMPLE_VIDEO_MB_SIZE;

    /* allocate working buffer for decoder */
    ret_code = get_working_buffer_mpeg4 (dec_state);
    if (ret_code != SAMPLE_STATUS_NOERR) {
        decoder_free_mpeg4(dec_state);
        return ret_code;
    }
    
    /* initialize other members of decoder state structure */
    dec_state->vop_indx = 0;

    /* rectangular picture */
    dec_state->info_pic->pic_width  = dec_state->vol_display_width;
    dec_state->info_pic->pic_height = dec_state->vol_display_height;
    dec_state->info_pic->pic_plane_num   = 3;
    dec_state->info_pic->pic_channel_num = 3;
    dec_state->info_pic->pic_format = SAMPLE_YCbCr411;
    
    dec_state->info_pic->pic_plane_step[0] =
        dec_state->frame_step_set.y_step;
    dec_state->info_pic->pic_plane_step[1] =
        dec_state->frame_step_set.cb_step;
    dec_state->info_pic->pic_plane_step[2] =
        dec_state->frame_step_set.cr_step;

    /* skip stuffing bits to search for next_start_code */
    if (stream_buf->bs_cur_bitoffset) {
        stream_buf->bs_cur_bitoffset = 0;
        stream_buf->bs_cur_byte++;
    }//     printf("stream_buf offset: %d\n", stream_buf->bs_cur_byte-stream_buf->bs_buffer);

    /* search for the following next_start_code in the buffer */
    ret_code = search_next_sc_mpeg4(stream_buf, &next_sc_pos);//     printf("stream_buf offset: %d\n", stream_buf->bs_cur_byte-stream_buf->bs_buffer);
    if (ret_code != SAMPLE_STATUS_NOERR) {
        decoder_free_mpeg4(dec_state);
        return ret_code;
    }
    stream_buf->bs_cur_byte = next_sc_pos;//     printf("stream_buf offset: %d\n", stream_buf->bs_cur_byte-stream_buf->bs_buffer);    //    printf("next sc pos = %d\n", next_sc_pos - stream_buf->bs_buffer);
    return SAMPLE_STATUS_NOERR;
}


/******************************************************************************
// Name:                init_vop_infor_dec_mpeg4
// Desicription:
//                      Initialize VOP information struct at the beginning of
//                      decoding each VOP
//  Input Arguments:
//      dec_state       Pointer to the general state struct of MPEG-4 decoder
//      vop_infor       Pointer to vop information struct of MPEG-4 decoder
//
//  Output Arguments:
//      dec_state       Pointer to the updated state struct of MPEG-4 decoder
//      vop_infor       Pointer to updated vop infor struct of MPEG-4 decoder
//
//  Returns:
//      SAMPLE_STATUS_NOERR  If succeeds
//  Note:  
//  support I-VOP, P-VOP initialization
******************************************************************************/
sample_status init_vop_infor_dec_mpeg4(mp4_dec_state     *dec_state,
                                       mp4_dec_vop_infor *vop_infor)
{
    int     i;
    
    vop_infor->mb_indx   = 0;   

    /* init qp_buf ptr */
    vop_infor->cur_qp    = dec_state->vop_quant;
    vop_infor->qp_buf    = dec_state->qp_buf;    

    /* init buffer ptrs: ac/dc prediction coefficient buffer */
    vop_infor->coef_buf_row.y_ptr  = dec_state->coef_buf_row.y_ptr  + 16;
    vop_infor->coef_buf_row.cb_ptr = dec_state->coef_buf_row.cb_ptr + 8;
    vop_infor->coef_buf_row.cr_ptr = dec_state->coef_buf_row.cr_ptr + 8;

    vop_infor->coef_buf_col.y_ptr  = dec_state->coef_buf_col.y_ptr;    
    vop_infor->coef_buf_col.cb_ptr = dec_state->coef_buf_col.cb_ptr;    
    vop_infor->coef_buf_col.cr_ptr = dec_state->coef_buf_col.cr_ptr;
    
    /* init the dc coefficient on the upper border */
    for (i = 0; i< dec_state->mb_per_row + 1; i++) {
        
        dec_state->coef_buf_row.y_ptr[i*16]   = (Ipp16s) -1;
        dec_state->coef_buf_row.y_ptr[i*16+8] = (Ipp16s) -1;
            
        dec_state->coef_buf_row.cb_ptr[i*8] = (Ipp16s) -1;
        dec_state->coef_buf_row.cr_ptr[i*8] = (Ipp16s) -1;
    }
    
    /* init the dc coefficient on the left border */
    dec_state->coef_buf_col.y_ptr[0]  = (Ipp16s) -1;
    dec_state->coef_buf_col.y_ptr[8]  = (Ipp16s) -1;
    dec_state->coef_buf_col.cb_ptr[0] = (Ipp16s) -1;
    dec_state->coef_buf_col.cr_ptr[0] = (Ipp16s) -1;
    
    /* init buffer ptrs: position the 1st MB in current VOP plane */
    vop_infor->cur_mb.y_ptr  = dec_state->cur_frame.y_ptr;
    vop_infor->cur_mb.cb_ptr = dec_state->cur_frame.cb_ptr;
    vop_infor->cur_mb.cr_ptr = dec_state->cur_frame.cr_ptr;
    

    if (PVOP == dec_state->vop_coding_type) {

        /* init buffer ptrs: position the 1st ref MB in ref VOP plane */
        vop_infor->fwd_ref_mb.y_ptr  = dec_state->fwd_ref_frame.y_ptr;
        vop_infor->fwd_ref_mb.cb_ptr = dec_state->fwd_ref_frame.cb_ptr;
        vop_infor->fwd_ref_mb.cr_ptr = dec_state->fwd_ref_frame.cr_ptr;
        
        /* init two motion compensation function ptrs */
        if(1 == dec_state->rounding) {
            vop_infor->recon_block_func_ptrer = (recon_block_func_ptr)
                ippiMCReconBlock_RoundOn;
            vop_infor->copy_block_func_ptrer  = (copy_block_func_ptr)
                ippiMCBlock_RoundOn_8u;
        } else {
            vop_infor->recon_block_func_ptrer = (recon_block_func_ptr)
                ippiMCReconBlock_RoundOff;
            vop_infor->copy_block_func_ptrer  = (copy_block_func_ptr)
                ippiMCBlock_RoundOff_8u;
        }
        
        /* init mv_buf ptr */
        vop_infor->mv_buf = dec_state->mv_buf;

        /* init tranp_buf ptr */
        vop_infor->tranp_buf = dec_state->tranp_buf;
        for(i=0; i< (dec_state->mb_per_row + 2) * 4; i++ ) {
            vop_infor->tranp_buf[i] = IPP_VIDEO_TRANSPARENT;
        }
    } else if (IVOP == dec_state->vop_coding_type) {
        /* tranp_buf and mv_buf are not used in ivop */
        vop_infor->mv_buf    = NULL;
        vop_infor->tranp_buf = NULL;
    }

    return SAMPLE_STATUS_NOERR;
}

/******************************************************************************
// Name:                decoder_free_mpeg4
// Desicription:
//                      Free working buffer of the MPEG-4 decoder
//  Input Arguments:
//      dec_state       Pointer to the general state struct of MPEG-4 decoder
//
//  Output Arguments:
//      dec_state       Pointer to the updated state struct of MPEG-4 decoder
//
//  Returns:
//      SAMPLE_STATUS_NOERR  If succeeds
//  Note:
//
******************************************************************************/
sample_status decoder_free_mpeg4(mp4_dec_state *dec_state)
{    
    /* cur_frame.y_ptr */
    if (dec_state->cur_frame.y_ptr) {
        dec_state->cur_frame.y_ptr -= dec_state->frame_step_set.y_step
            * SAMPLE_VIDEO_MB_SIZE + SAMPLE_VIDEO_MB_SIZE;
        free_align_mem_mpeg4((void**)&dec_state->cur_frame.y_ptr);
    }

    /* fwd_ref_frame.y_ptr */
    if (dec_state->fwd_ref_frame.y_ptr) {
        dec_state->fwd_ref_frame.y_ptr -= dec_state->frame_step_set.y_step
            * SAMPLE_VIDEO_MB_SIZE + SAMPLE_VIDEO_MB_SIZE;
        free_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.y_ptr);
    }

    /* cur_frame.cb_ptr */
    if (dec_state->cur_frame.cb_ptr) {
        dec_state->cur_frame.cb_ptr -= dec_state->frame_step_set.cb_step
            * SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
        free_align_mem_mpeg4((void**)&dec_state->cur_frame.cb_ptr);
    }

    /* fwd_ref_frame.cb_ptr */
    if (dec_state->fwd_ref_frame.cb_ptr) {
        dec_state->fwd_ref_frame.cb_ptr -= dec_state->frame_step_set.cb_step
            * SAMPLE_VIDEO_MB_SIZE / 2 +SAMPLE_VIDEO_MB_SIZE / 2;
        free_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.cb_ptr);
    }

    /* cur_frame.cr_ptr */
    if (dec_state->cur_frame.cr_ptr) {
        dec_state->cur_frame.cr_ptr -= dec_state->frame_step_set.cr_step
            * SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
        free_align_mem_mpeg4((void**)&dec_state->cur_frame.cr_ptr);
    }

    /* fwd_ref_frame.cr_ptr */
    if (dec_state->fwd_ref_frame.cr_ptr) {
        dec_state->fwd_ref_frame.cr_ptr -= dec_state->frame_step_set.cr_step
            * SAMPLE_VIDEO_MB_SIZE / 2 + SAMPLE_VIDEO_MB_SIZE / 2;
        free_align_mem_mpeg4((void**)&dec_state->fwd_ref_frame.cr_ptr);
    }

    /* coef_buf_row.y_ptr */
    if (dec_state->coef_buf_row.y_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_row.y_ptr);
    }

    /* coef_buf_col.y_ptr */
    if (dec_state->coef_buf_row.y_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_col.y_ptr);
    }

    /* coef_buf_row.cb_ptr */
    if (dec_state->coef_buf_row.cb_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_row.cb_ptr);
    }

    /* coef_buf_col.cb_ptr */
    if (dec_state->coef_buf_col.cb_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_col.cb_ptr);
    }

    /* coef_buf_row.cr_ptr */
    if (dec_state->coef_buf_row.cr_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_row.cr_ptr);
    }

    /* coef_buf_col.cr_ptr */
    if (dec_state->coef_buf_col.cr_ptr) {
        free_align_mem_mpeg4((void**)&dec_state->coef_buf_col.cr_ptr);
    }

    /* mv_buf */
    if (dec_state->mv_buf) {
        free_align_mem_mpeg4((void**)&dec_state->mv_buf);
    }

    /* tranp_buf */
    if (dec_state->tranp_buf) {
        free_align_mem_mpeg4((void**)&dec_state->tranp_buf);
    }

    /* qp_buf */
    if (dec_state->qp_buf) {
        free_align_mem_mpeg4((void**)&dec_state->qp_buf);
    }

    /* info_pic */
    if (dec_state->info_pic) {
        free_align_mem_mpeg4((void**)&dec_state->info_pic);
    }

    return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name:        decode_inter_mb_mpeg4
// Desicription:
//      Decode the texture data of an INTER macroblock
//
//  Input Arguments:
//      stream_buf  - Pointer to the source video bitstream 
//      dec_state   - Pointer to the general state struct of MPEG-4 decoder
//      vop_infor   - Pointer to the vop information struct of MPEG-4 decoder
//
//  Output Arguments:
//      stream_buf  - Pointer to the updated video bitstream
//      vop_infor   - Pointer to the updated vop information struct of MPEG-4
//                    decoder
//
//  Returns:
//     SAMPLE_STATUS_NOERR      If succeeds
//     SAMPLE_STATUS_ERR        If decoding fails
//  Note:
//  
******************************************************************************/
sample_status decode_inter_mb_mpeg4
(sample_bitstream  *stream_buf, const mp4_dec_state *dec_state,
 mp4_dec_vop_infor *vop_infor,  int mbx_indx, int mby_indx)
{
    IppiRect         ref_rect_vop;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -