mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 08:08:22 +00:00
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:
parent
a656d88bb5
commit
4aeacb6dbd
2 changed files with 169 additions and 49 deletions
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue