Commit e120979f authored by Sebastian Dröge's avatar Sebastian Dröge

theora: Port to 0.11 again with the new base classes

parent a8c40a65
...@@ -47,11 +47,13 @@ ...@@ -47,11 +47,13 @@
#include "gsttheoradec.h" #include "gsttheoradec.h"
#include <gst/tag/tag.h> #include <gst/tag/tag.h>
#include <gst/video/video.h> #include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
#define GST_CAT_DEFAULT theoradec_debug #define GST_CAT_DEFAULT theoradec_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 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_MV 0
#define THEORA_DEF_TELEMETRY_MBMODE 0 #define THEORA_DEF_TELEMETRY_MBMODE 0
#define THEORA_DEF_TELEMETRY_QI 0 #define THEORA_DEF_TELEMETRY_QI 0
...@@ -60,7 +62,6 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); ...@@ -60,7 +62,6 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum enum
{ {
PROP_0, PROP_0,
PROP_CROP,
PROP_TELEMETRY_MV, PROP_TELEMETRY_MV,
PROP_TELEMETRY_MBMODE, PROP_TELEMETRY_MBMODE,
PROP_TELEMETRY_QI, PROP_TELEMETRY_QI,
...@@ -71,8 +72,8 @@ static GstStaticPadTemplate theora_dec_src_factory = ...@@ -71,8 +72,8 @@ static GstStaticPadTemplate theora_dec_src_factory =
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 ("video/x-raw-yuv, " GST_STATIC_CAPS ("video/x-raw, "
"format = (fourcc) { I420, Y42B, Y444 }, " "format = (string) { I420, Y42B, Y444 }, "
"framerate = (fraction) [0/1, MAX], " "framerate = (fraction) [0/1, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
); );
...@@ -84,8 +85,8 @@ GST_STATIC_PAD_TEMPLATE ("sink", ...@@ -84,8 +85,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS ("video/x-theora") GST_STATIC_CAPS ("video/x-theora")
); );
GST_BOILERPLATE (GstTheoraDec, gst_theora_dec, GstVideoDecoder, #define gst_theora_dec_parent_class parent_class
GST_TYPE_VIDEO_DECODER); G_DEFINE_TYPE (GstTheoraDec, gst_theora_dec, GST_TYPE_VIDEO_DECODER);
static void theora_dec_get_property (GObject * object, guint prop_id, static void theora_dec_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
...@@ -105,22 +106,6 @@ static GstFlowReturn theora_dec_handle_frame (GstVideoDecoder * decoder, ...@@ -105,22 +106,6 @@ static GstFlowReturn theora_dec_handle_frame (GstVideoDecoder * decoder,
static GstFlowReturn theora_dec_decode_buffer (GstTheoraDec * dec, static GstFlowReturn theora_dec_decode_buffer (GstTheoraDec * dec,
GstBuffer * buf, GstVideoCodecFrame * frame); 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 static gboolean
gst_theora_dec_ctl_is_supported (int req) gst_theora_dec_ctl_is_supported (int req)
{ {
...@@ -132,16 +117,12 @@ static void ...@@ -132,16 +117,12 @@ static void
gst_theora_dec_class_init (GstTheoraDecClass * klass) gst_theora_dec_class_init (GstTheoraDecClass * klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
gobject_class->set_property = theora_dec_set_property; gobject_class->set_property = theora_dec_set_property;
gobject_class->get_property = theora_dec_get_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)) { if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_MV)) {
g_object_class_install_property (gobject_class, PROP_TELEMETRY_MV, g_object_class_install_property (gobject_class, PROP_TELEMETRY_MV,
g_param_spec_int ("visualize-motion-vectors", g_param_spec_int ("visualize-motion-vectors",
...@@ -186,6 +167,15 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass) ...@@ -186,6 +167,15 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 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->start = GST_DEBUG_FUNCPTR (theora_dec_start);
video_decoder_class->stop = GST_DEBUG_FUNCPTR (theora_dec_stop); video_decoder_class->stop = GST_DEBUG_FUNCPTR (theora_dec_stop);
video_decoder_class->reset = GST_DEBUG_FUNCPTR (theora_dec_reset); video_decoder_class->reset = GST_DEBUG_FUNCPTR (theora_dec_reset);
...@@ -198,9 +188,8 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass) ...@@ -198,9 +188,8 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
} }
static void 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_mv = THEORA_DEF_TELEMETRY_MV;
dec->telemetry_mbmode = THEORA_DEF_TELEMETRY_MBMODE; dec->telemetry_mbmode = THEORA_DEF_TELEMETRY_MBMODE;
dec->telemetry_qi = THEORA_DEF_TELEMETRY_QI; dec->telemetry_qi = THEORA_DEF_TELEMETRY_QI;
...@@ -269,10 +258,11 @@ theora_dec_parse (GstVideoDecoder * decoder, ...@@ -269,10 +258,11 @@ theora_dec_parse (GstVideoDecoder * decoder,
av = gst_adapter_available (adapter); 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 */ /* check for keyframe; must not be header packet */
if (!(data[0] & 0x80) && (data[0] & 0x40) == 0) if (!(data[0] & 0x80) && (data[0] & 0x40) == 0)
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
gst_adapter_unmap (adapter);
/* and pass along all */ /* and pass along all */
gst_video_decoder_add_to_frame (decoder, av); gst_video_decoder_add_to_frame (decoder, av);
...@@ -295,15 +285,17 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state) ...@@ -295,15 +285,17 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
/* FIXME : Interesting, we always accept any kind of caps ? */ /* FIXME : Interesting, we always accept any kind of caps ? */
if (state->codec_data) { if (state->codec_data) {
GstBuffer *buffer; GstBuffer *buffer;
GstMapInfo minfo;
guint8 *data; guint8 *data;
guint size; guint size;
guint offset; guint offset;
buffer = state->codec_data; buffer = state->codec_data;
gst_buffer_map (buffer, &minfo, GST_MAP_READ);
offset = 0; offset = 0;
size = GST_BUFFER_SIZE (buffer); size = minfo.size;
data = GST_BUFFER_DATA (buffer); data = (guint8 *) minfo.data;
while (size > 2) { while (size > 2) {
guint psize; guint psize;
...@@ -318,7 +310,7 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state) ...@@ -318,7 +310,7 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
/* make sure we don't read too much */ /* make sure we don't read too much */
psize = MIN (psize, size); psize = MIN (psize, size);
buf = gst_buffer_create_sub (buffer, offset, psize); buf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, psize);
/* first buffer is a discont buffer */ /* first buffer is a discont buffer */
if (offset == 2) if (offset == 2)
...@@ -333,6 +325,8 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state) ...@@ -333,6 +325,8 @@ theora_dec_set_format (GstVideoDecoder * bdec, GstVideoCodecState * state)
data += psize; data += psize;
offset += psize; offset += psize;
} }
gst_buffer_unmap (buffer, &minfo);
} }
GST_DEBUG_OBJECT (dec, "Done"); GST_DEBUG_OBJECT (dec, "Done");
...@@ -344,24 +338,17 @@ static GstFlowReturn ...@@ -344,24 +338,17 @@ static GstFlowReturn
theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet) theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
{ {
gchar *encoder = NULL; gchar *encoder = NULL;
GstBuffer *buf;
GstTagList *list; GstTagList *list;
GST_DEBUG_OBJECT (dec, "parsing comment packet"); GST_DEBUG_OBJECT (dec, "parsing comment packet");
buf = gst_buffer_new ();
GST_BUFFER_SIZE (buf) = packet->bytes;
GST_BUFFER_DATA (buf) = packet->packet;
list = list =
gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\201theora", 7, gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes,
&encoder); (guint8 *) "\201theora", 7, &encoder);
gst_buffer_unref (buf);
if (!list) { if (!list) {
GST_ERROR_OBJECT (dec, "couldn't decode comments"); GST_ERROR_OBJECT (dec, "couldn't decode comments");
list = gst_tag_list_new (); list = gst_tag_list_new_empty ();
} }
if (encoder) { if (encoder) {
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
...@@ -437,29 +424,13 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet) ...@@ -437,29 +424,13 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
goto unsupported_format; goto unsupported_format;
} }
if (dec->crop) { /* FIXME: Use crop metadata */
GST_VIDEO_INFO_WIDTH (info) = dec->info.pic_width;
GST_VIDEO_INFO_HEIGHT (info) = dec->info.pic_height; /* no cropping, use the encoded dimensions */
dec->offset_x = dec->info.pic_x; GST_VIDEO_INFO_WIDTH (info) = dec->info.frame_width;
dec->offset_y = dec->info.pic_y; GST_VIDEO_INFO_HEIGHT (info) = dec->info.frame_height;
/* Ensure correct offsets in chroma for formats that need it dec->offset_x = 0;
* by rounding the offset. libtheora will add proper pixels, dec->offset_y = 0;
* 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;
}
GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d", GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
info->width, info->height, dec->offset_x, dec->offset_y); info->width, info->height, dec->offset_x, dec->offset_y);
...@@ -504,8 +475,8 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet) ...@@ -504,8 +475,8 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
/* FIXME : Put this on the next outgoing frame */ /* FIXME : Put this on the next outgoing frame */
/* FIXME : */ /* FIXME : */
if (dec->tags) { if (dec->tags) {
gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), gst_pad_push_event (GST_VIDEO_DECODER (dec)->srcpad,
GST_VIDEO_DECODER_SRC_PAD (dec), dec->tags); gst_event_new_tag (dec->tags));
dec->tags = NULL; dec->tags = NULL;
} }
...@@ -569,6 +540,7 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, ...@@ -569,6 +540,7 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
int i, plane; int i, plane;
guint8 *dest, *src; guint8 *dest, *src;
GstBuffer *out; GstBuffer *out;
GstMapInfo minfo;
result = gst_video_decoder_alloc_output_frame (decoder, frame); result = gst_video_decoder_alloc_output_frame (decoder, frame);
...@@ -581,13 +553,15 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, ...@@ -581,13 +553,15 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
out = frame->output_buffer; out = frame->output_buffer;
info = &dec->output_state->info; 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++) { for (plane = 0; plane < 3; plane++) {
width = GST_VIDEO_INFO_COMP_WIDTH (info, plane); width = GST_VIDEO_INFO_COMP_WIDTH (info, plane);
height = GST_VIDEO_INFO_COMP_HEIGHT (info, plane); height = GST_VIDEO_INFO_COMP_HEIGHT (info, plane);
stride = GST_VIDEO_INFO_COMP_STRIDE (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 = buf[plane].data;
src += src +=
((height == ((height ==
...@@ -605,6 +579,8 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, ...@@ -605,6 +579,8 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf,
} }
} }
gst_buffer_unmap (out, &minfo);
return GST_FLOW_OK; return GST_FLOW_OK;
} }
...@@ -700,10 +676,12 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf, ...@@ -700,10 +676,12 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf,
{ {
ogg_packet packet; ogg_packet packet;
GstFlowReturn result = GST_FLOW_OK; GstFlowReturn result = GST_FLOW_OK;
GstMapInfo minfo;
/* make ogg_packet out of the buffer */ /* make ogg_packet out of the buffer */
packet.packet = GST_BUFFER_DATA (buf); gst_buffer_map (buf, &minfo, GST_MAP_READ);
packet.bytes = GST_BUFFER_SIZE (buf); packet.packet = minfo.data;
packet.bytes = minfo.size;
packet.granulepos = -1; packet.granulepos = -1;
packet.packetno = 0; /* we don't really care */ packet.packetno = 0; /* we don't really care */
packet.b_o_s = dec->have_header ? 0 : 1; packet.b_o_s = dec->have_header ? 0 : 1;
...@@ -732,6 +710,8 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf, ...@@ -732,6 +710,8 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf,
} }
done: done:
gst_buffer_unmap (buf, &minfo);
return result; return result;
} }
...@@ -757,9 +737,6 @@ theora_dec_set_property (GObject * object, guint prop_id, ...@@ -757,9 +737,6 @@ theora_dec_set_property (GObject * object, guint prop_id,
GstTheoraDec *dec = GST_THEORA_DEC (object); GstTheoraDec *dec = GST_THEORA_DEC (object);
switch (prop_id) { switch (prop_id) {
case PROP_CROP:
dec->crop = g_value_get_boolean (value);
break;
case PROP_TELEMETRY_MV: case PROP_TELEMETRY_MV:
dec->telemetry_mv = g_value_get_int (value); dec->telemetry_mv = g_value_get_int (value);
break; break;
...@@ -785,9 +762,6 @@ theora_dec_get_property (GObject * object, guint prop_id, ...@@ -785,9 +762,6 @@ theora_dec_get_property (GObject * object, guint prop_id,
GstTheoraDec *dec = GST_THEORA_DEC (object); GstTheoraDec *dec = GST_THEORA_DEC (object);
switch (prop_id) { switch (prop_id) {
case PROP_CROP:
g_value_set_boolean (value, dec->crop);
break;
case PROP_TELEMETRY_MV: case PROP_TELEMETRY_MV:
g_value_set_int (value, dec->telemetry_mv); g_value_set_int (value, dec->telemetry_mv);
break; break;
......
...@@ -77,10 +77,7 @@ struct _GstTheoraDec ...@@ -77,10 +77,7 @@ struct _GstTheoraDec
gint telemetry_qi; gint telemetry_qi;
gint telemetry_bits; gint telemetry_bits;
gboolean crop;
GstTagList *tags; GstTagList *tags;
}; };
struct _GstTheoraDecClass struct _GstTheoraDecClass
......
...@@ -69,25 +69,6 @@ ...@@ -69,25 +69,6 @@
#define GST_CAT_DEFAULT theoraenc_debug #define GST_CAT_DEFAULT theoraenc_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 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()) #define GST_TYPE_MULTIPASS_MODE (gst_multipass_mode_get_type())
static GType static GType
gst_multipass_mode_get_type (void) gst_multipass_mode_get_type (void)
...@@ -136,18 +117,11 @@ _ilog (unsigned int v) ...@@ -136,18 +117,11 @@ _ilog (unsigned int v)
enum enum
{ {
PROP_0, PROP_0,
PROP_CENTER,
PROP_BORDER,
PROP_BITRATE, PROP_BITRATE,
PROP_QUALITY, PROP_QUALITY,
PROP_QUICK,
PROP_KEYFRAME_AUTO, PROP_KEYFRAME_AUTO,
PROP_KEYFRAME_FREQ, PROP_KEYFRAME_FREQ,
PROP_KEYFRAME_FREQ_FORCE, PROP_KEYFRAME_FREQ_FORCE,
PROP_KEYFRAME_THRESHOLD,
PROP_KEYFRAME_MINDISTANCE,
PROP_NOISE_SENSITIVITY,
PROP_SHARPNESS,
PROP_SPEEDLEVEL, PROP_SPEEDLEVEL,
PROP_VP3_COMPATIBLE, PROP_VP3_COMPATIBLE,
PROP_DROP_FRAMES, PROP_DROP_FRAMES,
...@@ -182,8 +156,8 @@ static GstStaticPadTemplate theora_enc_sink_factory = ...@@ -182,8 +156,8 @@ static GstStaticPadTemplate theora_enc_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, " GST_STATIC_CAPS ("video/x-raw, "
"format = (fourcc) { I420, Y42B, Y444 }, " "format = (string) { I420, Y42B, Y444 }, "
"framerate = (fraction) [1/MAX, MAX], " "framerate = (fraction) [1/MAX, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
); );
...@@ -192,11 +166,13 @@ static GstStaticPadTemplate theora_enc_src_factory = ...@@ -192,11 +166,13 @@ static GstStaticPadTemplate theora_enc_src_factory =
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 ("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, #define gst_theora_enc_parent_class parent_class
GST_TYPE_VIDEO_ENCODER); G_DEFINE_TYPE (GstTheoraEnc, gst_theora_enc, GST_TYPE_VIDEO_ENCODER);
static gboolean theora_enc_start (GstVideoEncoder * enc); static gboolean theora_enc_start (GstVideoEncoder * enc);
static gboolean theora_enc_stop (GstVideoEncoder * enc); static gboolean theora_enc_stop (GstVideoEncoder * enc);
...@@ -208,7 +184,8 @@ static GstFlowReturn theora_enc_pre_push (GstVideoEncoder * benc, ...@@ -208,7 +184,8 @@ static GstFlowReturn theora_enc_pre_push (GstVideoEncoder * benc,
GstVideoCodecFrame * frame); GstVideoCodecFrame * frame);
static GstFlowReturn theora_enc_finish (GstVideoEncoder * enc); 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, static void theora_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void theora_enc_set_property (GObject * object, guint prop_id, static void theora_enc_set_property (GObject * object, guint prop_id,
...@@ -219,9 +196,16 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc, ...@@ -219,9 +196,16 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
gboolean begin, gboolean eos); gboolean begin, gboolean eos);
static void static void
gst_theora_enc_base_init (gpointer g_class) gst_theora_enc_class_init (GstTheoraEncClass * klass)
{ {
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_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&theora_enc_src_factory)); gst_static_pad_template_get (&theora_enc_src_factory));
...@@ -231,18 +215,6 @@ gst_theora_enc_base_init (gpointer g_class) ...@@ -231,18 +215,6 @@ gst_theora_enc_base_init (gpointer g_class)
"Theora video encoder", "Codec/Encoder/Video", "Theora video encoder", "Codec/Encoder/Video",
"encode raw YUV video to a theora stream", "encode raw YUV video to a theora stream",
"Wim Taymans <wim@fluendo.com>"); "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->start = GST_DEBUG_FUNCPTR (theora_enc_start);
gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (theora_enc_stop); gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (theora_enc_stop);
...@@ -252,16 +224,8 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) ...@@ -252,16 +224,8 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
GST_DEBUG_FUNCPTR (theora_enc_handle_frame); GST_DEBUG_FUNCPTR (theora_enc_handle_frame);
gstvideo_encoder_class->pre_push = GST_DEBUG_FUNCPTR (theora_enc_pre_push); 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->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 */ /* general encoding stream options */
g_object_class_install_property (gobject_class, PROP_BITRATE, g_object_class_install_property (gobject_class, PROP_BITRATE,
g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)", g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
...@@ -273,10 +237,6 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) ...@@ -273,10 +237,6 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
THEORA_DEF_QUALITY, THEORA_DEF_QUALITY,
(GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_PLAYING)); 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_object_class_install_property (gobject_class, PROP_KEYFRAME_AUTO,
g_param_spec_boolean ("keyframe-auto", "Keyframe Auto", g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",