在做视频浓缩(视频摘要)项目时,我们希望按浓缩视频的文件名进行查找,进行重复播放该视频。然而, 由于前期生成的浓缩视频是以时间(年-月-日 小时分秒)命名的,对用户通常来说难以记忆,用户极有可能更改为方便自己记忆的文件名。这样,如果我们还是按照之前的时间去读取视频文件,由于文件名已经被修改,将无法读取文件。经讨论,我们考虑将时间直接写在AVI文件内部,但必须保证不破坏原有AVI文件的格式而导致文件无法播放。显然,假设AVI文件预留了一段自定义数据段给用户使用,那么,上述方法是可行的。为此,我们单独对AVI文件的格式做了解析,通过查阅文献与代码解析,事实表明,在AVI的头部,存在以“JUNK”开头的数据段为预留数据,用户可以写数据至该段。不过,由于AVI视频的压缩标准比较混乱,测试时发现并不是每一个AVI视频的都有该段预留数据。庆幸的是,我们生成的摘要视频含有JUNK开头的数据区域,笑。
解析的AVI视频都是不包含的声音的,如包含声音,解析的结果会有所不同,但大体相似。以下是我们对AVI文件格式解析的结果:
RIFF ——4字符
文件大小 ——int
文件类型 ——4字符,如AVI 或WAVE
//avi头部信息
LIST ——4字符
list的大小 ——int
hdrl ——4字符
avih ——4字符
AVI头部大小 ——int
MainAVIHeader头部结构 ——56字节
//avi流头部信息
LIST ——4字符
LIST的大小 ——int
strl ——4字符
strh ——4字符
AVI流头部大小 ——int
AVIStreamHeader流头部结构 ——56字节
//流格式块
strf ——4字符
块大小 ——int
是BITMAPINFO结构
//JUNK列表
JUNK ——4字符
预留数据 ——不同的avi长度不统一
//图像数据
LIST ——4字符
list的大小 ——int
movi(表示视频块的开始) ——4字符
视频帧1:00db + 帧数据大小 + 帧数据
视频帧2:00db + 帧数据大小 + 帧数据
视频帧3:00db + 帧数据大小 + 帧数据
视频帧4:00db + 帧数据大小 + 帧数据
视频帧N
附带结构体代码:
typedef struct _MainAVIHeader
{
DWORD dwMicroSecPerFrame;
DWORD dwMaxBytesPerSec;
DWORD dwPaddingGranularity;
DWORD dwFlages;
DWORD dwTotalFrame;
DWORD dwInitialFrame;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwwidth;
DWORD dwHeight;
DWORD dwReserved[4];
}MainAVIHeader;
typedef struct _AVIStreamHeader
{
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags;
WORD wPriofitv;
WORD wLanguage;
DWORD dwInitalFrames;
DWORD dwScale;
DWORD dwRate;
DWORD dwStart;
DWORD dwLength;
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT FcFrame;
}AVIStreamHeader;
typedef struct _BMPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrlmportant;
}BMPINFOHEADER;
typedef struct _BMPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
}BMPINFO;

8948

被折叠的 条评论
为什么被折叠?



