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;