Ejemplo n.º 1
0
void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
{
    int i;
    void *priv_ctx=NULL;
    if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
        AVCodecContext *avctx= ctx;
        if(codec && codec->priv_class && avctx->priv_data){
            priv_ctx= avctx->priv_data;
        }
    } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
        AVFormatContext *avctx = ctx;
        if (avctx->oformat && avctx->oformat->priv_class) {
            priv_ctx = avctx->priv_data;
        }
    }

    for(i=0; i<opt_name_count; i++){
        char buf[256];
        const AVOption *opt;
        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
        if(str && ((opt->flags & flags) == flags))
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
        /* We need to use a differnt system to pass options to the private context because
           it is not known which codec and thus context kind that will be when parsing options
           we thus use opt_values directly instead of opts_ctx */
        if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){
            av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL);
        }
    }
}
Ejemplo n.º 2
0
int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
    avcodec_get_context_defaults2(s, codec ? codec->type : AVMEDIA_TYPE_UNKNOWN);
    if(codec && codec->priv_data_size){
        if(!s->priv_data){
            s->priv_data= av_mallocz(codec->priv_data_size);
            if (!s->priv_data) {
                return AVERROR(ENOMEM);
            }
        }
        if(codec->priv_class){
            *(AVClass**)s->priv_data= codec->priv_class;
            av_opt_set_defaults(s->priv_data);
        }
    }
    if (codec && codec->defaults) {
        int ret;
        AVCodecDefault *d = codec->defaults;
        while (d->key) {
            ret = av_set_string3(s, d->key, d->value, 0, NULL);
            av_assert0(ret >= 0);
            d++;
        }
    }
    return 0;
}
Ejemplo n.º 3
0
static int opt_default2(const char *opt, const char *arg)
{
    const AVOption *o;
    if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
        if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
            av_dict_set(&video_opts, opt, arg, FLAGS);
        if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
            av_dict_set(&audio_opts, opt, arg, FLAGS);
        if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
            av_dict_set(&sub_opts, opt, arg, FLAGS);
    } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
        av_dict_set(&format_opts, opt, arg, FLAGS);
    else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
        // XXX we only support sws_flags, not arbitrary sws options
        int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
            return ret;
        }
    }

    if (!o) {
        SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM,    video_opts)
        SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM,    audio_opts)
        SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts)
    }

    if (o)
        return 0;
    fprintf(stderr, "Unrecognized option '%s'\n", opt);
    return AVERROR_OPTION_NOT_FOUND;
}
Ejemplo n.º 4
0
int opt_default(const char *opt, const char *arg)
{
    const AVOption *oc, *of, *os;
    char opt_stripped[128];
    const char *p;
    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc;

    if (!(p = strchr(opt, ':')))
        p = opt + strlen(opt);
    av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));

    if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
         ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
          (oc = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
        av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
    if ((of = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
        av_dict_set(&format_opts, opt, arg, FLAGS(of));
#if CONFIG_SWSCALE
    sc = sws_get_class();
    if ((os = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
        // XXX we only support sws_flags, not arbitrary sws options
        int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
            return ret;
        }
    }
#endif

    if (oc || of || os)
        return 0;
    av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
    return AVERROR_OPTION_NOT_FOUND;
}
Ejemplo n.º 5
0
static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
{
	char name[128];
	char *param;
	const AVOption *rv = NULL;

	PRINT("FFMPEG expert option: %s: ", prop->name);

	BLI_strncpy(name, prop->name, sizeof(name));

	param = strchr(name, ':');

	if (param) {
		*param++ = 0;
	}

	switch (prop->type) {
		case IDP_STRING:
			PRINT("%s.\n", IDP_String(prop));
			av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
			break;
		case IDP_FLOAT:
			PRINT("%g.\n", IDP_Float(prop));
			rv = av_set_double(c, prop->name, IDP_Float(prop));
			break;
		case IDP_INT:
			PRINT("%d.\n", IDP_Int(prop));

			if (param) {
				if (IDP_Int(prop)) {
					av_set_string3(c, name, param, 1, &rv);
				}
				else {
					return;
				}
			}
			else {
				rv = av_set_int(c, prop->name, IDP_Int(prop));
			}
			break;
	}

	if (!rv) {
		PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
	}
}
Ejemplo n.º 6
0
static int opt_default(const char *opt, const char *arg,
        AVCodecContext *avctx, int type) {
    int ret = 0;
    const AVOption *o = av_find_opt(avctx, opt, NULL, type, type);
    if (o != NULL) {
        ret = av_set_string3(avctx, opt, arg, 1, NULL);
    }
    return ret;
}
Ejemplo n.º 7
0
static int open_input(struct variant *var)
{
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    if (seg->key_type == KEY_NONE) {
        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ);
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        int ret;
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) {
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
            return ret;
        av_set_string3(var->input->priv_data, "key", key, 0, NULL);
        av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
        if ((ret = ffurl_connect(var->input)) < 0) {
            ffurl_close(var->input);
            var->input = NULL;
            return ret;
        }
        return 0;
    }
    return AVERROR(ENOSYS);
}
Ejemplo n.º 8
0
void set_context_opts(void *ctx, void *opts_ctx, int flags)
{
    int i;
    for(i=0; i<opt_name_count; i++){
        char buf[256];
        const AVOption *opt;
        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
        if(str && ((opt->flags & flags) == flags))
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
    }
}
Ejemplo n.º 9
0
int opt_default(const char *opt, const char *arg){
    int type;
    int ret= 0;
    const AVOption *o= NULL;
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};

    for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
        if(o2)
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
    }
    if(!o && avformat_opts)
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
    if(!o && sws_opts)
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
    if(!o){
        if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
        else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
        else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
    }
    if (o && ret < 0) {
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
        exit(1);
    }
    if (!o) {
        AVCodec *p = NULL;
        AVOutputFormat *oformat = NULL;
        while ((p=av_codec_next(p))){
            AVClass *c= p->priv_class;
            if(c && av_find_opt(&c, opt, NULL, 0, 0))
                break;
        }
        if (!p) {
            while ((oformat = av_oformat_next(oformat))) {
                const AVClass *c = oformat->priv_class;
                if (c && av_find_opt(&c, opt, NULL, 0, 0))
                    break;
            }
        }
        if(!p && !oformat){
            fprintf(stderr, "Unrecognized option '%s'\n", opt);
            exit(1);
        }
    }

//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));

    //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
    opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
    opt_values[opt_name_count]= o ? NULL : arg;
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
    opt_names[opt_name_count++]= o ? o->name : opt;

    if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
        av_log_set_level(AV_LOG_DEBUG);
    return 0;
}
Ejemplo n.º 10
0
void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
{
    int i;
    void *priv_ctx=NULL;
    if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
        AVCodecContext *avctx= ctx;
        if(codec && codec->priv_class && avctx->priv_data){
            priv_ctx= avctx->priv_data;
        }
    } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
        AVFormatContext *avctx = ctx;
        if (avctx->oformat && avctx->oformat->priv_class) {
            priv_ctx = avctx->priv_data;
        } else if (avctx->iformat && avctx->iformat->priv_class) {
            priv_ctx = avctx->priv_data;
        }
    }

    for(i=0; i<opt_name_count; i++){
        char buf[256];
        const AVOption *opt;
        const char *str;
        if (priv_ctx) {
            if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) {
                if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL) < 0) {
                    fprintf(stderr, "Invalid value '%s' for option '%s'\n",
                            opt_names[i], opt_values[i]);
                    exit(1);
                }
            } else
                goto global;
        } else {
        global:
            str = av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
            /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
            if (str && ((opt->flags & flags) == flags))
                av_set_string3(ctx, opt_names[i], str, 1, NULL);
        }
    }
}
Ejemplo n.º 11
0
static int CacheHttp_advanced_ffurl_open_h(URLContext ** h,const char * filename, int flags, const char * headers, int * http,CacheHttpContext* ctx) {
    if(ctx->ktype == KEY_NONE) {
        return CacheHttp_ffurl_open_h(h, filename, flags,headers, http);
    } else { //crypto streaming
        int ret = -1;
        URLContext* input = NULL;
        if ((ret = ffurl_alloc(&input, filename, AVIO_FLAG_READ|AVIO_FLAG_NONBLOCK)) < 0) {
            return ret;
        }

        av_set_string3(input->priv_data, "key", ctx->key, 0, NULL);
        av_set_string3(input->priv_data, "iv", ctx->iv, 0, NULL);
        if ((ret = ffurl_connect(input)) < 0) {
            ffurl_close(input);
            input = NULL;
            *h = NULL;
            return ret;
        }
        *h = input;
    }
    return 0;
}
Ejemplo n.º 12
0
int opt_default(const char *opt, const char *arg){
    int type;
    int ret= 0;
    const AVOption *o= NULL;
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};

    for(type=0; type<AVMEDIA_TYPE_NB && ret>= 0; type++){
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
        if(o2)
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
    }
    if(!o)
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
    if(!o && sws_opts)
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
    if(!o){
        if(opt[0] == 'a')
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
        else if(opt[0] == 'v')
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
        else if(opt[0] == 's')
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
    }
    if (o && ret < 0) {
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
        exit(1);
    }
    if (!o) {
        fprintf(stderr, "Unrecognized option '%s'\n", opt);
        exit(1);
    }

//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));

    //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
    opt_names[opt_name_count++]= o->name;

    if(avcodec_opts[0]->debug || avformat_opts->debug)
        av_log_set_level(AV_LOG_DEBUG);
    return 0;
}
Ejemplo n.º 13
0
int opt_default(const char *opt, const char *arg){
    int type;
    int ret= 0;
    const AVOption *o= NULL;
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
    AVCodec *p = NULL;
    AVOutputFormat *oformat = NULL;
    AVInputFormat *iformat = NULL;

    while ((p = av_codec_next(p))) {
        AVClass *c = p->priv_class;
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (p)
        goto out;
    while ((oformat = av_oformat_next(oformat))) {
        const AVClass *c = oformat->priv_class;
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (oformat)
        goto out;
    while ((iformat = av_iformat_next(iformat))) {
        const AVClass *c = iformat->priv_class;
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (iformat)
        goto out;

    for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
        if(o2)
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
    }
    if(!o && avformat_opts)
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
    if(!o && sws_opts)
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
    if(!o){
        if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
        else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
        else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
        if (ret >= 0)
            opt += 1;
    }
    if (o && ret < 0) {
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
        exit(1);
    }
    if (!o) {
        fprintf(stderr, "Unrecognized option '%s'\n", opt);
        exit(1);
    }

 out:
//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));

    opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
    opt_values[opt_name_count] = av_strdup(arg);
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
    opt_names[opt_name_count++] = av_strdup(opt);

    if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
        av_log_set_level(AV_LOG_DEBUG);
    return 0;
}
Ejemplo n.º 14
0
const AVOption *av_set_string(void *obj, const char *name, const char *val){
    const AVOption *o;
    if (av_set_string3(obj, name, val, 0, &o) < 0)
        return NULL;
    return o;
}
Ejemplo n.º 15
0
const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){
    const AVOption *o;
    if (av_set_string3(obj, name, val, alloc, &o) < 0)
        return NULL;
    return o;
}
Ejemplo n.º 16
0
static pj_status_t h264_preopen(ffmpeg_private *ff)
{
    h264_data *data;
    pjmedia_h264_packetizer_cfg pktz_cfg;
    pj_status_t status;

    data = PJ_POOL_ZALLOC_T(ff->pool, h264_data);
    ff->data = data;

    /* Parse remote fmtp */
    status = pjmedia_vid_codec_h264_parse_fmtp(&ff->param.enc_fmtp,
					       &data->fmtp);
    if (status != PJ_SUCCESS)
	return status;

    /* Create packetizer */
    pktz_cfg.mtu = ff->param.enc_mtu;
#if 0
    if (data->fmtp.packetization_mode == 0)
	pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
    else if (data->fmtp.packetization_mode == 1)
	pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;
    else
	return PJ_ENOTSUP;
#else
    if (data->fmtp.packetization_mode!=
				PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL &&
	data->fmtp.packetization_mode!=
				PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED)
    {
	return PJ_ENOTSUP;
    }
    /* Better always send in single NAL mode for better compatibility */
    pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
#endif

    status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);
    if (status != PJ_SUCCESS)
	return status;

    /* Apply SDP fmtp to format in codec param */
    if (!ff->param.ignore_fmtp) {
	status = pjmedia_vid_codec_h264_apply_fmtp(&ff->param);
	if (status != PJ_SUCCESS)
	    return status;
    }

    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
	pjmedia_video_format_detail *vfd;
	AVCodecContext *ctx = ff->enc_ctx;
	const char *profile = NULL;

	vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 
						     PJ_TRUE);

	/* Override generic params after applying SDP fmtp */
	ctx->width = vfd->size.w;
	ctx->height = vfd->size.h;
	ctx->time_base.num = vfd->fps.denum;
	ctx->time_base.den = vfd->fps.num;

	/* Apply profile. */
	ctx->profile  = data->fmtp.profile_idc;
	switch (ctx->profile) {
	case PROFILE_H264_BASELINE:
	    profile = "baseline";
	    break;
	case PROFILE_H264_MAIN:
	    profile = "main";
	    break;
	default:
	    break;
	}
	if (profile &&
	    av_set_string3(ctx->priv_data, "profile", profile, 0, NULL))
	{
	    PJ_LOG(3, (THIS_FILE, "Failed to set H264 profile"));
	}

	/* Apply profile constraint bits. */
	//PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg);
	if (data->fmtp.profile_iop) {
#if defined(FF_PROFILE_H264_CONSTRAINED)
	    ctx->profile |= FF_PROFILE_H264_CONSTRAINED;
#endif
	}

	/* Apply profile level. */
	ctx->level    = data->fmtp.level;

	/* Limit NAL unit size as we prefer single NAL unit packetization */
	if (!av_set_int(ctx->priv_data, "slice-max-size", ff->param.enc_mtu))
	{
	    PJ_LOG(3, (THIS_FILE, "Failed to set H264 max NAL size to %d",
		       ff->param.enc_mtu));
	}

	/* Apply intra-refresh */
	if (!av_set_int(ctx->priv_data, "intra-refresh", 1))
	{
	    PJ_LOG(3, (THIS_FILE, "Failed to set x264 intra-refresh"));
	}

	/* Misc x264 settings (performance, quality, latency, etc).
	 * Let's just use the x264 predefined preset & tune.
	 */
	if (av_set_string3(ctx->priv_data, "preset", "veryfast", 0, NULL))
	{
	    PJ_LOG(3, (THIS_FILE, "Failed to set x264 preset 'veryfast'"));
	}
	if (av_set_string3(ctx->priv_data, "tune", "animation+zerolatency",
			   0, NULL))
	{
	    PJ_LOG(3, (THIS_FILE, "Failed to set x264 tune 'zerolatency'"));
	}
    }

    if (ff->param.dir & PJMEDIA_DIR_DECODING) {
	AVCodecContext *ctx = ff->dec_ctx;

	/* Apply the "sprop-parameter-sets" fmtp from remote SDP to
	 * extradata of ffmpeg codec context.
	 */
	if (data->fmtp.sprop_param_sets_len) {
	    ctx->extradata_size = data->fmtp.sprop_param_sets_len;
	    ctx->extradata = data->fmtp.sprop_param_sets;
	}
    }

    return PJ_SUCCESS;
}