【三方库】ohos_ijkplayer v2.0.9 鸿蒙平台稳定性与质量提升
📢 【三方库】ohos_ijkplayer v2.0.9 鸿蒙平台稳定性与质量提升
ohos_ijkplayer v2.0.9 已发布。本次升级聚焦该库稳定性与质量提升,修复回调引用被提前删除导致的崩溃问题,并全面加固视频录制流程的内存安全与线程生命周期管理,兼容升级,开发者无需修改现有代码即可享受本次改进。推荐所有该库用户升级至本版本。
版本概览
| 类型 | 内容 |
|---|---|
| 稳定性 | 修复回调引用可能被提前删除导致的崩溃问题 #233 |
| 质量提升 | 优化录屏和截图流程 |
稳定性提升
修复回调引用可能被提前删除导致的崩溃问题 #233
问题:在 XComponent Surface 销毁(onSurfaceDestroyedCB)时,IJKPlayerNapi::callBackRefMessage_ 通过 napi_delete_reference 被同步删除,而此前由 messageCallBack 通过 uv_queue_work 投递的 after_message 任务可能仍在 libuv 队列中,并持有指向同一个 callbackRef 的 CallbackContext。当 after_message 在 ref 被删除后执行 napi_get_reference_value(context->env, context->callbackRef, &callback) 时,操作的是已释放的引用,导致崩溃。此外存在多处并发与内存隐患:CallbackContext::obj 为未初始化的裸指针且为浅拷贝(直接指向调用方缓冲区,调用方释放后即悬空);ijkPlayerNapi_ 静态 map 的读写(getInstance、onSurfaceDestroyedCB)无任何锁保护,多线程并发访问存在数据竞争。
修复(ijkplayer/src/main/cpp/napi/ijkplayer_napi.cpp +146/-34、ijkplayer_napi.h +2/-0):
- 新增静态互斥锁
IJKPlayerNapi::mapMutex_,在getInstance、新增的getInstanceLocked及onSurfaceDestroyedCB中以std::lock_guard<std::mutex>保护ijkPlayerNapi_的全部查找/插入/删除,消除数据竞争。 - 在
messageCallBack中对obj改为深拷贝(malloc+memcpy),并将CallbackContext::obj初始化为nullptr,避免悬空指针;新增统一的freeCallbackContext辅助函数(空指针安全,先free(obj)再delete context)集中释放上下文。 - 在
after_message中增加对context、context->env、context->callbackRef的空指针校验,并检查napi_get_reference_value的返回值(napi_status),失败时调用freeCallbackContext释放并提前返回,杜绝对已删除引用的访问。 - 新增
queueRefCleanup机制:onSurfaceDestroyedCB不再同步调用napi_delete_reference,而是把 ref 删除动作以uv_work_t投递到 libuv 事件循环(cleanup_message_ref回调中执行napi_delete_reference),确保 ref 仅在 loop 线程上、待所有挂起的after_message执行完毕后才被删除,从根因上消除竞态。 onSurfaceDestroyedCB重构为“持锁摘除、解锁后清理”:在锁内将callBackRefMessage_/envMessage_取出并置空、从 map 中erase;锁外再调用queueRefCleanup延迟删 ref,并delete实例与ijkPlayerNapiProxy_,避免持锁销毁引发死锁与 use-after-free。
质量提升
优化录屏和截图流程
针对视频录制管线(软解 record_video_frame 与硬解 RecordMediaCodecVideoFrame 共用的帧采集/编码写入路径,截图 is_screenshot 复用同一帧管线)进行系统性加固,解决分辨率切换时录制概率崩溃(关联 issue #377,MR #231)并补齐多处空指针与内存安全缺陷。主要改动文件:ijkplayer/src/main/cpp/ijkplayer/record/ijkplayer_record.cpp(+150/-20)、ff_ffplay.c(+40/-4)、ffpipenode_ohos_mediacodec_vdec.cpp(-3)。
帧率获取安全化:
- 新增
GetSafeRecordFrameRate(FFPlayer*),在调用av_guess_frame_rate前对ffp->is->ic、ffp->is->video_st整条指针链做空指针校验,失败时回退到基于 PTS 的CalculateFrameRate,再回退DEFAULT_FRAME_RATE;替换OpenVideo、VideoAudioStreamAndAvcodecOpen、WriteRecordFile中所有裸av_q2d(av_guess_frame_rate(...))调用。 CalculateFrameRate增加ffp/is/video_st与recordFramesQueue的空指针保护,并校验队列有效后再读取 PTS。
录制帧队列内存修复:
ffp_start_record修复严重分配错误:recordFramesQueue由sizeof(int)改为sizeof(RecordFrameData)(原写法缓冲区严重不足,存在越界风险),分配后memset清零并检查malloc返回值。- 启动新录制前先
pthread_join残留录制线程并重置srcFormat.width/height = 0;释放旧recordFilePath避免泄漏;pthread_create失败时回滚recordFilePath、recordFramesQueue并复位录制状态。
分辨率切换尺寸错乱修复:
- 移除
record_video_frame(软解)与RecordMediaCodecVideoFrame(硬解)中“每帧覆写srcFormat.width/height”的逻辑——该写法在分辨率切换后会用旧尺寸误导编码器。 StartEncoderWrite改用编码器实际尺寸videoCodec->width/height(取自recordWriteData->video_st.st->codec)作为sws输出尺寸,而非易失真的srcFormat,确保分辨率切换后缩放目标正确。
帧写入健壮性:
WriteVideoFrameData增加帧尺寸校验(width/height > 0)、数据缓冲区校验(data0/data1/data2非空)、目标编码帧dstFrame空指针校验,并检查sws_scale返回值,失败时打日志并返回,避免向无效内存写入。record_video_frame增加data0/data1/data2的malloc失败检查与逐项释放。
编码器收尾与线程同步:
- 新增
FlushVideoEncoder/FlushAudioEncoder:在ReleaseResources中先排空编码器残留包(avcodec_encode_video2/avcodec_encode_audio2传 NULL 帧)再av_write_trailer,避免尾帧丢失;并增加fmt空指针校验。 ffp_stop_record增加pthread_join等待录制线程结束,确保资源释放时序正确。FindRecordResult优化:先查ijkplayerRecordResultMap,命中即返回,避免不必要的条件变量等待。
兼容性说明
- 无 Breaking Changes,API 接口保持不变。
- 仅内部实现优化,现有代码无需修改。
- 从 v2.0.8 起升级至 v2.0.9 均为兼容性升级。
升级方式
- 鸿蒙原生:
oh-package.json5→"@ohos/ijkplayer": "^2.0.9",执行ohpm install。
相关链接
- 文档:https://gitcode.com/CPF-ApplicationTPC/ohos_ijkplayer/blob/master/README.md
- CHANGELOG:https://gitcode.com/CPF-ApplicationTPC/ohos_ijkplayer/blob/master/CHANGELOG.md
- 反馈:https://gitcode.com/CPF-ApplicationTPC/ohos_ijkplayer/issues
更多推荐




所有评论(0)