ijkplayer加速播放
生活随笔
收集整理的這篇文章主要介紹了
ijkplayer加速播放
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最新在寫一個公司的直播類項目,要求視頻播放延遲200毫秒以內,采用kcp協議,ijkplayer做接收端的播放器,ijkplayer加速播放的地方做個記錄,以免自己忘記
修改ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c里的
static int ffplay_video_thread這個方法
static int ffplay_video_thread(void *arg) {FFPlayer *ffp = arg;VideoState *is = ffp->is;AVFrame *frame = av_frame_alloc();double pts;double duration;int ret;AVRational tb = is->video_st->time_base;AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);int64_t dst_pts = -1;int64_t last_dst_pts = -1;int retry_convert_image = 0;int convert_frame_count = 0;#if CONFIG_AVFILTERAVFilterGraph *graph = avfilter_graph_alloc();AVFilterContext *filt_out = NULL, *filt_in = NULL;int last_w = 0;int last_h = 0;enum AVPixelFormat last_format = -2;int last_serial = -1;int last_vfilter_idx = 0;if (!graph) {av_frame_free(&frame);return AVERROR(ENOMEM);}#elseffp_notify_msg2(ffp, FFP_MSG_VIDEO_ROTATION_CHANGED, ffp_get_video_rotate_degrees(ffp)); #endifif (!frame) { #if CONFIG_AVFILTERavfilter_graph_free(&graph); #endifreturn AVERROR(ENOMEM);}for (;;) {ret = get_video_frame(ffp, frame);if (ret < 0)goto the_end;if (!ret)continue;if (ffp->get_frame_mode) {if (!ffp->get_img_info || ffp->get_img_info->count <= 0) {av_frame_unref(frame);continue;}last_dst_pts = dst_pts;if (dst_pts < 0) {dst_pts = ffp->get_img_info->start_time;} else {dst_pts += (ffp->get_img_info->end_time - ffp->get_img_info->start_time) / (ffp->get_img_info->num - 1);}pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);pts = pts * 1000;if (pts >= dst_pts) {while (retry_convert_image <= MAX_RETRY_CONVERT_IMAGE) {ret = convert_image(ffp, frame, (int64_t)pts, frame->width, frame->height);if (!ret) {convert_frame_count++;break;}retry_convert_image++;av_log(NULL, AV_LOG_ERROR, "convert image error retry_convert_image = %d\n", retry_convert_image);}retry_convert_image = 0;if (ret || ffp->get_img_info->count <= 0) {if (ret) {av_log(NULL, AV_LOG_ERROR, "convert image abort ret = %d\n", ret);ffp_notify_msg3(ffp, FFP_MSG_GET_IMG_STATE, 0, ret);} else {av_log(NULL, AV_LOG_INFO, "convert image complete convert_frame_count = %d\n", convert_frame_count);}goto the_end;}} else {dst_pts = last_dst_pts;}av_frame_unref(frame);continue;}#if CONFIG_AVFILTERif ( last_w != frame->width|| last_h != frame->height|| last_format != frame->format|| last_serial != is->viddec.pkt_serial|| ffp->vf_changed|| last_vfilter_idx != is->vfilter_idx) {SDL_LockMutex(ffp->vf_mutex);ffp->vf_changed = 0;av_log(NULL, AV_LOG_DEBUG,"Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",last_w, last_h,(const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,frame->width, frame->height,(const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);avfilter_graph_free(&graph);graph = avfilter_graph_alloc();if ((ret = configure_video_filters(ffp, graph, is, ffp->vfilters_list ? ffp->vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {// FIXME: post errorSDL_UnlockMutex(ffp->vf_mutex);goto the_end;}filt_in = is->in_video_filter;filt_out = is->out_video_filter;last_w = frame->width;last_h = frame->height;last_format = frame->format;last_serial = is->viddec.pkt_serial;last_vfilter_idx = is->vfilter_idx;frame_rate = av_buffersink_get_frame_rate(filt_out);SDL_UnlockMutex(ffp->vf_mutex);}ret = av_buffersrc_add_frame(filt_in, frame);if (ret < 0)goto the_end;while (ret >= 0) {is->frame_last_returned_time = av_gettime_relative() / 1000000.0;ret = av_buffersink_get_frame_flags(filt_out, frame, 0);if (ret < 0) {if (ret == AVERROR_EOF)is->viddec.finished = is->viddec.pkt_serial;ret = 0;break;}is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)is->frame_last_filter_delay = 0;tb = av_buffersink_get_time_base(filt_out); #endif//獲取緩存的packets,因為我們不需要緩存,這里加速播int64_t video_cache_packets= ffp->stat.video_cache.packets;//每秒是30幀,有緩沖的時候,120 四倍的播放速率if(video_cache_packets>=2){frame_rate.num=120;}//沒有緩存的時候,按正常29幀的速率來播放if(video_cache_packets==0){frame_rate.num=29;}duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);//超過5幀,1幀播放0.005秒if(video_cache_packets>=5){duration=0.005;}pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);ret = queue_picture(ffp, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);av_frame_unref(frame); #if CONFIG_AVFILTER} #endifif (ret < 0)goto the_end;}the_end: #if CONFIG_AVFILTERavfilter_graph_free(&graph); #endifav_log(NULL, AV_LOG_INFO, "convert image convert_frame_count = %d\n", convert_frame_count);av_frame_free(&frame);return 0; }在
//獲取緩存的packets,因為我們不需要緩存,這里加速播
這里做修改
總結
以上是生活随笔為你收集整理的ijkplayer加速播放的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery FlexSlider插件一
- 下一篇: AppInventor学习笔记:幸运抽奖