y4m: port to 0.11

This commit is contained in:
Wim Taymans 2011-10-16 17:41:45 +02:00
parent e856f6f475
commit 4a3dbe3d42
3 changed files with 83 additions and 105 deletions

View file

@ -302,7 +302,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \
mpegpsmux mpegvideoparse mve mxf nsf nuvdemux \ mpegpsmux mpegvideoparse mve mxf nsf nuvdemux \
patchdetect pcapparse pnm rawparse real removesilence rtpmux rtpvp8 scaletempo \ patchdetect pcapparse pnm rawparse real removesilence rtpmux rtpvp8 scaletempo \
sdi segmentclip siren speed subenc stereo tta videofilters \ sdi segmentclip siren speed subenc stereo tta videofilters \
videomaxrate videomeasure videoparsers videosignal vmnc y4m \ videomaxrate videomeasure videoparsers videosignal vmnc \
decklink fbdev linsys shm vcd \ decklink fbdev linsys shm vcd \
voaacenc apexsink bz2 camerabin2 cdaudio celt cog curl dc1394 dirac directfb dts resindvd \ voaacenc apexsink bz2 camerabin2 cdaudio celt cog curl dc1394 dirac directfb dts resindvd \
gsettings gsm jp2k ladspa modplug mpeg2enc mplex mimic \ gsettings gsm jp2k ladspa modplug mpeg2enc mplex mimic \

View file

@ -82,17 +82,25 @@ static GstStaticPadTemplate gst_y4m_dec_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{I420,Y42B,Y444}")) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{I420,Y42B,Y444}"))
); );
/* class initialization */ /* class initialization */
#define gst_y4m_dec_parent_class parent_class
GST_BOILERPLATE (GstY4mDec, gst_y4m_dec, GstElement, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstY4mDec, gst_y4m_dec, GST_TYPE_ELEMENT);
static void static void
gst_y4m_dec_base_init (gpointer g_class) gst_y4m_dec_class_init (GstY4mDecClass * klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class->set_property = gst_y4m_dec_set_property;
gobject_class->get_property = gst_y4m_dec_get_property;
gobject_class->dispose = gst_y4m_dec_dispose;
gobject_class->finalize = gst_y4m_dec_finalize;
element_class->change_state = GST_DEBUG_FUNCPTR (gst_y4m_dec_change_state);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_y4m_dec_src_template)); gst_static_pad_template_get (&gst_y4m_dec_src_template));
@ -105,21 +113,7 @@ gst_y4m_dec_base_init (gpointer g_class)
} }
static void static void
gst_y4m_dec_class_init (GstY4mDecClass * klass) gst_y4m_dec_init (GstY4mDec * y4mdec)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class->set_property = gst_y4m_dec_set_property;
gobject_class->get_property = gst_y4m_dec_get_property;
gobject_class->dispose = gst_y4m_dec_dispose;
gobject_class->finalize = gst_y4m_dec_finalize;
element_class->change_state = GST_DEBUG_FUNCPTR (gst_y4m_dec_change_state);
}
static void
gst_y4m_dec_init (GstY4mDec * y4mdec, GstY4mDecClass * y4mdec_class)
{ {
y4mdec->adapter = gst_adapter_new (); y4mdec->adapter = gst_adapter_new ();
@ -232,15 +226,15 @@ gst_y4m_dec_change_state (GstElement * element, GstStateChange transition)
static GstClockTime static GstClockTime
gst_y4m_dec_frames_to_timestamp (GstY4mDec * y4mdec, int frame_index) gst_y4m_dec_frames_to_timestamp (GstY4mDec * y4mdec, int frame_index)
{ {
return gst_util_uint64_scale (frame_index, GST_SECOND * y4mdec->fps_d, return gst_util_uint64_scale (frame_index, GST_SECOND * y4mdec->info.fps_d,
y4mdec->fps_n); y4mdec->info.fps_n);
} }
static int static int
gst_y4m_dec_timestamp_to_frames (GstY4mDec * y4mdec, GstClockTime timestamp) gst_y4m_dec_timestamp_to_frames (GstY4mDec * y4mdec, GstClockTime timestamp)
{ {
return gst_util_uint64_scale (timestamp, y4mdec->fps_n, return gst_util_uint64_scale (timestamp, y4mdec->info.fps_n,
GST_SECOND * y4mdec->fps_d); GST_SECOND * y4mdec->info.fps_d);
} }
static int static int
@ -248,13 +242,13 @@ gst_y4m_dec_bytes_to_frames (GstY4mDec * y4mdec, gint64 bytes)
{ {
if (bytes < y4mdec->header_size) if (bytes < y4mdec->header_size)
return 0; return 0;
return (bytes - y4mdec->header_size) / (y4mdec->frame_size + 6); return (bytes - y4mdec->header_size) / (y4mdec->info.size + 6);
} }
static gint64 static gint64
gst_y4m_dec_frames_to_bytes (GstY4mDec * y4mdec, int frame_index) gst_y4m_dec_frames_to_bytes (GstY4mDec * y4mdec, int frame_index)
{ {
return y4mdec->header_size + (y4mdec->frame_size + 6) * frame_index; return y4mdec->header_size + (y4mdec->info.size + 6) * frame_index;
} }
static GstClockTime static GstClockTime
@ -269,8 +263,12 @@ static gboolean
gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header) gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
{ {
char *end; char *end;
int format = 420; int iformat = 420;
int interlaced_char = 0; int interlaced_char = 0;
gint fps_n = 0, fps_d = 0;
gint par_n = 0, par_d = 0;
gint width = 0, height = 0;
GstVideoFormat format;
if (memcmp (header, "YUV4MPEG2 ", 10) != 0) { if (memcmp (header, "YUV4MPEG2 ", 10) != 0) {
return FALSE; return FALSE;
@ -285,21 +283,21 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
break; break;
case 'C': case 'C':
header++; header++;
format = strtoul (header, &end, 10); iformat = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
break; break;
case 'W': case 'W':
header++; header++;
y4mdec->width = strtoul (header, &end, 10); width = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
break; break;
case 'H': case 'H':
header++; header++;
y4mdec->height = strtoul (header, &end, 10); height = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
@ -315,7 +313,7 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
break; break;
case 'F': case 'F':
header++; header++;
y4mdec->fps_n = strtoul (header, &end, 10); fps_n = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
@ -324,14 +322,14 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
return FALSE; return FALSE;
} }
header++; header++;
y4mdec->fps_d = strtoul (header, &end, 10); fps_d = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
break; break;
case 'A': case 'A':
header++; header++;
y4mdec->par_n = strtoul (header, &end, 10); par_n = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
@ -340,7 +338,7 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
return FALSE; return FALSE;
} }
header++; header++;
y4mdec->par_d = strtoul (header, &end, 10); par_d = strtoul (header, &end, 10);
if (end == header) if (end == header)
goto error; goto error;
header = end; header = end;
@ -354,41 +352,39 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
} }
} }
switch (format) { switch (iformat) {
case 420: case 420:
y4mdec->format = GST_VIDEO_FORMAT_I420; format = GST_VIDEO_FORMAT_I420;
break; break;
case 422: case 422:
y4mdec->format = GST_VIDEO_FORMAT_Y42B; format = GST_VIDEO_FORMAT_Y42B;
break; break;
case 444: case 444:
y4mdec->format = GST_VIDEO_FORMAT_Y444; format = GST_VIDEO_FORMAT_Y444;
break; break;
default: default:
GST_WARNING_OBJECT (y4mdec, "unknown y4m format %d", format); GST_WARNING_OBJECT (y4mdec, "unknown y4m format %d", iformat);
return FALSE; return FALSE;
} }
if (y4mdec->width <= 0 || y4mdec->width > MAX_SIZE || if (width <= 0 || width > MAX_SIZE || height <= 0 || height > MAX_SIZE) {
y4mdec->height <= 0 || y4mdec->height > MAX_SIZE) { GST_WARNING_OBJECT (y4mdec, "Dimensions %dx%d out of range", width, height);
GST_WARNING_OBJECT (y4mdec, "Dimensions %dx%d out of range",
y4mdec->width, y4mdec->height);
return FALSE; return FALSE;
} }
y4mdec->frame_size = gst_video_format_get_size (y4mdec->format, gst_video_info_set_format (&y4mdec->info, format, width, height);
y4mdec->width, y4mdec->height);
switch (interlaced_char) { switch (interlaced_char) {
case 0: case 0:
case '?': case '?':
case 'p': case 'p':
y4mdec->interlaced = FALSE; y4mdec->info.flags &= ~GST_VIDEO_FLAG_INTERLACED;
break; break;
case 't': case 't':
case 'b': case 'b':
y4mdec->interlaced = TRUE; y4mdec->info.flags |= GST_VIDEO_FLAG_INTERLACED;
y4mdec->tff = (interlaced_char == 't'); if (interlaced_char == 't')
y4mdec->info.flags |= GST_VIDEO_FLAG_TFF;
break; break;
default: default:
GST_WARNING_OBJECT (y4mdec, "Unknown interlaced char '%c'", GST_WARNING_OBJECT (y4mdec, "Unknown interlaced char '%c'",
@ -397,14 +393,19 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
break; break;
} }
if (y4mdec->fps_n == 0) if (fps_n == 0)
y4mdec->fps_n = 1; fps_n = 1;
if (y4mdec->fps_d == 0) if (fps_d == 0)
y4mdec->fps_d = 1; fps_d = 1;
if (y4mdec->par_n == 0) if (par_n == 0)
y4mdec->par_n = 1; par_n = 1;
if (y4mdec->par_d == 0) if (par_d == 0)
y4mdec->par_d = 1; par_d = 1;
y4mdec->info.fps_n = fps_n;
y4mdec->info.fps_d = fps_d;
y4mdec->info.par_n = par_n;
y4mdec->info.par_d = par_d;
return TRUE; return TRUE;
error: error:
@ -460,10 +461,7 @@ gst_y4m_dec_chain (GstPad * pad, GstBuffer * buffer)
y4mdec->header_size = strlen (header) + 1; y4mdec->header_size = strlen (header) + 1;
gst_adapter_flush (y4mdec->adapter, y4mdec->header_size); gst_adapter_flush (y4mdec->adapter, y4mdec->header_size);
caps = gst_video_format_new_caps_interlaced (y4mdec->format, caps = gst_video_info_to_caps (&y4mdec->info);
y4mdec->width, y4mdec->height,
y4mdec->fps_n, y4mdec->fps_d,
y4mdec->par_n, y4mdec->par_d, y4mdec->interlaced);
ret = gst_pad_set_caps (y4mdec->srcpad, caps); ret = gst_pad_set_caps (y4mdec->srcpad, caps);
gst_caps_unref (caps); gst_caps_unref (caps);
if (!ret) { if (!ret) {
@ -477,21 +475,25 @@ gst_y4m_dec_chain (GstPad * pad, GstBuffer * buffer)
if (y4mdec->have_new_segment) { if (y4mdec->have_new_segment) {
GstEvent *event; GstEvent *event;
GstClockTime start = gst_y4m_dec_bytes_to_timestamp (y4mdec, GstClockTime start = gst_y4m_dec_bytes_to_timestamp (y4mdec,
y4mdec->segment_start); y4mdec->segment.start);
GstClockTime stop = gst_y4m_dec_bytes_to_timestamp (y4mdec, GstClockTime stop = gst_y4m_dec_bytes_to_timestamp (y4mdec,
y4mdec->segment_stop); y4mdec->segment.stop);
GstClockTime position = gst_y4m_dec_bytes_to_timestamp (y4mdec, GstClockTime time = gst_y4m_dec_bytes_to_timestamp (y4mdec,
y4mdec->segment_position); y4mdec->segment.time);
GstSegment seg;
event = gst_event_new_new_segment (FALSE, 1.0, gst_segment_init (&seg, GST_FORMAT_TIME);
GST_FORMAT_TIME, start, stop, position); seg.start = start;
seg.stop = stop;
seg.time = time;
event = gst_event_new_segment (&seg);
gst_pad_push_event (y4mdec->srcpad, event); gst_pad_push_event (y4mdec->srcpad, event);
//gst_event_unref (event); //gst_event_unref (event);
y4mdec->have_new_segment = FALSE; y4mdec->have_new_segment = FALSE;
y4mdec->frame_index = gst_y4m_dec_bytes_to_frames (y4mdec, y4mdec->frame_index = gst_y4m_dec_bytes_to_frames (y4mdec,
y4mdec->segment_position); y4mdec->segment.time);
GST_DEBUG ("new frame_index %d", y4mdec->frame_index); GST_DEBUG ("new frame_index %d", y4mdec->frame_index);
} }
@ -515,25 +517,24 @@ gst_y4m_dec_chain (GstPad * pad, GstBuffer * buffer)
} }
len = strlen (header); len = strlen (header);
if (n_avail < y4mdec->frame_size + len + 1) { if (n_avail < y4mdec->info.size + len + 1) {
/* not enough data */ /* not enough data */
GST_DEBUG ("not enough data for frame %d < %d", GST_DEBUG ("not enough data for frame %d < %d",
n_avail, y4mdec->frame_size + len + 1); n_avail, y4mdec->info.size + len + 1);
break; break;
} }
gst_adapter_flush (y4mdec->adapter, len + 1); gst_adapter_flush (y4mdec->adapter, len + 1);
buffer = gst_adapter_take_buffer (y4mdec->adapter, y4mdec->frame_size); buffer = gst_adapter_take_buffer (y4mdec->adapter, y4mdec->info.size);
GST_BUFFER_CAPS (buffer) = gst_caps_ref (GST_PAD_CAPS (y4mdec->srcpad));
GST_BUFFER_TIMESTAMP (buffer) = GST_BUFFER_TIMESTAMP (buffer) =
gst_y4m_dec_frames_to_timestamp (y4mdec, y4mdec->frame_index); gst_y4m_dec_frames_to_timestamp (y4mdec, y4mdec->frame_index);
GST_BUFFER_DURATION (buffer) = GST_BUFFER_DURATION (buffer) =
gst_y4m_dec_frames_to_timestamp (y4mdec, y4mdec->frame_index + 1) - gst_y4m_dec_frames_to_timestamp (y4mdec, y4mdec->frame_index + 1) -
GST_BUFFER_TIMESTAMP (buffer); GST_BUFFER_TIMESTAMP (buffer);
if (y4mdec->interlaced && y4mdec->tff) { if (y4mdec->info.flags & GST_VIDEO_FLAG_TFF) {
GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_TFF); GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF);
} }
y4mdec->frame_index++; y4mdec->frame_index++;
@ -565,28 +566,16 @@ gst_y4m_dec_sink_event (GstPad * pad, GstEvent * event)
case GST_EVENT_FLUSH_STOP: case GST_EVENT_FLUSH_STOP:
res = gst_pad_push_event (y4mdec->srcpad, event); res = gst_pad_push_event (y4mdec->srcpad, event);
break; break;
case GST_EVENT_NEWSEGMENT: case GST_EVENT_SEGMENT:
{ {
gboolean update; GstSegment seg;
gdouble rate;
gdouble applied_rate;
GstFormat format;
gint64 start;
gint64 stop;
gint64 position;
gst_event_parse_new_segment_full (event, &update, &rate, gst_event_copy_segment (event, &seg);
&applied_rate, &format, &start, &stop, &position);
GST_DEBUG ("new_segment: update: %d rate: %g applied_rate: %g " GST_DEBUG ("segment: %" GST_SEGMENT_FORMAT, &seg);
"format: %d start: %" G_GUINT64_FORMAT " stop: %" G_GUINT64_FORMAT
" position %" G_GUINT64_FORMAT,
update, rate, applied_rate, format, start, stop, position);
if (format == GST_FORMAT_BYTES) { if (seg.format == GST_FORMAT_BYTES) {
y4mdec->segment_start = start; y4mdec->segment = seg;
y4mdec->segment_stop = stop;
y4mdec->segment_position = position;
y4mdec->have_new_segment = TRUE; y4mdec->have_new_segment = TRUE;
} }

View file

@ -48,20 +48,9 @@ struct _GstY4mDec
int header_size; int header_size;
gboolean have_new_segment; gboolean have_new_segment;
gint64 segment_start; GstSegment segment;
gint64 segment_stop;
gint64 segment_position;
int width; GstVideoInfo info;
int height;
GstVideoFormat format;
gboolean interlaced;
gboolean tff;
int fps_n;
int fps_d;
int par_n;
int par_d;
int frame_size;
}; };
struct _GstY4mDecClass struct _GstY4mDecClass