📄 mp4_picture.c
字号:
/********************************************************************************
* *
* This code has been developed by Project Mayo. This software is an *
* implementation of a part of one or more MPEG-4 Video tools as *
* specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies (including Project Mayo), will have no liability for use of *
* this software or modifications or derivatives thereof. *
* *
********************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* The GPL can be found at: http://www.gnu.org/copyleft/gpl.html *
* *
* Authors: *
* *
* Andrea Graziani (Ag): *
* - Original source code (Open Divx Decoder 0.4a). *
* *
* Marc Dukette (Md) and *
* Pedro Mateu (Pm): *
* - Heavily modified and optimized code + MIPS ASM *
* *
********************************************************************************/
// INCLUDE
#include "global.h"
#include "../decore.h"
// FUNCTION DECLARATIONS
extern void IVOP_macroblock();
extern void PVOP_macroblock();
unsigned char Decode_MPEG4_Picture (unsigned char *Frame_Buffer, unsigned char Render_Flag);
static void make_edge (unsigned char *frame_pic, int width, int height, int edge);
static void PictureDisplay(unsigned char *bmp);
static void Decode_I_Frame(unsigned char *Frame_Buffer);
static void Decode_P_Frame(unsigned char *Frame_Buffer);
#ifdef MIPS_ASM_64
#include "MIPS_functions.c"
#endif
// Purpose: decode and display a Vop
unsigned char Decode_MPEG4_Picture(unsigned char *Frame_Buffer, unsigned char Render_Flag)
{
mp4_hdr.mba = 0;
mp4_hdr.mb_xpos = 0;
mp4_hdr.mb_ypos = 0;
switch (mp4_hdr.prediction_type) {
case I_VOP:
Decode_I_Frame(Frame_Buffer);
break;
case P_VOP:
Decode_P_Frame(Frame_Buffer);
break;
case B_VOP:
return 1;
default:
break;
}
return 0;
}
static void Decode_I_Frame(unsigned char *Frame_Buffer)
{
#ifdef MIPS_ASM_64
CPU_64_on();
#endif
do {
IVOP_macroblock();
mp4_hdr.mba++;
} while ((nextbits_bytealigned(23)) && (mp4_hdr.mba < mp4_hdr.mba_size));
#ifdef MIPS_ASM_64
CPU_64_off();
#endif
mp4_hdr.last_prediction_type=mp4_hdr.prediction_type;
PictureDisplay(Frame_Buffer);
}
static void Decode_P_Frame(unsigned char *Frame_Buffer)
{
// exchange ref and for frames
unsigned char i;
unsigned char *tmp;
for (i = 0; i < 3; i++) {
tmp = frame_ref[i];
frame_ref[i] = frame_for[i];
frame_for[i] = tmp;
}
#ifdef MIPS_ASM_64
CPU_64_on();
#endif
// add edge to decoded frame
make_edge (frame_for[0], mp4_hdr.coded_picture_width, mp4_hdr.coded_picture_height, 32);
make_edge (frame_for[1], mp4_hdr.coded_picture_width>>1, mp4_hdr.coded_picture_height>>1, 16);
make_edge (frame_for[2], mp4_hdr.coded_picture_width>>1, mp4_hdr.coded_picture_height>>1, 16);
// macroblock reconstruction
do {
PVOP_macroblock();
mp4_hdr.mba++;
} while ((nextbits_bytealigned(23)) && (mp4_hdr.mba < mp4_hdr.mba_size));
#ifdef MIPS_ASM_64
CPU_64_off();
#endif
mp4_hdr.last_prediction_type=mp4_hdr.prediction_type;
PictureDisplay(Frame_Buffer);
}
static void make_edge (unsigned char *frame_pic,
int edged_width, int edged_height, int edge)
{
int j;
int width = edged_width - (edge<<1);
int height = edged_height - (edge<<1);
unsigned char *p_border;
// left and right edges
p_border = frame_pic;
for (j = height;j!=0 ;j--)
{
#ifdef MIPS_ASM_64
MIPS_MEM_SET((p_border - edge), *(p_border), edge);
MIPS_MEM_SET((p_border + width),*(p_border + (width-1)), edge);
#else
memset((p_border - edge), *(p_border), edge);
memset((p_border + width),*(p_border + (width-1)), edge);
#endif
p_border += edged_width;
}
// top edge
p_border = frame_pic-edge;
for (j = edge;j>0; j--)
{
#ifdef MIPS_ASM_64
MIPS_edge_copy(p_border-edged_width, p_border, edged_width);
#else
memcpy(p_border-edged_width, p_border, edged_width);
#endif
p_border-=edged_width;
}
// bottom edge
p_border = frame_pic-edge+(edged_width*(height-1));
for (j = edge;j>0; j--)
{
#ifdef MIPS_ASM_64
MIPS_edge_copy(p_border+edged_width, p_border, edged_width);
#else
memcpy(p_border+edged_width, p_border, edged_width);
#endif
p_border+=edged_width;
}
}
/**/
// Purpose: manages a one frame buffer for re-ordering frames prior to
// displaying or writing to a file
static void PictureDisplay(unsigned char *bmp)
{
AVPicture * p=(AVPicture *) bmp;
p->data[0]=frame_ref[0];
p->data[1]=frame_ref[1];
p->data[2]=frame_ref[2];
p->linesize[0]=mp4_hdr.coded_picture_width;
p->linesize[1]=mp4_hdr.coded_picture_width>>1;
p->linesize[2]=mp4_hdr.coded_picture_width>>1;
#ifdef ARM
p->last_picture[0]=frame_for[0];
p->last_picture[1]=frame_for[1];
p->last_picture[2]=frame_for[2];
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -