h5网站有哪些,网站需求清单,网站建设合同内容与结构,个人建网站步骤一开始我尝试是通过设置ijkplayer的参数去修改延迟#xff0c;参数的修改能把ijkplayer的开播延迟拉到200ms左右#xff0c;但是随着播放时间增加延迟也在增加#xff0c;然后带着问题去网上寻找答案#xff0c;找到暴走大牙和Gongjia两位大神的解决方案#xff0c;但是这…一开始我尝试是通过设置ijkplayer的参数去修改延迟参数的修改能把ijkplayer的开播延迟拉到200ms左右但是随着播放时间增加延迟也在增加然后带着问题去网上寻找答案找到暴走大牙和Gongjia两位大神的解决方案但是这种方案仅适用于带有音频流的现在适配的流仅有视频流用了这两位的方案后丢帧是可以但是延迟的问题并没有解决因为没有音频流的视频的时间基准是用视频流的时间丢完帧后视频会卡顿等待视频的时间基准。后来我在ijkplayer的issue上找了很多关于卡顿的问题都没有找到解决方案后面尝试通过变速的方式去解决这个问题找到了Mr_xkHuang的一篇ijkplayer-音视频变速播放实现才了解到了单视频流的视频和有音视频流的视频关于时间基准的差别。修改了时间基准之后长时直播的延迟问题解决了。ff_ffplay.c代码修改如下static int read_thread(void *arg){.....if (st_index[AVMEDIA_TYPE_AUDIO] 0) {stream_component_open(ffp,st_index[AVMEDIA_TYPE_AUDIO]);} else {//添加新代码ffp-av_sync_type AV_SYNC_EXTERNAL_CLOCK;//注释掉原有代码// ffp-av_sync_type AV_SYNC_VIDEO_MASTER;is-av_sync_type ffp-av_sync_type;}.....}经过上面的修改长时放置直播软解码延迟稳定在400ms左右硬解码延迟稳定在200ms左右但是出现了一个更加严重的问题那就是闪退代码会在renderer_yuv420sp_vtb.m这个类static GLboolean yuv420sp_vtb_uploadTexture(IJK_GLES2_Renderer *renderer, SDL_VoutOverlay *overlay){.....}这个方法内的随机几行代码奔溃报的错误是EXC_BAD_ACCESS通过打开僵尸对象检测发现是CVPixelBufferRef pixel_buffer这个对象的原因然后通过和一个做c语言的大神沟通后他告诉我要从对象初始化和查对象被释放这两个地方入手。经过一番查找找到pixel_buffer是通过SDL_VoutOverlay *overlay这个类拿到的然后我就在ijksdl_vout_overlay_videotoolbox.m这个类的overlay的初始化方法里面加了SDL_VoutOverlay *SDL_VoutVideoToolBox_CreateOverlay(int width, int height, SDL_Vout *display){...//addif (opaque-pixel_buffer ! NULL) {CVBufferRelease(opaque-pixel_buffer);}opaque-pixel_buffer NULL;return overlay;}当时我是用的模拟器测试的结果很美好没有闪退了年轻的我以为bug已经解决了但是我想用真机测试下延迟问题时突然发现闪退依然存在。然后我就继续去找还有没有哪里有使用pixel_buffer这个结构体的。但是仅有创建pixel_buffer的ijksdl_vout_overlay_videotoolbox.m和使用pixel_buffer的renderer_yuv420sp_vtb.m这两个类使用了pixel_buffer一时间大神给的方向找不到路了。后面我考虑到既然是EXC_BAD_ACCESS那么久应该是野指针的问题我就冲这个方向入手在使用pixel_buffer的地方对这个结构体进行retain操作增加它的引用计数使它不被释放结果是有一点用处奔溃的概率降低了以前1-5分钟就会奔溃的代码现在可以到20-30分钟奔溃这让我以为找到了一条正确的路结果确实我把引用计数增加做到了极致仍然会有闪退。这时候我知道我是找错了方向之后想到pixel_buffer是通过解码后的frame数据转换而来的有没有可能是frame被释放了导致pixel_buffer这个结构体内部的指针形成野指针。带着这样的疑问我开始打印所有释放frame的地方结果真的找到了每次奔溃的时候都连着调用了两次释放frame。后面我顺着这个释放的流程将渲染与释放的各个地方按上打印终于理清楚了ijkplayer渲染的流程。通过对这里流程的理清楚我发现终于找到了为什么会发生这样的问题,既然知道了是由于在渲染之前frame就被释放了这样就好解决问题了。整体是frame在还么有进行渲染就进行了引用释放释放后frame在进行渲染时就会导致上面的情况我的最终如下修改对ijksdl_vout.h 文件overlay的定义位置添加了一个属性struct SDL_VoutOverlay {//addbool nowUseing;//当前是否还在使用中}然后在ijksdl_vout_overlay_videotoolbox.m这个类中//这是overlay的frame数据重载方法static int func_fill_frame(SDL_VoutOverlay *overlay, const AVFrame *frame){//add// printf(new func_fill_frame :%p\n,overlay);if (overlay-NowUseing) {//如果当前frame正在使用中就不进行数据加载// printf(nowUsing want new func_fill_frame:%p\n,overlay);return 1;}overlay-nowUseing true;//数据重载后将overlay的使用状态置为true....}//overlay的初始化方法SDL_VoutOverlay *SDL_VoutVideoToolBox_CreateOverlay(int width, int height, SDL_Vout *display){.....//addoverlay-nowUseing false;//初始化nowUsing//初始化pixel_bufferif (opaque-pixel_buffer ! NULL) {CVBufferRelease(opaque-pixel_buffer);}opaque-pixel_buffer NULL;return overlay;}在renderer_yuv420sp_vtb.m这个类中//渲染的方法static GLboolean yuv420sp_vtb_uploadTexture(IJK_GLES2_Renderer *renderer, SDL_VoutOverlay *overlay){//addif (!overlay-nowUseing) {return GL_FALSE;}.....//add// printf(display over:%p\n,overlay);overlay-nowUseing false;return GL_TRUE;}在ff_ffplay.c这个类中//这是item的引用释放方法修改为如果该frame还没有渲染这不释放引用。static void frame_queue_unref_item(Frame *vp){//添加这行防止刚启动APP或者切换前后台bmp为nullbmp-nowUseing闪退if (!vp-bmp) {av_frame_unref(vp-frame);vp-frame NULL;SDL_VoutUnrefYUVOverlay(vp-bmp);avsubtitle_free(vp-sub);return;}if (vp-bmp-nowUseing) {printf(nowUsing wait av_frame_unref:%p\n,vp-bmp);}else {// printf(SDL_VoutUnrefYUVOverlay(vp-bmp):%p\n,vp-bmp);av_frame_unref(vp-frame);vp-frame NULL;SDL_VoutUnrefYUVOverlay(vp-bmp);avsubtitle_free(vp-sub);}}这个解决办法并不完美只是粗暴的处理不让程序崩溃我觉得最好的解决办法应该是找到为什么overlay会在使用前释放。然后让这种情况不再出现。最近没有时间去处理这个问题后面有时间了再来解决。