Example #1
0
static int send_packet(struct videnc_state *ves, bool marker,
		       const uint8_t *pld, size_t pld_len)
{
	daala_packet dp;
	int err;

	memset(&dp, 0, sizeof(dp));

	dp.packet = (uint8_t *)pld;
	dp.bytes = pld_len;
	dp.b_o_s = marker;

	err = ves->pkth(marker, NULL, 0, pld, pld_len, ves->arg);
	if (err)
		return err;

	++ves->stats.n_packet;
	++ves->stats.valid;

	if (daala_packet_isheader(&dp))
		++ves->stats.n_header;
	else if (daala_packet_iskeyframe(&dp) > 0)
		++ves->stats.n_keyframe;

	return 0;
}
Example #2
0
static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    ogg_packet oggpacket;
    block_t *p_block;
    od_img img;

    if( !p_pict ) return NULL;

    const int i_width = p_sys->di.pic_width;
    const int i_height = p_sys->di.pic_height;

    /* Sanity check */
    if( p_pict->p[0].i_pitch < i_width ||
        p_pict->p[0].i_lines < i_height )
    {
        msg_Err( p_enc, "frame is smaller than encoding size"
                 "(%ix%i->%ix%i) -> dropping frame",
                 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
                 i_width, i_height );
        return NULL;
    }

    /* Daala is a one-frame-in, one-frame-out system. Submit a frame
     * for compression and pull out the packet. */

    img.nplanes = p_sys->di.nplanes;
    img.width = i_width;
    img.height = i_height;
    for( int i = 0; i < img.nplanes; i++ )
    {
        img.planes[i].data = p_pict->p[i].p_pixels;
        img.planes[i].xdec = p_sys->di.plane_info[i].xdec;
        img.planes[i].ydec = p_sys->di.plane_info[i].ydec;
        img.planes[i].xstride = 1;
        img.planes[i].ystride = p_pict->p[i].i_pitch;
    }

    if( daala_encode_img_in( p_sys->dcx, &img, 0 ) < 0 )
    {
        msg_Warn( p_enc, "failed encoding a frame" );
        return NULL;
    }

    daala_encode_packet_out( p_sys->dcx, 0, &oggpacket );

    /* Ogg packet to block */
    p_block = block_Alloc( oggpacket.bytes );
    memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
    p_block->i_dts = p_block->i_pts = p_pict->date;

    if( daala_packet_iskeyframe( oggpacket.packet, oggpacket.bytes ) )
        p_block->i_flags |= BLOCK_FLAG_TYPE_I;

    return p_block;
}
Example #3
0
/*****************************************************************************
 * DecodePacket: decodes a Daala packet.
 *****************************************************************************/
static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    picture_t *p_pic;
    od_img ycbcr;

    if (daala_decode_packet_in( p_sys->dcx, &ycbcr, p_oggpacket ) < 0)
        return NULL; /* bad packet */

    /* Check for keyframe */
    if( daala_packet_iskeyframe( p_oggpacket->packet, p_oggpacket->bytes ) )
        p_sys->b_decoded_first_keyframe = true;

    /* Get a new picture */
    p_pic = decoder_NewPicture( p_dec );
    if( !p_pic ) return NULL;

    daala_CopyPicture( p_pic, &ycbcr );

    p_pic->date = p_sys->i_pts;

    return p_pic;
}
Example #4
0
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;
}