Example #1
0
static pj_status_t h264_preopen(openh264_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 (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;    
    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;
    }

    return PJ_SUCCESS;
}
Example #2
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;
}