📄 mp4evops.c
字号:
/******************************************************************************
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2003 Intel Corporation. All Rights Reserved.
//
// Description: VOP or frame encoding functions of MPEG-4 video encoder
// sample code for Intel(R) Integrated Performance Primitives.
// Functions List:
// encode_pvop_mpeg4()
// encode_ivop_mpeg4()
// encode_mpeg4()
******************************************************************************/
#include "sampmp4.h"
/******************************************************************************
// Name: encode_pvop_mpeg4
// Desicription:
// Encode the PVOP data in non-ER mode
//
// Input Arguments:
// stream_buf - Pointer to the output video bitstream
// enc_state - Pointer to the general state struct of MPEG-4 encoder
// vop_infor - Pointer to the vop information struct of MPEG-4 encoder
//
// Output Arguments:
// stream_buf - Pointer to the updated output video bitstream after
// compression
// enc_state - Pointer to the updated general state struct of MPEG-4
// encoder
// vop_infor - Pointer to the updated vop information struct of MPEG-4
// encoder
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If encoding fails
// Note:
// Motion estimation based on macroblocks are performed in this function.
******************************************************************************/
sample_status encode_pvop_mpeg4(sample_bitstream *stream_buf,
mp4_enc_state *enc_state,
mp4_enc_vop_infor *vop_infor)
{
Ipp16u *src_sum_mb;
Ipp8u *y_plane;
Ipp8u *src_cur_mb, *src_ref_mb, *src_ref_rec_mb, *src_ref_ori_mb;
Ipp8u transp_curmb_buf[4 + 4];
Ipp8u* transp_curmb = (Ipp8u*)SAMPLE_ALIGN4(transp_curmb_buf);
Ipp8u tmp_cur_mb_buf[64 * 6 + 8];
Ipp8u* tmp_cur_mb = (Ipp8u*)SAMPLE_ALIGN8(tmp_cur_mb_buf);
Ipp8u* type_cur_mb;
int mbx_indx, mby_indx, i, j, y_step;
int mad = 0;
IppiRect ref_rect;
IppMotionVector *mv_cur_mb, mv_pred;
IppMotionVector *mv_left_mb, *mv_top_mb, *mv_top_right_mb;
sample_status ret_code;
/* initialize high-level encoder state */
ret_code = init_vop_infor_enc_mpeg4(enc_state, vop_infor);
if (SAMPLE_STATUS_NOERR != ret_code ) {
return ret_code;
}
/* for rectangular shape, all four blocks in one macroblock are not
// transparent */
for(i = 0; i < 4; i++) {
transp_curmb[i] = IPP_VIDEO_OPAQUE;
}
ref_rect.x = - SAMPLE_VIDEO_MB_SIZE;
ref_rect.y = - SAMPLE_VIDEO_MB_SIZE;
ref_rect.height = enc_state->frame_dimension.height + 2 * SAMPLE_VIDEO_MB_SIZE;
ref_rect.width = enc_state->frame_dimension.width + 2 * SAMPLE_VIDEO_MB_SIZE;
/* forward reference plane */
y_step = enc_state->frame_step_set.y_step;
y_plane = enc_state->fwd_ref_frame.y_ptr - 16 - 16 * y_step;
/* compute summation plane based on blocks of 4 * 4 pixels in forward
// reference plane */
/* y_plane and enc_state->ysum_plane must be 8 bytes aligned */
ret_code = ippiSumNorm_VOP_MPEG4_8u16u(
y_plane,
&ref_rect,
enc_state->ysum_plane,
5,
y_step);
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
}
mv_cur_mb = enc_state->mv_plane;
type_cur_mb = enc_state->mb_type_plane;
src_sum_mb = enc_state->ysum_plane + 16 + 16 * y_step;
src_cur_mb = enc_state->cur_frame.y_ptr;
src_ref_ori_mb = enc_state->fwd_ref_frame.y_ptr;
src_ref_rec_mb = enc_state->fwd_ref_rec_frame.y_ptr;
src_ref_mb = (enc_state->use_src_me == 1) ? src_ref_ori_mb : NULL;
for(mby_indx = 0; mby_indx < enc_state->mb_per_col; mby_indx++) {
for(mbx_indx = 0; mbx_indx < enc_state->mb_per_row; mbx_indx++) {
/* locate three neighbourhood macroblocks for candidate predictors
// Please refer to subclause 7.6.5 of ISO/IEC 14496-2:2001(E) */
mv_left_mb = mv_cur_mb - 4;
mv_top_mb = mv_cur_mb - 4 * (enc_state->mb_per_row + 2);
mv_top_right_mb = mv_top_mb + 4;
/* form the motion vector predictor by a median filtering of three
// candidate predictors for the first block in one macroblock */
/* mv_cur_mb, mv_left_mb, mv_top_mb, mv_top_right_mb must be
// 4 bytes aligned */
ret_code = ippiFindMVpred_MPEG4(
mv_cur_mb,
mv_left_mb,
mv_top_mb,
mv_top_right_mb,
vop_infor->tranp_buf,
vop_infor->tranp_buf + 4,
vop_infor->tranp_buf + 8,
transp_curmb,
&mv_pred,
NULL,
0);
if (ippStsNoErr != ret_code) {
return ret_code;
}
/* copy the macroblock in the plane to a contiguous 16*16 buffer */
for(i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
tmp_cur_mb[i * 16 + j] = src_cur_mb[y_step * i + j];
}
}
/* perform 16x16 size block match with Successive Elimination
// Algorithm */
/* src_ref_mb, src_ref_rec_mb, src_sum_mb, tmp_cur_mb must be
// 8 bytes aligned */
ret_code = ippiMotionEstimation_16x16_SEA(
src_ref_mb,
src_ref_rec_mb,
src_sum_mb,
tmp_cur_mb,
&ref_rect,
&vop_infor->cur_point,
&mv_pred,
mv_cur_mb,
type_cur_mb,
&mad,
y_step,
enc_state->rounding,
enc_state->search_range,
5);
if (ippStsNoErr != ret_code) {
return SAMPLE_STATUS_ERR;
}
/* update pointers for next macroblock in the same row */
src_sum_mb += SAMPLE_VIDEO_MB_SIZE;
src_cur_mb += SAMPLE_VIDEO_MB_SIZE;
src_ref_rec_mb += SAMPLE_VIDEO_MB_SIZE;
if (src_ref_mb) {
src_ref_mb += SAMPLE_VIDEO_MB_SIZE;
}
vop_infor->tranp_buf += 4;
if (0 == mby_indx) {
for(i=0;i<4;i++){
vop_infor->tranp_buf[i] = IPP_VIDEO_OPAQUE;
}
}
vop_infor->cur_point.x += 16;
vop_infor->ref_point.x += 16;
mv_cur_mb += 4;
type_cur_mb ++;
} /* loop for each low */
/* update pointers for first macroblock in the next row */
src_sum_mb += 16 * y_step - 16 * enc_state->mb_per_row;
src_cur_mb += 16 * y_step - 16 * enc_state->mb_per_row;
src_ref_rec_mb += 16 * y_step - 16 * enc_state->mb_per_row;
if (src_ref_mb) {
src_ref_mb += 16 * y_step - 16 * enc_state->mb_per_row;
}
vop_infor->tranp_buf = enc_state->tranp_buf;
vop_infor->cur_point.x = 0;
vop_infor->ref_point.x = 0;
vop_infor->cur_point.y += 16;
vop_infor->ref_point.y += 16;
mv_cur_mb += 2 * 4;
} /* loop for each column */
/* dump vop header information into output stream */
ret_code = create_vop_header_mpeg4 (stream_buf, enc_state, vop_infor);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
/* begin texture encoding */
for(i=0; i< (enc_state->mb_per_row + 2) * 4; i++ ) {
vop_infor->tranp_buf[i] = IPP_VIDEO_TRANSPARENT;
}
vop_infor->cur_point.x = 0;
vop_infor->ref_point.x = 0;
vop_infor->cur_point.y = 0;
vop_infor->ref_point.y = 0;
mv_cur_mb = enc_state->mv_plane;
type_cur_mb = enc_state->mb_type_plane;
/**************************************************************************
// begin the encoding of PVOP, MB by MB. notes the pointers should be set
// or reset at the beginning and ending per Row
**************************************************************************/
for(mby_indx = 0; mby_indx < enc_state -> mb_per_col; mby_indx ++){
for(mbx_indx = 0; mbx_indx < enc_state -> mb_per_row ; mbx_indx ++) {
vop_infor->mb_type = *type_cur_mb;
if ((IPP_VIDEO_INTRA == vop_infor->mb_type)
|| (IPP_VIDEO_INTRA_Q == vop_infor->mb_type)) {
ret_code = encode_intra_mb_mpeg4(stream_buf, enc_state, vop_infor);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
} else {
ret_code = encode_inter_mb_mpeg4(stream_buf, enc_state, vop_infor, mv_cur_mb, transp_curmb);
if (SAMPLE_STATUS_NOERR != ret_code) {
return ret_code;
}
}
/* update for the next macroblck in the same row */
vop_infor->mb_indx ++;
vop_infor->cur_mb.y_ptr += SAMPLE_VIDEO_MB_SIZE;
vop_infor->cur_mb.cb_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->cur_mb.cr_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->fwd_ref_mb.y_ptr += SAMPLE_VIDEO_MB_SIZE;
vop_infor->fwd_ref_mb.cb_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->fwd_ref_mb.cr_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->rec_mb.y_ptr += SAMPLE_VIDEO_MB_SIZE;
vop_infor->rec_mb.cb_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->rec_mb.cr_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->fwd_ref_rec_mb.y_ptr += SAMPLE_VIDEO_MB_SIZE;
vop_infor->fwd_ref_rec_mb.cb_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->fwd_ref_rec_mb.cr_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->coef_buf_row.y_ptr += SAMPLE_VIDEO_MB_SIZE;
vop_infor->coef_buf_row.cb_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
vop_infor->coef_buf_row.cr_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -