📄 mp4ebuff.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: Stream buffer processing functions of MPEG-4 video encoder
// sample code for Intel(R) Integrated Performance Primitives.
// Functions List:
// put_bits_mpeg4()
// dump_video_buffer()
// load_extend_picture()
// init_output_video_buffer()
// release_output_video_buffer()
******************************************************************************/
#include <memory.h>
#include <malloc.h>
#include "sampmp4.h"
/******************************************************************************
// Name: load_extend_picture
// Description: Load one frame (picture) of YUV4:2:0 raw data to buffer,
// and expand its height and width to be multiples of 16.
//
// Input Arguments:
// fpin Pointer to input file stream buffer
// pic Pointer to input bitstream buffer structure of MPEG-4
// encoder
//
// Output Arguments:
// pic Pointer to updated input bitstream buffer structure of
// MPEG-4 encoder with loaded raw data.
//
// Return: None
******************************************************************************/
void load_extend_picture(FILE *fpin, sample_picture *pic)
{
Ipp8u *tmp_ptr = NULL;
int i = 0, j = 0, w_rim = 0, h_rim = 0;
/* copy y plane */
tmp_ptr = pic->pic_plane[0];
for (i = 0; i < pic->pic_height; i++) {
fread((void*)tmp_ptr, 1, pic->pic_width, fpin);
tmp_ptr += pic->pic_plane_step[0];
}
/* copy u plane */
tmp_ptr = pic->pic_plane[1];
for (i = 0; i < pic->pic_height/2; i++) {
fread((void*)tmp_ptr, 1, pic->pic_width/2, fpin);
tmp_ptr += pic->pic_plane_step[1];
}
/* copy v plane */
tmp_ptr = pic->pic_plane[2];
for (i = 0; i < pic->pic_height/2; i++) {
fread((void*)tmp_ptr, 1, pic->pic_width/2, fpin);
tmp_ptr += pic->pic_plane_step[2];
}
/* extend the picture width to be mutiples of MacroBlocks */
w_rim = pic->pic_width & 15;
if (w_rim) {
w_rim = 16 - w_rim;
/* entend y plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[0] + pic->pic_width - 1;
for (i = 0; i < pic->pic_height; i++) {
for (j = 1; j <= w_rim; j++) {
tmp_ptr[j] = tmp_ptr[0];
}
tmp_ptr += pic->pic_plane_step[0];
}
/* extend u plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[1] + pic->pic_width/2 - 1;
for (i = 0; i < pic->pic_height/2; i++) {
for (j = 1; j <= w_rim/2; j++) {
tmp_ptr[j] = tmp_ptr[0];
}
tmp_ptr += pic->pic_plane_step[1];
}
/* extend v plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[2] + pic->pic_width/2 - 1;
for (i = 0; i < pic->pic_height/2; i++) {
for (j = 1; j <= w_rim/2; j++) {
tmp_ptr[j] = tmp_ptr[0];
}
tmp_ptr += pic->pic_plane_step[2];
}
}
/* extend the picture height to mutiples of MacroBlocks */
h_rim = pic->pic_height & 15;
if (h_rim) {
h_rim = 16 - h_rim;
/* extend y plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[0] + pic->pic_plane_step[0]
* (pic->pic_height - 1);
for (i = 0; i < pic->pic_width + w_rim; i++) {
for (j = 1; j <= h_rim; j++) {
tmp_ptr[j * pic->pic_plane_step[0]] = tmp_ptr[0];
}
tmp_ptr ++;
}
/* extend u plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[1] + pic->pic_plane_step[1]
* (pic->pic_height/2 - 1);
for (i = 0; i < (pic->pic_width + w_rim)/2; i++) {
for (j = 1; j <= h_rim/2; j++) {
tmp_ptr[j * pic->pic_plane_step[1]] = tmp_ptr[0];
}
tmp_ptr ++;
}
/* extend v plane */
tmp_ptr = (Ipp8u*)pic->pic_plane[2] + pic->pic_plane_step[2]
* (pic->pic_height/2 - 1);
for (i = 0; i < (pic->pic_width + w_rim)/2; i++) {
for (j = 1; j <= h_rim/2; j++) {
tmp_ptr[j * pic->pic_plane_step[2]] = tmp_ptr[0];
}
tmp_ptr ++;
}
}
return;
}
/******************************************************************************
// Name: put_bits_mpeg4
// Description: Write N bits to output video buffer
// Input Arguments:
// stream_buf Pointer to the destination compressed video bitstream
// n_bits Number of bits to write, i.e., N (N <= 32)
// data Data containing the N bits
//
// Output Arguments:
// stream_buf Pointer to the updated output video stream after the N
// bits are filled in
//
// Returns:
// None
******************************************************************************/
void put_bits_mpeg4(sample_bitstream *stream_buf, Ipp32u data, int n_bits)
{
int odd_bits = 0, n_bytes = 0;
/* input data is written in big endian */
data = data << (32 - n_bits);
if (stream_buf->bs_cur_bitoffset) {
odd_bits = 8 - stream_buf->bs_cur_bitoffset;
*stream_buf->bs_cur_byte++ |= data >> (32 - odd_bits);
data = data << odd_bits;
n_bits -= odd_bits;
}
if (0 < n_bits) {
n_bytes = (n_bits + 7) / 8;
while (n_bytes--) {
*stream_buf->bs_cur_byte++ = (unsigned char)(data >> 24);
data = data << 8;
}
stream_buf->bs_cur_bitoffset = n_bits & 7;
} else {
stream_buf->bs_cur_bitoffset = (8 + n_bits) & 7;
}
if (stream_buf->bs_cur_bitoffset) {
stream_buf->bs_cur_byte --;
}
return;
}
/******************************************************************************
// Name: dump_video_buffer
// Description: Output video bitstream from buffer to file stream
//
// Input Arguments:
// stream_buf Pointer to the video bitstream buffer
// fpout Pointer to the output file stream
//
// Output Arguments:
// stream_buf Pointer to updated video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_ERR If error occurs in writing data to file
******************************************************************************/
sample_status dump_video_buffer(sample_bitstream *stream_buf, FILE *fpout)
{
unsigned int data_len = 0;
data_len = stream_buf->bs_cur_byte - stream_buf->bs_buffer;
if (fwrite((void*)stream_buf->bs_buffer, 1, data_len, fpout) != data_len) {
return SAMPLE_STATUS_ERR;
}
if (stream_buf->bs_cur_bitoffset) {
/* copy remaining bits */
stream_buf->bs_buffer[0] = stream_buf->bs_cur_byte[0];
}
stream_buf->bs_cur_byte = stream_buf->bs_buffer;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: init_output_video_buffer
// Description: Initialize the output video bitstream buffer
//
// Input Arguments:
// stream_buf Pointer to output video bitstream buffer
// size Bytes to allocate for the bitstream buffer
//
// Output Arguments:
// stream_buf Pointer to allocated video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
// SAMPLE_STATUS_NOMEM_ERR If memory allocation fails
******************************************************************************/
sample_status init_output_video_buffer (sample_bitstream *stream_buf, int size)
{
/* reset the struct to zeroes */
memset((void*)stream_buf, 0, sizeof(sample_bitstream));
/* initialize the output video bitstream buffer which is large enough
// to store one compressed frame plus header */
stream_buf->bs_buffer = (Ipp8u*)malloc(size);
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, size);
}
/* set current pointer to the start of buffer for there's no data written
// at beginning */
stream_buf->bs_cur_byte = stream_buf->bs_buffer;
stream_buf->bs_cur_bitoffset = 0;
stream_buf->bs_bytelen = size;
return SAMPLE_STATUS_NOERR;
}
/*****************************************************************************
// Name: release_output_video_buffer
// Description: Release the output video bitstream buffer
//
// Input Arguments:
// stream_buf Pointer to output video bitstream buffer
//
// Output Arguments:
// stream_buf Pointer to released video bitstream buffer
//
// Returns:
// SAMPLE_STATUS_NOERR If succeeds
*****************************************************************************/
sample_status release_output_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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -