Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
George Kiagiadakis
gst-plugins-good
Commits
9290baba
Commit
9290baba
authored
Jun 09, 2011
by
Wim Taymans
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
goom: port goom
parent
710fa239
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
107 deletions
+114
-107
gst/goom/gstgoom.c
gst/goom/gstgoom.c
+113
-107
gst/goom/gstgoom.h
gst/goom/gstgoom.h
+1
-0
No files found.
gst/goom/gstgoom.c
View file @
9290baba
/* gstgoom.c: implementation of goom drawing element
* Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
* (C) <2006> Wim Taymans <wim at fluendo dot com>
* (C) <2011> Wim Taymans <wim.taymans at gmail dot com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
...
...
@@ -86,9 +87,6 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
);
static
void
gst_goom_class_init
(
GstGoomClass
*
klass
);
static
void
gst_goom_base_init
(
GstGoomClass
*
klass
);
static
void
gst_goom_init
(
GstGoom
*
goom
);
static
void
gst_goom_finalize
(
GObject
*
object
);
static
GstStateChangeReturn
gst_goom_change_state
(
GstElement
*
element
,
...
...
@@ -100,48 +98,8 @@ static gboolean gst_goom_sink_event (GstPad * pad, GstEvent * event);
static
gboolean
gst_goom_src_query
(
GstPad
*
pad
,
GstQuery
*
query
);
static
gboolean
gst_goom_sink_setcaps
(
GstPad
*
pad
,
GstCaps
*
caps
);
static
gboolean
gst_goom_src_setcaps
(
GstPad
*
pad
,
GstCaps
*
caps
);
static
GstElementClass
*
parent_class
=
NULL
;
GType
gst_goom_get_type
(
void
)
{
static
GType
type
=
0
;
if
(
!
type
)
{
static
const
GTypeInfo
info
=
{
sizeof
(
GstGoomClass
),
(
GBaseInitFunc
)
gst_goom_base_init
,
NULL
,
(
GClassInitFunc
)
gst_goom_class_init
,
NULL
,
NULL
,
sizeof
(
GstGoom
),
0
,
(
GInstanceInitFunc
)
gst_goom_init
,
};
type
=
g_type_register_static
(
GST_TYPE_ELEMENT
,
"GstGoom"
,
&
info
,
0
);
}
return
type
;
}
static
void
gst_goom_base_init
(
GstGoomClass
*
klass
)
{
GstElementClass
*
element_class
=
GST_ELEMENT_CLASS
(
klass
);
gst_element_class_set_details_simple
(
element_class
,
"GOOM: what a GOOM!"
,
"Visualization"
,
"Takes frames of data and outputs video frames using the GOOM filter"
,
"Wim Taymans <wim@fluendo.com>"
);
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
sink_template
));
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
src_template
));
}
#define gst_goom_parent_class parent_class
G_DEFINE_TYPE
(
GstGoom
,
gst_goom
,
GST_TYPE_ELEMENT
);
static
void
gst_goom_class_init
(
GstGoomClass
*
klass
)
...
...
@@ -152,10 +110,17 @@ gst_goom_class_init (GstGoomClass * klass)
gobject_class
=
(
GObjectClass
*
)
klass
;
gstelement_class
=
(
GstElementClass
*
)
klass
;
parent_class
=
g_type_class_peek_parent
(
klass
);
gobject_class
->
finalize
=
gst_goom_finalize
;
gst_element_class_set_details_simple
(
gstelement_class
,
"GOOM: what a GOOM!"
,
"Visualization"
,
"Takes frames of data and outputs video frames using the GOOM filter"
,
"Wim Taymans <wim@fluendo.com>"
);
gst_element_class_add_pad_template
(
gstelement_class
,
gst_static_pad_template_get
(
&
sink_template
));
gst_element_class_add_pad_template
(
gstelement_class
,
gst_static_pad_template_get
(
&
src_template
));
gstelement_class
->
change_state
=
GST_DEBUG_FUNCPTR
(
gst_goom_change_state
);
}
...
...
@@ -168,13 +133,9 @@ gst_goom_init (GstGoom * goom)
GST_DEBUG_FUNCPTR
(
gst_goom_chain
));
gst_pad_set_event_function
(
goom
->
sinkpad
,
GST_DEBUG_FUNCPTR
(
gst_goom_sink_event
));
gst_pad_set_setcaps_function
(
goom
->
sinkpad
,
GST_DEBUG_FUNCPTR
(
gst_goom_sink_setcaps
));
gst_element_add_pad
(
GST_ELEMENT
(
goom
),
goom
->
sinkpad
);
goom
->
srcpad
=
gst_pad_new_from_static_template
(
&
src_template
,
"src"
);
gst_pad_set_setcaps_function
(
goom
->
srcpad
,
GST_DEBUG_FUNCPTR
(
gst_goom_src_setcaps
));
gst_pad_set_event_function
(
goom
->
srcpad
,
GST_DEBUG_FUNCPTR
(
gst_goom_src_event
));
gst_pad_set_query_function
(
goom
->
srcpad
,
...
...
@@ -203,6 +164,8 @@ gst_goom_finalize (GObject * object)
goom
->
plugin
=
NULL
;
g_object_unref
(
goom
->
adapter
);
if
(
goom
->
pool
)
gst_object_unref
(
goom
->
pool
);
G_OBJECT_CLASS
(
parent_class
)
->
finalize
(
object
);
}
...
...
@@ -220,14 +183,11 @@ gst_goom_reset (GstGoom * goom)
}
static
gboolean
gst_goom_sink_setcaps
(
Gst
Pad
*
pad
,
GstCaps
*
caps
)
gst_goom_sink_setcaps
(
Gst
Goom
*
goom
,
GstCaps
*
caps
)
{
GstGoom
*
goom
;
GstStructure
*
structure
;
gboolean
res
;
goom
=
GST_GOOM
(
GST_PAD_PARENT
(
pad
));
structure
=
gst_caps_get_structure
(
caps
,
0
);
res
=
gst_structure_get_int
(
structure
,
"channels"
,
&
goom
->
channels
);
...
...
@@ -235,24 +195,21 @@ gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps)
goom
->
bps
=
goom
->
channels
*
sizeof
(
gint16
);
return
res
;
return
TRUE
;
}
static
gboolean
gst_goom_src_setcaps
(
Gst
Pad
*
pad
,
GstCaps
*
caps
)
gst_goom_src_setcaps
(
Gst
Goom
*
goom
,
GstCaps
*
caps
)
{
GstGoom
*
goom
;
GstStructure
*
structure
;
goom
=
GST_GOOM
(
GST_PAD_PARENT
(
pad
));
gboolean
res
;
structure
=
gst_caps_get_structure
(
caps
,
0
);
if
(
!
gst_structure_get_int
(
structure
,
"width"
,
&
goom
->
width
)
||
!
gst_structure_get_int
(
structure
,
"height"
,
&
goom
->
height
)
||
!
gst_structure_get_fraction
(
structure
,
"framerate"
,
&
goom
->
fps_n
,
&
goom
->
fps_d
))
return
FALSE
;
goto
error
;
goom_set_resolution
(
goom
->
plugin
,
goom
->
width
,
goom
->
height
);
...
...
@@ -266,32 +223,46 @@ gst_goom_src_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT
(
goom
,
"dimension %dx%d, framerate %d/%d, spf %d"
,
goom
->
width
,
goom
->
height
,
goom
->
fps_n
,
goom
->
fps_d
,
goom
->
spf
);
return
TRUE
;
res
=
gst_pad_push_event
(
goom
->
srcpad
,
gst_event_new_caps
(
caps
));
return
res
;
/* ERRORS */
error:
{
GST_DEBUG_OBJECT
(
goom
,
"error parsing caps"
);
return
FALSE
;
}
}
static
gboolean
gst_goom_src_negotiate
(
GstGoom
*
goom
)
{
gboolean
res
;
GstCaps
*
othercaps
,
*
target
;
GstStructure
*
structure
;
const
GstCaps
*
templ
;
GstCaps
*
templ
;
GstQuery
*
query
;
GstBufferPool
*
pool
=
NULL
;
guint
size
,
min
,
max
,
prefix
,
alignment
;
templ
=
gst_pad_get_pad_template_caps
(
goom
->
srcpad
);
GST_DEBUG_OBJECT
(
goom
,
"performing negotiation"
);
/* see what the peer can do */
othercaps
=
gst_pad_peer_get_caps
(
goom
->
srcpad
);
othercaps
=
gst_pad_peer_get_caps
(
goom
->
srcpad
,
NULL
);
if
(
othercaps
)
{
target
=
gst_caps_intersect
(
othercaps
,
templ
);
gst_caps_unref
(
othercaps
);
gst_caps_unref
(
templ
);
if
(
gst_caps_is_empty
(
target
))
goto
no_format
;
gst_caps_truncate
(
target
);
}
else
{
target
=
gst_caps_ref
((
GstCaps
*
)
templ
)
;
target
=
templ
;
}
structure
=
gst_caps_get_structure
(
target
,
0
);
...
...
@@ -300,7 +271,42 @@ gst_goom_src_negotiate (GstGoom * goom)
gst_structure_fixate_field_nearest_fraction
(
structure
,
"framerate"
,
DEFAULT_FPS_N
,
DEFAULT_FPS_D
);
gst_pad_set_caps
(
goom
->
srcpad
,
target
);
res
=
gst_goom_src_setcaps
(
goom
,
target
);
/* try to get a bufferpool now */
/* find a pool for the negotiated caps now */
query
=
gst_query_new_allocation
(
target
,
TRUE
);
if
(
gst_pad_peer_query
(
goom
->
srcpad
,
query
))
{
/* we got configuration from our peer, parse them */
gst_query_parse_allocation_params
(
query
,
&
size
,
&
min
,
&
max
,
&
prefix
,
&
alignment
,
&
pool
);
}
else
{
size
=
goom
->
outsize
;
min
=
max
=
0
;
prefix
=
0
;
alignment
=
1
;
}
if
(
pool
==
NULL
)
{
GstStructure
*
config
;
/* we did not get a pool, make one ourselves then */
pool
=
gst_buffer_pool_new
();
config
=
gst_buffer_pool_get_config
(
pool
);
gst_buffer_pool_config_set
(
config
,
target
,
size
,
min
,
max
,
prefix
,
0
,
alignment
);
gst_buffer_pool_set_config
(
pool
,
config
);
}
if
(
goom
->
pool
)
gst_object_unref
(
goom
->
pool
);
goom
->
pool
=
pool
;
/* and activate */
gst_buffer_pool_set_active
(
pool
,
TRUE
);
gst_caps_unref
(
target
);
return
TRUE
;
...
...
@@ -327,7 +333,7 @@ gst_goom_src_event (GstPad * pad, GstEvent * event)
GstClockTimeDiff
diff
;
GstClockTime
timestamp
;
gst_event_parse_qos
(
event
,
&
proportion
,
&
diff
,
&
timestamp
);
gst_event_parse_qos
(
event
,
NULL
,
&
proportion
,
&
diff
,
&
timestamp
);
/* save stuff for the _chain() function */
GST_OBJECT_LOCK
(
goom
);
...
...
@@ -361,6 +367,14 @@ gst_goom_sink_event (GstPad * pad, GstEvent * event)
goom
=
GST_GOOM
(
gst_pad_get_parent
(
pad
));
switch
(
GST_EVENT_TYPE
(
event
))
{
case
GST_EVENT_CAPS
:
{
GstCaps
*
caps
;
gst_event_parse_caps
(
event
,
&
caps
);
res
=
gst_goom_sink_setcaps
(
goom
,
caps
);
break
;
}
case
GST_EVENT_FLUSH_START
:
res
=
gst_pad_push_event
(
goom
->
srcpad
,
event
);
break
;
...
...
@@ -368,22 +382,12 @@ gst_goom_sink_event (GstPad * pad, GstEvent * event)
gst_goom_reset
(
goom
);
res
=
gst_pad_push_event
(
goom
->
srcpad
,
event
);
break
;
case
GST_EVENT_
NEW
SEGMENT
:
case
GST_EVENT_SEGMENT
:
{
GstFormat
format
;
gdouble
rate
,
arate
;
gint64
start
,
stop
,
time
;
gboolean
update
;
/* the newsegment values are used to clip the input samples
* and to convert the incomming timestamps to running time so
* we can do QoS */
gst_event_parse_new_segment_full
(
event
,
&
update
,
&
rate
,
&
arate
,
&
format
,
&
start
,
&
stop
,
&
time
);
/* now configure the values */
gst_segment_set_newsegment_full
(
&
goom
->
segment
,
update
,
rate
,
arate
,
format
,
start
,
stop
,
time
);
gst_event_copy_segment
(
event
,
&
goom
->
segment
);
res
=
gst_pad_push_event
(
goom
->
srcpad
,
event
);
break
;
...
...
@@ -454,29 +458,26 @@ gst_goom_src_query (GstPad * pad, GstQuery * query)
return
res
;
}
/* make sure we are negotiated */
static
GstFlowReturn
get_buffer
(
GstGoom
*
goom
,
GstBuffer
**
outbuf
)
ensure_negotiated
(
GstGoom
*
goom
)
{
GstFlowReturn
ret
;
gboolean
reconfigure
;
GST_OBJECT_LOCK
(
goom
->
srcpad
);
reconfigure
=
GST_PAD_NEEDS_RECONFIGURE
(
goom
->
srcpad
);
GST_OBJECT_FLAG_UNSET
(
goom
->
srcpad
,
GST_PAD_NEED_RECONFIGURE
);
GST_OBJECT_UNLOCK
(
goom
->
srcpad
);
if
(
GST_PAD_CAPS
(
goom
->
srcpad
)
==
NULL
)
{
/* we don't know an output format yet, pick one */
if
(
reconfigure
||
!
gst_pad_has_current_caps
(
goom
->
srcpad
))
{
if
(
!
gst_goom_src_negotiate
(
goom
))
return
GST_FLOW_NOT_NEGOTIATED
;
}
GST_DEBUG_OBJECT
(
goom
,
"allocating output buffer with caps %"
GST_PTR_FORMAT
,
GST_PAD_CAPS
(
goom
->
srcpad
));
ret
=
gst_pad_alloc_buffer_and_set_caps
(
goom
->
srcpad
,
GST_BUFFER_OFFSET_NONE
,
goom
->
outsize
,
GST_PAD_CAPS
(
goom
->
srcpad
),
outbuf
);
if
(
ret
!=
GST_FLOW_OK
)
return
ret
;
return
GST_FLOW_OK
;
}
static
GstFlowReturn
gst_goom_chain
(
GstPad
*
pad
,
GstBuffer
*
buffer
)
{
...
...
@@ -490,14 +491,11 @@ gst_goom_chain (GstPad * pad, GstBuffer * buffer)
goto
beach
;
}
/* If we don't have an output format yet, preallocate a buffer to try and
* set one */
if
(
GST_PAD_CAPS
(
goom
->
srcpad
)
==
NULL
)
{
ret
=
get_buffer
(
goom
,
&
outbuf
);
if
(
ret
!=
GST_FLOW_OK
)
{
gst_buffer_unref
(
buffer
);
goto
beach
;
}
/* Make sure have an output format */
ret
=
ensure_negotiated
(
goom
);
if
(
ret
!=
GST_FLOW_OK
)
{
gst_buffer_unref
(
buffer
);
goto
beach
;
}
/* don't try to combine samples from discont buffer */
...
...
@@ -507,7 +505,7 @@ gst_goom_chain (GstPad * pad, GstBuffer * buffer)
GST_DEBUG_OBJECT
(
goom
,
"Input buffer has %d samples, time=%"
G_GUINT64_FORMAT
,
GST_BUFFER_SIZE
(
buffer
)
/
goom
->
bps
,
GST_BUFFER_TIMESTAMP
(
buffer
));
gst_buffer_get_size
(
buffer
)
/
goom
->
bps
,
GST_BUFFER_TIMESTAMP
(
buffer
));
/* Collect samples until we have enough for an output frame */
gst_adapter_push
(
goom
->
adapter
,
buffer
);
...
...
@@ -565,7 +563,7 @@ gst_goom_chain (GstPad * pad, GstBuffer * buffer)
/* get next GOOM_SAMPLES, we have at least this amount of samples */
data
=
(
const
guint16
*
)
gst_adapter_
peek
(
goom
->
adapter
,
(
const
guint16
*
)
gst_adapter_
map
(
goom
->
adapter
,
GOOM_SAMPLES
*
goom
->
bps
);
if
(
goom
->
channels
==
2
)
{
...
...
@@ -583,18 +581,21 @@ gst_goom_chain (GstPad * pad, GstBuffer * buffer)
/* alloc a buffer if we don't have one yet, this happens
* when we pushed a buffer in this while loop before */
if
(
outbuf
==
NULL
)
{
ret
=
get_buffer
(
goom
,
&
outbuf
);
GST_DEBUG_OBJECT
(
goom
,
"allocating output buffer"
);
ret
=
gst_buffer_pool_acquire_buffer
(
goom
->
pool
,
&
outbuf
,
NULL
);
if
(
ret
!=
GST_FLOW_OK
)
{
gst_adapter_unmap
(
goom
->
adapter
,
0
);
goto
beach
;
}
}
GST_BUFFER_TIMESTAMP
(
outbuf
)
=
timestamp
;
GST_BUFFER_DURATION
(
outbuf
)
=
goom
->
duration
;
GST_BUFFER_SIZE
(
outbuf
)
=
goom
->
outsize
;
out_frame
=
(
guchar
*
)
goom_update
(
goom
->
plugin
,
goom
->
datain
,
0
,
0
);
memcpy
(
GST_BUFFER_DATA
(
outbuf
),
out_frame
,
goom
->
outsize
);
gst_buffer_fill
(
outbuf
,
0
,
out_frame
,
goom
->
outsize
);
gst_adapter_unmap
(
goom
->
adapter
,
0
);
GST_DEBUG
(
"Pushing frame with time=%"
GST_TIME_FORMAT
", duration=%"
GST_TIME_FORMAT
,
GST_TIME_ARGS
(
timestamp
),
...
...
@@ -645,6 +646,11 @@ gst_goom_change_state (GstElement * element, GstStateChange transition)
switch
(
transition
)
{
case
GST_STATE_CHANGE_PAUSED_TO_READY
:
if
(
goom
->
pool
)
{
gst_buffer_pool_set_active
(
goom
->
pool
,
FALSE
);
gst_object_unref
(
goom
->
pool
);
goom
->
pool
=
NULL
;
}
break
;
case
GST_STATE_CHANGE_READY_TO_NULL
:
break
;
...
...
gst/goom/gstgoom.h
View file @
9290baba
...
...
@@ -57,6 +57,7 @@ struct _GstGoom
gint
height
;
GstClockTime
duration
;
guint
outsize
;
GstBufferPool
*
pool
;
/* samples per frame */
guint
spf
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment