当前位置:网站首页>Ijkplayer source code - setting options
Ijkplayer source code - setting options
2022-06-13 02:43:00 【Original general breaking】
In the last section we talked about
if (ffp->mediacodec_all_videos || ffp->mediacodec_avc || ffp->mediacodec_hevc || ffp->mediacodec_mpeg2)mediacodec_all_videos、 mediacodec_avc 、mediacodec_hevc、mediacodec_mpeg2 Where is it set .
Search the entire ijk The code of does not find the setting of the above variable , But I found
static const AVOption ffp_context_options[] = {
......
{ "mediacodec", "MediaCodec: enable H264 (deprecated by 'mediacodec-avc')",
OPTION_OFFSET(mediacodec_avc), OPTION_INT(0, 0, 1) },
{ "mediacodec-auto-rotate", "MediaCodec: auto rotate frame depending on meta",
OPTION_OFFSET(mediacodec_auto_rotate), OPTION_INT(0, 0, 1) },
{ "mediacodec-all-videos", "MediaCodec: enable all videos",
OPTION_OFFSET(mediacodec_all_videos), OPTION_INT(0, 0, 1) },
{ "mediacodec-avc", "MediaCodec: enable H264",
OPTION_OFFSET(mediacodec_avc), OPTION_INT(0, 0, 1) },
{ "mediacodec-hevc", "MediaCodec: enable HEVC",
OPTION_OFFSET(mediacodec_hevc), OPTION_INT(0, 0, 1) },
{ "mediacodec-mpeg2", "MediaCodec: enable MPEG2VIDEO",
OPTION_OFFSET(mediacodec_mpeg2), OPTION_INT(0, 0, 1) },
{ "mediacodec-mpeg4", "MediaCodec: enable MPEG4",
OPTION_OFFSET(mediacodec_mpeg4), OPTION_INT(0, 0, 1) },
......
}What is it? ?
#define OPTION_OFFSET(x) offsetof(FFPlayer, x)
#define OPTION_INT(default__, min__, max__) \
.type = AV_OPT_TYPE_INT, \
{ .i64 = default__ }, \
.min = min__, \
.max = max__, \
.flags = AV_OPT_FLAG_DECODING_PARAMI can probably guess what it means by AvOption To set it up ,OPTION_OFFSET Is to move to FFPlayer Structure of the mediacodec_all_videos, And use AvOption Of value To assign .
Let's see
Creating ffplayer When it comes to the player
const AVClass ffp_context_class = {
.class_name = "FFPlayer",
.item_name = ffp_context_to_name,
.option = ffp_context_options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = ffp_context_child_next,
.child_class_next = ffp_context_child_class_next,
};
FFPlayer *ffp_create()
{
av_log(NULL, AV_LOG_INFO, "av_version_info: %s\n", av_version_info());
av_log(NULL, AV_LOG_INFO, "ijk_version_info: %s\n", ijk_version_info());
FFPlayer* ffp = (FFPlayer*) av_mallocz(sizeof(FFPlayer));
if (!ffp)
return NULL;
msg_queue_init(&ffp->msg_queue);
ffp->af_mutex = SDL_CreateMutex();
ffp->vf_mutex = SDL_CreateMutex();
ffp_reset_internal(ffp);
ffp->av_class = &ffp_context_class;
ffp->meta = ijkmeta_create();
av_opt_set_defaults(ffp);
return ffp;
}
IjkMediaPlayer *ijkmp_create(int (*msg_loop)(void*))
{
IjkMediaPlayer *mp = (IjkMediaPlayer *) mallocz(sizeof(IjkMediaPlayer));
if (!mp)
goto fail;
mp->ffplayer = ffp_create();
if (!mp->ffplayer)
goto fail;
mp->msg_loop = msg_loop;
ijkmp_inc_ref(mp);
pthread_mutex_init(&mp->mutex, NULL);
return mp;
fail:
ijkmp_destroy_p(&mp);
return NULL;
}We see that this creates ffplayer
Let's take a look at
typedef struct FFPlayer {
const AVClass *av_class;
/* ffplay context */
VideoState *is;
/* format/codec options */
AVDictionary *format_opts;
AVDictionary *codec_opts;
AVDictionary *sws_dict;
AVDictionary *player_opts;
AVDictionary *swr_opts;
AVDictionary *swr_preset_opts;
/* ffplay options specified by the user */
#ifdef FFP_MERGE
AVInputFormat *file_iformat;
#endif
char *input_filename;
#ifdef FFP_MERGE
const char *window_title;
int fs_screen_width;
int fs_screen_height;
int default_width;
int default_height;
int screen_width;
int screen_height;
#endif
int audio_disable;
int video_disable;
int subtitle_disable;
const char* wanted_stream_spec[AVMEDIA_TYPE_NB];
int seek_by_bytes;
int display_disable;
int show_status;
int av_sync_type;
int64_t start_time;
int64_t duration;
int fast;
int genpts;
int lowres;
int decoder_reorder_pts;
int autoexit;
#ifdef FFP_MERGE
int exit_on_keydown;
int exit_on_mousedown;
#endif
int loop;
int framedrop;
int64_t seek_at_start;
int subtitle;
int infinite_buffer;
enum ShowMode show_mode;
char *audio_codec_name;
char *subtitle_codec_name;
char *video_codec_name;
double rdftspeed;
#ifdef FFP_MERGE
int64_t cursor_last_shown;
int cursor_hidden;
#endif
#if CONFIG_AVFILTER
const char **vfilters_list;
int nb_vfilters;
char *afilters;
char *vfilter0;
#endif
int autorotate;
int find_stream_info;
unsigned sws_flags;
/* current context */
#ifdef FFP_MERGE
int is_full_screen;
#endif
int64_t audio_callback_time;
#ifdef FFP_MERGE
SDL_Surface *screen;
#endif
/* extra fields */
SDL_Aout *aout;
SDL_Vout *vout;
struct IJKFF_Pipeline *pipeline;
struct IJKFF_Pipenode *node_vdec;
int sar_num;
int sar_den;
char *video_codec_info;
char *audio_codec_info;
char *subtitle_codec_info;
Uint32 overlay_format;
int last_error;
int prepared;
int auto_resume;
int error;
int error_count;
int start_on_prepared;
int first_video_frame_rendered;
int first_audio_frame_rendered;
int sync_av_start;
MessageQueue msg_queue;
int64_t playable_duration_ms;
int packet_buffering;
int pictq_size;
int max_fps;
int startup_volume;
int videotoolbox;
int vtb_max_frame_width;
int vtb_async;
int vtb_wait_async;
int vtb_handle_resolution_change;
int mediacodec_all_videos;
int mediacodec_avc;
int mediacodec_hevc;
int mediacodec_mpeg2;
int mediacodec_mpeg4;
int mediacodec_handle_resolution_change;
int mediacodec_auto_rotate;
int opensles;
int soundtouch_enable;
char *iformat_name;
int no_time_adjust;
double preset_5_1_center_mix_level;
struct IjkMediaMeta *meta;
SDL_SpeedSampler vfps_sampler;
SDL_SpeedSampler vdps_sampler;
/* filters */
SDL_mutex *vf_mutex;
SDL_mutex *af_mutex;
int vf_changed;
int af_changed;
float pf_playback_rate;
int pf_playback_rate_changed;
float pf_playback_volume;
int pf_playback_volume_changed;
void *inject_opaque;
void *ijkio_inject_opaque;
FFStatistic stat;
FFDemuxCacheControl dcc;
AVApplicationContext *app_ctx;
IjkIOManagerContext *ijkio_manager_ctx;
int enable_accurate_seek;
int accurate_seek_timeout;
int mediacodec_sync;
int skip_calc_frame_rate;
int get_frame_mode;
GetImgInfo *get_img_info;
int async_init_decoder;
char *video_mime_type;
char *mediacodec_default_name;
int ijkmeta_delay_init;
int render_wait_start;
} FFPlayer;Let's note that the following fields are
const AVClass *av_class; ( first )
AVDictionary *player_opts;
int mediacodec_all_videos;
Let's now set mediacodec_all_videos
setPlayerOption("mediacodec_all_videos", 1);
CustomIjkMediaPlayer.java
There are the following member functions
public class CustomIjkMediaPlayer extends IjkPlayer {
public CustomIjkMediaPlayer(Context context) {
super(context);
}
/**
* Set up IjkMediaPlayer.OPT_CATEGORY_PLAYER Related configuration
*/
public void setPlayerOption(String name, String value) {
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, name, value);
}
/**
* Set up IjkMediaPlayer.OPT_CATEGORY_PLAYER Related configuration
*/
public void setPlayerOption(String name, long value) {
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, name, value);
}
}public final class IjkMediaPlayer extends AbstractMediaPlayer {
public void setOption(int category, String name, String value)
{
_setOption(category, name, value);
}
public void setOption(int category, String name, long value)
{
_setOption(category, name, value);
}
private native void _setOption(int category, String name, String value);
private native void _setOption(int category, String name, long value);
}Let's see native layer
src\main\jni\ijkmedia\ijkplayer\android\ijkplayer_jni.c
{ "_setOption", "(ILjava/lang/String;Ljava/lang/String;)V", (void *) IjkMediaPlayer_setOption },
{ "_setOption", "(ILjava/lang/String;J)V", (void *) IjkMediaPlayer_setOptionLong },
static void
IjkMediaPlayer_setOptionLong(JNIEnv *env, jobject thiz, jint category, jobject name, jlong value)
{
MPTRACE("%s\n", __func__);
IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
const char *c_name = NULL;
JNI_CHECK_GOTO(mp, env, "java/lang/IllegalStateException", "mpjni: setOptionLong: null mp", LABEL_RETURN);
c_name = (*env)->GetStringUTFChars(env, name, NULL );
JNI_CHECK_GOTO(c_name, env, "java/lang/OutOfMemoryError", "mpjni: setOptionLong: name.string oom", LABEL_RETURN);
ijkmp_set_option_int(mp, category, c_name, value);
LABEL_RETURN:
if (c_name)
(*env)->ReleaseStringUTFChars(env, name, c_name);
ijkmp_dec_ref_p(&mp);
}
The next step is
void ijkmp_set_option_int(IjkMediaPlayer *mp, int opt_category, const char *name, int64_t value)
{
assert(mp);
// MPTRACE("%s(%s, %"PRId64")\n", __func__, name, value);
pthread_mutex_lock(&mp->mutex);
ffp_set_option_int(mp->ffplayer, opt_category, name, value);
pthread_mutex_unlock(&mp->mutex);
// MPTRACE("%s()=void\n", __func__);
}
void ffp_set_option_int(FFPlayer *ffp, int opt_category, const char *name, int64_t value)
{
if (!ffp)
return;
AVDictionary **dict = ffp_get_opt_dict(ffp, opt_category);
av_dict_set_int(dict, name, value, 0);
}
Let's look at
static AVDictionary **ffp_get_opt_dict(FFPlayer *ffp, int opt_category)
{
assert(ffp);
switch (opt_category) {
case FFP_OPT_CATEGORY_FORMAT: return &ffp->format_opts;
case FFP_OPT_CATEGORY_CODEC: return &ffp->codec_opts;
case FFP_OPT_CATEGORY_SWS: return &ffp->sws_dict;
case FFP_OPT_CATEGORY_PLAYER: return &ffp->player_opts;
case FFP_OPT_CATEGORY_SWR: return &ffp->swr_opts;
default:
av_log(ffp, AV_LOG_ERROR, "unknown option category %d\n", opt_category);
return NULL;
}
}
You can know that it is set to player_opts
So let's see player_opts Yes FFPlayer Field settings for
int ffp_prepare_async_l(FFPlayer *ffp, const char *file_name)
{
assert(ffp);
assert(!ffp->is);
assert(file_name);
if (av_stristart(file_name, "rtmp", NULL) ||
av_stristart(file_name, "rtsp", NULL)) {
// There is total different meaning for 'timeout' option in rtmp
av_log(ffp, AV_LOG_WARNING, "remove 'timeout' option for rtmp.\n");
av_dict_set(&ffp->format_opts, "timeout", NULL, 0);
}
/* there is a length limit in avformat */
if (strlen(file_name) + 1 > 1024) {
av_log(ffp, AV_LOG_ERROR, "%s too long url\n", __func__);
if (avio_find_protocol_name("ijklongurl:")) {
av_dict_set(&ffp->format_opts, "ijklongurl-url", file_name, 0);
file_name = "ijklongurl:";
}
}
av_log(NULL, AV_LOG_INFO, "===== versions =====\n");
ffp_show_version_str(ffp, "ijkplayer", ijk_version_info());
ffp_show_version_str(ffp, "FFmpeg", av_version_info());
ffp_show_version_int(ffp, "libavutil", avutil_version());
ffp_show_version_int(ffp, "libavcodec", avcodec_version());
ffp_show_version_int(ffp, "libavformat", avformat_version());
ffp_show_version_int(ffp, "libswscale", swscale_version());
ffp_show_version_int(ffp, "libswresample", swresample_version());
av_log(NULL, AV_LOG_INFO, "===== options =====\n");
ffp_show_dict(ffp, "player-opts", ffp->player_opts);
ffp_show_dict(ffp, "format-opts", ffp->format_opts);
ffp_show_dict(ffp, "codec-opts ", ffp->codec_opts);
ffp_show_dict(ffp, "sws-opts ", ffp->sws_dict);
ffp_show_dict(ffp, "swr-opts ", ffp->swr_opts);
av_log(NULL, AV_LOG_INFO, "===================\n");
av_opt_set_dict(ffp, &ffp->player_opts);
if (!ffp->aout) {
ffp->aout = ffpipeline_open_audio_output(ffp->pipeline, ffp);
if (!ffp->aout)
return -1;
}
#if CONFIG_AVFILTER
if (ffp->vfilter0) {
GROW_ARRAY(ffp->vfilters_list, ffp->nb_vfilters);
ffp->vfilters_list[ffp->nb_vfilters - 1] = ffp->vfilter0;
}
#endif
VideoState *is = stream_open(ffp, file_name, NULL);
if (!is) {
av_log(NULL, AV_LOG_WARNING, "ffp_prepare_async_l: stream_open failed OOM");
return EIJK_OUT_OF_MEMORY;
}
ffp->is = is;
ffp->input_filename = av_strdup(file_name);
return 0;
}We see that av_opt_set_dict(ffp, &ffp->player_opts);
/**
* Set all the options from a given dictionary on an object.
*
* @param obj a struct whose first element is a pointer to AVClass
* @param options options to process. This dictionary will be freed and replaced
* by a new one containing all options not found in obj.
* Of course this new dictionary needs to be freed by caller
* with av_dict_free().
*
* @return 0 on success, a negative AVERROR if some option was found in obj,
* but could not be set.
*
* @see av_dict_copy()
*/
int av_opt_set_dict(void *obj, struct AVDictionary **options);ffp The first field of must be AVContext, We have already satisfied this .
It's just a way of playeropts Set to AVClass Of option, and AVClass Of option again ffp_context_options
Let's see. ffp_context_options So we can be right FFPlayer The field of .
Code awesome , Worth learning .
边栏推荐
猜你喜欢
![[thoughts in the essay] mourn for development technology expert Mao Xingyun](/img/6b/d1ef40855fc5ba8275dc624ed61dc2.jpg)
[thoughts in the essay] mourn for development technology expert Mao Xingyun
![[reading papers] visual convolution zfnet](/img/01/4181f19b2d24b842488522c2001970.jpg)
[reading papers] visual convolution zfnet

Opencvshare4 and vs2019 configuration

微信云开发粗糙理解

Introduction and download of common data sets for in-depth learning (with network disk link)

regular expression

Uni app Foundation
![[data analysis and visualization] key points of data drawing 4- problems of pie chart](/img/e1/618ff53b33b4b1de6acf4942130c17.jpg)
[data analysis and visualization] key points of data drawing 4- problems of pie chart

Matlab: obtain the figure edge contour and divide the figure n equally

JS deconstruction assignment
随机推荐
[data analysis and visualization] key points of data drawing 5- the problem of error line
Traverse the array and delete an element until it is deleted
Implementing fillet in custom dialog
Vant realizes the adaptation of mobile terminal
L1 regularization and its sparsity
[data and Analysis Visualization] D3 introductory tutorial 1-d3 basic knowledge
02 优化微信开发者工具默认的结构
重定向设置参数-RedirectAttributes
C # illustrated tutorial (Fourth Edition) chapter7-7.2 accessing inherited members
vant实现移动端的适配
Leetcode 926. Flip string to monotonically increasing [prefix and]
[common tools] pyautogui tutorial
Ffmpeg principle
Detailed explanation of handwritten numeral recognition based on support vector machine (Matlab GUI code, providing handwriting pad)
Thinking back from the eight queens' question
Change the topic of change tax
[thoughts in the essay] mourn for development technology expert Mao Xingyun
Word splitting problem
too old resource version,Code:410
[data analysis and visualization] key points of data drawing 3- spaghetti map