在流中定位
AVIFile 提供了多种查找和移动到数据流中某个位置的方法。 通过本部分中的函数和宏,应用程序可以在流中的示例) 中找到包含完整图像 (起始位置、长度和关键帧。 函数和宏还通过计算从流开始到流中任意点播放流所需的时间,将时间与流中的位置相关联。
查找起始位置
可以使用 AVIStreamStart 函数检索视频流中第一帧的示例编号。 (电影的帧可能从示例 0 或 1 开始,具体取决于 author.) 也可以使用 AVIStreamInfo 函数获取此信息。 此函数将示例编号存储在 AVISTREAMINFO 结构的 dwStart 成员中。 可以使用 AVIStreamStartTime 宏检索流第一个示例的开始时间。
可以使用 AVIStreamLength 函数检索流长度。 此函数返回流中的样本数。 还可以使用 AVIStreamInfo 函数获取此信息。 此函数将流长度存储在 AVISTREAMINFO 结构的 dwLength 成员中。 若要检索流的长度(以毫秒为单位),请使用 AVIStreamLengthTime 宏。
在视频流中,每个示例通常对应于一帧视频。 但是,可能存在没有视频数据的样本。 如果调用指定其中一个位置的 AVIStreamRead 函数,它将返回 0 字节的数据长度。 可以使用 AVIStreamFindSample 函数并指定FIND_ANY标志来查找包含数据的示例。
在音频流中,每个示例对应于音频数据的一个数据块。 例如,如果音频数据具有 22 kHz ADPCM (自适应差分脉冲代码调制) 格式, 则 AVIStreamLength 的每个样本对应于一个包含 256 字节的压缩音频数据块。 此音频数据块在未压缩时包含大约 500 个音频样本。 但是,AVIFile 的函数和宏将每个 256 字节块视为单个示例。
注意
流范围内从流开始到结束的有效位置,即流起始点及其长度之和。 由起始位置的总和和表示的位置和长度对应于呈现最后一个数据后的时间;它不包含任何数据。 可以使用 AVIStreamEnd 宏检索表示流末尾的示例编号。 可以使用 AVIStreamEndTime 宏检索表示流结束的时间值(以毫秒为单位)。
查找示例和关键帧
可以使用 AVIStreamFindSample 函数在流中搜索不同类型的样本。 此函数从指定的样本编号开始,通过流向后或向前搜索相应类型的样本。 可以通过在 AVIStreamFindSample 调用序列中指定标志,在流中搜索不同类型的样本。 指定FIND_ANY标志以查找非空样本或跳过缺少数据的示例。 指定FIND_KEY标志以搜索包含数据的关键帧以呈现完整图像,而无需引用以前的帧。 指定FIND_FORMAT标志以搜索对格式的更改。 AVIStreamFindSample 主要用于视频流。
几个使用 AVIFile 函数的宏补充了流搜索功能。 以下列表提供了每个宏的简要说明。 搜索特定位置或数据类型的宏需要在流中指定起始位置。
宏 | 说明 |
---|---|
AVIStreamIsKeyFrame | 指示指定流中的示例是否为关键帧。 |
AVIStreamNearestKeyFrame | 在流中的指定位置或之前找到关键帧。 |
AVIStreamNearestKeyFrameTime | 确定与关键帧开头相对应的时间,该时间最接近 (或之前) 流中的指定时间。 |
AVIStreamNearestSample | 查找流中指定位置或之前最接近的无空样本。 |
AVIStreamNearestSampleTime | 确定与样本开始时间相对应的时间,该时间最接近流中的指定时间。 |
AVIStreamNextKeyFrame | 查找流中指定位置后面的下一个关键帧。 |
AVIStreamNextKeyFrameTime | 返回流中下一个关键帧的时间,从给定时间开始。 |
AVIStreamNextSample | 从流中的指定位置查找下一个非空样本。 |
AVIStreamNextSampleTime | 返回示例更改为流中的下一个示例的时间。 |
AVIStreamPrevKeyFrame | 查找流中指定位置之前的关键帧。 |
AVIStreamPrevKeyFrameTime | 返回流中上一个关键帧的时间,从给定时间开始。 |
AVIStreamPrevSample | 查找流中指定位置前面的非空样本。 |
AVIStreamPrevSampleTime | 确定上一个示例在流中替换其前置任务的时间。 |
AVIStreamSampleToSample | 返回流中的示例,该流与第二个流中发生的示例同时发生。 |
在示例和时间之间切换
可以使用 AVIStreamSampleToTime 函数确定从流开始到样本的已用时间。 此函数将样本数转换为以毫秒表示的时间值。 对于跨) 几毫秒的视频帧 (,此值表示自播放开始以来示例开始播放的时间,并假定视频剪辑以正常速度播放。 对于音频示例 ((以毫秒) 为单位)具有多个样本,时间值对应于样本开始播放的时间,并假定音频流以正常速度播放。
相反,可以使用 AVIStreamTimeToSample 函数查找与时间值关联的示例编号。 此函数将毫秒值转换为样本数,并假定视频剪辑以正常速度播放。
由于 AVIStreamSampleToTime 返回帧开始播放的时间,因此 AVIStreamSampleToTime 与 AVIStreamTimeToSample 之间的关系并非真正相反。 他们确定文件中的位置比确定时间更明确。 例如,两个连续的音频样本可能都在相同的毫秒内播放。 使用 AVIStreamSampleToTime 转换样本编号将导致相同的时间值。 如果使用 AVIStreamTimeToSample 将时间值转换回样本数,则会引用单个样本。