美文网首页
ijkplayer分析一:初始化

ijkplayer分析一:初始化

作者: 九流程序员_風 | 来源:发表于2019-01-16 19:17 被阅读0次
    new IjkMediaPlayer();
    

    IjkMediaPlayer.java中初始化方法:

    public IjkMediaPlayer() {
       this(sLocalLibLoader);
    }
    

    调用

    public IjkMediaPlayer(IjkLibLoader libLoader) {
        //初始化player
        initPlayer(libLoader);
    }
    
    private void initPlayer(IjkLibLoader libLoader) {
        loadLibrariesOnce(libLoader);//加载native库,注册静态方法
        initNativeOnce();
        Looper looper;
        if ((looper = Looper.myLooper()) !=null) {
            mEventHandler =new EventHandler(this, looper);
        }else if ((looper = Looper.getMainLooper()) !=null) {
            mEventHandler =new EventHandler(this, looper);
        }else {
            mEventHandler =null;
        }
        native_setup(new WeakReference<IjkMediaPlayer>(this));//弱引用给到native层用
    }
    

    加载native库

    public static void loadLibrariesOnce(IjkLibLoader libLoader) {
        synchronized (IjkMediaPlayer.class) {
            if (!mIsLibLoaded) {
                if (libLoader ==null)
                    libLoader =sLocalLibLoader;
                    libLoader.loadLibrary("ijkffmpeg");
                    libLoader.loadLibrary("ijksdl");
                    libLoader.loadLibrary("ijkplayer");
                    mIsLibLoaded =true;
            }
        }
    }
    

    ijkplayer_jni.c:
    当去加载native库时,会调用JNI_OnLoad方法:

    JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved){
        JNIEnv* env = NULL;
        g_jvm = vm;
        if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
            return -1;
        }
        assert(env != NULL);
        pthread_mutex_init(&g_clazz.mutex, NULL );
        // FindClass returns LocalReference
        IJK_FIND_JAVA_CLASS(env, g_clazz.clazz, JNI_CLASS_IJKPLAYER);
        (*env)->RegisterNatives(env, g_clazz.clazz, g_methods, NELEM(g_methods) );//注册静态方法
        ijkmp_global_init();//注册编解码器,网络一些初始化工作
        ijkmp_global_set_inject_callback(inject_callback);//设置回调
        FFmpegApi_global_init(env);//注册base64编码方法
        return JNI_VERSION_1_4;
    }
    

    ijkplayer.c: ijkmp_global_init():

    void ijkmp_global_init()
    {
        ffp_global_init();
    }
    

    ff_ffplayer.c : ffp_global_init():

    void ffp_global_init(){
        if (g_ffmpeg_global_inited)//如果初始过了,返回
            return;
        ALOGD("ijkmediaplayer version : %s", ijkmp_version());
        /* register all codecs, demux and protocols */
        avcodec_register_all();//注册编解码器
    #if CONFIG_AVDEVICE
        avdevice_register_all();//注册设备
    #endif
    #if CONFIG_AVFILTER
        avfilter_register_all();//注册滤镜,用于图像处理,音频重采样处理等
    #endif
        av_register_all();//注册,包括编解码器以及网络其他等
        ijkav_register_all();//注册网络协议
        avformat_network_init();
        av_lockmgr_register(lockmgr);
        av_log_set_callback(ffp_log_callback_brief);
        av_init_packet(&flush_pkt);
        flush_pkt.data = (uint8_t *)&flush_pkt;
        g_ffmpeg_global_inited =true;
    }
    

    native_setup(new WeakReference<IjkMediaPlayer>(this));
    ijkplayer_jni.c:IjkMediaPlayer_native_setup();

    static void IjkMediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
    {
        MPTRACE("%s\n", __func__);
        IjkMediaPlayer *mp = ijkmp_android_create(message_loop);//创建IjkMediaPlayer指针
        JNI_CHECK_GOTO(mp, env, "java/lang/OutOfMemoryError", "mpjni: native_setup: ijkmp_create() failed", LABEL_RETURN);
    
        jni_set_media_player(env, thiz, mp);//把旧的player释放掉,设置新的player
        ijkmp_set_weak_thiz(mp, (*env)->NewGlobalRef(env, weak_this));//设置全局弱引用player
        ijkmp_set_inject_opaque(mp, ijkmp_get_weak_thiz(mp));//设置AVApplication
        ijkmp_set_ijkio_inject_opaque(mp, ijkmp_get_weak_thiz(mp));//设置io
        ijkmp_android_set_mediacodec_select_callback(mp, mediacodec_select_callback, ijkmp_get_weak_thiz(mp));//设置编码回调
    
    LABEL_RETURN:
        ijkmp_dec_ref_p(&mp);
    }
    

    IjkMediaPlayer *mp = ijkmp_android_create(message_loop)
    ijkplayer_android.c:

    IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*))
    {
        //创建播放器
        IjkMediaPlayer *mp = ijkmp_create(msg_loop);
        if (!mp)
            goto fail;
        //创建渲染输出对象
        mp->ffplayer->vout = SDL_VoutAndroid_CreateForAndroidSurface();
        if (!mp->ffplayer->vout)
            goto fail;
        //创建pipeline,视频编解码器,音频输出
        mp->ffplayer->pipeline = ffpipeline_create_from_android(mp->ffplayer);
        if (!mp->ffplayer->pipeline)
            goto fail;
    
        ffpipeline_set_vout(mp->ffplayer->pipeline, mp->ffplayer->vout);
    
        return mp;
    
    fail:
        ijkmp_dec_ref_p(&mp);
        return NULL;
    }
    

    IjkMediaPlayer *mp = ijkmp_create(msg_loop);
    ijkplayer.c

    IjkMediaPlayer *ijkmp_create(int (*msg_loop)(void*))
    {
        IjkMediaPlayer *mp = (IjkMediaPlayer *) mallocz(sizeof(IjkMediaPlayer));
        if (!mp)
            goto fail;
        mp->ffplayer = ffp_create();
        if (!mp->ffplayer)
            goto fail;
    
        mp->msg_loop = msg_loop;
    
        ijkmp_inc_ref(mp);
        pthread_mutex_init(&mp->mutex, NULL);
    
        return mp;
    
        fail:
        ijkmp_destroy_p(&mp);
        return NULL;
    }
    

    mp->ffplayer = ffp_create();
    ff_ffplay.c:

    FFPlayer *ffp_create()
    {
        av_log(NULL, AV_LOG_INFO, "av_version_info: %s\n", av_version_info());
        av_log(NULL, AV_LOG_INFO, "ijk_version_info: %s\n", ijk_version_info());
    
        FFPlayer* ffp = (FFPlayer*) av_mallocz(sizeof(FFPlayer));
        if (!ffp)
            return NULL;
    
        msg_queue_init(&ffp->msg_queue);
        ffp->af_mutex = SDL_CreateMutex();
        ffp->vf_mutex = SDL_CreateMutex();
    
        ffp_reset_internal(ffp);
        ffp->av_class = &ffp_context_class;
        ffp->meta = ijkmeta_create();
    
        av_opt_set_defaults(ffp);
    
        return ffp;
    }
    

    涉及到到结构体:
    IjkMediaPlayer,在ijkplayer_internal.h中:

    struct IjkMediaPlayer {
        volatile int ref_count;
        pthread_mutex_t mutex;
        FFPlayer *ffplayer;
    
        int (*msg_loop)(void*);
        SDL_Thread *msg_thread;
        SDL_Thread _msg_thread;
    
        int mp_state;
        char *data_source;
        void *weak_thiz;
    
        int restart;
        int restart_from_beginning;
        int seek_req;
        long seek_msec;
    };
    

    FFPlayer结构体,在ff_ffplay_def.h中:

    typedef struct FFPlayer {
        const AVClass *av_class;
    
        /* ffplay context */
        VideoState *is;
    
        /* format/codec options */
        AVDictionary *format_opts;
        AVDictionary *codec_opts;
        AVDictionary *sws_dict;
        AVDictionary *player_opts;
        AVDictionary *swr_opts;
        AVDictionary *swr_preset_opts;
    
        /* ffplay options specified by the user */
    #ifdef FFP_MERGE
        AVInputFormat *file_iformat;
    #endif
        char *input_filename;
    #ifdef FFP_MERGE
        const char *window_title;
        int fs_screen_width;
        int fs_screen_height;
        int default_width;
        int default_height;
        int screen_width;
        int screen_height;
    #endif
        int audio_disable;
        int video_disable;
        int subtitle_disable;
        const char* wanted_stream_spec[AVMEDIA_TYPE_NB];
        int seek_by_bytes;
        int display_disable;
        int show_status;
        int av_sync_type;
        int64_t start_time;
        int64_t duration;
        int fast;
        int genpts;
        int lowres;
        int decoder_reorder_pts;
        int autoexit;
    #ifdef FFP_MERGE
        int exit_on_keydown;
        int exit_on_mousedown;
    #endif
        int loop;
        int framedrop;
        int64_t seek_at_start;
        int subtitle;
        int infinite_buffer;
        enum ShowMode show_mode;
        char *audio_codec_name;
        char *subtitle_codec_name;
        char *video_codec_name;
        double rdftspeed;
    #ifdef FFP_MERGE
        int64_t cursor_last_shown;
        int cursor_hidden;
    #endif
    #if CONFIG_AVFILTER
        const char **vfilters_list;
        int nb_vfilters;
        char *afilters;
        char *vfilter0;
    #endif
        int autorotate;
        int find_stream_info;
        unsigned sws_flags;
    
        /* current context */
    #ifdef FFP_MERGE
        int is_full_screen;
    #endif
        int64_t audio_callback_time;
    #ifdef FFP_MERGE
        SDL_Surface *screen;
    #endif
    
        /* extra fields */
        SDL_Aout *aout;
        SDL_Vout *vout;
        struct IJKFF_Pipeline *pipeline;
        struct IJKFF_Pipenode *node_vdec;
        int sar_num;
        int sar_den;
    
        char *video_codec_info;
        char *audio_codec_info;
        char *subtitle_codec_info;
        Uint32 overlay_format;
    
        int last_error;
        int prepared;
        int auto_resume;
        int error;
        int error_count;
        int start_on_prepared;
        int first_video_frame_rendered;
        int first_audio_frame_rendered;
        int sync_av_start;
    
        MessageQueue msg_queue;
    
        int64_t playable_duration_ms;
    
        int packet_buffering;
        int pictq_size;
        int max_fps;
        int startup_volume;
    
        int videotoolbox;
        int vtb_max_frame_width;
        int vtb_async;
        int vtb_wait_async;
        int vtb_handle_resolution_change;
    
        int mediacodec_all_videos;
        int mediacodec_avc;
        int mediacodec_hevc;
        int mediacodec_mpeg2;
        int mediacodec_mpeg4;
        int mediacodec_handle_resolution_change;
        int mediacodec_auto_rotate;
    
        int opensles;
        int soundtouch_enable;
    
        char *iformat_name;
    
        int no_time_adjust;
        double preset_5_1_center_mix_level;
    
        struct IjkMediaMeta *meta;
    
        SDL_SpeedSampler vfps_sampler;
        SDL_SpeedSampler vdps_sampler;
    
        /* filters */
        SDL_mutex  *vf_mutex;
        SDL_mutex  *af_mutex;
        int         vf_changed;
        int         af_changed;
        float       pf_playback_rate;
        int         pf_playback_rate_changed;
        float       pf_playback_volume;
        int         pf_playback_volume_changed;
    
        void               *inject_opaque;
        void               *ijkio_inject_opaque;
        FFStatistic         stat;
        FFDemuxCacheControl dcc;
    
        AVApplicationContext *app_ctx;
        IjkIOManagerContext *ijkio_manager_ctx;
    
        int enable_accurate_seek;
        int accurate_seek_timeout;
        int mediacodec_sync;
        int skip_calc_frame_rate;
        int get_frame_mode;
        GetImgInfo *get_img_info;
        int async_init_decoder;
        char *video_mime_type;
        char *mediacodec_default_name;
        int ijkmeta_delay_init;
        int render_wait_start;
    }
    

    相关文章

      网友评论

          本文标题:ijkplayer分析一:初始化

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