美文网首页Android开发杂记
关于编译android ijkplayer遇到的问题

关于编译android ijkplayer遇到的问题

作者: 浅吟且行的时光 | 来源:发表于2019-03-01 10:19 被阅读3次

    1. 执行./init-android.sh git拉取出错

    
    error: RPC failed; curl 18 transfer closed with outstanding read data remaining 
    fatal: The remote end hung up unexpectedly
    fatal: early EOF
    fatal: index-pack failed```
    
    ----- 解决方法 -----
    配置git缓冲区大小,命令行输入:git config --global http.postBuffer 2124288000
    查看设置参数输入:git config --list
    

    2.执行./init-android.sh遇到的问题

    error: RPC failed; curl 56 SSLRead() return error -9806.42 MiB/s     
    fatal: The remote end hung up unexpectedly
    fatal: early EOF
    fatal: index-pack failed
    error: Could not fetch origin
    

    ----- 解决方法 -----
    安装命令行输入:ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    3.执行./compile-ffmpeg.sh all出错

    IJK_NDK_REL=19.0.4442982
    You need the NDKr10e or later
    

    ----- 解决方法 -----
    使用的ndk版本过高,使用低版本的

    4.支持rtsp协议

    • 修改module-lite.s 件 录:~/config/module-lite.sh 将这 :
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtp"
    

    替换为:

    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
    
    • 接着在下面添加上:
      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-
      demuxer=rtsp"
      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-
      protocol=tcp"
      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-
      decoder=mjpeg"
      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-
      demuxer=mjpeg"
    

    5. 解决延时大问题(优化后延时400毫秒左右)

    • ~/ijkmedia/ijkplayer/ff_ffplay.c文件中 将这一方法:
    static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue
    *q, AVPacket *pkt, int *serial, int *finished)
    {
    assert(finished);
    if (!ffp->packet_buffering)
    return packet_queue_get(q, pkt, 1, serial); while (1) {
    int new_packet = packet_queue_get(q, pkt, 0, serial); if (new_packet < 0)
    return -1;
    else if (new_packet == 0) {
    if (q->is_buffer_indicator && !*finished) ffp_toggle_buffering(ffp, 1);
    new_packet = packet_queue_get(q, pkt, 1, serial); if (new_packet < 0)
    return -1; }
    if (*finished == *serial) { av_packet_unref(pkt); continue;
    }
    else break;
    }
    return 1; }
    
    

    替换为:

    static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue
    *q, AVPacket *pkt, int *serial, int *finished){
    if (!ffp->packet_buffering)
    return packet_queue_get(q, pkt, 1, serial);
    while (1) {
    int new_packet = packet_queue_get(q, pkt, 1, serial); if (new_packet < 0){
    new_packet = packet_queue_get(q, pkt, 0, serial); if(new_packet < 0)
    return -1;
    }else if (new_packet == 0) {
    if (q->is_buffer_indicator && !*finished) ffp_toggle_buffering(ffp, 1);
    new_packet = packet_queue_get(q, pkt, 1, serial); if (new_packet < 0)
    return -1; }
    if (*finished == *serial) { av_packet_unref(pkt); continue;
    }
    else break;
    }
    return 1; }
    
    • ~/ijkmedia/ijkplayer/ff_ffplay.c```文件中 修改这一方法为:
    static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
        //注释的源代码
        /*if (vp->serial == nextvp->serial) {
            double duration = nextvp->pts - vp->pts;
            if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
                return vp->duration;
            else
                return duration;
        } else {
            return 0.0;
        }*/
        //新增代码
        return vp->duration;
    }
    
    • ~/ijkmedia/ijkplayer/ff_ffplay.c```文件中 修改这一方法为:
    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_AVFILTER
        AVFilterGraph *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);
        }
    
    #else
        ffp_notify_msg2(ffp, FFP_MSG_VIDEO_ROTATION_CHANGED, ffp_get_video_rotate_degrees(ffp));
    #endif
    
        if (!frame) {
    #if CONFIG_AVFILTER
            avfilter_graph_free(&graph);
    #endif
            return 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_AVFILTER
            if (   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 error
                    SDL_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   
                //注释的代码
                //duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
                //新增代码
                duration=0.01;
                //////////
                
                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
            }
    #endif
    
            if (ret < 0)
                goto the_end;
        }
     the_end:
    #if CONFIG_AVFILTER
        avfilter_graph_free(&graph);
    #endif
        av_log(NULL, AV_LOG_INFO, "convert image convert_frame_count = %d\n", convert_frame_count);
        av_frame_free(&frame);
        return 0;
    }
    
    • 编译后的Demo工程中setOption
    ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);
    ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 0);
    

    6. 执行./init-android.sh git拉取源码慢,几kb/s

    • 修改host文件,添加:
    # Github
    151.101.185.194 github.global.ssl.fastly.net 192.30.253.112 github.com
    151.101.112.133 assets-cdn.github.com 151.101.184.133 assets-cdn.github.com 185.199.108.153 documentcloud.github.com 192.30.253.118 gist.github.com 185.199.108.153 help.github.com 192.30.253.120 nodeload.github.com 151.101.112.133 raw.github.com
    23.21.63.56 status.github.com
    192.30.253.1668 training.github.com 192.30.253.112 www.github.com
    151.101.13.194 github.global.ssl.fastly.net 151.101.12.133 avatars0.githubusercontent.com 151.101.112.133 avatars1.githubusercontent.com
    
    • 使用电信宽带

    相关文章

      网友评论

        本文标题:关于编译android ijkplayer遇到的问题

        本文链接:https://www.haomeiwen.com/subject/pavruqtx.html