ijkplayer程序结构整理

整个程序的结构从文件:

ijkplayer_jni.c开始:

参照:

static JNINativeMethod g_methods[] = {

......

}

 

一、在JNI_OnLoad()/ijkplayer_jni.c 调用ijkmp_global_init()/ff_ffplay.c完成ffmpeg的初始化,调用FFmpegApi_global_init()/ffmpeg_api_jni.c中完成g_methods中函数的注册

 

二、IjkMediaPlayer_native_init()/ijkplayer_jni.c 为空

 

三、IjkMediaPlayer_native_setup()/ijkplayer_jni.c

1.ijkmp_android_create()/ijkplayer_jni.c

1.1. 创建相应的结构并设置消息处理函数ijkmp_android_create()/ijkplayer_android.c--->message_loop()/ijkplayer_jni.c--->message_loop_n()/ijkplayer_jni.c

2.ijkmp_create()/ijkplayer_android.c

3.ffpipeline_create_from_android()/ffpipeline_android.c

{

......

pipeline->func_open_video_decoder= func_open_video_decoder;

......

}

4.

staticIJKFF_Pipenode *func_open_video_decoder(IJKFF_Pipeline *pipeline, FFPlayer*ffp)

{

    IJKFF_Pipeline_Opaque *opaque =pipeline->opaque;

    IJKFF_Pipenode        *node = NULL;

 

    if (ffp->mediacodec) //根据是否设置mediacodec参数决定是否启用硬解码

        node =ffpipenode_create_video_decoder_from_android_mediacodec(ffp, pipeline,opaque->weak_vout);

    if (!node) {

        node =ffpipenode_create_video_decoder_from_ffplay(ffp);

    }

 

    return node;

}

 

 

四、IjkMediaPlayer_setVideoSurface() //设置surface

1.IjkMediaPlayer_setVideoSurface()/ijkplayer_jni.c

2.ijkmp_android_set_surface()/ijkplayer_android.c

3.ijkmp_android_set_surface_l()/ijkplayer_android.c

     3.1.SDL_VoutAndroid_SetAndroidSurface()/ijkplayer_android.c-->SDL_VoutAndroid_SetAndroidSurface()/ijksdl_vout_android_surface.c--->SDL_VoutAndroid_SetNativeWindow()/ijksdl_vout_android_nativewindow.c--->SDL_VoutAndroid_SetNativeWindow_l()/ijksdl_vout_android_nativewindow.c

   3.2.ffpipeline_set_surface()/ffpipeline_android.c

 

 

五、IjkMediaPlayer_prepareAsync() //初始化

1. IjkMediaPlayer_prepareAsync()/ijkplayer_jni.c

2. ijkmp_prepare_async()/ijkplayer.c

3. ijkmp_prepare_async_l()/ijkplayer.c

4.mp->msg_thread = SDL_CreateThreadEx(&mp->_msg_thread,mp->msg_loop, mp, "ff_msg_loop"); 创建相应的消息处理线程

5.ffp_prepare_async_l()/ff_ffplay.c

6.stream_open()/ff_ffplayer.c

{

......

is->video_refresh_tid= SDL_CreateThreadEx(&is->_video_refresh_tid, video_refresh_thread, ffp,"ff_vout");  //启用相应的显示线程

......

 

}

 

6.1.video_refresh_thread()/ff_ffplay.c

6.2.ffpipenode_run_sync()/ff_ffpipenode.c

 

6.3.staticint func_run_sync(IJKFF_Pipenode *node)

{

    IJKFF_Pipenode_Opaque *opaque =node->opaque;

 

    returnffp_video_refresh_thread(opaque->ffp);

}//ffpipenode_ffplay_vout.c

 

6.4.int ffp_video_refresh_thread(FFPlayer*ffp)

{

    return ffplay_video_refresh_thread(ffp);

}//ff_ffplay.c

 

 

 

 

 

 

6.5.video_refresh()/ff_ffplay.c

6.6.video_display2()/ff_ffplay.c

6.7.video_image_display2()/ff_ffplay.c

{

......

SDL_VoutDisplayYUVOverlay(ffp->vout,vp->bmp);  //显示相应的数据

......

}

 

7.stream_open()/ff_ffplayer.c

{

......

is->read_tid= SDL_CreateThreadEx(&is->_read_tid, read_thread, ffp,"ff_read"); //创建读线程

......

 

}

 

staticint read_thread(void *arg)

{

......

stream_component_open()

......

ret = av_read_frame(ic,pkt);

......

//ifaudio

packet_queue_put(&is->audioq,pkt);

......

//ifvideo

packet_queue_put(&is->videoq,pkt);

......

 

}

 

staticint stream_component_open(FFPlayer *ffp, int stream_index)

{

......

//ifaudio 创建audio解码线程

decoder_start(&is->auddec,audio_thread, ffp, "ff_audio_dec");

//ifvideo 创建video解码线程

decoder_start(&is->viddec,video_thread, ffp, "ff_video_dec");

}

 

 

8.//声音解码线程

staticint audio_thread(void *arg)

{

......

if((got_frame = decoder_decode_frame(ffp, &is->auddec, frame, NULL)) <0)

......

frame_queue_push(&is->sampq);

......

}  //

 

 

9.//视频解码线程

staticint video_thread(void *arg)

{

    FFPlayer *ffp = (FFPlayer *)arg;

    int      ret = 0;

 

    if (ffp->node_vdec) {

        ret =ffpipenode_run_sync(ffp->node_vdec);

    }

    return ret;

}  //ff_ffplay.c

 

intffpipenode_run_sync(IJKFF_Pipenode *node)

{

    return node->func_run_sync(node);  //此处区分软硬解码部分

}  //ff_ffpipenode.c

 

//软解码部分

staticint func_run_sync(IJKFF_Pipenode *node)

{

    IJKFF_Pipenode_Opaque *opaque = node->opaque;

    return ffp_video_thread(opaque->ffp);

}  //ffpipenode_ffplay_vdec.c

 

intffp_video_thread(FFPlayer *ffp)

{

    return ffplay_video_thread(ffp);

}  //ff_ffplay.c

 

 

 

 

 

staticint ffplay_video_thread(void *arg)

{

......

    for (;;) {

        ret = get_video_frame(ffp, frame);

......

ret =queue_picture(ffp, frame, pts, duration, av_frame_get_pkt_pos(frame),is->viddec.pkt_serial);

......

}  //ff_ffplay.c

 

staticint get_video_frame(FFPlayer *ffp, AVFrame *frame)

{

    VideoState *is = ffp->is;

    int got_picture;

 

    if ((got_picture =decoder_decode_frame(ffp, &is->viddec, frame, NULL)) < 0) //解码相应的视频数据

        return -1;

......

}//ff_ffplay.c

 

 

//硬解码部分

staticint func_run_sync(IJKFF_Pipenode *node)

{

......

opaque->enqueue_thread= SDL_CreateThreadEx(&opaque->_enqueue_thread, enqueue_thread_func,node, "amediacodec_input_thread"); //创建线程处理解析后的视频数据送到硬解码器去解码

......

 

}//ffpipenode_android_mediacodec_vdec.c

 

 

staticint enqueue_thread_func(void *arg)

{

......

ret =feed_input_buffer(env, node, AMC_INPUT_TIMEOUT_US, &dequeue_count);

......

}//ffpipenode_android_mediacodec_vdec.c

 

 

 

 

 

 

staticint feed_input_buffer(JNIEnv *env, IJKFF_Pipenode *node, int64_t timeUs, int*enqueue_count)

{

......

if(ffp_packet_queue_get_or_buffering(ffp, d->queue, &pkt,&d->pkt_serial, &d->finished) < 0) { //取得相应的packet

......

input_buffer_ptr= SDL_AMediaCodec_getInputBuffer(opaque->acodec, input_buffer_index,&input_buffer_size); //得到硬解码器的 inputbuffer地址

......

memcpy(input_buffer_ptr,d->pkt_temp.data, copy_size); //拷入相应的数据

......

amc_ret= SDL_AMediaCodec_queueInputBuffer(opaque->acodec, input_buffer_index, 0,copy_size, time_stamp, 0); //送到解码器去解码

......

}//ffpipenode_android_mediacodec_vdec.c

 

 

intffp_packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt,int *serial, int *finished)

{

    return packet_queue_get_or_buffering(ffp,q, pkt, serial, finished);

}//ff_ffplay.c

 

staticint packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt,int *serial, int *finished)

{

......

intnew_packet = packet_queue_get(q, pkt, 0, serial);  //获取解析之后的视频数据AVPacket

......

}//ff_ffplay.c

 

staticint func_run_sync(IJKFF_Pipenode *node)

{

.....

opaque->enqueue_thread= SDL_CreateThreadEx(&opaque->_enqueue_thread, enqueue_thread_func,node, "amediacodec_input_thread");

......

ret =drain_output_buffer(env, node, timeUs, &dequeue_count); //获取硬解码之后的数据

......

}//ffpipenode_android_mediacodec_vdec.c

staticint drain_output_buffer(JNIEnv *env, IJKFF_Pipenode *node, int64_t timeUs, int*dequeue_count)

{

......

int ret= drain_output_buffer_l(env, node, timeUs, dequeue_count);

......

}//ffpipenode_android_mediacodec_vdec.c

 

 

staticint drain_output_buffer_l(JNIEnv *env, IJKFF_Pipenode *node, int64_t timeUs,int *dequeue_count)

{

......

output_buffer_index= SDL_AMediaCodec_dequeueOutputBuffer(opaque->acodec, &bufferInfo,timeUs); //获取解码后的视频数据

...

ret =amc_queue_picture_buffer(node, output_buffer_index, &bufferInfo); //插入到显示队列

......

}//ffpipenode_android_mediacodec_vdec.c

 

staticint amc_queue_picture_buffer()

{

......

returnamc_queue_picture(node, opaque->acodec, output_buffer_index, buffer_info,pts, duration, 0, is->viddec.pkt_serial);

}

 

六、IjkMediaPlayer_start()//设置开始后的各种状态

staticvoid

IjkMediaPlayer_start(JNIEnv*env, jobject thiz)

{

......

ijkmp_start(mp);

......

}//ijkplayer_jni.c

 

intijkmp_start(IjkMediaPlayer *mp)

{

......

intretval = ijkmp_start_l(mp);

......

}//ijkplayer_jni.c

 

 

staticint ijkmp_start_l(IjkMediaPlayer *mp)

{

......

MP_RET_IF_FAILED(ikjmp_chkst_start_l(mp->mp_state));

......

}

 

七、IjkMediaPlayer_stop()//设置停止状态

IjkMediaPlayer_stop()//ijkplayer_jni.c--->ijkmp_stop()//ijkplayer_jni.c--->ijkmp_stop_l()//ijkplayer.c

 

八、IjkMediaPlayer_seekTo()//发送seek消息及相应的时间信息

IjkMediaPlayer_seekTo()//ijkplayer_jni.c--->ijkmp_seek_to()//ijkplayer.c--->ijkmp_seek_to_l()//ijkplayer.c

intijkmp_seek_to_l(IjkMediaPlayer *mp, long msec)

{

......

ffp_notify_msg2(mp->ffplayer,FFP_REQ_SEEK, (int)msec);

......

}

 

九、IjkMediaPlayer_pause()//设置播放器暂停

IjkMediaPlayer_pause()//ijkplayer_jni.c--->ijkmp_pause()//ijkplayer.c--->ijkmp_pause_l()//ijkplayer.c

staticint ijkmp_pause_l(IjkMediaPlayer *mp)

{

......

ffp_notify_msg1(mp->ffplayer,FFP_REQ_PAUSE);

......

}

 

十、IjkMediaPlayer_isPlaying()//查询播放器状态

IjkMediaPlayer_isPlaying()//ijkplayer_jni.c--->ijkmp_is_playing()//ijkplayer.c

 

 

十一、IjkMediaPlayer_getCurrentPosition()//得到当前已经播放的时间

IjkMediaPlayer_getCurrentPosition()//ijkplayer_jni.c--->ijkmp_get_current_position()//ijkplayer.c--->ijkmp_get_current_position_l()//ijkplayer.c--->ffp_get_current_position_l()//ff_ffplay.c

 

十二、IjkMediaPlayer_getDuration()//得到播放文件总时长

IjkMediaPlayer_getDuration()//ijkplayer_jni.c--->ijkmp_get_duration()//ijkplayer.c--->ijkmp_get_duration_l()//ijkplayer.c--->ffp_get_duration_l()//ff_ffplay.c

 

 

十三、IjkMediaPlayer_release()//播放器退出处理

IjkMediaPlayer_release()//ijkplayer_jni.c

{

......

ijkmp_android_set_surface(env,mp, NULL ); //surface置空

ijkmp_shutdown(mp);

......

}

 

ijkmp_shutdown()//ijkplayer.c--->ijkmp_shutdown_l()//ijkplayer.c--->ffp_stop_l()//ff_ffplay.c

intffp_stop_l(FFPlayer *ffp)

{

......

if (is)

    is->abort_request = 1; //设置退出标志

......

}

 

十四、IjkMediaPlayer_reset()//播放器重置

staticvoid IjkMediaPlayer_reset(JNIEnv *env, jobject thiz)

{

......

    IjkMediaPlayer_release(env, thiz);  //播放器退出

    IjkMediaPlayer_native_setup(env, thiz,weak_thiz); //新建播放器

......

}

 

十五、IjkMediaPlayer_setVolume()//设置音量

IjkMediaPlayer_setVolume()//ijkplayer_jni.c--->ijkmp_android_set_volume()//ijkplayer_android.c

voidijkmp_android_set_volume(JNIEnv *env, IjkMediaPlayer *mp, float left, floatright)

{

......

SDL_AoutSetStereoVolume(mp->ffplayer->aout,left, right);

......

}

 

十六、IjkMediaPlayer_native_finalize()//调用release函数

staticvoid IjkMediaPlayer_native_finalize(JNIEnv *env, jobject thiz, jobject name,jobject value)

{

    MPTRACE("%s\n", __func__);

    IjkMediaPlayer_release(env, thiz);

}

 

 

十七、IjkMediaPlayer_setOption()//设置播放器参数

IjkMediaPlayer_setOption()//ijkplayer_jni.c--->ijkmp_set_option()//ijkplayer.c--->ffp_set_option()//ff_ffplay.c--->av_dict_set()

 

十八、IjkMediaPlayer_setOptionLong()//设置长整形参数

IjkMediaPlayer_setOptionLong()//ijkplayer_jni.c--->ijkmp_set_option_int()//ijkplayer.c--->ffp_set_option_int()//ff_ffplay.c--->av_dict_set_int()

 

十九、IjkMediaPlayer_getColorFormatName()//颜色格式转换

IjkMediaPlayer_getColorFormatName()//ijkplayer_jni.c--->SDL_AMediaCodec_getColorFormatName()//ijksdl_codec_android_mediadef.c

 

二十、IjkMediaPlayer_getVideoCodecInfo()//获取视频信息

IjkMediaPlayer_getVideoCodecInfo()//ijkplayer_jni.c--->ijkmp_get_video_codec_info()//ijkplayer.c--->ffp_get_video_codec_info()//ff_ffplay.c

 

二十一、IjkMediaPlayer_getAudioCodecInfo()//获取音频信息

IjkMediaPlayer_getAudioCodecInfo()//ijkplayer_jni.c--->ijkmp_get_audio_codec_info()//ijkplayer.c--->ffp_get_audio_codec_info()//ff_ffplay.c

 

二十二、IjkMediaPlayer_getMediaMeta()//获取指定文件的额外参数

IjkMediaPlayer_getMediaMeta()//ijkplayer_jni.c--->ijkmp_get_meta_l()//ijkplayer.c--->ffp_get_meta_l()//ff_ffplay.c

 

二十三、IjkMediaPlayer_native_profileBegin()//调用指定的动态库

 

二十四、IjkMediaPlayer_native_profileEnd()//释放动态库

 

二十五、IjkMediaPlayer_native_setLogLevel()//设置log级别

IjkMediaPlayer_native_setLogLevel()//ijkplayer_jni.c--->ijkmp_global_set_log_level()//ijkplayer.c--->ffp_global_set_log_level()//ff_ffplay.c-->av_log_set_level()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值