Ejemplo n.º 1
0
int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
{
	int i, err, ret;
	int pix_fmt;

	if (!st || !frame)
		return EINVAL;

	switch (frame->fmt) {

	case VID_FMT_YUV420P:
		pix_fmt = AV_PIX_FMT_YUV420P;
		break;

	case VID_FMT_NV12:
		pix_fmt = AV_PIX_FMT_NV12;
		break;

	default:
		warning("avcodec: pixel format not supported (%s)\n",
			vidfmt_name(frame->fmt));
		return ENOTSUP;
	}

	if (!st->ctx || !vidsz_cmp(&st->encsize, &frame->size)) {

		err = open_encoder(st, &st->encprm, &frame->size, pix_fmt);
		if (err) {
			warning("avcodec: open_encoder: %m\n", err);
			return err;
		}
	}

	for (i=0; i<4; i++) {
		st->pict->data[i]     = frame->data[i];
		st->pict->linesize[i] = frame->linesize[i];
	}
	st->pict->pts = st->pts++;
	if (update) {
		debug("avcodec: encoder picture update\n");
		st->pict->key_frame = 1;
#ifdef FF_I_TYPE
		st->pict->pict_type = FF_I_TYPE;  /* Infra Frame */
#else
		st->pict->pict_type = AV_PICTURE_TYPE_I;
#endif
	}
	else {
		st->pict->key_frame = 0;
		st->pict->pict_type = 0;
	}

	mbuf_rewind(st->mb);

#if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0)
	do {
		AVPacket avpkt;
		int got_packet;

		av_init_packet(&avpkt);

		avpkt.data = st->mb->buf;
		avpkt.size = (int)st->mb->size;

		ret = avcodec_encode_video2(st->ctx, &avpkt,
					    st->pict, &got_packet);
		if (ret < 0)
			return EBADMSG;
		if (!got_packet)
			return 0;

		mbuf_set_end(st->mb, avpkt.size);

	} while (0);
#else
	ret = avcodec_encode_video(st->ctx, st->mb->buf,
				   (int)st->mb->size, st->pict);
	if (ret < 0 )
		return EBADMSG;

	/* todo: figure out proper buffer size */
	if (ret > (int)st->sz_max) {
		debug("avcodec: grow encode buffer %u --> %d\n",
		      st->sz_max, ret);
		st->sz_max = ret;
	}

	mbuf_set_end(st->mb, ret);
#endif

	switch (st->codec_id) {

	case AV_CODEC_ID_H263:
		err = h263_packetize(st, st->mb, st->pkth, st->arg);
		break;

	case AV_CODEC_ID_H264:
		err = h264_packetize(st->mb->buf, st->mb->end,
				     st->encprm.pktsize,
				     st->pkth, st->arg);
		break;

	case AV_CODEC_ID_MPEG4:
		err = general_packetize(st->mb, st->encprm.pktsize,
					st->pkth, st->arg);
		break;

	default:
		err = EPROTO;
		break;
	}

	return err;
}
Ejemplo n.º 2
0
static int enc(struct vidcodec_st *st, bool update,
	       const struct vidframe *frame)
{
	int i, err, ret;

	if (!st->enc.ctx || !vidsz_cmp(&st->encsize, &frame->size)) {

		err = open_encoder(st, &st->encprm, &frame->size);
		if (err) {
			DEBUG_WARNING("open_encoder: %m\n", err);
			return err;
		}
	}

	for (i=0; i<4; i++) {
		st->enc.pict->data[i]     = frame->data[i];
		st->enc.pict->linesize[i] = frame->linesize[i];
	}
	st->enc.pict->pts = st->pts++;
	if (update) {
		re_printf("avcodec encoder picture update\n");
		st->enc.pict->key_frame = 1;
#ifdef FF_I_TYPE
		st->enc.pict->pict_type = FF_I_TYPE;  /* Infra Frame */
#else
		st->enc.pict->pict_type = AV_PICTURE_TYPE_I;
#endif
	}
	else {
		st->enc.pict->key_frame = 0;
		st->enc.pict->pict_type = 0;
	}

	mbuf_rewind(st->enc.mb);

#if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0)
	do {
		AVPacket avpkt;
		int got_packet;

		avpkt.data = st->enc.mb->buf;
		avpkt.size = (int)st->enc.mb->size;

		ret = avcodec_encode_video2(st->enc.ctx, &avpkt,
					    st->enc.pict, &got_packet);
		if (ret < 0)
			return EBADMSG;
		if (!got_packet)
			return 0;

		mbuf_set_end(st->enc.mb, avpkt.size);

	} while (0);
#else
	ret = avcodec_encode_video(st->enc.ctx, st->enc.mb->buf,
				   (int)st->enc.mb->size, st->enc.pict);
	if (ret < 0 )
		return EBADMSG;

	/* todo: figure out proper buffer size */
	if (ret > (int)st->enc.sz_max) {
		re_printf("note: grow encode buffer %u --> %d\n",
			  st->enc.sz_max, ret);
		st->enc.sz_max = ret;
	}

	mbuf_set_end(st->enc.mb, ret);
#endif

	switch (st->codec_id) {

	case CODEC_ID_H263:
		err = h263_packetize(st, st->enc.mb);
		break;

	case CODEC_ID_H264:
		err = h264_packetize(st, st->enc.mb);
		break;

	case CODEC_ID_MPEG4:
		err = general_packetize(st, st->enc.mb);
		break;

	default:
		err = EPROTO;
		break;
	}

	return err;
}
Ejemplo n.º 3
0
int h265_encode(struct videnc_state *st, bool update,
		const struct vidframe *frame,
		videnc_packet_h *pkth, void *arg)
{
	x265_picture *pic_in = NULL, pic_out;
	x265_nal *nalv;
	uint32_t i, nalc = 0;
	int n, err = 0;

	if (!st || !frame || !pkth || frame->fmt != VID_FMT_YUV420P)
		return EINVAL;

	if (!st->x265 || !vidsz_cmp(&st->size, &frame->size)) {

		err = open_encoder(st, &frame->size);
		if (err)
			return err;

		st->size = frame->size;
	}

	if (update) {
		debug("h265: encode: picture update was requested\n");
	}

	pic_in = x265_picture_alloc();
	if (!pic_in) {
		warning("h265: x265_picture_alloc failed\n");
		return ENOMEM;
	}

	x265_picture_init(st->param, pic_in);

	pic_in->sliceType  = update ? X265_TYPE_IDR : X265_TYPE_AUTO;
	pic_in->pts        = ++st->pts;      /* XXX: add PTS to API */
	pic_in->colorSpace = X265_CSP_I420;

	for (i=0; i<3; i++) {
		pic_in->planes[i] = frame->data[i];
		pic_in->stride[i] = frame->linesize[i];
	}

	/* NOTE: important to get the PTS of the "out" picture */
	n = x265_encoder_encode(st->x265, &nalv, &nalc, pic_in, &pic_out);
	if (n <= 0)
		goto out;

	for (i=0; i<nalc; i++) {

		x265_nal *nal = &nalv[i];
		uint8_t *p = nal->payload;
		size_t len = nal->sizeBytes;
		bool marker;

#if 1
		debug("h265: encode: %s type=%2d  %s\n",
			  h265_is_keyframe(nal->type) ? "<KEY>" : "     ",
			  nal->type, h265_nalunit_name(nal->type));
#endif

		h265_skip_startcode(&p, &len);

		/* XXX: use pic_out.pts */

		marker = (i+1)==nalc;  /* last NAL */

		err = packetize(marker, p, len, st->pktsize, pkth, arg);
		if (err)
			goto out;
	}

 out:
	if (pic_in)
		x265_picture_free(pic_in);

	return err;
}
Ejemplo n.º 4
0
int h265_encode(struct videnc_state *st, bool update,
		const struct vidframe *frame, uint64_t timestamp)
{
	AVFrame *pict = NULL;
	AVPacket *pkt = NULL;
	uint64_t rtp_ts;
	int i, ret, got_packet = 0, err = 0;

	if (!st || !frame)
		return EINVAL;

	if (!st->ctx || !vidsz_cmp(&st->size, &frame->size) ||
	    st->fmt != frame->fmt) {

		enum AVPixelFormat pix_fmt;

		pix_fmt = vidfmt_to_avpixfmt(frame->fmt);
		if (pix_fmt == AV_PIX_FMT_NONE) {
			warning("h265: encode: pixel format not supported"
				" (%s)\n", vidfmt_name(frame->fmt));
			return ENOTSUP;
		}

		debug("h265: encoder: reset %u x %u (%s)\n",
		      frame->size.w, frame->size.h, vidfmt_name(frame->fmt));

		err = open_encoder(st, &frame->size, pix_fmt);
		if (err)
			return err;

		st->size = frame->size;
		st->fmt = frame->fmt;
	}

	pict = av_frame_alloc();
	if (!pict) {
		err = ENOMEM;
		goto out;
	}

	pict->format = st->ctx->pix_fmt;
	pict->width = frame->size.w;
	pict->height = frame->size.h;
	pict->pts = timestamp;

	for (i=0; i<4; i++) {
		pict->data[i]     = frame->data[i];
		pict->linesize[i] = frame->linesize[i];
	}

	if (update) {
		debug("h265: encoder picture update\n");
		pict->key_frame = 1;
		pict->pict_type = AV_PICTURE_TYPE_I;
	}

#if LIBAVUTIL_VERSION_MAJOR >= 55
	pict->color_range = AVCOL_RANGE_MPEG;
#endif

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)

	pkt = av_packet_alloc();
	if (!pkt) {
		err = ENOMEM;
		goto out;
	}

	ret = avcodec_send_frame(st->ctx, pict);
	if (ret < 0) {
		err = EBADMSG;
		goto out;
	}

	/* NOTE: packet contains 4-byte startcode */
	ret = avcodec_receive_packet(st->ctx, pkt);
	if (ret < 0) {
		info("h265: no packet yet ..\n");
		err = 0;
		goto out;
	}

	got_packet = 1;
#else
	pkt = av_malloc(sizeof(*pkt));
	if (!pkt) {
		err = ENOMEM;
		goto out;
	}

	av_init_packet(pkt);
	av_new_packet(pkt, 65536);

	ret = avcodec_encode_video2(st->ctx, pkt, pict, &got_packet);
	if (ret < 0) {
		err = EBADMSG;
		goto out;
	}
#endif

	if (!got_packet)
		goto out;

	rtp_ts = video_calc_rtp_timestamp_fix(pkt->dts);

	err = packetize_annexb(rtp_ts, pkt->data, pkt->size,
			       st->pktsize, st->pkth, st->arg);
	if (err)
		goto out;

 out:
	if (pict)
		av_free(pict);
	if (pkt)
		av_packet_free(&pkt);

	return err;
}
Ejemplo n.º 5
0
int daala_encode(struct videnc_state *ves, bool update,
		 const struct vidframe *frame)
{
	int r, err = 0;
	daala_image img;
	unsigned i;
	(void)update;  /* XXX: how to force a KEY-frame? */

	if (!ves || !frame || frame->fmt != VID_FMT_YUV420P)
		return EINVAL;

	++ves->stats.n_frame;

	if (!ves->enc || !vidsz_cmp(&ves->size, &frame->size)) {

		err = open_encoder(ves, &frame->size);
		if (err)
			return err;

		ves->size = frame->size;
	}

	img.planes[0].data = frame->data[0];
	img.planes[0].xdec = 0;
	img.planes[0].ydec = 0;
	img.planes[0].xstride = 1;
	img.planes[0].ystride = frame->linesize[0];

	img.planes[1].data = frame->data[1];
	img.planes[1].xdec = 1;
	img.planes[1].ydec = 1;
	img.planes[1].xstride = 1;
	img.planes[1].ystride = frame->linesize[1];

	img.planes[2].data = frame->data[2];
	img.planes[2].xdec = 1;
	img.planes[2].ydec = 1;
	img.planes[2].xstride = 1;
	img.planes[2].ystride = frame->linesize[2];

	for (i=0; i<3; i++)
		img.planes[i].bitdepth = 8;

	img.nplanes = 3;

	img.width = frame->size.w;
	img.height = frame->size.h;

	r = daala_encode_img_in(ves->enc, &img, 0);
	if (r != 0) {
		warning("daala: encoder: encode_img_in failed (ret = %d)\n",
			r);
		return EPROTO;
	}

	for (;;) {
		daala_packet dp;

		r = daala_encode_packet_out(ves->enc, 0, &dp);
		if (r < 0) {
			warning("daala: encoder: packet_out ret=%d\n", r);
			break;
		}
		else if (r == 0) {
			break;
		}

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

	return 0;
}