H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_endian.h

#ifndef IJKSDL__IJKSDL_ENDIAN_H
#define IJKSDL__IJKSDL_ENDIAN_H

#define SDL_LIL_ENDIAN  1234
#define SDL_BIG_ENDIAN  4321

#ifndef SDL_BYTEORDER           /* Not defined in SDL_config.h? */
#ifdef __linux__
#include <endian.h>
#define SDL_BYTEORDER  __BYTE_ORDER
#else /* __linux __ */
#if defined(__hppa__) || \
    defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
    (defined(__MIPS__) && defined(__MISPEB__)) || \
    defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
    defined(__sparc__)
#define SDL_BYTEORDER   SDL_BIG_ENDIAN
#else
#define SDL_BYTEORDER   SDL_LIL_ENDIAN
#endif
#endif /* __linux __ */
#endif /* !SDL_BYTEORDER */

#endif
定义宏 SDL_BYTEORDER
 
H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_fourcc.h
#ifndef IJKSDL__IJKSDL_FOURCC_H
#define IJKSDL__IJKSDL_FOURCC_H

#include "ijksdl_stdinc.h"
#include "ijksdl_endian.h"

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#   define SDL_FOURCC(a, b, c, d) \
        (((uint32_t)a) | (((uint32_t)b) << 8) | (((uint32_t)c) << 16) | (((uint32_t)d) << 24))
#   define SDL_TWOCC(a, b) \
        ((uint16_t)(a) | ((uint16_t)(b) << 8))
#else
#   define SDL_FOURCC(a, b, c, d) \
        (((uint32_t)d) | (((uint32_t)c) << 8) | (((uint32_t)b) << 16) | (((uint32_t)a) << 24))
#   define SDL_TWOCC( a, b ) \
        ((uint16_t)(b) | ((uint16_t)(a) << 8))
#endif

/*-
 *  http://www.webartz.com/fourcc/indexyuv.htm
 *  http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
 *  http://www.fourcc.org/yuv.php
 */

// YUV formats
#define SDL_FCC_YV12    SDL_FOURCC('Y', 'V', '1', '2')  /**< bpp=12, Planar mode: Y + V + U  (3 planes) */
#define SDL_FCC_IYUV    SDL_FOURCC('I', 'Y', 'U', 'V')  /**< bpp=12, Planar mode: Y + U + V  (3 planes) */
#define SDL_FCC_I420    SDL_FOURCC('I', '4', '2', '0')  /**< bpp=12, Planar mode: Y + U + V  (3 planes) */
#define SDL_FCC_I444P10LE   SDL_FOURCC('I', '4', 'A', 'L')

#define SDL_FCC_YUV2    SDL_FOURCC('Y', 'U', 'V', '2')  /**< bpp=16, Packed mode: Y0+U0+Y1+V0 (1 plane) */
#define SDL_FCC_UYVY    SDL_FOURCC('U', 'Y', 'V', 'Y')  /**< bpp=16, Packed mode: U0+Y0+V0+Y1 (1 plane) */
#define SDL_FCC_YVYU    SDL_FOURCC('Y', 'V', 'Y', 'U')  /**< bpp=16, Packed mode: Y0+V0+Y1+U0 (1 plane) */

#define SDL_FCC_NV12    SDL_FOURCC('N', 'V', '1', '2')

// RGB formats
#define SDL_FCC_RV16    SDL_FOURCC('R', 'V', '1', '6')    /**< bpp=16, RGB565 */
#define SDL_FCC_RV24    SDL_FOURCC('R', 'V', '2', '4')    /**< bpp=24, RGB888 */
#define SDL_FCC_RV32    SDL_FOURCC('R', 'V', '3', '2')    /**< bpp=32, RGBX8888 */

// opaque formats
#define SDL_FCC__AMC    SDL_FOURCC('_', 'A', 'M', 'C')    /**< Android MediaCodec */
#define SDL_FCC__VTB    SDL_FOURCC('_', 'V', 'T', 'B')    /**< iOS VideoToolbox */
#define SDL_FCC__GLES2  SDL_FOURCC('_', 'E', 'S', '2')    /**< let Vout choose format */

// undefine
#define SDL_FCC_UNDF    SDL_FOURCC('U', 'N', 'D', 'F')    /**< undefined */

enum {
    IJK_AV_PIX_FMT__START = 10000,
    IJK_AV_PIX_FMT__ANDROID_MEDIACODEC,
    IJK_AV_PIX_FMT__VIDEO_TOOLBOX,
};

#endif

定义各种颜色格式RGB空间,YUV空间,Android Media Codec. iOS Video Toolbox.

 

H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_thread.h

H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_thread.c

对pthread线程的封装

 

H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_video.h

#ifndef IJKSDL__IJKSDL_VIDEO_H
#define IJKSDL__IJKSDL_VIDEO_H

#include "ijksdl_stdinc.h"
#include "ijksdl_fourcc.h"

#endif

 

H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_vout.h

#ifndef IJKSDL__IJKSDL_VOUT_H
#define IJKSDL__IJKSDL_VOUT_H

#include "ijksdl_stdinc.h"
#include "ijksdl_class.h"
#include "ijksdl_mutex.h"
#include "ijksdl_video.h"
#include "ffmpeg/ijksdl_inc_ffmpeg.h"

typedef struct SDL_VoutOverlay_Opaque SDL_VoutOverlay_Opaque;
typedef struct SDL_VoutOverlay 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);
};

typedef struct SDL_Vout_Opaque SDL_Vout_Opaque;
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);
    void (*free_l)(SDL_Vout *vout);
    int (*display_overlay)(SDL_Vout *vout, SDL_VoutOverlay *overlay);

    Uint32 overlay_format;
};

void SDL_VoutFree(SDL_Vout *vout);
void SDL_VoutFreeP(SDL_Vout **pvout);
int  SDL_VoutDisplayYUVOverlay(SDL_Vout *vout, SDL_VoutOverlay *overlay);
int  SDL_VoutSetOverlayFormat(SDL_Vout *vout, Uint32 overlay_format);

SDL_VoutOverlay *SDL_Vout_CreateOverlay(int width, int height, int frame_format, SDL_Vout *vout);
int     SDL_VoutLockYUVOverlay(SDL_VoutOverlay *overlay);
int     SDL_VoutUnlockYUVOverlay(SDL_VoutOverlay *overlay);
void    SDL_VoutFreeYUVOverlay(SDL_VoutOverlay *overlay);
void    SDL_VoutUnrefYUVOverlay(SDL_VoutOverlay *overlay);
int     SDL_VoutFillFrameYUVOverlay(SDL_VoutOverlay *overlay, const AVFrame *frame);

#endif
#ifndef IJKSDL__IJKSDL_VOUT_H
#define IJKSDL__IJKSDL_VOUT_H

#include "ijksdl_stdinc.h"
#include "ijksdl_class.h"
#include "ijksdl_mutex.h"
#include "ijksdl_video.h"
#include "ffmpeg/ijksdl_inc_ffmpeg.h"

typedef struct SDL_VoutOverlay_Opaque SDL_VoutOverlay_Opaque;
typedef struct SDL_VoutOverlay 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);
};

typedef struct SDL_Vout_Opaque SDL_Vout_Opaque;
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);
    void (*free_l)(SDL_Vout *vout);
    int (*display_overlay)(SDL_Vout *vout, SDL_VoutOverlay *overlay);

    Uint32 overlay_format;
};

void SDL_VoutFree(SDL_Vout *vout);
void SDL_VoutFreeP(SDL_Vout **pvout);
int  SDL_VoutDisplayYUVOverlay(SDL_Vout *vout, SDL_VoutOverlay *overlay);
int  SDL_VoutSetOverlayFormat(SDL_Vout *vout, Uint32 overlay_format);

SDL_VoutOverlay *SDL_Vout_CreateOverlay(int width, int height, int frame_format, SDL_Vout *vout);
int     SDL_VoutLockYUVOverlay(SDL_VoutOverlay *overlay);
int     SDL_VoutUnlockYUVOverlay(SDL_VoutOverlay *overlay);
void    SDL_VoutFreeYUVOverlay(SDL_VoutOverlay *overlay);
void    SDL_VoutUnrefYUVOverlay(SDL_VoutOverlay *overlay);
int     SDL_VoutFillFrameYUVOverlay(SDL_VoutOverlay *overlay, const AVFrame *frame);

#endif
#include "ijksdl_class.h"
定义 SDL_Class
typedef struct SDL_Class {
    const char *name;
} SDL_Class;
#include "ffmpeg/ijksdl_inc_ffmpeg.h"
#ifndef IJKSDL__FFMPEG__IJKSDL_FFINC_H
#define IJKSDL__FFMPEG__IJKSDL_FFINC_H

#include "libavutil/imgutils.h"
#include "libavutil/pixfmt.h"
#include "libavutil/frame.h"
#include "libavutil/common.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"

#include "../ijksdl_inc_internal.h"

#endif

包含 FFmpeg库中的头文件

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

 H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_vout_internal.h

 
#ifndef IJKSDL__IJKSDL_VOUT_INTERNAL_H
#define IJKSDL__IJKSDL_VOUT_INTERNAL_H

#include <stdlib.h>
#include <string.h>
#include "ijksdl_vout.h"

inline static SDL_Vout *SDL_Vout_CreateInternal(size_t opaque_size)
{
    SDL_Vout *vout = (SDL_Vout*) calloc(1, sizeof(SDL_Vout));
    if (!vout)
        return NULL;

    vout->opaque = calloc(1, opaque_size);
    if (!vout->opaque) {
        free(vout);
        return NULL;
    }

    vout->mutex = SDL_CreateMutex();
    if (vout->mutex == NULL) {
        free(vout->opaque);
        free(vout);
        return NULL;
    }

    return vout;
}

inline static void SDL_Vout_FreeInternal(SDL_Vout *vout)
{
    if (!vout)
        return;

    if (vout->mutex) {
        SDL_DestroyMutex(vout->mutex);
    }

    free(vout->opaque);
    memset(vout, 0, sizeof(SDL_Vout));
    free(vout);
}

inline static SDL_VoutOverlay *SDL_VoutOverlay_CreateInternal(size_t opaque_size)
{
    SDL_VoutOverlay *overlay = (SDL_VoutOverlay*) calloc(1, sizeof(SDL_VoutOverlay));
    if (!overlay)
        return NULL;

    overlay->opaque = calloc(1, opaque_size);
    if (!overlay->opaque) {
        free(overlay);
        return NULL;
    }
    return overlay;
}

inline static void SDL_VoutOverlay_FreeInternal(SDL_VoutOverlay *overlay)
{
    if (!overlay)
        return;

    if (overlay->opaque)
        free(overlay->opaque);

    memset(overlay, 0, sizeof(SDL_VoutOverlay));
    free(overlay);
}

#endif
SDL_VoutOverlay 和 SDL_Vout的创建和释放函数.

H:\code\ijkplayer-android\ijkmedia\ijksdl\ijksdl_vout.c
#include "ijksdl_vout.h"
#include <stdlib.h>

#include <assert.h>
#if defined(__ANDROID__)
// 引入
ANativeWindow *  ANativeWindow_fromSurface (JNIEnv *env, jobject surface)

#include
<android/native_window_jni.h> #endif void SDL_VoutFree(SDL_Vout *vout) { if (!vout) return; if (vout->free_l) { vout->free_l(vout); } else { free(vout); } } void SDL_VoutFreeP(SDL_Vout **pvout) { if (!pvout) return; SDL_VoutFree(*pvout); *pvout = NULL; } int SDL_VoutDisplayYUVOverlay(SDL_Vout *vout, SDL_VoutOverlay *overlay) { if (vout && overlay && vout->display_overlay) return vout->display_overlay(vout, overlay); return -1; } int SDL_VoutSetOverlayFormat(SDL_Vout *vout, Uint32 overlay_format) { if (!vout) return -1; vout->overlay_format = overlay_format; return 0; } SDL_VoutOverlay *SDL_Vout_CreateOverlay(int width, int height, int frame_format, SDL_Vout *vout) { if (vout && vout->create_overlay) return vout->create_overlay(width, height, frame_format, vout); return NULL; } int SDL_VoutLockYUVOverlay(SDL_VoutOverlay *overlay) { if (overlay && overlay->lock) return overlay->lock(overlay); return -1; } int SDL_VoutUnlockYUVOverlay(SDL_VoutOverlay *overlay) { if (overlay && overlay->unlock) return overlay->unlock(overlay); return -1; } void SDL_VoutFreeYUVOverlay(SDL_VoutOverlay *overlay) { if (!overlay) return; if (overlay->free_l) { overlay->free_l(overlay); } else { free(overlay); } } void SDL_VoutUnrefYUVOverlay(SDL_VoutOverlay *overlay) { if (overlay && overlay->unref) overlay->unref(overlay); } int SDL_VoutFillFrameYUVOverlay(SDL_VoutOverlay *overlay, const AVFrame *frame) { if (!overlay || !overlay->func_fill_frame) return -1; return overlay->func_fill_frame(overlay, frame); }

SDL_Vout 由 

SDL_VoutAndroid_CreateForAndroidSurface函数创建
函数调用流程
IjkMediaPlayer_native_setup --> ijkmp_android_create -->  SDL_VoutAndroid_CreateForAndroidSurface --> 
SDL_VoutAndroid_CreateForANativeWindow
 
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;

    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;
}
SDL_Vout *SDL_VoutAndroid_CreateForAndroidSurface()
{
    return SDL_VoutAndroid_CreateForANativeWindow();
}
// H:\code\ijkplayer-android\ijkmedia\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; }

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;