📄 mp4dutil.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: Utility functions of MPEG-4 video decoder sample code for
// Intel(R) Integrated Performance Primitives.
// Functions List:
// copy_mb_from_ref_plane()
// lookup_uvmv_mpeg4()
// expand_frame_dec_mpeg4()
// set_ref_frame_dec_mpeg4()
// search_next_sc_mpeg4()
// insert_sc_mpeg4()
******************************************************************************/
#include "sampmp4.h"
/******************************************************************************
// Name: copy_mb_from_ref_plane
// Desicription:
// Copy macroblock pixels from referrence plane to current plane
// Input Arguments:
// src_y - Pointer to the luminance block in referrence plane
// src_cb - Pointer to the chrominance (Cb) block in referrence plane
// src_cr - Pointer to the chrominance (Cr) block in referrence plane
// src_y_step - step of referrence luminance plane
// src_cb_step - step of referrence chrominance (Cb) plane
// src_cr_step - step of referrence chrominance (Cr) plane
// dst_y_step - step of current luminance plane
// dst_cb_step - step of current chrominance (Cb) plane
// dst_cr_step - step of current chrominance (Cr) plane
//
// Output Arguments:
// dst_y - Pointer to the luminance block in current plane
// dst_cb - Pointer to the chrominance (Cb) block in current plane
// dst_cr - Pointer to the chrominance (Cr) block in current plane
// SAMPLE_STATUS_NOERR If succeeds
// Note:
******************************************************************************/
sample_status copy_mb_from_ref_plane
(const Ipp8u *src_y, int src_y_step, const Ipp8u *src_cb, int src_cb_step,
const Ipp8u *src_cr, int src_cr_step, Ipp8u *dst_y, int dst_y_step,
Ipp8u *dst_cb, int dst_cb_step, Ipp8u *dst_cr, int dst_cr_step)
{
int i, j;
/* Copy Y MB from fwd_ref_mb */
for (i = 0; i < SAMPLE_VIDEO_MB_SIZE; i++) {
for (j=0; j < SAMPLE_VIDEO_MB_SIZE; j++) {
dst_y[j] = src_y[j];
}
src_y += src_y_step;
dst_y += dst_y_step;
}
/* Copy UV MB from fwd_ref_mb */
for (i = 0; i < SAMPLE_VIDEO_BLOCK_SIZE; i ++) {
for (j = 0; j < SAMPLE_VIDEO_BLOCK_SIZE; j++) {
dst_cb[j] = src_cb[j];
dst_cr[j] = src_cr[j];
}
src_cb += src_cb_step;
dst_cb += dst_cb_step;
src_cr += src_cr_step;
dst_cr += dst_cr_step;
}
return SAMPLE_STATUS_NOERR;
}
/*****************************************************************************
// Name: lookup_uvmv_mpeg4()
// Description: Look up the motion vector of chrominace block based on the
// motion vector of luminance block.
// Input Arguments:
// mv_lum Pointer to the Motion Vector of Luminance block.
// (1st lumianance block in macroblock)
// mb_type macroblock type
// Output Arguments:
// mv_chr Pointer to the Motion Vector of Luminance block.
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// Notes:
******************************************************************************/
sample_status lookup_uvmv_mpeg4
(IppMotionVector *mv_lum, IppMotionVector *mv_chr, int mb_type)
{
int k ;
int dx, dy;
if ((IPP_VIDEO_INTER4V == mb_type) || (IPP_VIDEO_DIRECT == mb_type)) {
dx = mv_lum[0].dx + mv_lum[1].dx + mv_lum[2].dx + mv_lum[3].dx;
dy = mv_lum[0].dy + mv_lum[1].dy + mv_lum[2].dy + mv_lum[3].dy;
if (0 == dx) {
mv_chr->dx = 0;
} else if (0 < dx) {
k = dx & 0x0f;
mv_chr->dx = (Ipp16s)((dx >> 4) << 1);
if(13 < k) {
mv_chr->dx += 2;
} else if(2 < k) {
mv_chr->dx += 1;
}
} else {
k = (-dx) & 0x0f;
mv_chr->dx = (Ipp16s)(((-dx) >> 4) << 1);
if(13 < k) {
mv_chr->dx += 2;
} else if(2 < k) {
mv_chr->dx += 1;
}
mv_chr->dx = (Ipp16s)(-(mv_chr->dx));
}
if (0 == dy) {
mv_chr->dy = 0;
} else if(0 < dy) {
k = dy & 0x0f;
mv_chr->dy = (Ipp16s)((dy >> 4) << 1);
if(13 < k) {
mv_chr->dy += 2;
} else if(2 < k) {
mv_chr->dy += 1;
}
} else {
k = (-dy) & 0x0f;
mv_chr->dy = (Ipp16s)(((-dy) >> 4) << 1);
if(13 < k) {
mv_chr->dy += 2;
} else if(2 < k) {
mv_chr->dy += 1;
}
mv_chr->dy = (Ipp16s)(-(mv_chr->dy));
}
} else {
if (0 == mv_lum[0].dx) {
mv_chr->dx = 0;
} else if(0 < mv_lum[0].dx) {
mv_chr->dx = (Ipp16s)((mv_lum[0].dx >> 2) << 1);
if(mv_lum[0].dx & 0x3) {
mv_chr->dx += 1;
}
} else {
mv_chr->dx = (Ipp16s)(((-mv_lum[0].dx) >> 2) << 1);
if(mv_lum[0].dx & 0x3) {
mv_chr->dx += 1;
}
mv_chr->dx = (Ipp16s)(-(mv_chr->dx));
}
if (0 == mv_lum[0].dy) {
mv_chr->dy = 0;
} else if(0 < mv_lum[0].dy) {
mv_chr->dy = (Ipp16s)((mv_lum[0].dy >> 2) << 1);
if(mv_lum[0].dy & 0x3) {
mv_chr->dy += 1;
}
} else {
mv_chr->dy = (Ipp16s)(((-mv_lum[0].dy) >> 2) << 1);
if(mv_lum[0].dy & 0x3) {
mv_chr->dy += 1;
}
mv_chr->dy = (Ipp16s)(-(mv_chr->dy));
}
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: expand_frame_dec_mpeg4
// Description: expand reference rectangular VOP with one MacroBlock in
// size to handle unrestricted motion compensated
// prediction over the picture boundaries
//
// Input Arguments:
// dec_state Pointer to the general state struct of MPEG-4 decoder
// Output Arguments:
// dec_state Pointer to the updated general state struct of MPEG-4
// decoder
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
******************************************************************************/
sample_status expand_frame_dec_mpeg4 (mp4_dec_state *dec_state)
{
int y_step = dec_state->frame_step_set.y_step;
int cb_step = dec_state->frame_step_set.cb_step;
int cr_step = dec_state->frame_step_set.cr_step;
int width = dec_state->frame_dimension.width;
int height = dec_state->frame_dimension.height;
Ipp8u *y_ptr = dec_state->fwd_ref_frame.y_ptr - SAMPLE_VIDEO_MB_SIZE
* y_step - SAMPLE_VIDEO_MB_SIZE;
Ipp8u *cb_ptr = dec_state->fwd_ref_frame.cb_ptr - SAMPLE_VIDEO_BLOCK_SIZE
* cb_step - SAMPLE_VIDEO_BLOCK_SIZE;
Ipp8u *cr_ptr = dec_state->fwd_ref_frame.cr_ptr - SAMPLE_VIDEO_BLOCK_SIZE
* cr_step - SAMPLE_VIDEO_BLOCK_SIZE;
/* Padding expandY */
/* y_ptr must be 8 byte aligned */
ippiExpandFrame_H263_8u(y_ptr, width,height, SAMPLE_VIDEO_MB_SIZE, y_step);
/* Padding expandU */
/* cb_ptr must be 8 byte aligned */
ippiExpandFrame_H263_8u(cb_ptr, width/2, height/2, SAMPLE_VIDEO_BLOCK_SIZE,
cb_step);
/* Padding expandV */
/* cr_ptr must be 8 byte aligned */
ippiExpandFrame_H263_8u(cr_ptr, width/2, height/2, SAMPLE_VIDEO_BLOCK_SIZE,
cr_step);
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: set_ref_frame_dec_mpeg4
// Description: set reference plane, namely switch between current frame
// and forward reference frame
//
// 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
******************************************************************************/
sample_status set_ref_frame_dec_mpeg4 (mp4_dec_state *dec_state)
{
sample_spacial_ptrset tmp_frame;
/* switch current and previous ref frame */
tmp_frame = dec_state->fwd_ref_frame;
dec_state->fwd_ref_frame = dec_state->cur_frame;
dec_state->cur_frame = tmp_frame;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: search_next_sc_mpeg4
// Description: search for next_start_code to delimit the whole
// unit of the object (vop, gov, user data) and
// guarantee its complete residence in the buffer
//
// Input Arguments:
// stream_buf Pointer to the source video bitstream
//
// Output Arguments:
// result_pos Pointer to the position of next_start_code if
// it's found
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_SYNCNOTFOUND_ERR If cannot find next sync code
******************************************************************************/
sample_status search_next_sc_mpeg4
(const sample_bitstream *stream_buf, Ipp8u **result_pos)
{
sample_bitstream stream;
Ipp32u code;
int data_len;
stream.bs_cur_byte = stream_buf->bs_cur_byte;
stream.bs_cur_bitoffset = 0;
data_len = stream_buf->bs_bytelen - (stream_buf->bs_cur_byte
- stream_buf->bs_buffer);
/* search for the prefix 24 bits of next_start_code */
if (3 > data_len) {
return SAMPLE_STATUS_SYNCNOTFOUND_ERR;
} else {
code = get_bits_mpeg4(&stream, 24);
data_len -= 3;
}
while ((MPEG4_PREFIX_SC != code) && (0 < data_len)) {
code = ((code << 8) | get_bits_mpeg4(&stream, 8)) & 0xFFFFFF;
data_len -= 1;
}
if (MPEG4_PREFIX_SC != code) {
return SAMPLE_STATUS_SYNCNOTFOUND_ERR;
} else {
*result_pos = stream.bs_cur_byte;
return SAMPLE_STATUS_NOERR;
}
}
/***************************************************************************
// Name: insert_sc_mpeg4
// Description: insert sync code at the end of stream
//
// Input Arguments:
// stream_buf Pointer to video bitstream buffer
//
// Output Arguments:
// stream_buf Pointer to updated video bitstream buffer
//
// Returns:
// None
//
*****************************************************************************/
void insert_sc_mpeg4 (sample_bitstream *stream_buf)
{
/* video buffer was allocated extra 3 bytes to ensure it will not
// overflow */
stream_buf->bs_buffer[stream_buf->bs_bytelen + 0] = 0x00;
stream_buf->bs_buffer[stream_buf->bs_bytelen + 1] = 0x00;
stream_buf->bs_buffer[stream_buf->bs_bytelen + 2] = 0x01;
stream_buf->bs_bytelen += 3;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -