播放一段时间后字幕会偶尔不更新显示
这个问题还是挺严重的大佬,之前跟我另外一个问题给你一起反馈过了,之前说过我想要打印内嵌字幕,现在我自己引入你的源码改好了,但现在这个字幕偶尔一两句漏掉没有成功刷新的bug实在太严重了,看视频有时候字幕老是漏刷新,源码我看了好久也根本不知道从哪里改好,希望能提高优先度先修复这个bug吧,视频只要播一段时间,字幕就会偶尔一两句漏掉没有成功刷新...,或者给个思路能不能跟我说你源码哪里是处理这段的逻辑,我自己看看能不能找到问题把他改了然后提交个分支给你?
问题截图+示例文件+示例字幕的文件我重新单独给你发一下: https://1drv.ms/f/c/1fa0162b1b6471cf/EjEZCixF_49Ag5YCJtBRYw8Bbb0C0eXjsYnWBalm2cXDww?e=hgYr90 测试设备iphone12跟14
好的,我抽空看下。 字幕这块的基本思路是开辟一个线程预先渲染,等到播放视频时根据时间戳找到合适的字幕,然后打包生成纹理,最后一并渲染。
好的,我抽空看下。 字幕这块的基本思路是开辟一个线程预先渲染,等到视频时间根据播放时间找到合适的字幕,然后分配生成纹理,最后并渲染。
好的,感谢大佬
好的,我抽空看下。 字幕这块的基本思路是开辟一个线程预先渲染,等到播放视频时根据时间戳找到合适的字幕,然后打包生成纹理,最后一并渲染。
找了挺久,错误大概是这样,字幕在这个函数就报错了:
Frame *sp = frame_queue_peek_writable_noblock(com->frameq);
if (!sp) {
ff_subtitle_buffer_release(&buffer);
result = -7;
break;
}
原因是执行frame_queue_peek_writable_noblock的时候,f->size还是没有更新,导致无法触发f->size >= f->max_size
Frame *frame_queue_peek_writable_noblock(FrameQueue *f)
{
SDL_LockMutex(f->mutex);
if (f->size >= f->max_size || f->pktq->abort_request) {
SDL_UnlockMutex(f->mutex);
return NULL;
}
SDL_UnlockMutex(f->mutex);
return &f->queue[f->windex];
}
f->size的值继续追踪,找到frame_queue_next,发现rindex_shown这个值不会及时变空导致这里没办法执行size的递减函数
void frame_queue_next(FrameQueue *f)
{
if (f->keep_last && !f->rindex_shown) {
f->rindex_shown = 1;
return;
}
Frame *frame = &f->queue[f->rindex];
double du = frame->duration;
frame_queue_unref_item(frame);
if (++f->rindex == f->max_size)
f->rindex = 0;
SDL_LockMutex(f->mutex);
f->size--;
f->duration -= du;
SDL_CondSignal(f->cond);
SDL_UnlockMutex(f->mutex);
}
现在找不到rindex_shown在什么时候重置,希望大佬帮忙看一下
好的,我抽空看下。 字幕这块的基本思路是开辟一个线程预先渲染,等到播放视频时根据时间戳找到合适的字幕,然后打包生成纹理,最后一并渲染。
今天周末又针对这个问题排查了很久,现在我确定是在frame_queue_peek_writable_noblock这个函数,我把它修改成同步的函数frame_queue_peek_writable就没问题了,代价就是刷出去重新进来,画面会卡住! frame_queue_peek_writable_noblock这个地方我找不到更上一级,目前知道了触发这个字幕问题,是因为字幕还没渲染(写的太慢/读的太快),这个异步的函数就开始去取下一条字幕,结果导致f->size永远==f->max_size,感觉真的太复杂了,异步的状态下,建议不要搞末位递增,而是判断消耗完毕之后,一次性再加载16条字幕进来似乎比较合理。
使用noblock的方法是故意的,具体原因我看看代码,一时想不起来了。消耗完了再读16个怕来不急加载。