ijkplayer硬件解码分析
总流程图:1
2
3
4
5
6
7
8
9
10stream_component_open() ->
ffpipeline_open_video_decoder() ->
func_open_video_decoder() ->
ffpipenode_create_video_decoder_from_android_mediacodec() ->
reconfigure_codec_l() \----> SDL_AMediaFormatJava_createVideoFormat()
\----> create_codec_l() -> SDL_AMediaCodecJava_createByCodecName() ->
\
\----> SDL_AMediaCodec_configure_surface() ->
func_configure_surface()[SDL_AMediaCodecJava_configure_surface()] ->
jmid_configure()[configure(MediaFormat format, Surface surface, MediaCrypto crypto, int flags) java]
ff_ffplay.c 中stream_component_open()打开video stream.
调用
ffpipeline_open_video_decoder()调用
func_open_video_decoder()1
2
3
4
5
6
7
8
9
10
11
12static IJKFF_Pipenode *func_open_video_decoder(IJKFF_Pipeline *pipeline, FFPlayer *ffp)
{
IJKFF_Pipeline_Opaque *opaque = pipeline->opaque;
IJKFF_Pipenode *node = NULL;
if (opaque->mediacodec_enabled) //mediacodec_enabled可以在Java代码中设置以开启硬件解码. 由此处进入libstagefright的ACodec
node = ffpipenode_create_video_decoder_from_android_mediacodec(ffp, pipeline, opaque->weak_vout);
if (!node) //如果失败则进入ffmpeg的软件解码
node = ffpipenode_create_video_decoder_from_ffplay(ffp);
return node;
}首先通过SDL_AMediaFormatJava_createVideoFormat()调用 MediaFormat.java中的createVideoFormat()来配置各种metadata.然后在create_codec_l()中通过
SDL_AMediaCodecJava_createByCodecName()或者SDL_AMediaCodecJava_createDecoderByType()调用MediaCodec.java的createByCodecName()或者createDecoderByType().
Media
1 | SDL_AMediaFormat *SDL_AMediaFormatJava_createVideoFormat(JNIEnv *env, const char *mime, int width, int height) |