JAVA选修课期末报告.docx
- 文档编号:9148531
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:14
- 大小:187.65KB
JAVA选修课期末报告.docx
《JAVA选修课期末报告.docx》由会员分享,可在线阅读,更多相关《JAVA选修课期末报告.docx(14页珍藏版)》请在冰豆网上搜索。
JAVA选修课期末报告
HarbinInstituteofTechnology
选修课课程设计报告
课程名称:
Java网络编程
课程类型:
全校选修
实验项目名称:
Java软件系统
实验题目:
基于Java的MPEG-1播放器
班号:
学号:
姓名:
报告日期:
一、题目分析
本题目要求采用Java语言编写一个MPEG-1解码器,并将其嵌入到Web中展示出来。
将MPEG-1解码器按照功能分为三个层次:
a)码流层b)图像层c)宏块层。
根据这三个层次分别编写功能模块,完成视频的解码过程。
二、总体设计
图1MPEG-1解码器的工作流程图
如上所示,解码器的主题在于对MPEG-1比特流的解析。
此过程经过一系列反变换将其还原为视频流输出。
MPEG-1比特流的结构由ISO的MPEG标准文档给出。
如题目分析中所述,解码器的主体部分分为三个层次,每个层次对应几个功能模块。
下面对每个模块进行功能介绍。
图2解码器的层次及其功能模块
Ø码流层:
采用BitInputStream进行MPEG-1码流的读取和输出,
采用VLCInputStream进行Huffman变长编码的读取和解析,
MPEGVideoStream用以输出解码后的视频流
Ø图像层:
采用Picture进行MPEG-1码流的解码
采用MotionVector读取和运算宏块层的运动矢量
IDCT作反离散余弦变换
Ø宏块层
采用Macroblock对宏块层基本单位进行读取运算和输出(至图像层)
三、算法设计
Huffman变长编码
Ø原理
Huffman编码是一种可变长编码方式,是由美国数学家DavidHuffman创立的,是二叉树的一种特殊转化形式。
编码的原理是:
将使用次数多的代码转换成长度较短的代码,而使用次数少的可以使用较长的编码,并且保持编码的唯一可解性。
Huffman算法的最根本的原则是:
累计的(字符的统计数字*字符的编码长度)为最小,也就是权值(字符的统计数字*字符的编码长度)的和最小。
ØHuffman树
Huffman树是二叉树的一种特殊转化形式。
以下是构件Huffman树的例子:
比如有以下数据,ABFACGCAHGBBAACECDFGFAAEABBB
先进行统计A(8)B(6)C(4)D
(1)E
(2)F(3)G(3)H
(1) 括号里面的是统计次数
生成Huffman树:
每次取最小的那两个节点(node)合并成一个节点(node),并且将累计数值相加作为新的接点的累计数值,最顶层的是根节点(root) 注:
列表中最小节点的是指包括合并了的节点在内的所有节点,已经合并的节点不在列表中
运算的过程如下:
1:
D+H
(2)
2:
DE+H(4)
3:
F+G(6)
4:
C+DEH(8)
5:
B+FG(12)
6:
A+CDEH(16)
7:
ACDEH+BFG(28)
那么转化为Huffman树就是
Huffman树 层数
Root
┌┴┐
ACDEH BFG 1
┌┴┐┌┴┐
CDEHAB FG 2
┌┴┐ ┌┴┐
DEH C F G 3
┌┴┐
DH E 4
┌┴┐
D H 5
取左面是1右面是0则有。
注:
层数就是位数或者说是代码长度,权值=代码长度*该字的统计次数。
代码 位数 权值
A=10 2 16
B=01 2 12
C=110 3 12
D=11111 5 5
E=1110 4 8
F=001 3 9
G=000 2 6
H=11110 5 5
可以看出Huffman代码是唯一可解的(uniquelydecodable),如果你读到110就一定是C,不会有任何一个编码是以110开始的。
Ø编码和解码
编码:
将ABCDEFGH用Huffman树产生的编码对应着写到文件中,并且保留原始的Huffman树,主要是编码段的信息。
一般要编码256个元素的话需要511个单位来储存Huffman树,每个Huffman树都必须有以下的结构:
code,char,left,right,probability(出现次数),通常情况是利用一个数组结构。
因为在解码的时候只需要用到code,所以只需要记录每个元素的编码就可以了。
解码:
利用文件中保存的Huffman编码,一一对应,解读编码,把可变长编码转换为定长编码。
IDCT变换
图3IDCT蝶形算法
之后根据亮度的量化参数QP进行反量化和IDCT中的比例变换。
(1)
这里
是指比例变换系数在(0,0)处的值。
运动估计搜索算法
用来在参考帧(已解码的帧)中寻找匹配(SAD最小)的块作为参考块,差值作为运动矢量。
在传输过程中,需传递所选取块的参考帧号,参考块的位置,以及运动矢量。
相对应的参考块已经解码所以无需传输。
作用原理:
这里采用六边形搜索算法。
Step1:
搜索起始点预测
Step2:
不对称十字搜索
Step3:
非平衡多六边形搜索
a)
正方形搜索
b)多六边形搜索
Step4:
扩展六边形搜索
a)小六边形搜索
b)小菱形搜索
运动补偿
图4运动补偿部分算法流程图
四、测试结果
在MPEGPlayer.html文档中写以下源代码得到在Web下的MPEG-1视频流random.mpg的循环播放。
五、附录:
源代码(带注释)
这里仅以BitInputStream为例,其他请参见MPEGPlayer.java源代码
importjava.io.*;
import.*;
importjava.awt.*;
importjava.awt.image.*;
importjava.applet.*;
/**
*Thisclassrepresentsabufferedinputstreamwhichcanread
*variablelengthcodesfromMPEG-1videostreams.
*/
classBitInputStream{
/**
*MPEGvideolayersstartcodes
*/
publicfinalstaticintSYNC_START_CODE=0x000001;
publicfinalstaticintPIC_START_CODE=0x00000100;
publicfinalstaticintSLICE_MIN_CODE=0x00000101;
publicfinalstaticintSLICE_MAX_CODE=0x000001af;
publicfinalstaticintUSER_START_CODE=0x000001b2;
publicfinalstaticintSEQ_START_CODE=0x000001b3;
publicfinalstaticintEXT_START_CODE=0x000001b5;
publicfinalstaticintSEQ_END_CODE=0x000001b7;
publicfinalstaticintGOP_START_CODE=0x000001b8;
/**
*Theunderlyinginputstream
*/
privateInputStreamstream;
/**
*Thebitbuffervariables
*/
privateintbitbuffer,bitcount;
/**
*The32bitbuffervariables
*/
privateintbuffer[],count,position;
/**
*Initializesthebitinputstreamobject
*/
publicBitInputStream(InputStreaminputStream){
stream=inputStream;
buffer=newint[1024];
bitbuffer=bitcount=0;
count=position=0;
}
/**
*ReadsthenextMPEG-1layerstartcode
*/
publicintgetCode()throwsIOException{
alignBits(8);
while(showBits(24)!
=SYNC_START_CODE)
flushBits(8);
returngetBits(32);
}
/**
*ShowsthenextMPEG-1layerstartcode
*/
publicintshowCode()throwsIOException{
alignBits(8);
while(showBits(24)!
=SYNC_START_CODE)
flushBits(8);
returnshowBits(32);
}
/**
*Readsthenextvariablelengthcode
*/
publicintgetBits(intnbits)throwsIOException{
intbits;
if(nbits<=bitcount){
bits=bitbuffer>>>(32-nbits);
bitbuffer<<=nbits;
bitcount-=nbits;
}
else{
bits=bitbuffer>>>(32-nbits);
nbits-=bitcount;
bitbuffer=get32Bits();
bits|=bitbuffer>>>(32-nbits);
bitbuffer<<=nbits;
bitcount=32-nbits;
}
if(nbits>=32)
bitbuffer=0;
returnbits;
}
/**
*Showsthenextvariablelengthcode
*/
publicintshowBits(intnbits)throwsIOException{
intbits=bitbuffer>>>(32-nbits);
if(nbits>bitcount){
bits|=show32Bits()>>>(32+bitcount-nbits);
}
returnbits;
}
/**
*Flushesthecurrentvariablelengthcode
*/
publicvoidflushBits(intnbits)throwsIOException{
if(nbits<=bitcount){
bitbuffer<<=nbits;
bitcount-=nbits;
}
else{
nbits-=bitcount;
bitbuffer=get32Bits()< bitcount=32-nbits; } } /** *Alignstheinputstreampointertoagivenboundary */ publicvoidalignBits(intnbits)throwsIOException{ flushBits(bitcount%nbits); } /** *Readsthenext32-bitcodefromthebufferedstream */ privateintget32Bits()throwsIOException{ if(position>=count){ position=0; for(count=0;count buffer[count]=read32Bits(); } returnbuffer[position++]; } /** *Showsthenext32-bitcodefromthebufferedstream */ privateintshow32Bits()throwsIOException{ if(position>=count){ position=0; for(count=0;count buffer[count]=read32Bits(); } returnbuffer[position]; } /** *Reads32-bitbigendiancodesfromthestream */ privateintread32Bits()throwsIOException{ if(stream.available()<=0) returnSEQ_END_CODE; inta0=stream.read()&0xff; inta1=stream.read()&0xff; inta2=stream.read()&0xff; inta3=stream.read()&0xff; return(a0<<24)+(a1<<16)+(a2<<8)+(a3<<0); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAVA 选修课 期末 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)