IJK源码分析-android篇

        整个IJK播放器框架相较于原始ffplay.c播放器,在三处进行了抽象,分别是:
(1)解码器配置初始化操作,对应的数据结构是:
 

struct IJKFF_Pipeline {
    SDL_Class             *opaque_class;
    IJKFF_Pipeline_Opaque *opaque;

    void            (*func_destroy)             (IJKFF_Pipeline *pipeline);
    IJKFF_Pipenode *(*func_open_video_decoder)  (IJKFF_Pipeline *pipeline, FFPlayer *ffp);
    SDL_Aout       *(*func_open_audio_output)   (IJKFF_Pipeline *pipeline, FFPlayer *ffp);
    IJKFF_Pipenode *(*func_init_video_decoder)  (IJKFF_Pipeline *pipeline, FFPlayer *ffp);
    int           (*func_config_video_decoder)  (IJKFF_Pipeline *pipeline, FFPlayer *ffp);
};

在该抽象里针对视频,完成了mediacodec方式解码和软解码的统一接入,对音频实现了opensles的渲染方式和audiotrack方式渲染,这很自然,因为视频的重点是解码,而音频的重点是渲染,当然,不是说视频的渲染不重要,于是有了第二个抽象SDL_Vout。

        对于android平台,该数据结构实际上就是通过接口ffpipeline_create_from_android创建为平台专有的,具体流程是:

IJK源码分析-android篇_第1张图片

(2)视频渲染,对应的数据结构是:

struct SDL_Vout {
    SDL_mutex *mutex;

    SDL_Class       *opaque_class;
    SDL_Vout_Opaque *opaque;
    SDL_VoutOverlay *(*create_overlay)(int width, int height, int frame_format, SDL_Vout *vout);
    void (*free_l)(SDL_Vout *vout);
    int (*display_overlay)(SDL_Vout *vout, SDL_VoutOverlay *overlay);

    Uint32 overlay_output_format;
};
其中SDL_VoutOverlay的定义是:
struct SDL_VoutOverlay {
    int w; /**< Read-only */
    int h; /**< Read-only */
    Uint32 format; /**< Read-only */
    int planes; /**< Read-only */
    Uint16 *pitches; /**< in bytes, Read-only */
    Uint8 **pixels; /**< Read-write */

    int is_private;

    int sar_num;
    int sar_den;

    SDL_Class               *opaque_class;
    SDL_VoutOverlay_Opaque  *opaque;

    void    (*free_l)(SDL_VoutOverlay *overlay);
    int     (*lock)(SDL_VoutOverlay *overlay);
    int     (*unlock)(SDL_VoutOverlay *overlay);
    void    (*unref)(SDL_VoutOverlay *overlay);

    int     (*func_fill_frame)(SDL_VoutOverlay *overlay, const AVFrame *frame);
};

该抽象实现了mediacodec解码器接口surface渲染和opengl方式渲染的统一接入接口。

(3)把从av_read_frame接口返回的packet进行解码,并queue_picture放置到渲染帧队列里去这个过程进行抽象,形成IJKFF_Pipenode:

struct IJKFF_Pipenode {
    SDL_mutex *mutex;
    void *opaque;

    void (*func_destroy) (IJKFF_Pipenode *node);
    int  (*func_run_sync)(IJKFF_Pipenode *node);
    int  (*func_flush)   (IJKFF_Pipenode *node); // optional
};

IJK播放器经过以上三点抽象后,形成与ffplay不同的整体架构:

IJK源码分析-android篇_第2张图片

1,IJK基于mediacodec硬解码的渲染流程

        IJK播放器如果是使用mediacodec硬解码,则是用mediacodec的config接口设置进来的surface直接渲染,实际上并没有将Frame传递给其他模块,若想通过OpenGL方式渲染,走软解渲染一样的流程,则必须进行定制开发。

2,IJK基于软解的渲染流程

    IJK基于软解的渲染是通过OpenGL方式渲染的。

你可能感兴趣的:(android)