Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Dröge
gst-plugins-base
Commits
e120979f
Commit
e120979f
authored
Apr 24, 2012
by
Sebastian Dröge
Browse files
theora: Port to 0.11 again with the new base classes
parent
a8c40a65
Changes
4
Hide whitespace changes
Inline
Side-by-side
ext/theora/gsttheoradec.c
View file @
e120979f
...
...
@@ -47,11 +47,13 @@
#include "gsttheoradec.h"
#include <gst/tag/tag.h>
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
#define GST_CAT_DEFAULT theoradec_debug
GST_DEBUG_CATEGORY_STATIC
(
GST_CAT_DEFAULT
);
GST_DEBUG_CATEGORY_EXTERN
(
GST_CAT_PERFORMANCE
);
#define THEORA_DEF_CROP TRUE
#define THEORA_DEF_TELEMETRY_MV 0
#define THEORA_DEF_TELEMETRY_MBMODE 0
#define THEORA_DEF_TELEMETRY_QI 0
...
...
@@ -60,7 +62,6 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum
{
PROP_0
,
PROP_CROP
,
PROP_TELEMETRY_MV
,
PROP_TELEMETRY_MBMODE
,
PROP_TELEMETRY_QI
,
...
...
@@ -71,8 +72,8 @@ static GstStaticPadTemplate theora_dec_src_factory =
GST_STATIC_PAD_TEMPLATE
(
"src"
,
GST_PAD_SRC
,
GST_PAD_ALWAYS
,
GST_STATIC_CAPS
(
"video/x-raw
-yuv
, "
"format = (
fourcc
) { I420, Y42B, Y444 }, "
GST_STATIC_CAPS
(
"video/x-raw, "
"format = (
string
) { I420, Y42B, Y444 }, "
"framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]"
)
);
...
...
@@ -84,8 +85,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS
(
"video/x-theora"
)
);
GST_BOILERPLATE
(
GstTheoraDec
,
gst_theora_dec
,
GstVideoDecoder
,
GST_TYPE_VIDEO_DECODER
);
#define gst_theora_dec_parent_class parent_class
G_DEFINE_TYPE
(
GstTheoraDec
,
gst_theora_dec
,
GST_TYPE_VIDEO_DECODER
);
static
void
theora_dec_get_property
(
GObject
*
object
,
guint
prop_id
,
GValue
*
value
,
GParamSpec
*
pspec
);
...
...
@@ -105,22 +106,6 @@ static GstFlowReturn theora_dec_handle_frame (GstVideoDecoder * decoder,
static
GstFlowReturn
theora_dec_decode_buffer
(
GstTheoraDec
*
dec
,
GstBuffer
*
buf
,
GstVideoCodecFrame
*
frame
);
static
void
gst_theora_dec_base_init
(
gpointer
g_class
)
{
GstElementClass
*
element_class
=
GST_ELEMENT_CLASS
(
g_class
);
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
theora_dec_src_factory
));
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
theora_dec_sink_factory
));
gst_element_class_set_details_simple
(
element_class
,
"Theora video decoder"
,
"Codec/Decoder/Video"
,
"decode raw theora streams to raw YUV video"
,
"Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>"
);
}
static
gboolean
gst_theora_dec_ctl_is_supported
(
int
req
)
{
...
...
@@ -132,16 +117,12 @@ static void
gst_theora_dec_class_init
(
GstTheoraDecClass
*
klass
)
{
GObjectClass
*
gobject_class
=
G_OBJECT_CLASS
(
klass
);
GstElementClass
*
element_class
=
GST_ELEMENT_CLASS
(
klass
);
GstVideoDecoderClass
*
video_decoder_class
=
GST_VIDEO_DECODER_CLASS
(
klass
);
gobject_class
->
set_property
=
theora_dec_set_property
;
gobject_class
->
get_property
=
theora_dec_get_property
;
g_object_class_install_property
(
gobject_class
,
PROP_CROP
,
g_param_spec_boolean
(
"crop"
,
"Crop"
,
"Crop the image to the visible region"
,
THEORA_DEF_CROP
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
if
(
gst_theora_dec_ctl_is_supported
(
TH_DECCTL_SET_TELEMETRY_MV
))
{
g_object_class_install_property
(
gobject_class
,
PROP_TELEMETRY_MV
,
g_param_spec_int
(
"visualize-motion-vectors"
,
...
...
@@ -186,6 +167,15 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
}
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
theora_dec_src_factory
));
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
theora_dec_sink_factory
));
gst_element_class_set_details_simple
(
element_class
,
"Theora video decoder"
,
"Codec/Decoder/Video"
,
"decode raw theora streams to raw YUV video"
,
"Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>"
);
video_decoder_class
->
start
=
GST_DEBUG_FUNCPTR
(
theora_dec_start
);
video_decoder_class
->
stop
=
GST_DEBUG_FUNCPTR
(
theora_dec_stop
);
video_decoder_class
->
reset
=
GST_DEBUG_FUNCPTR
(
theora_dec_reset
);
...
...
@@ -198,9 +188,8 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
}
static
void
gst_theora_dec_init
(
GstTheoraDec
*
dec
,
GstTheoraDecClass
*
g_class
)
gst_theora_dec_init
(
GstTheoraDec
*
dec
)
{
dec
->
crop
=
THEORA_DEF_CROP
;
dec
->
telemetry_mv
=
THEORA_DEF_TELEMETRY_MV
;
dec
->
telemetry_mbmode
=
THEORA_DEF_TELEMETRY_MBMODE
;
dec
->
telemetry_qi
=
THEORA_DEF_TELEMETRY_QI
;
...
...
@@ -269,10 +258,11 @@ theora_dec_parse (GstVideoDecoder * decoder,
av
=
gst_adapter_available
(
adapter
);
data
=
gst_adapter_
peek
(
adapter
,
1
);
data
=
gst_adapter_
map
(
adapter
,
1
);
/* check for keyframe; must not be header packet */
if
(
!
(
data
[
0
]
&
0x80
)
&&
(
data
[
0
]
&
0x40
)
==
0
)
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT
(
frame
);
gst_adapter_unmap
(
adapter
);
/* and pass along all */
gst_video_decoder_add_to_frame
(
decoder
,
av
);
...
...
@@ -295,15 +285,17 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
/* FIXME : Interesting, we always accept any kind of caps ? */
if
(
state
->
codec_data
)
{
GstBuffer
*
buffer
;
GstMapInfo
minfo
;
guint8
*
data
;
guint
size
;
guint
offset
;
buffer
=
state
->
codec_data
;
gst_buffer_map
(
buffer
,
&
minfo
,
GST_MAP_READ
);
offset
=
0
;
size
=
GST_BUFFER_SIZE
(
buffer
)
;
data
=
GST_BUFFER_DATA
(
buffer
)
;
size
=
minfo
.
size
;
data
=
(
guint8
*
)
minfo
.
data
;
while
(
size
>
2
)
{
guint
psize
;
...
...
@@ -318,7 +310,7 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
/* make sure we don't read too much */
psize
=
MIN
(
psize
,
size
);
buf
=
gst_buffer_c
reate_sub
(
buffer
,
offset
,
psize
);
buf
=
gst_buffer_c
opy_region
(
buffer
,
GST_BUFFER_COPY_ALL
,
offset
,
psize
);
/* first buffer is a discont buffer */
if
(
offset
==
2
)
...
...
@@ -333,6 +325,8 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
data
+=
psize
;
offset
+=
psize
;
}
gst_buffer_unmap
(
buffer
,
&
minfo
);
}
GST_DEBUG_OBJECT
(
dec
,
"Done"
);
...
...
@@ -344,24 +338,17 @@ static GstFlowReturn
theora_handle_comment_packet
(
GstTheoraDec
*
dec
,
ogg_packet
*
packet
)
{
gchar
*
encoder
=
NULL
;
GstBuffer
*
buf
;
GstTagList
*
list
;
GST_DEBUG_OBJECT
(
dec
,
"parsing comment packet"
);
buf
=
gst_buffer_new
();
GST_BUFFER_SIZE
(
buf
)
=
packet
->
bytes
;
GST_BUFFER_DATA
(
buf
)
=
packet
->
packet
;
list
=
gst_tag_list_from_vorbiscomment_buffer
(
buf
,
(
guint8
*
)
"
\201
theora"
,
7
,
&
encoder
);
gst_buffer_unref
(
buf
);
gst_tag_list_from_vorbiscomment
(
packet
->
packet
,
packet
->
bytes
,
(
guint8
*
)
"
\201
theora"
,
7
,
&
encoder
);
if
(
!
list
)
{
GST_ERROR_OBJECT
(
dec
,
"couldn't decode comments"
);
list
=
gst_tag_list_new
();
list
=
gst_tag_list_new
_empty
();
}
if
(
encoder
)
{
gst_tag_list_add
(
list
,
GST_TAG_MERGE_REPLACE
,
...
...
@@ -437,29 +424,13 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
goto
unsupported_format
;
}
if
(
dec
->
crop
)
{
GST_VIDEO_INFO_WIDTH
(
info
)
=
dec
->
info
.
pic_width
;
GST_VIDEO_INFO_HEIGHT
(
info
)
=
dec
->
info
.
pic_height
;
dec
->
offset_x
=
dec
->
info
.
pic_x
;
dec
->
offset_y
=
dec
->
info
.
pic_y
;
/* Ensure correct offsets in chroma for formats that need it
* by rounding the offset. libtheora will add proper pixels,
* so no need to handle them ourselves. */
if
(
dec
->
offset_x
&
1
&&
dec
->
info
.
pixel_fmt
!=
TH_PF_444
)
{
dec
->
offset_x
--
;
GST_VIDEO_INFO_WIDTH
(
info
)
++
;
}
if
(
dec
->
offset_y
&
1
&&
dec
->
info
.
pixel_fmt
==
TH_PF_420
)
{
dec
->
offset_y
--
;
GST_VIDEO_INFO_HEIGHT
(
info
)
++
;
}
}
else
{
/* no cropping, use the encoded dimensions */
GST_VIDEO_INFO_WIDTH
(
info
)
=
dec
->
info
.
frame_width
;
GST_VIDEO_INFO_HEIGHT
(
info
)
=
dec
->
info
.
frame_height
;
dec
->
offset_x
=
0
;
dec
->
offset_y
=
0
;
}
/* FIXME: Use crop metadata */
/* no cropping, use the encoded dimensions */
GST_VIDEO_INFO_WIDTH
(
info
)
=
dec
->
info
.
frame_width
;
GST_VIDEO_INFO_HEIGHT
(
info
)
=
dec
->
info
.
frame_height
;
dec
->
offset_x
=
0
;
dec
->
offset_y
=
0
;
GST_DEBUG_OBJECT
(
dec
,
"after fixup frame dimension %dx%d, offset %d:%d"
,
info
->
width
,
info
->
height
,
dec
->
offset_x
,
dec
->
offset_y
);
...
...
@@ -504,8 +475,8 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
/* FIXME : Put this on the next outgoing frame */
/* FIXME : */
if
(
dec
->
tags
)
{
gst_
element_found_tags_for_pad
(
GST_ELEMENT_CAST
(
dec
)
,
GST_VIDEO_DECODER_SRC_PAD
(
dec
),
dec
->
tags
);
gst_
pad_push_event
(
GST_VIDEO_DECODER
(
dec
)
->
srcpad
,
gst_event_new_tag
(
dec
->
tags
)
)
;
dec
->
tags
=
NULL
;
}
...
...
@@ -569,6 +540,7 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
int
i
,
plane
;
guint8
*
dest
,
*
src
;
GstBuffer
*
out
;
GstMapInfo
minfo
;
result
=
gst_video_decoder_alloc_output_frame
(
decoder
,
frame
);
...
...
@@ -581,13 +553,15 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
out
=
frame
->
output_buffer
;
info
=
&
dec
->
output_state
->
info
;
/* FIXME : Use GstVideoInfo */
gst_buffer_map
(
out
,
&
minfo
,
GST_MAP_WRITE
);
/* FIXME : Use crop metadata */
for
(
plane
=
0
;
plane
<
3
;
plane
++
)
{
width
=
GST_VIDEO_INFO_COMP_WIDTH
(
info
,
plane
);
height
=
GST_VIDEO_INFO_COMP_HEIGHT
(
info
,
plane
);
stride
=
GST_VIDEO_INFO_COMP_STRIDE
(
info
,
plane
);
dest
=
GST_BUFFER_DATA
(
out
)
+
GST_VIDEO_INFO_COMP_OFFSET
(
info
,
plane
);
dest
=
minfo
.
data
+
GST_VIDEO_INFO_COMP_OFFSET
(
info
,
plane
);
src
=
buf
[
plane
].
data
;
src
+=
((
height
==
...
...
@@ -605,6 +579,8 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
}
}
gst_buffer_unmap
(
out
,
&
minfo
);
return
GST_FLOW_OK
;
}
...
...
@@ -700,10 +676,12 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf,
{
ogg_packet
packet
;
GstFlowReturn
result
=
GST_FLOW_OK
;
GstMapInfo
minfo
;
/* make ogg_packet out of the buffer */
packet
.
packet
=
GST_BUFFER_DATA
(
buf
);
packet
.
bytes
=
GST_BUFFER_SIZE
(
buf
);
gst_buffer_map
(
buf
,
&
minfo
,
GST_MAP_READ
);
packet
.
packet
=
minfo
.
data
;
packet
.
bytes
=
minfo
.
size
;
packet
.
granulepos
=
-
1
;
packet
.
packetno
=
0
;
/* we don't really care */
packet
.
b_o_s
=
dec
->
have_header
?
0
:
1
;
...
...
@@ -732,6 +710,8 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf,
}
done:
gst_buffer_unmap
(
buf
,
&
minfo
);
return
result
;
}
...
...
@@ -757,9 +737,6 @@ theora_dec_set_property (GObject * object, guint prop_id,
GstTheoraDec
*
dec
=
GST_THEORA_DEC
(
object
);
switch
(
prop_id
)
{
case
PROP_CROP
:
dec
->
crop
=
g_value_get_boolean
(
value
);
break
;
case
PROP_TELEMETRY_MV
:
dec
->
telemetry_mv
=
g_value_get_int
(
value
);
break
;
...
...
@@ -785,9 +762,6 @@ theora_dec_get_property (GObject * object, guint prop_id,
GstTheoraDec
*
dec
=
GST_THEORA_DEC
(
object
);
switch
(
prop_id
)
{
case
PROP_CROP
:
g_value_set_boolean
(
value
,
dec
->
crop
);
break
;
case
PROP_TELEMETRY_MV
:
g_value_set_int
(
value
,
dec
->
telemetry_mv
);
break
;
...
...
ext/theora/gsttheoradec.h
View file @
e120979f
...
...
@@ -77,10 +77,7 @@ struct _GstTheoraDec
gint
telemetry_qi
;
gint
telemetry_bits
;
gboolean
crop
;
GstTagList
*
tags
;
};
struct
_GstTheoraDecClass
...
...
ext/theora/gsttheoraenc.c
View file @
e120979f
...
...
@@ -69,25 +69,6 @@
#define GST_CAT_DEFAULT theoraenc_debug
GST_DEBUG_CATEGORY_STATIC
(
GST_CAT_DEFAULT
);
#define GST_TYPE_BORDER_MODE (gst_border_mode_get_type())
static
GType
gst_border_mode_get_type
(
void
)
{
static
GType
border_mode_type
=
0
;
static
const
GEnumValue
border_mode
[]
=
{
{
BORDER_NONE
,
"No Border"
,
"none"
},
{
BORDER_BLACK
,
"Black Border"
,
"black"
},
{
BORDER_MIRROR
,
"Mirror image in borders"
,
"mirror"
},
{
0
,
NULL
,
NULL
},
};
if
(
!
border_mode_type
)
{
border_mode_type
=
g_enum_register_static
(
"GstTheoraEncBorderMode"
,
border_mode
);
}
return
border_mode_type
;
}
#define GST_TYPE_MULTIPASS_MODE (gst_multipass_mode_get_type())
static
GType
gst_multipass_mode_get_type
(
void
)
...
...
@@ -136,18 +117,11 @@ _ilog (unsigned int v)
enum
{
PROP_0
,
PROP_CENTER
,
PROP_BORDER
,
PROP_BITRATE
,
PROP_QUALITY
,
PROP_QUICK
,
PROP_KEYFRAME_AUTO
,
PROP_KEYFRAME_FREQ
,
PROP_KEYFRAME_FREQ_FORCE
,
PROP_KEYFRAME_THRESHOLD
,
PROP_KEYFRAME_MINDISTANCE
,
PROP_NOISE_SENSITIVITY
,
PROP_SHARPNESS
,
PROP_SPEEDLEVEL
,
PROP_VP3_COMPATIBLE
,
PROP_DROP_FRAMES
,
...
...
@@ -182,8 +156,8 @@ static GstStaticPadTemplate theora_enc_sink_factory =
GST_STATIC_PAD_TEMPLATE
(
"sink"
,
GST_PAD_SINK
,
GST_PAD_ALWAYS
,
GST_STATIC_CAPS
(
"video/x-raw
-yuv
, "
"format = (
fourcc
) { I420, Y42B, Y444 }, "
GST_STATIC_CAPS
(
"video/x-raw, "
"format = (
string
) { I420, Y42B, Y444 }, "
"framerate = (fraction) [1/MAX, MAX], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]"
)
);
...
...
@@ -192,11 +166,13 @@ static GstStaticPadTemplate theora_enc_src_factory =
GST_STATIC_PAD_TEMPLATE
(
"src"
,
GST_PAD_SRC
,
GST_PAD_ALWAYS
,
GST_STATIC_CAPS
(
"video/x-theora"
)
GST_STATIC_CAPS
(
"video/x-theora, "
"framerate = (fraction) [1/MAX, MAX], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]"
)
);
GST_BOILERPLATE
(
GstTheoraEnc
,
gst_theora_enc
,
GstVideoEncoder
,
GST_TYPE_VIDEO_ENCODER
);
#define gst_theora_enc_parent_class parent_class
G_DEFINE_TYPE
(
GstTheoraEnc
,
gst_theora_enc
,
GST_TYPE_VIDEO_ENCODER
);
static
gboolean
theora_enc_start
(
GstVideoEncoder
*
enc
);
static
gboolean
theora_enc_stop
(
GstVideoEncoder
*
enc
);
...
...
@@ -208,7 +184,8 @@ static GstFlowReturn theora_enc_pre_push (GstVideoEncoder * benc,
GstVideoCodecFrame
*
frame
);
static
GstFlowReturn
theora_enc_finish
(
GstVideoEncoder
*
enc
);
static
GstCaps
*
theora_enc_sink_getcaps
(
GstPad
*
pad
);
static
GstCaps
*
theora_enc_getcaps
(
GstVideoEncoder
*
encoder
,
GstCaps
*
filter
);
static
void
theora_enc_get_property
(
GObject
*
object
,
guint
prop_id
,
GValue
*
value
,
GParamSpec
*
pspec
);
static
void
theora_enc_set_property
(
GObject
*
object
,
guint
prop_id
,
...
...
@@ -219,9 +196,16 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
gboolean
begin
,
gboolean
eos
);
static
void
gst_theora_enc_
b
as
e
_init
(
gpointer
g_c
lass
)
gst_theora_enc_
cl
as
s
_init
(
GstTheoraEncClass
*
k
lass
)
{
GstElementClass
*
element_class
=
GST_ELEMENT_CLASS
(
g_class
);
GObjectClass
*
gobject_class
=
(
GObjectClass
*
)
klass
;
GstElementClass
*
element_class
=
(
GstElementClass
*
)
klass
;
GstVideoEncoderClass
*
gstvideo_encoder_class
=
GST_VIDEO_ENCODER_CLASS
(
klass
);
gobject_class
->
set_property
=
theora_enc_set_property
;
gobject_class
->
get_property
=
theora_enc_get_property
;
gobject_class
->
finalize
=
theora_enc_finalize
;
gst_element_class_add_pad_template
(
element_class
,
gst_static_pad_template_get
(
&
theora_enc_src_factory
));
...
...
@@ -231,18 +215,6 @@ gst_theora_enc_base_init (gpointer g_class)
"Theora video encoder"
,
"Codec/Encoder/Video"
,
"encode raw YUV video to a theora stream"
,
"Wim Taymans <wim@fluendo.com>"
);
}
static
void
gst_theora_enc_class_init
(
GstTheoraEncClass
*
klass
)
{
GObjectClass
*
gobject_class
=
(
GObjectClass
*
)
klass
;
GstVideoEncoderClass
*
gstvideo_encoder_class
=
GST_VIDEO_ENCODER_CLASS
(
klass
);
gobject_class
->
set_property
=
theora_enc_set_property
;
gobject_class
->
get_property
=
theora_enc_get_property
;
gobject_class
->
finalize
=
theora_enc_finalize
;
gstvideo_encoder_class
->
start
=
GST_DEBUG_FUNCPTR
(
theora_enc_start
);
gstvideo_encoder_class
->
stop
=
GST_DEBUG_FUNCPTR
(
theora_enc_stop
);
...
...
@@ -252,16 +224,8 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
GST_DEBUG_FUNCPTR
(
theora_enc_handle_frame
);
gstvideo_encoder_class
->
pre_push
=
GST_DEBUG_FUNCPTR
(
theora_enc_pre_push
);
gstvideo_encoder_class
->
finish
=
GST_DEBUG_FUNCPTR
(
theora_enc_finish
);
gstvideo_encoder_class
->
getcaps
=
GST_DEBUG_FUNCPTR
(
theora_enc_getcaps
);
g_object_class_install_property
(
gobject_class
,
PROP_CENTER
,
g_param_spec_boolean
(
"center"
,
"Center"
,
"ignored and kept for API compat only"
,
TRUE
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_BORDER
,
g_param_spec_enum
(
"border"
,
"Border"
,
"ignored and kept for API compat only"
,
GST_TYPE_BORDER_MODE
,
BORDER_BLACK
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
/* general encoding stream options */
g_object_class_install_property
(
gobject_class
,
PROP_BITRATE
,
g_param_spec_int
(
"bitrate"
,
"Bitrate"
,
"Compressed video bitrate (kbps)"
,
...
...
@@ -273,10 +237,6 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
THEORA_DEF_QUALITY
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
|
GST_PARAM_MUTABLE_PLAYING
));
g_object_class_install_property
(
gobject_class
,
PROP_QUICK
,
g_param_spec_boolean
(
"quick"
,
"Quick"
,
"ignored and kept for API compat only"
,
TRUE
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_KEYFRAME_AUTO
,
g_param_spec_boolean
(
"keyframe-auto"
,
"Keyframe Auto"
,
"Automatic keyframe detection"
,
THEORA_DEF_KEYFRAME_AUTO
,
...
...
@@ -290,22 +250,6 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
"Force keyframe every N frames"
,
1
,
32768
,
THEORA_DEF_KEYFRAME_FREQ_FORCE
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_KEYFRAME_THRESHOLD
,
g_param_spec_int
(
"keyframe-threshold"
,
"Keyframe threshold"
,
"ignored and kept for API compat only"
,
0
,
32768
,
80
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_KEYFRAME_MINDISTANCE
,
g_param_spec_int
(
"keyframe-mindistance"
,
"Keyframe mindistance"
,
"ignored and kept for API compat only"
,
1
,
32768
,
8
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_NOISE_SENSITIVITY
,
g_param_spec_int
(
"noise-sensitivity"
,
"Noise sensitivity"
,
"ignored and kept for API compat only"
,
0
,
32768
,
1
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_SHARPNESS
,
g_param_spec_int
(
"sharpness"
,
"Sharpness"
,
"ignored and kept for API compat only"
,
0
,
2
,
0
,
(
GParamFlags
)
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_SPEEDLEVEL
,
g_param_spec_int
(
"speed-level"
,
"Speed level"
,
"Controls the amount of motion vector searching done while "
...
...
@@ -358,11 +302,8 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
}
static
void
gst_theora_enc_init
(
GstTheoraEnc
*
enc
,
GstTheoraEncClass
*
g_class
)
gst_theora_enc_init
(
GstTheoraEnc
*
enc
)
{
gst_pad_set_getcaps_function
(
GST_VIDEO_ENCODER_SINK_PAD
(
enc
),
GST_DEBUG_FUNCPTR
(
theora_enc_sink_getcaps
));
enc
->
video_bitrate
=
THEORA_DEF_BITRATE
;
enc
->
video_quality
=
THEORA_DEF_QUALITY
;
enc
->
keyframe_auto
=
THEORA_DEF_KEYFRAME_AUTO
;
...
...
@@ -571,9 +512,9 @@ theora_enc_get_supported_formats (void)
}
static
GstCaps
*
theora_enc_
sink_
getcaps
(
Gst
Pad
*
pad
)
theora_enc_getcaps
(
Gst
VideoEncoder
*
encoder
,
GstCaps
*
filter
)
{
GstCaps
*
caps
;
GstCaps
*
caps
,
*
ret
;
char
*
supported_formats
,
*
caps_string
;
supported_formats
=
theora_enc_get_supported_formats
();
...
...
@@ -582,8 +523,8 @@ theora_enc_sink_getcaps (GstPad * pad)
return
gst_caps_new_empty
();
}
caps_string
=
g_strdup_printf
(
"video/x-raw
-yuv
, "
"format = (
fourcc
) { %s }, "
caps_string
=
g_strdup_printf
(
"video/x-raw, "
"format = (
string
) { %s }, "
"framerate = (fraction) [1/MAX, MAX], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]"
,
supported_formats
);
...
...
@@ -592,7 +533,10 @@ theora_enc_sink_getcaps (GstPad * pad)
g_free
(
supported_formats
);
GST_DEBUG
(
"Supported caps: %"
GST_PTR_FORMAT
,
caps
);
return
caps
;
ret
=
gst_video_encoder_proxy_getcaps
(
encoder
,
caps
,
filter
);
gst_caps_unref
(
caps
);
return
ret
;
}
static
gboolean
...
...
@@ -682,14 +626,14 @@ theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet)
benc
=
GST_VIDEO_ENCODER
(
enc
);
buf
=
gst_buffer_new_a
nd_alloc
(
packet
->
bytes
);
buf
=
gst_buffer_new_a
llocate
(
NULL
,
packet
->
bytes
,
NULL
);
if
(
!
buf
)
{
GST_WARNING_OBJECT
(
enc
,
"Could not allocate buffer"
);
ret
=
GST_FLOW_ERROR
;
goto
done
;
}
memcpy
(
GST_BUFFER_DATA
(
buf
)
,
packet
->
packet
,
packet
->
bytes
);
gst_buffer_fill
(
buf
,
0
,
packet
->
packet
,
packet
->
bytes
);
frame
=
gst_video_encoder_get_oldest_frame
(
benc
);
frame
->
output_buffer
=
buf
;
...
...
@@ -728,7 +672,7 @@ theora_set_header_on_caps (GstCaps * caps, GList * buffers)
buffer
=
walk
->
data
;
/* mark buffer */
GST_BUFFER_FLAG_SET
(
buffer
,
GST_BUFFER_FLAG_
IN_CAPS
);
GST_BUFFER_FLAG_SET
(
buffer
,
GST_BUFFER_FLAG_
HEADER
);
/* Copy buffer, because we can't use the original -
* it creates a circular refcount with the caps<->buffers */
...
...
@@ -750,25 +694,11 @@ theora_set_header_on_caps (GstCaps * caps, GList * buffers)
}
static
void
theora_enc_init_buffer
(
th_ycbcr_buffer
buf
,
th_info
*
info
,
guint8
*
data
)
theora_enc_init_buffer
(
th_ycbcr_buffer
buf
,
GstVideoFrame
*
frame
)
{
GstVideo
Format
format
;
GstVideo
Info
vinfo
;
guint
i
;
switch
(
info
->
pixel_fmt
)
{
case
TH_PF_444
:
format
=
GST_VIDEO_FORMAT_Y444
;
break
;
case
TH_PF_420
:
format
=
GST_VIDEO_FORMAT_I420
;
break
;
case
TH_PF_422
:
format
=
GST_VIDEO_FORMAT_Y42B
;
break
;
default:
g_assert_not_reached
();
}
/* According to Theora developer Timothy Terriberry, the Theora
* encoder will not use memory outside of pic_width/height, even when
* the frame size is bigger. The values outside this region will be encoded
...
...
@@ -776,17 +706,17 @@ theora_enc_init_buffer (th_ycbcr_buffer buf, th_info * info, guint8 * data)
* Due to this, setting the frame's width/height as the buffer width/height
* is perfectly ok, even though it does not strictly look ok.
*/
gst_video_info_init
(
&
vinfo
);
gst_video_info_set_format
(
&
vinfo
,
GST_VIDEO_FRAME_FORMAT
(
frame
),
GST_ROUND_UP_16
(
GST_VIDEO_FRAME_WIDTH
(
frame
)),
GST_ROUND_UP_16
(
GST_VIDEO_FRAME_HEIGHT
(
frame
)));
for
(
i
=
0
;
i
<
3
;
i
++
)
{
buf
[
i
].
width
=
gst_video_format_get_component_width
(
format
,
i
,
info
->
frame_width
);
buf
[
i
].
height
=
gst_video_format_get_component_height
(
format
,
i
,
info
->
frame_height
);
buf
[
i
].
data
=
data
+
gst_video_format_get_component_offset
(
format
,
i
,
info
->
pic_width
,
info
->
pic_height
);
buf
[
i
].
stride
=
gst_video_format_get_row_stride
(
format
,
i
,
info
->
pic_width
);
buf
[
i
].
width
=
GST_VIDEO_INFO_COMP_WIDTH
(
&
vinfo
,
i
);
buf
[
i
].
height
=
GST_VIDEO_INFO_COMP_HEIGHT
(
&
vinfo
,
i
);
buf
[
i
].
data
=
GST_VIDEO_FRAME_COMP_DATA
(
frame
,
i
);
buf
[
i
].
stride
=
GST_VIDEO_FRAME_COMP_STRIDE
(
frame
,
i
);
}
}
...
...
@@ -795,22 +725,29 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc)
{
GstBuffer
*
cache_buf
;
const
guint8
*
cache_data
;
gsize
bytes_read
=
0
,
bytes_consumed
=
0
;
gsize
bytes_read
=
0
;
gssize
bytes_consumed
=
0
;
GIOStatus
stat
=
G_IO_STATUS_NORMAL
;
gboolean
done
=
FALSE
;
while
(
!
done
)
{
if
(
gst_adapter_available
(
enc
->
multipass_cache_adapter
)
==
0
)
{