示例#1
0
文件: daala.c 项目: 9034725985/vlc
static int OpenEncoder( vlc_object_t *p_this )
{
    encoder_t *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys;
    ogg_packet header;
    int status;

    if( p_enc->fmt_out.i_codec != VLC_CODEC_DAALA &&
        !p_enc->b_force )
    {
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the encoder's structure */
    p_sys = malloc( sizeof( encoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    p_enc->p_sys = p_sys;

    p_enc->pf_encode_video = Encode;
    p_enc->fmt_in.i_codec = VLC_CODEC_I420;
    p_enc->fmt_out.i_codec = VLC_CODEC_DAALA;

    config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );

    char *psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX "chroma-fmt" );
    uint32_t i_codec;
    if( !psz_tmp ) {
        free(p_sys);
        return VLC_ENOMEM;
    } else {
        if( !strcmp( psz_tmp, "420" ) ) {
            i_codec = VLC_CODEC_I420;
        }
        else if( !strcmp( psz_tmp, "444" ) ) {
            i_codec = VLC_CODEC_I444;
        }
        else {
            msg_Err( p_enc, "Invalid chroma format: %s", psz_tmp );
            free( psz_tmp );
            free( p_sys );
            return VLC_EGENERIC;
        }
        free( psz_tmp );
        p_enc->fmt_in.i_codec = i_codec;
        /* update bits_per_pixel */
        video_format_Setup(&p_enc->fmt_in.video, i_codec,
                p_enc->fmt_in.video.i_width,
                p_enc->fmt_in.video.i_height,
                p_enc->fmt_in.video.i_visible_width,
                p_enc->fmt_in.video.i_visible_height,
                p_enc->fmt_in.video.i_sar_num,
                p_enc->fmt_in.video.i_sar_den);
    }

    daala_info_init( &p_sys->di );

    p_sys->di.pic_width = p_enc->fmt_in.video.i_visible_width;
    p_sys->di.pic_height = p_enc->fmt_in.video.i_visible_height;

    p_sys->di.nplanes = 3;
    for (int i = 0; i < p_sys->di.nplanes; i++)
    {
        p_sys->di.plane_info[i].xdec = i > 0 && i_codec != VLC_CODEC_I444;
        p_sys->di.plane_info[i].ydec = i_codec == VLC_CODEC_I420 ?
            p_sys->di.plane_info[i].xdec : 0;
    }
    p_sys->di.frame_duration = 1;

    if( !p_enc->fmt_in.video.i_frame_rate ||
        !p_enc->fmt_in.video.i_frame_rate_base )
    {
        p_sys->di.timebase_numerator = 25;
        p_sys->di.timebase_denominator = 1;
    }
    else
    {
        p_sys->di.timebase_numerator = p_enc->fmt_in.video.i_frame_rate;
        p_sys->di.timebase_denominator = p_enc->fmt_in.video.i_frame_rate_base;
    }

    if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
    {
        unsigned i_dst_num, i_dst_den;
        vlc_ureduce( &i_dst_num, &i_dst_den,
                     p_enc->fmt_in.video.i_sar_num,
                     p_enc->fmt_in.video.i_sar_den, 0 );
        p_sys->di.pixel_aspect_numerator = i_dst_num;
        p_sys->di.pixel_aspect_denominator = i_dst_den;
    }
    else
    {
        p_sys->di.pixel_aspect_numerator = 4;
        p_sys->di.pixel_aspect_denominator = 3;
    }

    p_sys->di.keyframe_rate = var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" );

    daala_enc_ctx *dcx;
    p_sys->dcx = dcx = daala_encode_create( &p_sys->di );
    if( !dcx )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    daala_comment_init( &p_sys->dc );

    int i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
    daala_encode_ctl( dcx, OD_SET_QUANT, &i_quality, sizeof(i_quality) );

    /* Create and store headers */
    while( ( status = daala_encode_flush_header( dcx, &p_sys->dc, &header ) ) )
    {
        if ( status < 0 )
        {
            CloseEncoder( p_this );
            return VLC_EGENERIC;
        }
        if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra,
                                &p_enc->fmt_out.p_extra, header.bytes,
                                header.packet ) )
        {
            p_enc->fmt_out.i_extra = 0;
            p_enc->fmt_out.p_extra = NULL;
        }
    }
    return VLC_SUCCESS;
}
示例#2
0
文件: encode.c 项目: GGGO/baresip
static int open_encoder(struct videnc_state *ves, const struct vidsz *size)
{
	daala_info di;
	daala_comment dc;
	daala_packet dp;
	int err = 0;
	int complexity = 7;
	int video_q = 30;
	int bitrate = ves->bitrate;

	info("daala: open encoder (%d x %d, %d bps)\n",
	     size->w, size->h, bitrate);

	if (ves->enc) {
		debug("daala: re-opening encoder\n");
		daala_encode_free(ves->enc);
	}

	daala_info_init(&di);
	daala_comment_init(&dc);

	di.pic_width = size->w;
	di.pic_height = size->h;
	di.timebase_numerator = 1;
	di.timebase_denominator = ves->fps;
	di.frame_duration = 1;
	di.pixel_aspect_numerator = -1;
	di.pixel_aspect_denominator = -1;
	di.nplanes = 3;
	di.plane_info[0].xdec = 0;  /* YUV420P */
	di.plane_info[0].ydec = 0;
	di.plane_info[1].xdec = 1;
	di.plane_info[1].ydec = 1;
	di.plane_info[2].xdec = 1;
	di.plane_info[2].ydec = 1;

	di.keyframe_rate = 100;

	info("daala: open encoder with bitstream version %u.%u.%u\n",
	     di.version_major, di.version_minor, di.version_sub);

	ves->enc = daala_encode_create(&di);
	if (!ves->enc) {
		warning("daala: failed to open DAALA encoder\n");
		return ENOMEM;
	}

	daala_encode_ctl(ves->enc, OD_SET_QUANT,
			 &video_q, sizeof(video_q));

	daala_encode_ctl(ves->enc, OD_SET_COMPLEXITY,
			 &complexity, sizeof(complexity));

	daala_encode_ctl(ves->enc, OD_SET_BITRATE,
			 &bitrate, sizeof(bitrate));

	for (;;) {
		int r;

		r = daala_encode_flush_header(ves->enc, &dc, &dp);
		if (r < 0) {
			warning("daala: flush_header returned %d\n", r);
			break;
		}
		else if (r == 0)
			break;

		debug("daala: header: %lld bytes header=%d key=%d\n",
			  dp.bytes,
			  daala_packet_isheader(&dp),
			  daala_packet_iskeyframe(&dp));

#if 0
		re_printf("bos=%lld, eos=%lld, granule=%lld, packetno=%lld\n",
			  dp.b_o_s,
			  dp.e_o_s,
			  dp.granulepos,
			  dp.packetno);
#endif

		err = send_packet(ves, dp.b_o_s, dp.packet, dp.bytes);
		if (err)
			break;
	}

	daala_info_clear(&di);
	daala_comment_clear(&dc);

	return err;
}