summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ext/dirac/gstdiracenc.cc213
2 files changed, 169 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index eb7da196..ec4ff7ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-29 David Schleef <ds@schleef.org>
+
+ * ext/dirac/gstdiracenc.cc: Fix EOS handling. Clean up at
+ object disposal. Handle 4:2:2 and 4:4:4 video.
+
2008-08-29 Jan Schmidt <Jan.Schmidt@sun.com>
* ext/resindvd/resindvdbin.c:
diff --git a/ext/dirac/gstdiracenc.cc b/ext/dirac/gstdiracenc.cc
index 5f359c5f..71baeb85 100644
--- a/ext/dirac/gstdiracenc.cc
+++ b/ext/dirac/gstdiracenc.cc
@@ -79,6 +79,7 @@ struct _GstDiracEnc
dirac_encoder_t *encoder;
dirac_sourceparams_t *src_params;
GstBuffer *buffer;
+ GstCaps *srccaps;
};
struct _GstDiracEncClass
@@ -137,7 +138,7 @@ static GstStaticPadTemplate gst_dirac_enc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, UYVY, AYUV }"))
);
static GstStaticPadTemplate gst_dirac_enc_src_template =
@@ -289,14 +290,8 @@ gst_dirac_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
gst_structure_get_fraction (structure, "pixel-aspect-ratio",
&dirac_enc->par_n, &dirac_enc->par_d);
- if (dirac_enc->fourcc != GST_MAKE_FOURCC ('I', '4', '2', '0')) {
- GST_ERROR
- ("Dirac encoder element is known to be buggy for video formats other that I420");
- }
-
switch (dirac_enc->fourcc) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
dirac_enc->enc_ctx.src_params.chroma = format420;
break;
case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
@@ -355,8 +350,7 @@ gst_dirac_enc_finalize (GObject * object)
dirac_enc = GST_DIRAC_ENC (object);
if (dirac_enc->encoder) {
- /* FIXME */
- //dirac_encoder_free (dirac_enc->encoder);
+ dirac_encoder_close (dirac_enc->encoder);
dirac_enc->encoder = NULL;
}
@@ -438,7 +432,7 @@ gst_dirac_enc_set_property (GObject * object, guint prop_id,
encoder->enc_ctx.enc_params.picture_coding_mode = g_value_get_int (value);
break;
case PROP_USE_VLC:
- encoder->enc_ctx.enc_params.using_ac = g_value_get_boolean (value);
+ encoder->enc_ctx.enc_params.using_ac = !g_value_get_boolean (value);
break;
}
}
@@ -447,32 +441,74 @@ static void
gst_dirac_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
- GstDiracEnc *src;
+ GstDiracEnc *encoder;
g_return_if_fail (GST_IS_DIRAC_ENC (object));
- src = GST_DIRAC_ENC (object);
+ encoder = GST_DIRAC_ENC (object);
-#if 0
- if (prop_id >= 1) {
- const DiracEncoderSetting *setting;
-
- setting = dirac_encoder_get_setting_info (prop_id - 1);
- switch (G_VALUE_TYPE (value)) {
- case G_TYPE_DOUBLE:
- g_value_set_double (value,
- dirac_encoder_setting_get_double (src->encoder, setting->name));
- break;
- case G_TYPE_INT:
- g_value_set_int (value,
- dirac_encoder_setting_get_double (src->encoder, setting->name));
- break;
- case G_TYPE_BOOLEAN:
- g_value_set_boolean (value,
- dirac_encoder_setting_get_double (src->encoder, setting->name));
- break;
- }
+ switch (prop_id) {
+ case PROP_L1_SEP:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.L1_sep);
+ break;
+ case PROP_NUM_L1:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.num_L1);
+ break;
+ case PROP_XBLEN:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.xblen);
+ break;
+ case PROP_YBLEN:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.yblen);
+ break;
+ case PROP_XBSEP:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.xbsep);
+ break;
+ case PROP_YBSEP:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.ybsep);
+ break;
+ case PROP_CPD:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.cpd);
+ break;
+ case PROP_QF:
+ g_value_set_double (value, encoder->enc_ctx.enc_params.qf);
+ break;
+ case PROP_TARGETRATE:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.trate);
+ break;
+ case PROP_LOSSLESS:
+ g_value_set_boolean (value, encoder->enc_ctx.enc_params.lossless);
+ break;
+ case PROP_IWLT_FILTER:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.intra_wlt_filter);
+ break;
+ case PROP_RWLT_FILTER:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.inter_wlt_filter);
+ break;
+ case PROP_WLT_DEPTH:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.wlt_depth);
+ break;
+ case PROP_MULTI_QUANTS:
+ g_value_set_boolean (value, encoder->enc_ctx.enc_params.multi_quants);
+ break;
+ case PROP_MV_PREC:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.mv_precision);
+ break;
+ case PROP_NO_SPARTITION:
+ g_value_set_boolean (value,
+ !encoder->enc_ctx.enc_params.spatial_partition);
+ break;
+ case PROP_PREFILTER:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.prefilter);
+ break;
+ case PROP_PREFILTER_STRENGTH:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.prefilter_strength);
+ break;
+ case PROP_PICTURE_CODING_MODE:
+ g_value_set_int (value, encoder->enc_ctx.enc_params.picture_coding_mode);
+ break;
+ case PROP_USE_VLC:
+ g_value_set_boolean (value, !encoder->enc_ctx.enc_params.using_ac);
+ break;
}
-#endif
}
static gboolean
@@ -732,8 +768,91 @@ gst_dirac_enc_chain (GstPad * pad, GstBuffer * buf)
dirac_enc->started = TRUE;
}
- dirac_encoder_load (dirac_enc->encoder, GST_BUFFER_DATA (buf),
- GST_BUFFER_SIZE (buf));
+ switch (dirac_enc->fourcc) {
+ case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+ dirac_encoder_load (dirac_enc->encoder, GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
+ break;
+ case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+ {
+ uint8_t *data;
+ uint8_t *bufdata = GST_BUFFER_DATA (buf);
+ int i, j;
+
+ data = (uint8_t *) g_malloc (GST_BUFFER_SIZE (buf));
+ for (j = 0; j < dirac_enc->height; j++) {
+ for (i = 0; i < dirac_enc->width; i++) {
+ data[j * dirac_enc->width + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 2];
+ }
+ for (i = 0; i < dirac_enc->width / 2; i++) {
+ data[dirac_enc->height * dirac_enc->width +
+ j * (dirac_enc->width / 2) + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 4 + 1];
+ data[dirac_enc->height * dirac_enc->width +
+ +dirac_enc->height * (dirac_enc->width / 2)
+ + j * (dirac_enc->width / 2) + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 4 + 3];
+ }
+ }
+ dirac_encoder_load (dirac_enc->encoder, data, GST_BUFFER_SIZE (buf));
+ g_free (data);
+ }
+ break;
+ case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+ {
+ uint8_t *data;
+ uint8_t *bufdata = GST_BUFFER_DATA (buf);
+ int i, j;
+
+ data = (uint8_t *) g_malloc (GST_BUFFER_SIZE (buf));
+ for (j = 0; j < dirac_enc->height; j++) {
+ for (i = 0; i < dirac_enc->width; i++) {
+ data[j * dirac_enc->width + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 2 + 1];
+ }
+ for (i = 0; i < dirac_enc->width / 2; i++) {
+ data[dirac_enc->height * dirac_enc->width +
+ j * (dirac_enc->width / 2) + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 4 + 0];
+ data[dirac_enc->height * dirac_enc->width +
+ +dirac_enc->height * (dirac_enc->width / 2)
+ + j * (dirac_enc->width / 2) + i] =
+ bufdata[j * dirac_enc->width * 2 + i * 4 + 2];
+ }
+ }
+ dirac_encoder_load (dirac_enc->encoder, data, GST_BUFFER_SIZE (buf));
+ g_free (data);
+ }
+ break;
+ case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
+ {
+ uint8_t *data;
+ uint8_t *bufdata = GST_BUFFER_DATA (buf);
+ int i, j;
+
+ data = (uint8_t *) g_malloc (GST_BUFFER_SIZE (buf));
+ for (j = 0; j < dirac_enc->height; j++) {
+ for (i = 0; i < dirac_enc->width; i++) {
+ data[j * dirac_enc->width + i] =
+ bufdata[j * dirac_enc->width * 4 + i * 4 + 1];
+ }
+ for (i = 0; i < dirac_enc->width; i++) {
+ data[dirac_enc->height * dirac_enc->width
+ + j * dirac_enc->width + i] =
+ bufdata[j * dirac_enc->width * 4 + i * 4 + 2];
+ data[2 * dirac_enc->height * dirac_enc->width +
+ +j * dirac_enc->width + i] =
+ bufdata[j * dirac_enc->width * 4 + i * 4 + 3];
+ }
+ }
+ dirac_encoder_load (dirac_enc->encoder, data, GST_BUFFER_SIZE (buf));
+ g_free (data);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
ret = gst_dirac_enc_process (dirac_enc, FALSE);
@@ -763,20 +882,19 @@ gst_dirac_enc_process (GstDiracEnc * dirac_enc, gboolean end_sequence)
dirac_enc->encoder->enc_buf.size = GST_BUFFER_SIZE (outbuf);
if (end_sequence) {
- /* FIXME this is a hack to make the code simpler. */
dirac_encoder_end_sequence (dirac_enc->encoder);
- state = ENC_STATE_AVAIL;
- } else {
- state = dirac_encoder_output (dirac_enc->encoder);
}
+ state = dirac_encoder_output (dirac_enc->encoder);
switch (state) {
case ENC_STATE_BUFFER:
+ gst_buffer_unref (outbuf);
break;
case ENC_STATE_INVALID:
GST_ERROR ("Dirac returned ENC_STATE_INVALID");
gst_buffer_unref (outbuf);
return GST_FLOW_ERROR;
+ case ENC_STATE_EOS:
case ENC_STATE_AVAIL:
parse_code = ((guint8 *) GST_BUFFER_DATA (outbuf))[4];
/* FIXME */
@@ -790,12 +908,14 @@ gst_dirac_enc_process (GstDiracEnc * dirac_enc, gboolean end_sequence)
dirac_enc->granulepos_low = dirac_enc->granulepos_offset +
presentation_frame + 1 - dirac_enc->granulepos_hi;
- gst_buffer_set_caps (outbuf,
- gst_caps_new_simple ("video/x-dirac",
- "width", G_TYPE_INT, dirac_enc->width,
- "height", G_TYPE_INT, dirac_enc->height,
- "framerate", GST_TYPE_FRACTION, dirac_enc->fps_n,
- dirac_enc->fps_d, NULL));
+ if (dirac_enc->srccaps == NULL) {
+ dirac_enc->srccaps = gst_caps_new_simple ("video/x-dirac",
+ "width", G_TYPE_INT, dirac_enc->width,
+ "height", G_TYPE_INT, dirac_enc->height,
+ "framerate", GST_TYPE_FRACTION, dirac_enc->fps_n,
+ dirac_enc->fps_d, NULL);
+ }
+ gst_buffer_set_caps (outbuf, dirac_enc->srccaps);
GST_BUFFER_SIZE (outbuf) = dirac_enc->encoder->enc_buf.size;
if (SCHRO_PARSE_CODE_IS_PICTURE (parse_code)) {
@@ -844,13 +964,8 @@ gst_dirac_enc_process (GstDiracEnc * dirac_enc, gboolean end_sequence)
gst_buffer_unref (outbuf);
return GST_FLOW_ERROR;
}
- if (end_sequence) {
- /* FIXME more hackage */
- return GST_FLOW_OK;
- }
} while (state == ENC_STATE_AVAIL);
- gst_buffer_unref (outbuf);
return GST_FLOW_OK;
}