ext/dirac/gstdiracenc.cc: Fix EOS handling. Clean up at object disposal. Handle 4:2:2 and 4:4:4 video.

Original commit message from CVS:
* ext/dirac/gstdiracenc.cc: Fix EOS handling.  Clean up at
object disposal.  Handle 4:2:2 and 4:4:4 video.
This commit is contained in:
David Schleef 2008-08-30 06:30:42 +00:00
parent a656d88bb5
commit 4aeacb6dbd
2 changed files with 169 additions and 49 deletions

View file

@ -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> 2008-08-29 Jan Schmidt <Jan.Schmidt@sun.com>
* ext/resindvd/resindvdbin.c: * ext/resindvd/resindvdbin.c:

View file

@ -79,6 +79,7 @@ struct _GstDiracEnc
dirac_encoder_t *encoder; dirac_encoder_t *encoder;
dirac_sourceparams_t *src_params; dirac_sourceparams_t *src_params;
GstBuffer *buffer; GstBuffer *buffer;
GstCaps *srccaps;
}; };
struct _GstDiracEncClass struct _GstDiracEncClass
@ -137,7 +138,7 @@ static GstStaticPadTemplate gst_dirac_enc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, 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 = 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", gst_structure_get_fraction (structure, "pixel-aspect-ratio",
&dirac_enc->par_n, &dirac_enc->par_d); &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) { switch (dirac_enc->fourcc) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'): case GST_MAKE_FOURCC ('I', '4', '2', '0'):
case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
dirac_enc->enc_ctx.src_params.chroma = format420; dirac_enc->enc_ctx.src_params.chroma = format420;
break; break;
case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
@ -355,8 +350,7 @@ gst_dirac_enc_finalize (GObject * object)
dirac_enc = GST_DIRAC_ENC (object); dirac_enc = GST_DIRAC_ENC (object);
if (dirac_enc->encoder) { if (dirac_enc->encoder) {
/* FIXME */ dirac_encoder_close (dirac_enc->encoder);
//dirac_encoder_free (dirac_enc->encoder);
dirac_enc->encoder = NULL; 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); encoder->enc_ctx.enc_params.picture_coding_mode = g_value_get_int (value);
break; break;
case PROP_USE_VLC: 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; break;
} }
} }
@ -447,32 +441,74 @@ static void
gst_dirac_enc_get_property (GObject * object, guint prop_id, GValue * value, gst_dirac_enc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec) GParamSpec * pspec)
{ {
GstDiracEnc *src; GstDiracEnc *encoder;
g_return_if_fail (GST_IS_DIRAC_ENC (object)); g_return_if_fail (GST_IS_DIRAC_ENC (object));
src = GST_DIRAC_ENC (object); encoder = GST_DIRAC_ENC (object);
#if 0 switch (prop_id) {
if (prop_id >= 1) { case PROP_L1_SEP:
const DiracEncoderSetting *setting; g_value_set_int (value, encoder->enc_ctx.enc_params.L1_sep);
break;
setting = dirac_encoder_get_setting_info (prop_id - 1); case PROP_NUM_L1:
switch (G_VALUE_TYPE (value)) { g_value_set_int (value, encoder->enc_ctx.enc_params.num_L1);
case G_TYPE_DOUBLE: break;
g_value_set_double (value, case PROP_XBLEN:
dirac_encoder_setting_get_double (src->encoder, setting->name)); g_value_set_int (value, encoder->enc_ctx.enc_params.xblen);
break; break;
case G_TYPE_INT: case PROP_YBLEN:
g_value_set_int (value, g_value_set_int (value, encoder->enc_ctx.enc_params.yblen);
dirac_encoder_setting_get_double (src->encoder, setting->name)); break;
break; case PROP_XBSEP:
case G_TYPE_BOOLEAN: g_value_set_int (value, encoder->enc_ctx.enc_params.xbsep);
g_value_set_boolean (value, break;
dirac_encoder_setting_get_double (src->encoder, setting->name)); case PROP_YBSEP:
break; 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 static gboolean
@ -732,8 +768,91 @@ gst_dirac_enc_chain (GstPad * pad, GstBuffer * buf)
dirac_enc->started = TRUE; dirac_enc->started = TRUE;
} }
dirac_encoder_load (dirac_enc->encoder, GST_BUFFER_DATA (buf), switch (dirac_enc->fourcc) {
GST_BUFFER_SIZE (buf)); 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); 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); dirac_enc->encoder->enc_buf.size = GST_BUFFER_SIZE (outbuf);
if (end_sequence) { if (end_sequence) {
/* FIXME this is a hack to make the code simpler. */
dirac_encoder_end_sequence (dirac_enc->encoder); 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) { switch (state) {
case ENC_STATE_BUFFER: case ENC_STATE_BUFFER:
gst_buffer_unref (outbuf);
break; break;
case ENC_STATE_INVALID: case ENC_STATE_INVALID:
GST_ERROR ("Dirac returned ENC_STATE_INVALID"); GST_ERROR ("Dirac returned ENC_STATE_INVALID");
gst_buffer_unref (outbuf); gst_buffer_unref (outbuf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
case ENC_STATE_EOS:
case ENC_STATE_AVAIL: case ENC_STATE_AVAIL:
parse_code = ((guint8 *) GST_BUFFER_DATA (outbuf))[4]; parse_code = ((guint8 *) GST_BUFFER_DATA (outbuf))[4];
/* FIXME */ /* FIXME */
@ -790,12 +908,14 @@ gst_dirac_enc_process (GstDiracEnc * dirac_enc, gboolean end_sequence)
dirac_enc->granulepos_low = dirac_enc->granulepos_offset + dirac_enc->granulepos_low = dirac_enc->granulepos_offset +
presentation_frame + 1 - dirac_enc->granulepos_hi; presentation_frame + 1 - dirac_enc->granulepos_hi;
gst_buffer_set_caps (outbuf, if (dirac_enc->srccaps == NULL) {
gst_caps_new_simple ("video/x-dirac", dirac_enc->srccaps = gst_caps_new_simple ("video/x-dirac",
"width", G_TYPE_INT, dirac_enc->width, "width", G_TYPE_INT, dirac_enc->width,
"height", G_TYPE_INT, dirac_enc->height, "height", G_TYPE_INT, dirac_enc->height,
"framerate", GST_TYPE_FRACTION, dirac_enc->fps_n, "framerate", GST_TYPE_FRACTION, dirac_enc->fps_n,
dirac_enc->fps_d, NULL)); dirac_enc->fps_d, NULL);
}
gst_buffer_set_caps (outbuf, dirac_enc->srccaps);
GST_BUFFER_SIZE (outbuf) = dirac_enc->encoder->enc_buf.size; GST_BUFFER_SIZE (outbuf) = dirac_enc->encoder->enc_buf.size;
if (SCHRO_PARSE_CODE_IS_PICTURE (parse_code)) { 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); gst_buffer_unref (outbuf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
if (end_sequence) {
/* FIXME more hackage */
return GST_FLOW_OK;
}
} while (state == ENC_STATE_AVAIL); } while (state == ENC_STATE_AVAIL);
gst_buffer_unref (outbuf);
return GST_FLOW_OK; return GST_FLOW_OK;
} }