summaryrefslogtreecommitdiff
path: root/ext/ffmpeg/gstffmpegenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffmpeg/gstffmpegenc.c')
-rw-r--r--ext/ffmpeg/gstffmpegenc.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c
index 0232392..abbfaae 100644
--- a/ext/ffmpeg/gstffmpegenc.c
+++ b/ext/ffmpeg/gstffmpegenc.c
@@ -21,6 +21,8 @@
#include <string.h>
+#define VIDEO_BUFFER_SIZE (1024*1024)
+
enum {
/* FILL ME */
LAST_SIGNAL
@@ -97,6 +99,8 @@ gst_ffmpegenc_me_method_get_type (void)
{ ME_FULL, "1", "full" },
{ ME_LOG, "2", "logarithmic" },
{ ME_PHODS, "3", "phods" },
+ { ME_EPZS, "4", "epzs" },
+ { ME_X1 , "5", "x1" },
{ 0, NULL, NULL },
};
if (!ffmpegenc_me_method_type) {
@@ -138,10 +142,10 @@ gst_ffmpegenc_class_init (GstFFMpegEncClass *klass)
if (klass->in_plugin->type == CODEC_TYPE_VIDEO) {
g_object_class_install_property(G_OBJECT_CLASS (klass), ARG_WIDTH,
g_param_spec_int ("width","width","width",
- 0, G_MAXINT, -1, G_PARAM_READWRITE));
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS (klass), ARG_HEIGHT,
g_param_spec_int ("height","height","height",
- 0, G_MAXINT, -1, G_PARAM_READWRITE));
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS (klass), ARG_BIT_RATE,
g_param_spec_int ("bit_rate","bit_rate","bit_rate",
0, G_MAXINT, 300000, G_PARAM_READWRITE));
@@ -184,12 +188,15 @@ gst_ffmpegenc_sinkconnect (GstPad *pad, GstCaps *caps)
return GST_PAD_CONNECT_DELAYED;
if (strstr (gst_caps_get_mime (caps), "audio/raw")) {
- ffmpegenc->context->sample_rate = gst_caps_get_int (caps, "rate");
- ffmpegenc->context->channels = gst_caps_get_int (caps, "channels");
+ gst_caps_get_int (caps, "rate", &ffmpegenc->context->sample_rate);
+ gst_caps_get_int (caps, "channels", &ffmpegenc->context->channels);
}
else if (strstr (gst_caps_get_mime (caps), "video/raw")) {
- ffmpegenc->in_width = gst_caps_get_int (caps, "width");
- ffmpegenc->in_height = gst_caps_get_int (caps, "height");
+ guint32 fourcc;
+
+ gst_caps_get_int (caps, "width", &ffmpegenc->in_width);
+ gst_caps_get_int (caps, "height", &ffmpegenc->in_height);
+
if (ffmpegenc->need_resample) {
ffmpegenc->context->width = ffmpegenc->out_width;
ffmpegenc->context->height = ffmpegenc->out_height;
@@ -198,7 +205,8 @@ gst_ffmpegenc_sinkconnect (GstPad *pad, GstCaps *caps)
ffmpegenc->context->width = ffmpegenc->in_width;
ffmpegenc->context->height = ffmpegenc->in_height;
}
- if (gst_caps_get_fourcc_int (caps, "format") == GST_STR_FOURCC ("I420")) {
+ gst_caps_get_fourcc_int (caps, "format", &fourcc);
+ if (fourcc == GST_STR_FOURCC ("I420")) {
ffmpegenc->context->pix_fmt = PIX_FMT_YUV420P;
}
else {
@@ -237,9 +245,13 @@ gst_ffmpegenc_init(GstFFMpegEnc *ffmpegenc)
ffmpegenc->sinkpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (gst_ffmpegenc_video_sink_factory), "sink");
gst_pad_set_chain_function (ffmpegenc->sinkpad, gst_ffmpegenc_chain_video);
- ffmpegenc->context->bit_rate = 300000;
+ ffmpegenc->context->bit_rate = 400000;
+ ffmpegenc->context->bit_rate_tolerance = 400000;
+ ffmpegenc->context->qmin = 3;
+ ffmpegenc->context->qmax = 15;
+ ffmpegenc->context->max_qdiff = 3;
ffmpegenc->context->gop_size = 15;
- ffmpegenc->context->frame_rate = 25;
+ ffmpegenc->context->frame_rate = 25 * FRAME_RATE_BASE;
ffmpegenc->out_width = -1;
ffmpegenc->out_height = -1;
}
@@ -333,6 +345,7 @@ gst_ffmpegenc_chain_video (GstPad *pad, GstBuffer *inbuf)
frame_size = ffmpegenc->in_width * ffmpegenc->in_height;
+ /*
switch (ffmpegenc->context->pix_fmt) {
case PIX_FMT_YUV422:
{
@@ -341,7 +354,7 @@ gst_ffmpegenc_chain_video (GstPad *pad, GstBuffer *inbuf)
temp = g_malloc ((frame_size * 3) /2 );
size = (frame_size * 3)/2;
- img_convert_to_yuv420 (temp, data, PIX_FMT_YUV422,
+ img_convert (temp, PIX_FMT_YUV422, data, PIX_FMT_YUV420P,
ffmpegenc->in_width, ffmpegenc->in_height);
data = temp;
free_data = TRUE;
@@ -350,33 +363,27 @@ gst_ffmpegenc_chain_video (GstPad *pad, GstBuffer *inbuf)
default:
break;
}
+ */
- picture.data[0] = data;
- picture.data[1] = picture.data[0] + frame_size;
- picture.data[2] = picture.data[1] + (frame_size >> 2);
- picture.linesize[0] = ffmpegenc->in_width;
- picture.linesize[1] = ffmpegenc->in_width >> 1;
- picture.linesize[2] = ffmpegenc->in_width >> 1;
+ avpicture_fill (&picture, data, PIX_FMT_YUV420P, ffmpegenc->in_width, ffmpegenc->in_height);
toencode = &picture;
if (ffmpegenc->need_resample) {
gint rframe_size = ffmpegenc->context->width * ffmpegenc->context->height;
+ guint8 *rdata;
+
+ rdata = g_malloc ((rframe_size * 3)/2);
+ avpicture_fill (&rpicture, rdata, PIX_FMT_YUV420P, ffmpegenc->context->width, ffmpegenc->context->height);
- rpicture.data[0] = g_malloc ((rframe_size * 3)/2);
- rpicture.data[1] = rpicture.data[0] + rframe_size;
- rpicture.data[2] = rpicture.data[1] + (rframe_size >> 2);
- rpicture.linesize[0] = ffmpegenc->context->width;
- rpicture.linesize[1] = ffmpegenc->context->width >> 1;
- rpicture.linesize[2] = ffmpegenc->context->width >> 1;
free_res = TRUE;
toencode = &rpicture;
img_resample (ffmpegenc->resample, &rpicture, &picture);
}
-
+
outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) = size;
- GST_BUFFER_DATA (outbuf) = g_malloc (size);
+ GST_BUFFER_SIZE (outbuf) = VIDEO_BUFFER_SIZE;
+ GST_BUFFER_DATA (outbuf) = g_malloc (VIDEO_BUFFER_SIZE);
GST_BUFFER_SIZE (outbuf) = avcodec_encode_video (ffmpegenc->context, GST_BUFFER_DATA (outbuf),
GST_BUFFER_SIZE (outbuf), toencode);