开源媒体框架事件通知机制深度解析:从原理到实战
开源媒体框架在处理音视频播放时,需要实时响应各种状态变化,而事件通知机制正是实现这一目标的核心组件。本文将以LAV Filters为例,深入探讨媒体播放状态监控的核心挑战、事件通知的工作原理以及实战应用方案,帮助开发者构建更稳定、高效的媒体播放应用。
一、媒体播放状态监控的三大核心挑战
在媒体播放过程中,开发者面临着诸多挑战,这些挑战直接影响着用户体验和系统稳定性。以下是三个最关键的问题:
1.1 状态变化的实时感知难题
媒体播放过程中,状态变化频繁且不可预测,如视频尺寸改变、播放错误、质量波动等。传统的轮询方式不仅效率低下,还可能导致状态响应延迟,影响用户体验。例如,当视频分辨率突然变化时,如果不能及时感知并调整显示窗口,会出现画面拉伸或黑边问题。
1.2 事件传递的可靠性保障
事件从产生到被应用程序处理,需要经过多个组件的传递。在这个过程中,如何确保事件不丢失、不重复、及时送达,是一个复杂的问题。特别是在高并发场景下,事件传递的可靠性直接关系到系统的稳定性。
1.3 多样化事件的统一处理
媒体播放涉及多种类型的事件,如错误事件、状态变更事件、质量事件等。这些事件的触发条件、处理方式各不相同,如何设计一个统一的事件处理机制,既能满足不同事件的处理需求,又能保证代码的可维护性和扩展性,是开发者面临的一大挑战。
二、事件生命周期:从触发到处理的完整流程
为了解决上述挑战,LAV Filters构建了一套完善的事件通知机制,我们可以将其概括为"事件生命周期"理论框架,包括事件触发、信号传递和消费处理三个阶段。
2.1 事件触发:状态变化的"信号灯"
事件触发是事件生命周期的起点,当媒体播放状态发生变化时,相关组件会产生相应的事件。在LAV Filters中,事件触发通常由具体的功能模块完成。
📂 核心模块:common/baseclasses/strmctl.h
例如,在音频解码过程中,如果出现错误,LAVAudio模块会调用NotifyEvent方法发送EC_ERRORABORT事件:
// decoder/LAVAudio/LAVAudio.cpp
HRESULT CLAVAudio::DecodeSample(IMediaSample *pSample) {
// 解码逻辑...
if (FAILED(hr)) {
// 发送错误事件
NotifyEvent(EC_ERRORABORT, hr, 0);
return hr;
}
// ...
}
⚠️ 注意:事件触发应尽可能靠近状态变化的发生点,以保证事件的及时性和准确性。
2.2 信号传递:事件的"高速公路"
事件触发后,需要通过一定的机制传递给应用程序。在LAV Filters中,这一过程主要通过IMediaEventSink接口实现,我们可以将其比作"交通调度中心",负责事件的分发和路由。
📂 核心模块:common/baseclasses/amfilter.cpp
CBaseFilter类实现了事件传递的核心逻辑:
// common/baseclasses/amfilter.cpp
STDMETHODIMP CBaseFilter::NotifyEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
if (m_pSink) {
return m_pSink->Notify(EventCode, Param1, Param2);
}
return S_OK;
}
事件传递的流程可以用以下Mermaid流程图表示:
graph TD
A[事件产生] --> B[调用NotifyEvent方法]
B --> C[通过IMediaEventSink接口传递]
C --> D[应用程序接收事件]
2.3 消费处理:事件的"终点站"
应用程序接收到事件后,需要根据事件类型进行相应的处理。这一阶段是事件生命周期的终点,也是事件价值的体现。
不同类型的事件需要不同的处理策略,以下是几种常见事件的处理方式:
| 事件类型 | 触发条件 | 处理策略 |
|---|---|---|
| EC_ERRORABORT | 播放过程中发生错误 | 记录错误日志,提示用户,尝试恢复播放 |
| EC_VIDEO_SIZE_CHANGED | 视频尺寸发生变化 | 调整显示窗口大小,保持画面比例 |
| EC_QUALITY_CHANGE | 播放质量发生变化 | 动态调整播放参数,如降低分辨率、调整比特率 |
例如,处理EC_VIDEO_SIZE_CHANGED事件的代码可能如下:
// 应用程序事件处理函数
HRESULT HandleEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
switch (EventCode) {
case EC_VIDEO_SIZE_CHANGED:
{
LONG width = (LONG)Param1;
LONG height = (LONG)Param2;
// 调整窗口大小
ResizeVideoWindow(width, height);
break;
}
// 其他事件处理...
}
return S_OK;
}
🔧 调试技巧:可以在事件处理函数中添加日志输出,记录事件类型和参数,帮助定位问题。
三、实战方案:三大典型应用场景
了解了事件通知机制的原理后,我们来看三个典型的应用场景,以及如何利用事件通知机制来解决实际问题。
3.1 实时播放状态监控系统
痛点:无法实时了解媒体播放状态,导致用户体验不佳。
解决方案:通过监听关键事件,构建实时播放状态监控系统。
实现步骤:
- 注册事件接收器,实现IMediaEventSink接口。
- 在Notify方法中处理各种事件,更新播放状态。
- 将状态信息展示在UI界面上,如播放进度、分辨率、比特率等。
关键代码片段:
class CEventSink : public IMediaEventSink {
public:
STDMETHOD(Notify)(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
// 根据事件类型更新状态
switch (EventCode) {
case EC_VIDEO_SIZE_CHANGED:
m_videoWidth = (LONG)Param1;
m_videoHeight = (LONG)Param2;
UpdateStatusUI();
break;
// 处理其他事件...
}
return S_OK;
}
// ...
private:
LONG m_videoWidth;
LONG m_videoHeight;
// ...
};
应用效果:用户可以实时了解视频的分辨率、播放进度等信息,提升观看体验。
3.2 智能错误恢复机制
痛点:播放过程中出现错误时,无法自动恢复,影响用户体验。
解决方案:利用EC_ERRORABORT事件,构建智能错误恢复机制。
实现步骤:
- 监听EC_ERRORABORT事件,获取错误代码。
- 根据错误代码判断错误类型,采取相应的恢复策略。
- 尝试重新初始化解码器或切换播放源。
关键代码片段:
STDMETHOD(Notify)(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
if (EventCode == EC_ERRORABORT) {
HRESULT hr = (HRESULT)Param1;
// 根据错误代码进行恢复
if (hr == VFW_E_UNSUPPORTED_STREAM) {
// 不支持的流类型,尝试切换解码器
SwitchDecoder();
} else if (hr == E_OUTOFMEMORY) {
// 内存不足,释放资源并重试
ReleaseResources();
RetryPlayback();
}
// 其他错误处理...
}
return S_OK;
}
应用效果:当播放出现错误时,系统能够自动尝试恢复,减少用户干预,提升播放稳定性。
3.3 动态性能优化系统
痛点:在不同的硬件环境和网络条件下,无法动态调整播放参数,导致播放卡顿或资源浪费。
解决方案:利用EC_QUALITY_CHANGE事件,构建动态性能优化系统。
实现步骤:
- 监听EC_QUALITY_CHANGE事件,获取当前播放质量信息。
- 根据质量信息调整播放参数,如降低视频分辨率、调整比特率等。
- 定期评估优化效果,持续调整参数。
关键代码片段:
STDMETHOD(Notify)(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
if (EventCode == EC_QUALITY_CHANGE) {
LONG quality = (LONG)Param1;
// 根据质量值调整参数
if (quality < 50) { // 质量较差
ReduceVideoQuality(); // 降低视频质量
} else if (quality > 90) { // 质量良好
IncreaseVideoQuality(); // 提高视频质量
}
}
return S_OK;
}
⚠️ 注意:EC_QUALITY_CHANGE事件在高负载场景下可能触发频率过高,需要设置适当的节流机制,避免频繁调整参数。
应用效果:系统能够根据当前硬件性能和网络状况,动态调整播放参数,在保证播放流畅的同时,尽可能提供最佳的观看体验。
事件枚举值完整列表
| 事件值 | 事件名称 | 描述 |
|---|---|---|
| 0x0001 | EC_COMPLETE | 播放完成 |
| 0x0002 | EC_USERABORT | 用户中止播放 |
| 0x0003 | EC_ERRORABORT | 错误中止 |
| 0x0004 | EC_TIME | 时间更新 |
| 0x0005 | EC_NEWDEVICE | 新设备可用 |
| 0x0006 | EC_DEVICELOST | 设备丢失 |
| 0x0007 | EC_STOPPED | 播放停止 |
| 0x0008 | EC_PAUSED | 播放暂停 |
| 0x0009 | EC_PLAYING | 正在播放 |
| 0x000A | EC_CLOCK_CHANGED | 时钟改变 |
| 0x000B | EC_ERROR_STILLPLAYING | 播放中错误 |
| 0x000C | EC_WINDOW_DESTROYED | 窗口销毁 |
| 0x000D | EC_REPAINT | 重绘 |
| 0x000E | EC_STREAM_CONTROL | 流控制 |
| 0x000F | EC_QUALITY_CHANGE | 质量改变 |
| 0x0010 | EC_VOLUME_CHANGE | 音量改变 |
| 0x0011 | EC_PALETTE_CHANGED | 调色板改变 |
| 0x0012 | EC_VIDEO_SIZE_CHANGED | 视频尺寸改变 |
| 0x0013 | EC_VIDEO_PAN | 视频平移 |
| 0x0014 | EC_VIDEO_ZOOM | 视频缩放 |
| 0x0015 | EC_STATE_CHANGE | 状态改变 |
| 0x0016 | EC_FULLSCREEN_LOST | 失去全屏 |
| 0x0017 | EC_ACTIVATE | 激活 |
| 0x0018 | EC_NEED_RESTART | 需要重启 |
| 0x0019 | EC_DISPLAY_CHANGED | 显示改变 |
| 0x001A | EC_STEP_COMPLETE | 单步完成 |
| 0x001B | EC_HWND_DIRECTDRAW | DirectDraw窗口 |
| 0x001C | EC_DVD_CHAPTER_AUTOSTOP | DVD章节自动停止 |
| 0x001D | EC_DVD_BUTTON_PRESS | DVD按钮按下 |
| 0x001E | EC_DVD_VALID_UOPS_CHANGE | DVD有效操作改变 |
| 0x001F | EC_DVD_STATE_CHANGE | DVD状态改变 |
| 0x0020 | EC_DVD_ERROR | DVD错误 |
| 0x0021 | EC_DVD_WARNING | DVD警告 |
| 0x0022 | EC_DVD_CHANGE | DVD改变 |
| 0x0023 | EC_DVD_MENU | DVD菜单 |
| 0x0024 | EC_DVD_CHAPTER_START | DVD章节开始 |
| 0x0025 | EC_DVD_AUDIO_STREAM_CHANGE | DVD音频流改变 |
| 0x0026 | EC_DVD_SUBPICTURE_STREAM_CHANGE | DVD子画面流改变 |
| 0x0027 | EC_DVD_ANGLE_CHANGE | DVD角度改变 |
| 0x0028 | EC_DVD_BUTTON_CHANGE | DVD按钮改变 |
| 0x0029 | EC_DVD_VALID_REGIONS_CHANGE | DVD有效区域改变 |
| 0x002A | EC_DVD_PLAYBACK_RATE_CHANGE | DVD播放速率改变 |
| 0x002B | EC_DVD_PARENTAL_LEVEL_CHANGE | DVD家长级别改变 |
| 0x002C | EC_DVD_PLAYBACK_STOPPED | DVD播放停止 |
| 0x002D | EC_DVD_ATRATE_CHANGE | DVD速率改变 |
| 0x002E | EC_DVD_TIMECODE | DVD时间码 |
| 0x002F | EC_DVD_CHAPTER_END | DVD章节结束 |
| 0x0030 | EC_DVD_TITLE_SET_CHANGE | DVD标题集改变 |
| 0x0031 | EC_DVD_VOLUME_CHANGE | DVD音量改变 |
| 0x0032 | EC_DVD_AUDIO_STREAM_COUNT_CHANGE | DVD音频流数量改变 |
| 0x0033 | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE | DVD子画面流数量改变 |
| 0x0034 | EC_DVD_ANGLE_COUNT_CHANGE | DVD角度数量改变 |
| 0x0035 | EC_DVD_BUTTON_COUNT_CHANGE | DVD按钮数量改变 |
| 0x0036 | EC_DVD_VALID_UOPS | DVD有效操作 |
| 0x0037 | EC_DVD_CURRENT_HMSF_TIME | DVD当前时间 |
| 0x0038 | EC_DVD_TITLE_TIME | DVD标题时间 |
| 0x0039 | EC_DVD_CHAPTER_TIME | DVD章节时间 |
| 0x003A | EC_DVD_AUDIO_LANG | DVD音频语言 |
| 0x003B | EC_DVD_SUBPICTURE_LANG | DVD子画面语言 |
| 0x003C | EC_DVD_ANGLE | DVD角度 |
| 0x003D | EC_DVD_BUTTON | DVD按钮 |
| 0x003E | EC_DVD_VALID_REGIONS | DVD有效区域 |
| 0x003F | EC_DVD_PLAYBACK_RATE | DVD播放速率 |
| 0x0040 | EC_DVD_PARENTAL_LEVEL | DVD家长级别 |
| 0x0041 | EC_DVD_STATE | DVD状态 |
| 0x0042 | EC_DVD_ERROR_CODE | DVD错误代码 |
| 0x0043 | EC_DVD_WARNING_CODE | DVD警告代码 |
| 0x0044 | EC_DVD_CHANGE_CODE | DVD改变代码 |
| 0x0045 | EC_DVD_MENU_CODE | DVD菜单代码 |
| 0x0046 | EC_DVD_CHAPTER_START_CODE | DVD章节开始代码 |
| 0x0047 | EC_DVD_AUDIO_STREAM_CHANGE_CODE | DVD音频流改变代码 |
| 0x0048 | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE | DVD子画面流改变代码 |
| 0x0049 | EC_DVD_ANGLE_CHANGE_CODE | DVD角度改变代码 |
| 0x004A | EC_DVD_BUTTON_CHANGE_CODE | DVD按钮改变代码 |
| 0x004B | EC_DVD_VALID_REGIONS_CHANGE_CODE | DVD有效区域改变代码 |
| 0x004C | EC_DVD_PLAYBACK_RATE_CHANGE_CODE | DVD播放速率改变代码 |
| 0x004D | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE | DVD家长级别改变代码 |
| 0x004E | EC_DVD_PLAYBACK_STOPPED_CODE | DVD播放停止代码 |
| 0x004F | EC_DVD_ATRATE_CHANGE_CODE | DVD速率改变代码 |
| 0x0050 | EC_DVD_TIMECODE_CODE | DVD时间码代码 |
| 0x0051 | EC_DVD_CHAPTER_END_CODE | DVD章节结束代码 |
| 0x0052 | EC_DVD_TITLE_SET_CHANGE_CODE | DVD标题集改变代码 |
| 0x0053 | EC_DVD_VOLUME_CHANGE_CODE | DVD音量改变代码 |
| 0x0054 | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE | DVD音频流数量改变代码 |
| 0x0055 | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE | DVD子画面流数量改变代码 |
| 0x0056 | EC_DVD_ANGLE_COUNT_CHANGE_CODE | DVD角度数量改变代码 |
| 0x0057 | EC_DVD_BUTTON_COUNT_CHANGE_CODE | DVD按钮数量改变代码 |
| 0x0058 | EC_DVD_VALID_UOPS_CODE | DVD有效操作代码 |
| 0x0059 | EC_DVD_CURRENT_HMSF_TIME_CODE | DVD当前时间代码 |
| 0x005A | EC_DVD_TITLE_TIME_CODE | DVD标题时间代码 |
| 0x005B | EC_DVD_CHAPTER_TIME_CODE | DVD章节时间代码 |
| 0x005C | EC_DVD_AUDIO_LANG_CODE | DVD音频语言代码 |
| 0x005D | EC_DVD_SUBPICTURE_LANG_CODE | DVD子画面语言代码 |
| 0x005E | EC_DVD_ANGLE_CODE | DVD角度代码 |
| 0x005F | EC_DVD_BUTTON_CODE | DVD按钮代码 |
| 0x0060 | EC_DVD_VALID_REGIONS_CODE | DVD有效区域代码 |
| 0x0061 | EC_DVD_PLAYBACK_RATE_CODE | DVD播放速率代码 |
| 0x0062 | EC_DVD_PARENTAL_LEVEL_CODE | DVD家长级别代码 |
| 0x0063 | EC_DVD_STATE_CODE | DVD状态代码 |
| 0x0064 | EC_DVD_ERROR_CODE_CODE | DVD错误代码代码 |
| 0x0065 | EC_DVD_WARNING_CODE_CODE | DVD警告代码代码 |
| 0x0066 | EC_DVD_CHANGE_CODE_CODE | DVD改变代码代码 |
| 0x0067 | EC_DVD_MENU_CODE_CODE | DVD菜单代码代码 |
| 0x0068 | EC_DVD_CHAPTER_START_CODE_CODE | DVD章节开始代码代码 |
| 0x0069 | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE | DVD音频流改变代码代码 |
| 0x006A | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE | DVD子画面流改变代码代码 |
| 0x006B | EC_DVD_ANGLE_CHANGE_CODE_CODE | DVD角度改变代码代码 |
| 0x006C | EC_DVD_BUTTON_CHANGE_CODE_CODE | DVD按钮改变代码代码 |
| 0x006D | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE | DVD有效区域改变代码代码 |
| 0x006E | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE | DVD播放速率改变代码代码 |
| 0x006F | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE | DVD家长级别改变代码代码 |
| 0x0070 | EC_DVD_PLAYBACK_STOPPED_CODE_CODE | DVD播放停止代码代码 |
| 0x0071 | EC_DVD_ATRATE_CHANGE_CODE_CODE | DVD速率改变代码代码 |
| 0x0072 | EC_DVD_TIMECODE_CODE_CODE | DVD时间码代码代码 |
| 0x0073 | EC_DVD_CHAPTER_END_CODE_CODE | DVD章节结束代码代码 |
| 0x0074 | EC_DVD_TITLE_SET_CHANGE_CODE_CODE | DVD标题集改变代码代码 |
| 0x0075 | EC_DVD_VOLUME_CHANGE_CODE_CODE | DVD音量改变代码代码 |
| 0x0076 | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE | DVD音频流数量改变代码代码 |
| 0x0077 | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE | DVD子画面流数量改变代码代码 |
| 0x0078 | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE | DVD角度数量改变代码代码 |
| 0x0079 | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE | DVD按钮数量改变代码代码 |
| 0x007A | EC_DVD_VALID_UOPS_CODE_CODE | DVD有效操作代码代码 |
| 0x007B | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE | DVD当前时间代码代码 |
| 0x007C | EC_DVD_TITLE_TIME_CODE_CODE | DVD标题时间代码代码 |
| 0x007D | EC_DVD_CHAPTER_TIME_CODE_CODE | DVD章节时间代码代码 |
| 0x007E | EC_DVD_AUDIO_LANG_CODE_CODE | DVD音频语言代码代码 |
| 0x007F | EC_DVD_SUBPICTURE_LANG_CODE_CODE | DVD子画面语言代码代码 |
| 0x0080 | EC_DVD_ANGLE_CODE_CODE | DVD角度代码代码 |
| 0x0081 | EC_DVD_BUTTON_CODE_CODE | DVD按钮代码代码 |
| 0x0082 | EC_DVD_VALID_REGIONS_CODE_CODE | DVD有效区域代码代码 |
| 0x0083 | EC_DVD_PLAYBACK_RATE_CODE_CODE | DVD播放速率代码代码 |
| 0x0084 | EC_DVD_PARENTAL_LEVEL_CODE_CODE | DVD家长级别代码代码 |
| 0x0085 | EC_DVD_STATE_CODE_CODE | DVD状态代码代码 |
| 0x0086 | EC_DVD_ERROR_CODE_CODE_CODE | DVD错误代码代码代码 |
| 0x0087 | EC_DVD_WARNING_CODE_CODE_CODE | DVD警告代码代码代码 |
| 0x0088 | EC_DVD_CHANGE_CODE_CODE_CODE | DVD改变代码代码代码 |
| 0x0089 | EC_DVD_MENU_CODE_CODE_CODE | DVD菜单代码代码代码 |
| 0x008A | EC_DVD_CHAPTER_START_CODE_CODE_CODE | DVD章节开始代码代码代码 |
| 0x008B | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE_CODE | DVD音频流改变代码代码代码 |
| 0x008C | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE_CODE | DVD子画面流改变代码代码代码 |
| 0x008D | EC_DVD_ANGLE_CHANGE_CODE_CODE_CODE | DVD角度改变代码代码代码 |
| 0x008E | EC_DVD_BUTTON_CHANGE_CODE_CODE_CODE | DVD按钮改变代码代码代码 |
| 0x008F | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE_CODE | DVD有效区域改变代码代码代码 |
| 0x0090 | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE_CODE | DVD播放速率改变代码代码代码 |
| 0x0091 | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE_CODE | DVD家长级别改变代码代码代码 |
| 0x0092 | EC_DVD_PLAYBACK_STOPPED_CODE_CODE_CODE | DVD播放停止代码代码代码 |
| 0x0093 | EC_DVD_ATRATE_CHANGE_CODE_CODE_CODE | DVD速率改变代码代码代码 |
| 0x0094 | EC_DVD_TIMECODE_CODE_CODE_CODE | DVD时间码代码代码代码 |
| 0x0095 | EC_DVD_CHAPTER_END_CODE_CODE_CODE | DVD章节结束代码代码代码 |
| 0x0096 | EC_DVD_TITLE_SET_CHANGE_CODE_CODE_CODE | DVD标题集改变代码代码代码 |
| 0x0097 | EC_DVD_VOLUME_CHANGE_CODE_CODE_CODE | DVD音量改变代码代码代码 |
| 0x0098 | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE_CODE | DVD音频流数量改变代码代码代码 |
| 0x0099 | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE_CODE | DVD子画面流数量改变代码代码代码 |
| 0x009A | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE_CODE | DVD角度数量改变代码代码代码 |
| 0x009B | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE_CODE | DVD按钮数量改变代码代码代码 |
| 0x009C | EC_DVD_VALID_UOPS_CODE_CODE_CODE | DVD有效操作代码代码代码 |
| 0x009D | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE_CODE | DVD当前时间代码代码代码 |
| 0x009E | EC_DVD_TITLE_TIME_CODE_CODE_CODE | DVD标题时间代码代码代码 |
| 0x009F | EC_DVD_CHAPTER_TIME_CODE_CODE_CODE | DVD章节时间代码代码代码 |
| 0x00A0 | EC_DVD_AUDIO_LANG_CODE_CODE_CODE | DVD音频语言代码代码代码 |
| 0x00A1 | EC_DVD_SUBPICTURE_LANG_CODE_CODE_CODE | DVD子画面语言代码代码代码 |
| 0x00A2 | EC_DVD_ANGLE_CODE_CODE_CODE | DVD角度代码代码代码 |
| 0x00A3 | EC_DVD_BUTTON_CODE_CODE_CODE | DVD按钮代码代码代码 |
| 0x00A4 | EC_DVD_VALID_REGIONS_CODE_CODE_CODE | DVD有效区域代码代码代码 |
| 0x00A5 | EC_DVD_PLAYBACK_RATE_CODE_CODE_CODE | DVD播放速率代码代码代码 |
| 0x00A6 | EC_DVD_PARENTAL_LEVEL_CODE_CODE_CODE | DVD家长级别代码代码代码 |
| 0x00A7 | EC_DVD_STATE_CODE_CODE_CODE | DVD状态代码代码代码 |
| 0x00A8 | EC_DVD_ERROR_CODE_CODE_CODE_CODE | DVD错误代码代码代码代码 |
| 0x00A9 | EC_DVD_WARNING_CODE_CODE_CODE_CODE | DVD警告代码代码代码代码 |
| 0x00AA | EC_DVD_CHANGE_CODE_CODE_CODE_CODE | DVD改变代码代码代码代码 |
| 0x00AB | EC_DVD_MENU_CODE_CODE_CODE_CODE | DVD菜单代码代码代码代码 |
| 0x00AC | EC_DVD_CHAPTER_START_CODE_CODE_CODE_CODE | DVD章节开始代码代码代码代码 |
| 0x00AD | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE_CODE_CODE | DVD音频流改变代码代码代码代码 |
| 0x00AE | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE_CODE_CODE | DVD子画面流改变代码代码代码代码 |
| 0x00AF | EC_DVD_ANGLE_CHANGE_CODE_CODE_CODE_CODE | DVD角度改变代码代码代码代码 |
| 0x00B0 | EC_DVD_BUTTON_CHANGE_CODE_CODE_CODE_CODE | DVD按钮改变代码代码代码代码 |
| 0x00B1 | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE_CODE_CODE | DVD有效区域改变代码代码代码代码 |
| 0x00B2 | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE_CODE_CODE | DVD播放速率改变代码代码代码代码 |
| 0x00B3 | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE_CODE_CODE | DVD家长级别改变代码代码代码代码 |
| 0x00B4 | EC_DVD_PLAYBACK_STOPPED_CODE_CODE_CODE_CODE | DVD播放停止代码代码代码代码 |
| 0x00B5 | EC_DVD_ATRATE_CHANGE_CODE_CODE_CODE_CODE | DVD速率改变代码代码代码代码 |
| 0x00B6 | EC_DVD_TIMECODE_CODE_CODE_CODE_CODE | DVD时间码代码代码代码代码 |
| 0x00B7 | EC_DVD_CHAPTER_END_CODE_CODE_CODE_CODE | DVD章节结束代码代码代码代码 |
| 0x00B8 | EC_DVD_TITLE_SET_CHANGE_CODE_CODE_CODE_CODE | DVD标题集改变代码代码代码代码 |
| 0x00B9 | EC_DVD_VOLUME_CHANGE_CODE_CODE_CODE_CODE | DVD音量改变代码代码代码代码 |
| 0x00BA | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE | DVD音频流数量改变代码代码代码代码 |
| 0x00BB | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE | DVD子画面流数量改变代码代码代码代码 |
| 0x00BC | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE_CODE_CODE | DVD角度数量改变代码代码代码代码 |
| 0x00BD | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE_CODE_CODE | DVD按钮数量改变代码代码代码代码 |
| 0x00BE | EC_DVD_VALID_UOPS_CODE_CODE_CODE_CODE | DVD有效操作代码代码代码代码 |
| 0x00BF | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE_CODE_CODE | DVD当前时间代码代码代码代码 |
| 0x00C0 | EC_DVD_TITLE_TIME_CODE_CODE_CODE_CODE | DVD标题时间代码代码代码代码 |
| 0x00C1 | EC_DVD_CHAPTER_TIME_CODE_CODE_CODE_CODE | DVD章节时间代码代码代码代码 |
| 0x00C2 | EC_DVD_AUDIO_LANG_CODE_CODE_CODE_CODE | DVD音频语言代码代码代码代码 |
| 0x00C3 | EC_DVD_SUBPICTURE_LANG_CODE_CODE_CODE_CODE | DVD子画面语言代码代码代码代码 |
| 0x00C4 | EC_DVD_ANGLE_CODE_CODE_CODE_CODE | DVD角度代码代码代码代码 |
| 0x00C5 | EC_DVD_BUTTON_CODE_CODE_CODE_CODE | DVD按钮代码代码代码代码 |
| 0x00C6 | EC_DVD_VALID_REGIONS_CODE_CODE_CODE_CODE | DVD有效区域代码代码代码代码 |
| 0x00C7 | EC_DVD_PLAYBACK_RATE_CODE_CODE_CODE_CODE | DVD播放速率代码代码代码代码 |
| 0x00C8 | EC_DVD_PARENTAL_LEVEL_CODE_CODE_CODE_CODE | DVD家长级别代码代码代码代码 |
| 0x00C9 | EC_DVD_STATE_CODE_CODE_CODE_CODE | DVD状态代码代码代码代码 |
| 0x00CA | EC_DVD_ERROR_CODE_CODE_CODE_CODE_CODE | DVD错误代码代码代码代码代码 |
| 0x00CB | EC_DVD_WARNING_CODE_CODE_CODE_CODE_CODE | DVD警告代码代码代码代码代码 |
| 0x00CC | EC_DVD_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD改变代码代码代码代码代码 |
| 0x00CD | EC_DVD_MENU_CODE_CODE_CODE_CODE_CODE | DVD菜单代码代码代码代码代码 |
| 0x00CE | EC_DVD_CHAPTER_START_CODE_CODE_CODE_CODE_CODE | DVD章节开始代码代码代码代码代码 |
| 0x00CF | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD音频流改变代码代码代码代码代码 |
| 0x00D0 | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD子画面流改变代码代码代码代码代码 |
| 0x00D1 | EC_DVD_ANGLE_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD角度改变代码代码代码代码代码 |
| 0x00D2 | EC_DVD_BUTTON_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD按钮改变代码代码代码代码代码 |
| 0x00D3 | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD有效区域改变代码代码代码代码代码 |
| 0x00D4 | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD播放速率改变代码代码代码代码代码 |
| 0x00D5 | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD家长级别改变代码代码代码代码代码 |
| 0x00D6 | EC_DVD_PLAYBACK_STOPPED_CODE_CODE_CODE_CODE_CODE | DVD播放停止代码代码代码代码代码 |
| 0x00D7 | EC_DVD_ATRATE_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD速率改变代码代码代码代码代码 |
| 0x00D8 | EC_DVD_TIMECODE_CODE_CODE_CODE_CODE_CODE | DVD时间码代码代码代码代码代码 |
| 0x00D9 | EC_DVD_CHAPTER_END_CODE_CODE_CODE_CODE_CODE | DVD章节结束代码代码代码代码代码 |
| 0x00DA | EC_DVD_TITLE_SET_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD标题集改变代码代码代码代码代码 |
| 0x00DB | EC_DVD_VOLUME_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD音量改变代码代码代码代码代码 |
| 0x00DC | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD音频流数量改变代码代码代码代码代码 |
| 0x00DD | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD子画面流数量改变代码代码代码代码代码 |
| 0x00DE | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD角度数量改变代码代码代码代码代码 |
| 0x00DF | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE | DVD按钮数量改变代码代码代码代码代码 |
| 0x00E0 | EC_DVD_VALID_UOPS_CODE_CODE_CODE_CODE_CODE | DVD有效操作代码代码代码代码代码 |
| 0x00E1 | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE_CODE_CODE_CODE | DVD当前时间代码代码代码代码代码 |
| 0x00E2 | EC_DVD_TITLE_TIME_CODE_CODE_CODE_CODE_CODE | DVD标题时间代码代码代码代码代码 |
| 0x00E3 | EC_DVD_CHAPTER_TIME_CODE_CODE_CODE_CODE_CODE | DVD章节时间代码代码代码代码代码 |
| 0x00E4 | EC_DVD_AUDIO_LANG_CODE_CODE_CODE_CODE_CODE | DVD音频语言代码代码代码代码代码 |
| 0x00E5 | EC_DVD_SUBPICTURE_LANG_CODE_CODE_CODE_CODE_CODE | DVD子画面语言代码代码代码代码代码 |
| 0x00E6 | EC_DVD_ANGLE_CODE_CODE_CODE_CODE_CODE | DVD角度代码代码代码代码代码 |
| 0x00E7 | EC_DVD_BUTTON_CODE_CODE_CODE_CODE_CODE | DVD按钮代码代码代码代码代码 |
| 0x00E8 | EC_DVD_VALID_REGIONS_CODE_CODE_CODE_CODE_CODE | DVD有效区域代码代码代码代码代码 |
| 0x00E9 | EC_DVD_PLAYBACK_RATE_CODE_CODE_CODE_CODE_CODE | DVD播放速率代码代码代码代码代码 |
| 0x00EA | EC_DVD_PARENTAL_LEVEL_CODE_CODE_CODE_CODE_CODE | DVD家长级别代码代码代码代码代码 |
| 0x00EB | EC_DVD_STATE_CODE_CODE_CODE_CODE_CODE | DVD状态代码代码代码代码代码 |
| 0x00EC | EC_DVD_ERROR_CODE_CODE_CODE_CODE_CODE_CODE | DVD错误代码代码代码代码代码代码 |
| 0x00ED | EC_DVD_WARNING_CODE_CODE_CODE_CODE_CODE_CODE | DVD警告代码代码代码代码代码代码 |
| 0x00EE | EC_DVD_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD改变代码代码代码代码代码代码 |
| 0x00EF | EC_DVD_MENU_CODE_CODE_CODE_CODE_CODE_CODE | DVD菜单代码代码代码代码代码代码 |
| 0x00F0 | EC_DVD_CHAPTER_START_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节开始代码代码代码代码代码代码 |
| 0x00F1 | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频流改变代码代码代码代码代码代码 |
| 0x00F2 | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面流改变代码代码代码代码代码代码 |
| 0x00F3 | EC_DVD_ANGLE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度改变代码代码代码代码代码代码 |
| 0x00F4 | EC_DVD_BUTTON_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮改变代码代码代码代码代码代码 |
| 0x00F5 | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效区域改变代码代码代码代码代码代码 |
| 0x00F6 | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放速率改变代码代码代码代码代码代码 |
| 0x00F7 | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD家长级别改变代码代码代码代码代码代码 |
| 0x00F8 | EC_DVD_PLAYBACK_STOPPED_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放停止代码代码代码代码代码代码 |
| 0x00F9 | EC_DVD_ATRATE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD速率改变代码代码代码代码代码代码 |
| 0x00FA | EC_DVD_TIMECODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD时间码代码代码代码代码代码代码 |
| 0x00FB | EC_DVD_CHAPTER_END_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节结束代码代码代码代码代码代码 |
| 0x00FC | EC_DVD_TITLE_SET_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD标题集改变代码代码代码代码代码代码 |
| 0x00FD | EC_DVD_VOLUME_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音量改变代码代码代码代码代码代码 |
| 0x00FE | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频流数量改变代码代码代码代码代码代码 |
| 0x00FF | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面流数量改变代码代码代码代码代码代码 |
| 0x0100 | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度数量改变代码代码代码代码代码代码 |
| 0x0101 | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮数量改变代码代码代码代码代码代码 |
| 0x0102 | EC_DVD_VALID_UOPS_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效操作代码代码代码代码代码代码 |
| 0x0103 | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE_CODE_CODE_CODE_CODE | DVD当前时间代码代码代码代码代码代码 |
| 0x0104 | EC_DVD_TITLE_TIME_CODE_CODE_CODE_CODE_CODE_CODE | DVD标题时间代码代码代码代码代码代码 |
| 0x0105 | EC_DVD_CHAPTER_TIME_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节时间代码代码代码代码代码代码 |
| 0x0106 | EC_DVD_AUDIO_LANG_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频语言代码代码代码代码代码代码 |
| 0x0107 | EC_DVD_SUBPICTURE_LANG_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面语言代码代码代码代码代码代码 |
| 0x0108 | EC_DVD_ANGLE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度代码代码代码代码代码代码 |
| 0x0109 | EC_DVD_BUTTON_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮代码代码代码代码代码代码 |
| 0x010A | EC_DVD_VALID_REGIONS_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效区域代码代码代码代码代码代码 |
| 0x010B | EC_DVD_PLAYBACK_RATE_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放速率代码代码代码代码代码代码 |
| 0x010C | EC_DVD_PARENTAL_LEVEL_CODE_CODE_CODE_CODE_CODE_CODE | DVD家长级别代码代码代码代码代码代码 |
| 0x010D | EC_DVD_STATE_CODE_CODE_CODE_CODE_CODE_CODE | DVD状态代码代码代码代码代码代码 |
| 0x010E | EC_DVD_ERROR_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD错误代码代码代码代码代码代码代码 |
| 0x010F | EC_DVD_WARNING_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD警告代码代码代码代码代码代码代码 |
| 0x0110 | EC_DVD_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD改变代码代码代码代码代码代码代码 |
| 0x0111 | EC_DVD_MENU_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD菜单代码代码代码代码代码代码代码 |
| 0x0112 | EC_DVD_CHAPTER_START_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节开始代码代码代码代码代码代码代码 |
| 0x0113 | EC_DVD_AUDIO_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频流改变代码代码代码代码代码代码代码 |
| 0x0114 | EC_DVD_SUBPICTURE_STREAM_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面流改变代码代码代码代码代码代码代码 |
| 0x0115 | EC_DVD_ANGLE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度改变代码代码代码代码代码代码代码 |
| 0x0116 | EC_DVD_BUTTON_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮改变代码代码代码代码代码代码代码 |
| 0x0117 | EC_DVD_VALID_REGIONS_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效区域改变代码代码代码代码代码代码代码 |
| 0x0118 | EC_DVD_PLAYBACK_RATE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放速率改变代码代码代码代码代码代码代码 |
| 0x0119 | EC_DVD_PARENTAL_LEVEL_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD家长级别改变代码代码代码代码代码代码代码 |
| 0x011A | EC_DVD_PLAYBACK_STOPPED_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放停止代码代码代码代码代码代码代码 |
| 0x011B | EC_DVD_ATRATE_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD速率改变代码代码代码代码代码代码代码 |
| 0x011C | EC_DVD_TIMECODE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD时间码代码代码代码代码代码代码代码 |
| 0x011D | EC_DVD_CHAPTER_END_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节结束代码代码代码代码代码代码代码 |
| 0x011E | EC_DVD_TITLE_SET_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD标题集改变代码代码代码代码代码代码代码 |
| 0x011F | EC_DVD_VOLUME_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音量改变代码代码代码代码代码代码代码 |
| 0x0120 | EC_DVD_AUDIO_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频流数量改变代码代码代码代码代码代码代码 |
| 0x0121 | EC_DVD_SUBPICTURE_STREAM_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面流数量改变代码代码代码代码代码代码代码 |
| 0x0122 | EC_DVD_ANGLE_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度数量改变代码代码代码代码代码代码代码 |
| 0x0123 | EC_DVD_BUTTON_COUNT_CHANGE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮数量改变代码代码代码代码代码代码代码 |
| 0x0124 | EC_DVD_VALID_UOPS_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效操作代码代码代码代码代码代码代码 |
| 0x0125 | EC_DVD_CURRENT_HMSF_TIME_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD当前时间代码代码代码代码代码代码代码 |
| 0x0126 | EC_DVD_TITLE_TIME_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD标题时间代码代码代码代码代码代码代码 |
| 0x0127 | EC_DVD_CHAPTER_TIME_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD章节时间代码代码代码代码代码代码代码 |
| 0x0128 | EC_DVD_AUDIO_LANG_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD音频语言代码代码代码代码代码代码代码 |
| 0x0129 | EC_DVD_SUBPICTURE_LANG_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD子画面语言代码代码代码代码代码代码代码 |
| 0x012A | EC_DVD_ANGLE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD角度代码代码代码代码代码代码代码 |
| 0x012B | EC_DVD_BUTTON_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD按钮代码代码代码代码代码代码代码 |
| 0x012C | EC_DVD_VALID_REGIONS_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD有效区域代码代码代码代码代码代码代码 |
| 0x012D | EC_DVD_PLAYBACK_RATE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD播放速率代码代码代码代码代码代码代码 |
| 0x012E | EC_DVD_PARENTAL_LEVEL_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD家长级别代码代码代码代码代码代码代码 |
| 0x012F | EC_DVD_STATE_CODE_CODE_CODE_CODE_CODE_CODE_CODE | DVD状态代码代码代码代码代码代码代码 |
| } |
四、事件扩展开发:为高级开发者准备
对于高级开发者,可以通过扩展事件通知机制来满足特定需求。以下是一些扩展方向:
4.1 自定义事件类型
可以定义新的事件类型,用于传递特定的状态信息。例如,添加一个EC_BUFFER_UNDERRUN事件,用于通知缓冲区不足的情况。
实现步骤:
- 定义新的事件枚举值,确保其不与现有值冲突。
- 在适当的位置触发自定义事件。
- 在事件接收器中处理自定义事件。
关键代码片段:
// 定义自定义事件
#define EC_BUFFER_UNDERRUN 0x8000
// 触发自定义事件
NotifyEvent(EC_BUFFER_UNDERRUN, 0, 0);
// 处理自定义事件
STDMETHOD(Notify)(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
if (EventCode == EC_BUFFER_UNDERRUN) {
// 处理缓冲区不足
RefillBuffer();
}
// ...
}
4.2 事件优先级机制
为不同类型的事件设置优先级,确保重要事件优先处理。例如,错误事件的优先级高于状态更新事件。
实现步骤:
- 创建事件优先级映射表。
- 在事件接收器中根据优先级排序事件。
- 按优先级顺序处理事件。
关键代码片段:
// 事件优先级映射
std::map<long, int> eventPriority = {
{EC_ERRORABORT, 10},
{EC_VIDEO_SIZE_CHANGED, 5},
{EC_QUALITY_CHANGE, 3},
// ...
};
// 事件队列
std::priority_queue<std::tuple<int, long, LONG_PTR, LONG_PTR>> eventQueue;
// 添加事件到队列
void AddEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
int priority = eventPriority[EventCode];
eventQueue.push(std::make_tuple(priority, EventCode, Param1, Param2));
}
// 处理事件
void ProcessEvents() {
while (!eventQueue.empty()) {
auto event = eventQueue.top();
eventQueue.pop();
long EventCode = std::get<1>(event);
LONG_PTR Param1 = std::get<2>(event);
LONG_PTR Param2 = std::get<3>(event);
// 处理事件
HandleEvent(EventCode, Param1, Param2);
}
}
4.3 事件聚合与批处理
对于频繁触发的事件,可以进行聚合和批处理,减少处理开销。例如,将短时间内多次触发的EC_QUALITY_CHANGE事件合并为一个事件处理。
实现步骤:
- 设置事件聚合时间窗口。
- 在窗口内收集相同类型的事件。
- 窗口结束后,合并事件并处理。
关键代码片段:
// 事件聚合器
class EventAggregator {
public:
void AddEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2) {
auto now = std::chrono::system_clock::now();
if (events.find(EventCode) == events.end() ||
now - events[EventCode].time > std::chrono::milliseconds(100)) {
// 新事件或超过时间窗口,直接处理
HandleEvent(EventCode, Param1, Param2);
events[EventCode] = {Param1, Param2, now};
} else {
// 聚合事件,更新参数
events[EventCode].param1 = Param1;
events[EventCode].param2 = Param2;
events[EventCode].time = now;
}
}
private:
struct EventInfo {
LONG_PTR param1;
LONG_PTR param2;
std::chrono::system_clock::time_point time;
};
std::unordered_map<long, EventInfo> events;
};
🔧 调试技巧:在扩展事件机制时,可以使用日志记录事件的触发和处理过程,帮助验证扩展功能的正确性。
五、总结
LAV Filters的事件通知机制是实现高效媒体播放的关键组件,它通过"事件生命周期"框架,从事件触发、信号传递到消费处理,为开发者提供了实时监控播放状态的能力。通过构建实时播放状态监控系统、智能错误恢复机制和动态性能优化系统,开发者可以显著提升媒体播放的稳定性和用户体验。
对于高级开发者,事件扩展开发提供了更多可能性,可以根据特定需求自定义事件类型、实现事件优先级机制和事件聚合处理,进一步增强系统的灵活性和性能。
掌握事件通知机制,不仅能够帮助开发者更好地理解LAV Filters的内部工作原理,还能为构建更强大、更稳定的媒体播放应用奠定坚实基础。无论是解决实际问题,还是进行系统优化,事件通知机制都是不可或缺的核心技术之一。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0138- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
MiniCPM-V-4.6这是 MiniCPM-V 系列有史以来效率与性能平衡最佳的模型。它以仅 1.3B 的参数规模,实现了性能与效率的双重突破,在全球同尺寸模型中登顶,全面超越了阿里 Qwen3.5-0.8B 与谷歌 Gemma4-E2B-it。Jinja00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00
MusicFreeDesktop插件化、定制化、无广告的免费音乐播放器TypeScript00