ijkplayer源码---FFPlayer结构体3 SDL_Vout

SDL_Vout顾名思义应该和图像输出有关

SDL_Vout *vout;

我们看下vout那里进行的赋值

IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*))
{

  。。。。。。。
    mp->ffplayer->vout = SDL_VoutAndroid_CreateForAndroidSurface();
    if (!mp->ffplayer->vout)
        goto fail;
  。。。。。。。。
}


我们看下SDL_Vout的定义

ijkmedia/ijksdl/ijksdl_vout.h

typedef struct SDL_Vout SDL_Vout;
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);
    释放SDL_Vout
    void (*free_l)(SDL_Vout *vout);
    显示图层
    int (*display_overlay)(SDL_Vout *vout, SDL_VoutOverlay *overlay);
    图层格式
    Uint32 overlay_format;
};

 SDL_Class       *opaque_class;

我们看到SDL_Class只有一个name

typedef struct SDL_Class {
    const char *name;
} SDL_Class;

SDL_Vout_Opaque *opaque;

Opaque翻译为不透明的, 怎么赋值的呢?

我们进入

SDL_Vout *SDL_VoutAndroid_CreateForAndroidSurface()
{
    return SDL_VoutAndroid_CreateForANativeWindow();
}

ijksdl/android/ijksdl_vout_android_nativewindow.c
SDL_Vout *SDL_VoutAndroid_CreateForANativeWindow()
{
    SDL_Vout *vout = SDL_Vout_CreateInternal(sizeof(SDL_Vout_Opaque));
    if (!vout)
        return NULL;

    SDL_Vout_Opaque *opaque = vout->opaque;
    opaque->native_window = NULL;
    if (ISDL_Array__init(&opaque->overlay_manager, 32))
        goto fail;
    if (ISDL_Array__init(&opaque->overlay_pool, 32))
        goto fail;

    opaque->egl = IJK_EGL_create();
    if (!opaque->egl)
        goto fail;

    vout->opaque_class    = &g_nativewindow_class;
    vout->create_overlay  = func_create_overlay;
    vout->free_l          = func_free_l;
    vout->display_overlay = func_display_overlay;

    return vout;
fail:
    func_free_l(vout);
    return NULL;
}

所以 SDL_Vout_Opaque的定义是在ijkmedia/ijksdl/android/ijksdl_vout_android_nativewindow.c

typedef struct SDL_Vout_Opaque {
    ANativeWindow   *native_window;
    SDL_AMediaCodec *acodec;
    int              null_native_window_warned; // reduce log for null window
    int              next_buffer_id;

    ISDL_Array       overlay_manager;
    ISDL_Array       overlay_pool;

    IJK_EGL         *egl;
} SDL_Vout_Opaque;

SDL_VoutOverlay *(*create_overlay)(int width, int height, int frame_format, SDL_Vout *vout);

而这个函数指针在SDL_VoutAndroid_CreateForANativeWindow中进行了赋值

vout->create_overlay = func_create_overlay;

  
     static SDL_VoutOverlay *func_create_overlay_l(int width, int height, int frame_format, SDL_Vout *vout)
{
    switch (frame_format) {
    case IJK_AV_PIX_FMT__ANDROID_MEDIACODEC:
        return SDL_VoutAMediaCodec_CreateOverlay(width, height, vout);
    default:
        return SDL_VoutFFmpeg_CreateOverlay(width, height, frame_format, vout);
    }
}

可以大致猜到一个硬解码一个软解吗

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);
};

其中有个变量SDL_VoutOverlay_Opaque *opaque;

硬解码的情况下走的是

SDL_VoutAMediaCodec_CreateOverlay(width, height, vout);
ijksdl/android/ijksdl_vout_overlay_android_mediacodec.c 中定义的SDL_VoutOverlay_Opaque
typedef struct SDL_VoutOverlay_Opaque {
    SDL_mutex *mutex;

    SDL_Vout                   *vout;
    SDL_AMediaCodec            *acodec;

    SDL_AMediaCodecBufferProxy *buffer_proxy;

    Uint16 pitches[AV_NUM_DATA_POINTERS];
    Uint8 *pixels[AV_NUM_DATA_POINTERS];
} SDL_VoutOverlay_Opaque;

软解吗的情况下走

SDL_VoutFFmpeg_CreateOverlay
ijksdl/ffmpeg/ijksdl_vout_overlay_ffmpeg.c 中定义的SDL_VoutOverlay_Opaque
struct SDL_VoutOverlay_Opaque {
    SDL_mutex *mutex;

    AVFrame *managed_frame;
    AVBufferRef *frame_buffer;
    int planes;

    AVFrame *linked_frame;

    Uint16 pitches[AV_NUM_DATA_POINTERS];
    Uint8 *pixels[AV_NUM_DATA_POINTERS];

    int no_neon_warned;

    struct SwsContext *img_convert_ctx;
    int sws_flags;
};  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值