罗斯福年轻时照片:AVI破解及Android2.3实现
来源:百度文库 编辑:偶看新闻 时间:2024/04/28 01:57:10
1、AVI介绍
AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange FileFormat的缩写)文件格式,多用于音视频捕捉、编辑、回放等应用程序中。通常情况下,一个AVI文件可以包含多个不同类型的媒体流,是Windows操作系统上最基本的、也是最常用的一种媒体文件格式。
AVI的文件结构分为头部、主体和索引三部分。主体中图像数据和声音数据是交互存放的。从尾部的索引可以索引跳到自己想放的位置。AVI本身只是提供了这么一个框架,索引放在了文件尾部,内部的图像数据和声音顺据格式可以是任意的编码形式。
但AVI对高码率VBR(VariableBitRate,就是动态比特率,可以根据当前的需要定义不同的比特率,避免了浪费,并且提高了利用率)音频文件支持不好。因为容器里的图像和声音是分开的,所以播放时需要一个图像和声音的同步过程;VBR音轨是不断的在变换,而AVI没有时间戳去让VBR音轨和图像同步,这样就会产生图像声音不同步的问题。
兼容的视频编码:MPEG-2、MPEG-4、MPEG-4 H.264、VC-1(支持不太好)、VC-1;兼容的音频编码:LinearPCM、DTS-HD DTS、Dolby Digital、AC3、Dolby Digital Plus、Dolby TrueHD、DTSDigital Surround。
2、AVI文件组织方式
RIFF格式是一种树状的结构,其基本组成单元为LIST和CHUNK,分别如树的节点和叶子。在RIFF文件中,数据保存的基本单元是CHUNK,可用于保存音视频数据或者一些参数信息,LIST相当于文件系统的目录,可以包含多个CHUNK或者多个LIST。
AVI文件的两种原子类型:
(1)LIST
typedef struct{
DWORD dwList;
DWORD dwSize;
DWORD dwFourCC;
BYTE data[dwSize -4]; //contain lists and chunks
}LIST;
(2)CHUNK
typedef struct{
DWORD dwFourCC;
DWORD dwSize;
BYTE data[dwSize ]; //contain headers or video/audio data
}CHUNK;
用LIST类型的只有‘RIFF’或’LIST’,类似树枝,而CHUNK类似叶子。下图中ID为RIFF、hdrl、strl、odml、INFO、movi均为LIST类型,hdrl LST块定义AVI文件的数据格式,movi LIST包含音视频序列数据,idx1 CHUNK存放索引数据,该块可选。
HDRL LIST信息块
dwList为’LIST’,dwFourCC为’hdrl’,data部分包含了avih CHUNK和其他strl LIST,需要递归解析。Size部分是指从dwFourCC开始的字段大小。
AVIH CHUNK中data字段结构如下:
STRL LIST
这个LIST部分包括以下几个CHUNK:STRH、STRF、STRD、STRN、JUNK。iStreamListSize保存STRL LIST的data部分长度。
STRH CHUNK中data字段结构如下:
注意:
wPriority和wLanguage并不是四字节存储,解析时注意偏移位置,dWFlags有两种取值:AVISF_VIDEO_PALCHANGES、AVISF_DISABLED
rcFrame包括上left、top、right、bottom四个值,分别用short int(占两个字节)保存
帧率的计算:SamplingRate(samples/second)= dwRate/dwScale
STRF CHUNK
Strf结构与strh的fccType定义的类型有关。AVIStream::fccType的可能取值有:PV_2_AUDIO、PV_2_VIDEO、MIDI和TEXT。
(1)AVIStream::fccType为视频PV_2_VIDEO时,STRF CHUNK的结构为BITMAPINFO:
typedef struct
{
BitmapInfoHhr BmiHeader; //header
uint32 BmiColorsCount; //number of RGBQuads actually present
RGBQuad BmiColors[MAX_COLOR_TABLE_SIZE];
} BitMapInfoStruct;
RGBQuad结构如下:
typedef struct
{
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 Reserved;
} RGBQuad;
BitmapInfoHhr结构如下:
biClrUsed标识了BmiColorsCount,当这个字段值为0时,需要由biBiBitCount字段(每帧的比特数)决定color table的大小(BmiColorsCount):
biBiBitCount =1时,color table size = 2^1
biBiBitCount = 2时,color table size = 2^2
biBiBitCount = 4时,color table size = 2^4
biBiBitCount = 8时,color table size = 2^8
biBiBitCount = 16/32时,color table size由biCompression的值决定:
BiCompression= BI_BITFIELDS,color table size = 3
BiCompression= BI_ALPHABITFIELDS,color table size = 4
BiCompression= BI_RGB,color table size = 0
biBiBitCount = 24时,color table size = 0
BmiColors数组用来存放color table entry,详见ParseStreamFormat函数中的解析过程
(2) AVIStream::fccType为音频PV_2_AUDIO时,STRF CHUNK结构为WAVEFORMAT:
计算时间戳
音频根据帧率计算:
该帧大小arSize/每帧所占的字节数=samplecount
iTimeStampAudio = iTimeStampAudio+(sampleCount * 1000) / samplingRate
视频根据帧间隔计算:
frameDurationInms =(iMainHeader.iMicroSecPerFrame) / 1000
arTimeStamp = (iStreamSampleCount[aStreamNo] * (frameDurationInms))
查找sample:
确定时间,相对于媒体时间坐标系统
查找对应该时间戳的sample序号(需要在解析的时候保存到iIndexTable表,如果不存在该索引表,需要在解析movi chunk时记录下来)
根据sample号查找该sample在文件中位移和大小(索引表iIndexTable或movi chunk)
用Idx1中的标志位查找关键帧
3、代码清单
3.1》新增文件:
mydroid下framework/base/media/libstagefright路径
AVIExtractor.cpp、ChunkTable.cpp
mydroid下framework/base/media/libstagefright/include路径
AVIExtractor.h、AVIType.h、ChunkTable.h
3.2》部分修改:
mydroid下framework/base/media/libstagefright/
MediaExtractor.cpp、DataSource.cpp、MediaDefs.cpp
mydroid下framework/base/include/media/stagefright/
MediaExtractor.h
frameworks/base/media/libstagefright/codecs/m4v_h263/dec
M4vH263Decoder.cpp -----esds信息
frameworks/base/media/libstagefright/codecs/aacdec
AACDecoder.cpp -----esds信息
3.3》播放应用程序:
packages/apps/MediaPlayer 文件夹 ,由于Gallery不能识别avi文件,MediaPlayer.Apk(编译后生成)应用程序可选择要播放的文件。
3.4》AVIExtractor
AVIExtractor 负责AVI容器的解析,保存stream流到track链中。每个stream流(track)包含多个sample(帧),解码单位为sample,sample可能是以chunk或rec方式组织。
class AVIExtractor : public MediaExtractor {
public:
// Extractor assumes ownership of "source".
AVIExtractor(const sp &source);
virtual size_t countTracks(); /*Track <-> Stream*/
virtual sp getTrack(size_t index);
virtual sp getTrackMetaData(size_t index, uint32_t flags);
virtual sp getMetaData();
protected:
virtual ~AVIExtractor();
private:
struct Stream{
Stream *next;
sp meta;
uint32_t StreamNo; //stream序号
uint32_t NumOfSamples; //sample数
uint32_t NumOfIdxEntry; //stream中的idx单元数,= sample数
StreamHeader mStreamHeader;
StreamFormat mStreamFormat;
sp chunkTable;
};
sp mDataSource;
bool mHaveMetadata;
bool mHasVideo;
Stream *mFirstStream, *mLastStream;
sp mFileMetaData;
Vector mPath;
AVIFileMainHeader *mFileHeader;
uint32_t mStreamCount; /*stream numbers, stream == track*/
uint32_t mfileLength; /*file length*/
uint32_t mMoviChunkPos; /* some stuff for saving ... */
uint32_t mIdxChunkPos;
uint32_t mNextFramePos;
uint32_t mInitialFrames;
status_t readMetaData();
status_t parseChunk(off_t *offset, int depth);
status_t parseMetaData(off_t offset, size_t size);
AVIExtractor(const AVIExtractor &);
AVIExtractor &operator=(const AVIExtractor &);
};
函数说明:
countTracks():计算轨道数,即stream number,avih中的dwStreams
getTrack(size_t index):获取轨道,即取得相应的stream信息
getTrackMetaData:获取轨道元数据,即取得stream中的MetaData
getMetaData:获取文件信息,包括文件创建时间等信息
readMetaData():内部函数,读取文件元数据,调用具体的解析函数
parseChunk:内部函数,具体的解析函数
parseMetaData:内部函数,解析文件信息,保存在mFileMetaData,解析INFO LIST部分
Extractor->fileMetaData:封装文件信息(如文件类型、文件创建时间、tracknumber、作曲家、版权等信息,信息从INFO LISt获取)
mFileMetaData->setCString(kKeyMIMEType, "video/mp4")
mFileMetaData->setCString(kKeyDate, s.string())
mFileMetaData->setCString(kKeyCDTrackNumber, tmp)
mFileMetaData->setCString(kKeyDiscNumber, tmp)
mFileMetaData->setData()
3.5》AVISource
AVISource 保存avi文件中解析出的audio和 video frame(帧信息)
class AVISource : public MediaSource{
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
AVISource(const sp &format,
const sp &dataSource,
const sp &chunkTable,
uint32_t flags);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp getFormat();
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
//read是重要接口,返回给解码器解析的每一帧数据,以00dc或rec组织的数据块
protected:
virtual ~AVISource();
private:
Mutex mLock;
sp mFormat;
sp mDataSource;
//int32_t mTimescale;
sp mChunkTable;
uint32_t mCurrentSampleIndex;
uint32_t mFlags; //avih->flags
bool mStarted;
MediaBufferGroup *mGroup;
MediaBuffer *mBuffer;
uint8_t *mSrcBuffer;
AVISource(const AVISource &);
AVISource &operator=(const AVISource &);
};
3.6》Stream
Stream封装每个数据流的信息
Stream->meta封装音视流(轨道)的基本信息
包括音视频编码类型(如mp4a、mp3、avc等类型)、该track的时间长度、声道数、帧率、视频帧的宽和高、最大sample长度等。
mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
mLastTrack->meta->setInt64(kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
mLastTrack->meta->setInt32(kKeyWidth, width);
mLastTrack->meta->setInt32(kKeyHeight, height);
mLastTrack->meta->setInt32(kKeyMaxInputSize, XXX);
mLastTrack->meta->setData(kKeyAVCC,XXX);
Stream->chunkTable封装帧信息
Track对应一维链表IdxChunkTbl,保存当前流中每个数据块的信息,通过该信息可以查找具体的每一sample信息(在文件中的位移、大小、时间戳等)。与MP4不同的是,AVI在文件解析的时候创建一维链表,查找的时候计算相对简单。SampleIterator是通过IdxChunkTbl链查找当前播放的sample信息并保存,便于扩展,考虑多个sample以rec方式组织,此处的chunk实际为rec,其中包含多个数据块。
IdxChunkTbl数据结构:
struct IdxChunkTbl{
IdxChunkTbl *next;
uint32_t chunkId;
uint32_t flags;
uint32_t sampleIndex;
uint32_t offset;
uint32_t datasize;
uint32_t iTimeStamp;
bool isKeyFrame;
bool ifRecList;
bool ifNoTime;
};
IdxChunkTbl的建立过程:
如果idx1 chunk存在,那么每一帧的位移、大小等信息从idx1的子chunk获取,时间戳信息需要通过解析movi list建立;
如果idx1 chunk不存在,直接解析movi list创建IdxChunkTbl表。
AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange FileFormat的缩写)文件格式,多用于音视频捕捉、编辑、回放等应用程序中。通常情况下,一个AVI文件可以包含多个不同类型的媒体流,是Windows操作系统上最基本的、也是最常用的一种媒体文件格式。
AVI的文件结构分为头部、主体和索引三部分。主体中图像数据和声音数据是交互存放的。从尾部的索引可以索引跳到自己想放的位置。AVI本身只是提供了这么一个框架,索引放在了文件尾部,内部的图像数据和声音顺据格式可以是任意的编码形式。
但AVI对高码率VBR(VariableBitRate,就是动态比特率,可以根据当前的需要定义不同的比特率,避免了浪费,并且提高了利用率)音频文件支持不好。因为容器里的图像和声音是分开的,所以播放时需要一个图像和声音的同步过程;VBR音轨是不断的在变换,而AVI没有时间戳去让VBR音轨和图像同步,这样就会产生图像声音不同步的问题。
兼容的视频编码:MPEG-2、MPEG-4、MPEG-4 H.264、VC-1(支持不太好)、VC-1;兼容的音频编码:LinearPCM、DTS-HD DTS、Dolby Digital、AC3、Dolby Digital Plus、Dolby TrueHD、DTSDigital Surround。
2、AVI文件组织方式
RIFF格式是一种树状的结构,其基本组成单元为LIST和CHUNK,分别如树的节点和叶子。在RIFF文件中,数据保存的基本单元是CHUNK,可用于保存音视频数据或者一些参数信息,LIST相当于文件系统的目录,可以包含多个CHUNK或者多个LIST。
AVI文件的两种原子类型:
(1)LIST
typedef struct{
DWORD dwList;
DWORD dwSize;
DWORD dwFourCC;
BYTE data[dwSize -4]; //contain lists and chunks
}LIST;
(2)CHUNK
typedef struct{
DWORD dwFourCC;
DWORD dwSize;
BYTE data[dwSize ]; //contain headers or video/audio data
}CHUNK;
用LIST类型的只有‘RIFF’或’LIST’,类似树枝,而CHUNK类似叶子。下图中ID为RIFF、hdrl、strl、odml、INFO、movi均为LIST类型,hdrl LST块定义AVI文件的数据格式,movi LIST包含音视频序列数据,idx1 CHUNK存放索引数据,该块可选。
HDRL LIST信息块
dwList为’LIST’,dwFourCC为’hdrl’,data部分包含了avih CHUNK和其他strl LIST,需要递归解析。Size部分是指从dwFourCC开始的字段大小。
AVIH CHUNK中data字段结构如下:
STRL LIST
这个LIST部分包括以下几个CHUNK:STRH、STRF、STRD、STRN、JUNK。iStreamListSize保存STRL LIST的data部分长度。
STRH CHUNK中data字段结构如下:
注意:
wPriority和wLanguage并不是四字节存储,解析时注意偏移位置,dWFlags有两种取值:AVISF_VIDEO_PALCHANGES、AVISF_DISABLED
rcFrame包括上left、top、right、bottom四个值,分别用short int(占两个字节)保存
帧率的计算:SamplingRate(samples/second)= dwRate/dwScale
STRF CHUNK
Strf结构与strh的fccType定义的类型有关。AVIStream::fccType的可能取值有:PV_2_AUDIO、PV_2_VIDEO、MIDI和TEXT。
(1)AVIStream::fccType为视频PV_2_VIDEO时,STRF CHUNK的结构为BITMAPINFO:
typedef struct
{
BitmapInfoHhr BmiHeader; //header
uint32 BmiColorsCount; //number of RGBQuads actually present
RGBQuad BmiColors[MAX_COLOR_TABLE_SIZE];
} BitMapInfoStruct;
RGBQuad结构如下:
typedef struct
{
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 Reserved;
} RGBQuad;
BitmapInfoHhr结构如下:
biClrUsed标识了BmiColorsCount,当这个字段值为0时,需要由biBiBitCount字段(每帧的比特数)决定color table的大小(BmiColorsCount):
biBiBitCount =1时,color table size = 2^1
biBiBitCount = 2时,color table size = 2^2
biBiBitCount = 4时,color table size = 2^4
biBiBitCount = 8时,color table size = 2^8
biBiBitCount = 16/32时,color table size由biCompression的值决定:
BiCompression= BI_BITFIELDS,color table size = 3
BiCompression= BI_ALPHABITFIELDS,color table size = 4
BiCompression= BI_RGB,color table size = 0
biBiBitCount = 24时,color table size = 0
BmiColors数组用来存放color table entry,详见ParseStreamFormat函数中的解析过程
(2) AVIStream::fccType为音频PV_2_AUDIO时,STRF CHUNK结构为WAVEFORMAT:
计算时间戳
音频根据帧率计算:
该帧大小arSize/每帧所占的字节数=samplecount
iTimeStampAudio = iTimeStampAudio+(sampleCount * 1000) / samplingRate
视频根据帧间隔计算:
frameDurationInms =(iMainHeader.iMicroSecPerFrame) / 1000
arTimeStamp = (iStreamSampleCount[aStreamNo] * (frameDurationInms))
查找sample:
确定时间,相对于媒体时间坐标系统
查找对应该时间戳的sample序号(需要在解析的时候保存到iIndexTable表,如果不存在该索引表,需要在解析movi chunk时记录下来)
根据sample号查找该sample在文件中位移和大小(索引表iIndexTable或movi chunk)
用Idx1中的标志位查找关键帧
3、代码清单
3.1》新增文件:
mydroid下framework/base/media/libstagefright路径
AVIExtractor.cpp、ChunkTable.cpp
mydroid下framework/base/media/libstagefright/include路径
AVIExtractor.h、AVIType.h、ChunkTable.h
3.2》部分修改:
mydroid下framework/base/media/libstagefright/
MediaExtractor.cpp、DataSource.cpp、MediaDefs.cpp
mydroid下framework/base/include/media/stagefright/
MediaExtractor.h
frameworks/base/media/libstagefright/codecs/m4v_h263/dec
M4vH263Decoder.cpp -----esds信息
frameworks/base/media/libstagefright/codecs/aacdec
AACDecoder.cpp -----esds信息
3.3》播放应用程序:
packages/apps/MediaPlayer 文件夹 ,由于Gallery不能识别avi文件,MediaPlayer.Apk(编译后生成)应用程序可选择要播放的文件。
3.4》AVIExtractor
AVIExtractor 负责AVI容器的解析,保存stream流到track链中。每个stream流(track)包含多个sample(帧),解码单位为sample,sample可能是以chunk或rec方式组织。
class AVIExtractor : public MediaExtractor {
public:
// Extractor assumes ownership of "source".
AVIExtractor(const sp
virtual size_t countTracks(); /*Track <-> Stream*/
virtual sp
virtual sp
virtual sp
protected:
virtual ~AVIExtractor();
private:
struct Stream{
Stream *next;
sp
uint32_t StreamNo; //stream序号
uint32_t NumOfSamples; //sample数
uint32_t NumOfIdxEntry; //stream中的idx单元数,= sample数
StreamHeader mStreamHeader;
StreamFormat mStreamFormat;
sp
};
sp
bool mHaveMetadata;
bool mHasVideo;
Stream *mFirstStream, *mLastStream;
sp
Vector
AVIFileMainHeader *mFileHeader;
uint32_t mStreamCount; /*stream numbers, stream == track*/
uint32_t mfileLength; /*file length*/
uint32_t mMoviChunkPos; /* some stuff for saving ... */
uint32_t mIdxChunkPos;
uint32_t mNextFramePos;
uint32_t mInitialFrames;
status_t readMetaData();
status_t parseChunk(off_t *offset, int depth);
status_t parseMetaData(off_t offset, size_t size);
AVIExtractor(const AVIExtractor &);
AVIExtractor &operator=(const AVIExtractor &);
};
函数说明:
countTracks():计算轨道数,即stream number,avih中的dwStreams
getTrack(size_t index):获取轨道,即取得相应的stream信息
getTrackMetaData:获取轨道元数据,即取得stream中的MetaData
getMetaData:获取文件信息,包括文件创建时间等信息
readMetaData():内部函数,读取文件元数据,调用具体的解析函数
parseChunk:内部函数,具体的解析函数
parseMetaData:内部函数,解析文件信息,保存在mFileMetaData,解析INFO LIST部分
Extractor->fileMetaData:封装文件信息(如文件类型、文件创建时间、tracknumber、作曲家、版权等信息,信息从INFO LISt获取)
mFileMetaData->setCString(kKeyMIMEType, "video/mp4")
mFileMetaData->setCString(kKeyDate, s.string())
mFileMetaData->setCString(kKeyCDTrackNumber, tmp)
mFileMetaData->setCString(kKeyDiscNumber, tmp)
mFileMetaData->setData()
3.5》AVISource
AVISource 保存avi文件中解析出的audio和 video frame(帧信息)
class AVISource : public MediaSource{
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
AVISource(const sp
const sp
const sp
uint32_t flags);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
//read是重要接口,返回给解码器解析的每一帧数据,以00dc或rec组织的数据块
protected:
virtual ~AVISource();
private:
Mutex mLock;
sp
sp
//int32_t mTimescale;
sp
uint32_t mCurrentSampleIndex;
uint32_t mFlags; //avih->flags
bool mStarted;
MediaBufferGroup *mGroup;
MediaBuffer *mBuffer;
uint8_t *mSrcBuffer;
AVISource(const AVISource &);
AVISource &operator=(const AVISource &);
};
3.6》Stream
Stream封装每个数据流的信息
Stream->meta封装音视流(轨道)的基本信息
包括音视频编码类型(如mp4a、mp3、avc等类型)、该track的时间长度、声道数、帧率、视频帧的宽和高、最大sample长度等。
mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
mLastTrack->meta->setInt64(kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
mLastTrack->meta->setInt32(kKeyWidth, width);
mLastTrack->meta->setInt32(kKeyHeight, height);
mLastTrack->meta->setInt32(kKeyMaxInputSize, XXX);
mLastTrack->meta->setData(kKeyAVCC,XXX);
Stream->chunkTable封装帧信息
Track对应一维链表IdxChunkTbl,保存当前流中每个数据块的信息,通过该信息可以查找具体的每一sample信息(在文件中的位移、大小、时间戳等)。与MP4不同的是,AVI在文件解析的时候创建一维链表,查找的时候计算相对简单。SampleIterator是通过IdxChunkTbl链查找当前播放的sample信息并保存,便于扩展,考虑多个sample以rec方式组织,此处的chunk实际为rec,其中包含多个数据块。
IdxChunkTbl数据结构:
struct IdxChunkTbl{
IdxChunkTbl *next;
uint32_t chunkId;
uint32_t flags;
uint32_t sampleIndex;
uint32_t offset;
uint32_t datasize;
uint32_t iTimeStamp;
bool isKeyFrame;
bool ifRecList;
bool ifNoTime;
};
IdxChunkTbl的建立过程:
如果idx1 chunk存在,那么每一帧的位移、大小等信息从idx1的子chunk获取,时间戳信息需要通过解析movi list建立;
如果idx1 chunk不存在,直接解析movi list创建IdxChunkTbl表。
AVI体积及压缩问题
怎样实现AVI 3GP RM 视频之间的转换??需要什么软件啊?
怎样实现AVI 3GP RM 视频之间的转换??需要什么软件啊?
编程实现AVI转BMP的问题!
如何破解实名上网实现免费上网?
请问如何用MATLAB实现序列图片转换成AVI
求AVI分割软件下载,要破解注册的,谢谢。
谁有AVI MPEG ASF WMV Splitter的破解版?
ecu自学习功能原理及实现方法
自适应系统辨别算法及实现
共享上网类型及实现原理是什么?
什么是颤音?及实现的方法
VOIP的原理及实现在必要条件
如何实现自动变量排版及印刷
电话线如何实现打电话及上网
有关梦想及实现梦想的古诗
搜索引擎是怎么实现原理及方法
VPDN的实现方法,具体步骤及费用?
谁有<星月手机销售及维修入网管理系统V5.3>破解版
ACDsee7.0破解方法及注册码
求天网防火墙最新版及破解!
门禁系统的原理及应用、破解
破解程序及注册机使用方法是怎么回事
有会破解万象网管实现免费上网的吗?