Esempio n. 1
0
static void read_handler(int flags, void *arg)
{
	struct videnc_state *st = arg;
	struct v4l2_buffer buf;
	int err;
	(void)flags;

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

	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	buf.memory = V4L2_MEMORY_MMAP;
	buf.index = 0;

	if (-1 == xioctl(st->fd, VIDIOC_DQBUF, &buf)) {
		err = errno;
		warning("v4l2_codec: Retrieving Frame (%m)\n", err);
		return;
	}

#if 0
	debug("image captured at %ld, %ld\n",
	       buf.timestamp.tv_sec, buf.timestamp.tv_usec);
#endif

	{
		struct mbuf mb = {0,0,0,0};
		struct h264_hdr hdr;

		mb.buf = st->buffer;
		mb.pos = 4;
		mb.end = buf.bytesused - 4;
		mb.size = buf.bytesused;

		err = h264_hdr_decode(&hdr, &mb);
		if (err) {
			warning("could not decode H.264 header\n");
		}
		else {
			if (h264_is_keyframe(hdr.type))
				++st->stats.n_key;
			else
				++st->stats.n_delta;
		}
	}

	err = h264_packetize(st->buffer, buf.bytesused,
			     st->encprm.pktsize, st->pkth, st->arg);
	if (err) {
		warning("h264_packetize error (%m)\n", err);
	}

	query_buffer(st->fd);
}
Esempio n. 2
0
/* The appsink has received a buffer */
static void internal_appsink_new_buffer(GstElement *sink,
					struct videnc_state *st)
{
	GstBuffer *buffer;

	if (!st)
		return;

	/* Retrieve the buffer */
	g_signal_emit_by_name(sink, "pull-buffer", &buffer);

	if (buffer) {
		guint8 *data = GST_BUFFER_DATA(buffer);
		guint size = GST_BUFFER_SIZE(buffer);

		h264_packetize(data, size, st->pktsize,
			       st->pkth, st->pkth_arg);

		gst_buffer_unref(buffer);
	}
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}