mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
ext/dv/gstdvdec.*: Infer pixel-aspect-ratio from the video frame format if it isn't provided by the container, as hap...
Original commit message from CVS: * ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_sink_setcaps), (gst_dvdec_src_negotiate), (gst_dvdec_chain), (gst_dvdec_change_state): * ext/dv/gstdvdec.h: Infer pixel-aspect-ratio from the video frame format if it isn't provided by the container, as happens when playing DV from AVI or Quicktime containers. Patch by: Wim Taymans <wim@fluendo.com> Fixes #380944
This commit is contained in:
parent
beef8e0136
commit
9d501ec355
3 changed files with 128 additions and 25 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2007-03-09 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
||||
* ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_sink_setcaps),
|
||||
(gst_dvdec_src_negotiate), (gst_dvdec_chain),
|
||||
(gst_dvdec_change_state):
|
||||
* ext/dv/gstdvdec.h:
|
||||
Infer pixel-aspect-ratio from the video frame format if it isn't
|
||||
provided by the container, as happens when playing DV from AVI
|
||||
or Quicktime containers.
|
||||
|
||||
Patch by: Wim Taymans <wim@fluendo.com>
|
||||
Fixes #380944
|
||||
|
||||
2007-03-09 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_activate_streams):
|
||||
|
|
|
@ -58,8 +58,25 @@ GST_ELEMENT_DETAILS ("DV video decoder",
|
|||
"Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
/* sizes of one input buffer */
|
||||
#define NTSC_HEIGHT 480
|
||||
#define NTSC_BUFFER 120000
|
||||
#define NTSC_FRAMERATE_NUMERATOR 30000
|
||||
#define NTSC_FRAMERATE_DENOMINATOR 1001
|
||||
|
||||
#define PAL_HEIGHT 576
|
||||
#define PAL_BUFFER 144000
|
||||
#define PAL_FRAMERATE_NUMERATOR 25
|
||||
#define PAL_FRAMERATE_DENOMINATOR 1
|
||||
|
||||
#define PAL_NORMAL_PAR_X 59
|
||||
#define PAL_NORMAL_PAR_Y 54
|
||||
#define PAL_WIDE_PAR_X 118
|
||||
#define PAL_WIDE_PAR_Y 81
|
||||
|
||||
#define NTSC_NORMAL_PAR_X 10
|
||||
#define NTSC_NORMAL_PAR_Y 11
|
||||
#define NTSC_WIDE_PAR_X 40
|
||||
#define NTSC_WIDE_PAR_Y 33
|
||||
|
||||
#define DV_DEFAULT_QUALITY DV_QUALITY_BEST
|
||||
#define DV_DEFAULT_DECODE_NTH 1
|
||||
|
@ -217,7 +234,6 @@ gst_dvdec_init (GstDVDec * dvdec, GstDVDecClass * g_class)
|
|||
|
||||
dvdec->framerate_numerator = 0;
|
||||
dvdec->framerate_denominator = 0;
|
||||
dvdec->height = 0;
|
||||
dvdec->wide = FALSE;
|
||||
dvdec->drop_factor = 1;
|
||||
|
||||
|
@ -242,8 +258,6 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
{
|
||||
GstDVDec *dvdec;
|
||||
GstStructure *s;
|
||||
GstCaps *othercaps;
|
||||
gboolean gotpar = FALSE;
|
||||
const GValue *par = NULL, *rate = NULL;
|
||||
|
||||
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
|
||||
|
@ -251,18 +265,67 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
/* first parse the caps */
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!gst_structure_get_int (s, "height", &dvdec->height))
|
||||
goto error;
|
||||
if ((par = gst_structure_get_value (s, "pixel-aspect-ratio")))
|
||||
gotpar = TRUE;
|
||||
/* we allow framerate and PAR to be overwritten. framerate is mandatory. */
|
||||
if (!(rate = gst_structure_get_value (s, "framerate")))
|
||||
goto error;
|
||||
goto no_framerate;
|
||||
par = gst_structure_get_value (s, "pixel-aspect-ratio");
|
||||
|
||||
if (par) {
|
||||
dvdec->par_x = gst_value_get_fraction_numerator (par);
|
||||
dvdec->par_y = gst_value_get_fraction_denominator (par);
|
||||
dvdec->need_par = FALSE;
|
||||
} else {
|
||||
dvdec->par_x = 0;
|
||||
dvdec->par_y = 0;
|
||||
dvdec->need_par = TRUE;
|
||||
}
|
||||
dvdec->framerate_numerator = gst_value_get_fraction_numerator (rate);
|
||||
dvdec->framerate_denominator = gst_value_get_fraction_denominator (rate);
|
||||
dvdec->sink_negotiated = TRUE;
|
||||
dvdec->src_negotiated = FALSE;
|
||||
|
||||
gst_object_unref (dvdec);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_framerate:
|
||||
{
|
||||
GST_DEBUG_OBJECT (dvdec, "no framerate specified in caps");
|
||||
gst_object_unref (dvdec);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_dvdec_src_negotiate (GstDVDec * dvdec)
|
||||
{
|
||||
GstCaps *othercaps;
|
||||
|
||||
/* no PAR was specified in input, derive from encoded data */
|
||||
if (dvdec->need_par) {
|
||||
if (dvdec->PAL) {
|
||||
if (dvdec->wide) {
|
||||
dvdec->par_x = PAL_WIDE_PAR_X;
|
||||
dvdec->par_y = PAL_WIDE_PAR_Y;
|
||||
} else {
|
||||
dvdec->par_x = PAL_NORMAL_PAR_X;
|
||||
dvdec->par_y = PAL_NORMAL_PAR_Y;
|
||||
}
|
||||
} else {
|
||||
if (dvdec->wide) {
|
||||
dvdec->par_x = NTSC_WIDE_PAR_X;
|
||||
dvdec->par_y = NTSC_WIDE_PAR_Y;
|
||||
} else {
|
||||
dvdec->par_x = NTSC_NORMAL_PAR_X;
|
||||
dvdec->par_y = NTSC_NORMAL_PAR_Y;
|
||||
}
|
||||
}
|
||||
GST_DEBUG_OBJECT (dvdec, "Inferred PAR %d/%d from video format",
|
||||
dvdec->par_x, dvdec->par_y);
|
||||
}
|
||||
|
||||
/* ignoring rgb, bgr0 for now */
|
||||
|
||||
dvdec->bpp = 2;
|
||||
|
||||
othercaps = gst_caps_new_simple ("video/x-raw-yuv",
|
||||
|
@ -270,25 +333,16 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
"width", G_TYPE_INT, 720,
|
||||
"height", G_TYPE_INT, dvdec->height,
|
||||
"framerate", GST_TYPE_FRACTION, dvdec->framerate_numerator,
|
||||
dvdec->framerate_denominator, NULL);
|
||||
if (gotpar)
|
||||
gst_structure_set_value (gst_caps_get_structure (othercaps, 0),
|
||||
"pixel-aspect-ratio", par);
|
||||
dvdec->framerate_denominator,
|
||||
"pixel-aspect-ratio", GST_TYPE_FRACTION, dvdec->par_x,
|
||||
dvdec->par_y, NULL);
|
||||
|
||||
gst_pad_set_caps (dvdec->srcpad, othercaps);
|
||||
|
||||
gst_caps_unref (othercaps);
|
||||
|
||||
gst_object_unref (dvdec);
|
||||
dvdec->src_negotiated = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
{
|
||||
gst_object_unref (dvdec);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -342,6 +396,7 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
guint length;
|
||||
gint64 cstart, cstop;
|
||||
gboolean PAL, wide;
|
||||
|
||||
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
|
||||
inframe = GST_BUFFER_DATA (buf);
|
||||
|
@ -362,9 +417,13 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
if (G_UNLIKELY (dv_parse_header (dvdec->decoder, inframe) < 0))
|
||||
goto parse_header_error;
|
||||
|
||||
/* get size */
|
||||
PAL = dv_system_50_fields (dvdec->decoder);
|
||||
wide = dv_format_wide (dvdec->decoder);
|
||||
|
||||
/* check the buffer is of right size after we know if we are
|
||||
* dealing with PAL or NTSC */
|
||||
length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER);
|
||||
length = (PAL ? PAL_BUFFER : NTSC_BUFFER);
|
||||
if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < length))
|
||||
goto wrong_size;
|
||||
|
||||
|
@ -373,6 +432,22 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
if (dvdec->video_offset % dvdec->drop_factor != 0)
|
||||
goto skip;
|
||||
|
||||
/* renegotiate on change */
|
||||
if (PAL != dvdec->PAL || wide != dvdec->wide) {
|
||||
dvdec->src_negotiated = FALSE;
|
||||
dvdec->PAL = PAL;
|
||||
dvdec->wide = wide;
|
||||
}
|
||||
|
||||
dvdec->height = (dvdec->PAL ? PAL_HEIGHT : NTSC_HEIGHT);
|
||||
|
||||
|
||||
/* negotiate if not done yet */
|
||||
if (!dvdec->src_negotiated) {
|
||||
if (!gst_dvdec_src_negotiate (dvdec))
|
||||
goto not_negotiated;
|
||||
}
|
||||
|
||||
ret =
|
||||
gst_pad_alloc_buffer_and_set_caps (dvdec->srcpad, 0,
|
||||
(720 * dvdec->height) * dvdec->bpp,
|
||||
|
@ -429,6 +504,12 @@ parse_header_error:
|
|||
ret = GST_FLOW_ERROR;
|
||||
goto done;
|
||||
}
|
||||
not_negotiated:
|
||||
{
|
||||
GST_DEBUG_OBJECT (dvdec, "could not negotiate output");
|
||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
goto done;
|
||||
}
|
||||
no_buffer:
|
||||
{
|
||||
GST_DEBUG_OBJECT (dvdec, "could not allocate buffer");
|
||||
|
@ -459,6 +540,8 @@ gst_dvdec_change_state (GstElement * element, GstStateChange transition)
|
|||
dvdec->decoder->quality = qualities[dvdec->quality];
|
||||
dv_set_error_log (dvdec->decoder, NULL);
|
||||
gst_segment_init (dvdec->segment, GST_FORMAT_UNDEFINED);
|
||||
dvdec->src_negotiated = FALSE;
|
||||
dvdec->sink_negotiated = FALSE;
|
||||
/*
|
||||
* Enable this function call when libdv2 0.100 or higher is more
|
||||
* common
|
||||
|
|
|
@ -56,16 +56,23 @@ struct _GstDVDec {
|
|||
gboolean clamp_chroma;
|
||||
gint quality;
|
||||
|
||||
gint frame_len;
|
||||
gboolean PAL;
|
||||
gboolean wide;
|
||||
gint frame_len;
|
||||
|
||||
/* input caps */
|
||||
gboolean sink_negotiated;
|
||||
gint framerate_numerator;
|
||||
gint framerate_denominator;
|
||||
gint height;
|
||||
gboolean wide;
|
||||
gint par_x;
|
||||
gint par_y;
|
||||
gboolean need_par;
|
||||
|
||||
/* negotiated output */
|
||||
dv_color_space_t space;
|
||||
gint bpp;
|
||||
gboolean src_negotiated;
|
||||
|
||||
gint video_offset;
|
||||
gint drop_factor;
|
||||
|
|
Loading…
Reference in a new issue