ijkplayer

作者: 一川烟草i蓑衣 | 来源:发表于2019-05-28 11:20 被阅读0次

IjkMediaPlayer:入口类

https://blog.csdn.net/wangxiuwen12/article/details/84556860

结构为:

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; //面定义了很多种播放状态,比如,MP_STATE_IDLE ,MP_STATE_INITIALIZED,MP_STATE_ASYNC_PREPARING。ijkmp_change_state_l 函数专门用来改变mp_state 状态值

    char*data_source; //存储应用层传入的播放url

    void*weak_thiz;

int restart;

int restart_from_beginning;

int seek_req; //记录是否调用了ijkplayer.c里的ijkmp_seek_to

long seek_msec;//记录ijkmp_seek_to 要拖动到第几毫秒值

};

创建时机为:

IJKFFMoviePlayerController->initWithContentURLString:withOptions:{

IJKWeakHolder *weakHolder = [IJKWeakHolder new]; //保存了IJKFFMoviePlayerController的weak指针

 weakHolder.object= self;

 ijkmp_set_weak_thiz(_mediaPlayer, (__bridge_retained void*) self);//将IJKFFMoviePlayerController对象赋值给_mediaPlayer的weak_thiz属性

 ijkmp_set_inject_opaque(_mediaPlayer, (__bridge_retained void*) weakHolder); //将weakHolder赋值给_mediaPlayer->ffplayer的inject_opaque属性

 ijkmp_set_ijkio_inject_opaque(_mediaPlayer, (__bridge _retained void*)weakHolder); //将weakHolder赋值给_mediaPlayer->ffplayer的ijkio_inject_opaque属性,这个函数会调用ijkio_manager_create创建_mediaPlayer->ffplayer的(IjkIOManagerContext *)ijkio_manager_ctx属性,ijkio_manager_create内部会创建ijkio_manager_ctx的(IjkIOApplicationContext *)ijkio_app_ctx属性

}

ffmplay:属于IjkMediaPlayer对象,ijkplayer实际上是基于ffplay.c实现的

typedef struct FFPlayer {

  /* ffplay context */

    VideoState *is;

    void              *inject_opaque;

    void              *ijkio_inject_opaque;

 IjkIOManagerContext*ijkio_manager_ctx;

}

//VideoState也就代表着视频当前的状态,包括帧,数据,解码器等等

typedefs truct VideoState {

     SDL_Thread*read_tid; //视频读取数据线程

    SDL_Thread _read_tid;

   FrameQueue pictq;//解码后队列-视频

    FrameQueue sampq;//解码后队列-音频

 PacketQueue audioq;//解码前队列-视频

PacketQueue videoq;//解码前队列-音频

  SDL_Thread*video_refresh_tid; //视频刷新线程,负责显示

    SDL_Thread _video_refresh_tid;

}

SDL_Vout:属于ffmplay对象,图像渲染对象

IJKFF_Pipeline:属于ffmplay对象,包括视频解码以及音频输出部分

播放流程:

当外部调用prepareToPlay启动播放后,ijkplayer内部最终会调用到ffplay.c中的

int ffp_prepare_async_l(FFPlayer *ffp,const char*file_name)

该方法是启动播放器的入口函数,在此会设置player选项,打开audio output,最重要的是调用stream_open方法。

stream_open主要做了以下几件事情:

创建存放video/audio解码前数据的videoq/audioq

创建存放video/audio解码后数据的pictq/sampq

创建读数据线程read_thread

创建视频渲染线程video_refresh_thread

说明:subtitle是与video、audio平行的一个stream,ffplay中也支持对它的处理,即创建存放解码前后数据的两个queue,并且当文件中存在subtitle时,还会启动subtitle的解码线程

ffplay.c中主要的代码调用流程:

调用流程

显示过程:

IJKSDLGLView:核心显示类,包含CAEAGLLayer和framebuffer

- (void)display: (SDL_VoutOverlay*) overlay :每帧绘制

IJKSDLGLView属性:IJK_GLES2_Renderer盛放了opengl属性,在renderer文件内根据overlay->format创建

rgb565-用16位,2个字节表示rgb;rgb888-用24位,3个字节表示rgb;

avformat_open_input:

探测协议类型,如果是网络文件则创建网络链接等

假如url是:ijkio:cache:ffio:http://cdnup.huoying666.com/video/20190530/3411e912ba3ed1173070ad212899b560/3411e.mp4

ijkio是注册到ffmpge系统的私有协议,avformat_open_input方法会调用到ijkio的ijkio_open(URLContext *h)方法,h的prot属性是ijkio结构体

 Context *c = h->priv_data;//取出Context

 IjkIOManagerContext *manager_ctx = (IjkIOManagerContext *)(c->io_manager_ctx);//取出io_manager_ctx

 IjkURLContext *inner = NULL;

 ijkio_alloc_url(&inner, url); //alloc inner,inner的protprot是ijkio_cache_protocol,inner的priv_data是IjkIOCacheContext,IjkIOCacheContext也有一个IjkURLContext属性它的protrot是ijkffio,可以以此类推ijkioffio

 ijk_map_put(h->ijk_ctx_map, (int64_t)(intptr_t)h->cur_ffmpeg_ctx, inner);//h为上面取出的io_manager_ctx,将io_manager_ctx的cur_ffmpeg_ctx和inner关联,

会调用到ijkio_open这个方法,而cache:ffio:http://cdnup.huoying666.com/video/20190530/3411e912ba3ed1173070ad212899b560/3411e.mp4是ijk自己的协议IjkURLProtocol,最终会调用ijkio_alloc_url(),这个方法又会根据自己的协议来进行调用

相关文章

网友评论

      本文标题:ijkplayer

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