#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)
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,
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 ]")
);
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 ]")
);
-static GstCaps *theora_enc_src_caps;
+#define gst_theora_enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTheoraEnc, gst_theora_enc,
+ GST_TYPE_ELEMENT, G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
-static void
-_do_init (GType object_type)
-{
- const GInterfaceInfo preset_interface_info = {
- NULL, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
- g_type_add_interface_static (object_type, GST_TYPE_PRESET,
- &preset_interface_info);
-}
-
-GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
- GST_TYPE_ELEMENT, _do_init);
+static GstCaps *theora_enc_src_caps;
-static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
-static gboolean theora_enc_src_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean theora_enc_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean theora_enc_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static GstFlowReturn theora_enc_chain (GstPad * pad, GstObject * parent,
+ GstBuffer * buffer);
static GstStateChangeReturn theora_enc_change_state (GstElement * element,
GstStateChange transition);
-static GstCaps *theora_enc_sink_getcaps (GstPad * pad);
-static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean theora_enc_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
+static gboolean theora_enc_sink_setcaps (GstTheoraEnc * enc, GstCaps * caps);
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,
GstBuffer * buffer);
static void
-gst_theora_enc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_static_pad_template (element_class,
- &theora_enc_src_factory);
- gst_element_class_add_static_pad_template (element_class,
- &theora_enc_sink_factory);
- gst_element_class_set_details_simple (element_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;
gobject_class->get_property = theora_enc_get_property;
gobject_class->finalize = theora_enc_finalize;
- 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)",
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,
"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 analysis performed when encoding."
THEORA_DEF_DUP_ON_GAP,
(GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- caps_string = g_strdup_printf ("video/x-raw-yuv, "
- "format = (fourcc) { %s }, "
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&theora_enc_src_factory));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&theora_enc_sink_factory));
+ gst_element_class_set_details_simple (gstelement_class,
+ "Theora video encoder", "Codec/Encoder/Video",
+ "encode raw YUV video to a theora stream",
+ "Wim Taymans <wim@fluendo.com>");
+
+ caps_string = g_strdup_printf ("video/x-raw, "
+ "format = (string) { %s }, "
"framerate = (fraction) [1/MAX, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
theora_enc_get_supported_formats ());
}
static void
-gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
+gst_theora_enc_init (GstTheoraEnc * enc)
{
enc->sinkpad =
gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain);
gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event);
- gst_pad_set_getcaps_function (enc->sinkpad, theora_enc_sink_getcaps);
- gst_pad_set_setcaps_function (enc->sinkpad, theora_enc_sink_setcaps);
+ gst_pad_set_query_function (enc->sinkpad, theora_enc_sink_query);
gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
enc->srcpad =
static const struct
{
th_pixel_fmt pixelformat;
- const char fourcc[5];
+ const char fourcc[];
} formats[] = {
{
TH_PF_420, "I420"}, {
}
static GstCaps *
-theora_enc_sink_getcaps (GstPad * pad)
+theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
{
GstTheoraEnc *encoder;
GstPad *peer;
GstCaps *caps;
/* If we already have caps return them */
- if (GST_PAD_CAPS (pad))
- return gst_caps_ref (GST_PAD_CAPS (pad));
+ if ((caps = gst_pad_get_current_caps (pad)) != NULL)
+ return caps;
encoder = GST_THEORA_ENC (gst_pad_get_parent (pad));
if (!encoder)
GstStructure *s;
guint i, n;
- peer_caps = gst_pad_get_caps (peer);
+ peer_caps = gst_pad_query_caps (peer, NULL);
/* Translate peercaps to YUV */
peer_caps = gst_caps_make_writable (peer_caps);
for (i = 0; i < n; i++) {
s = gst_caps_get_structure (peer_caps, i);
- gst_structure_set_name (s, "video/x-raw-yuv");
+ gst_structure_set_name (s, "video/x-raw");
gst_structure_remove_field (s, "streamheader");
}
gst_object_unref (encoder);
+ if (filter) {
+ GstCaps *intersection;
+
+ intersection =
+ gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (caps);
+ caps = intersection;
+ }
+
return caps;
}
static gboolean
-theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
+theora_enc_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+ gboolean res = FALSE;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *filter, *caps;
+
+ gst_query_parse_caps (query, &filter);
+ caps = theora_enc_sink_getcaps (pad, filter);
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ break;
+ }
+ default:
+ res = gst_pad_query_default (pad, parent, query);
+ break;
+ }
+
+ return res;
+}
+
+static gboolean
+theora_enc_sink_setcaps (GstTheoraEnc * enc, GstCaps * caps)
{
- GstStructure *structure = gst_caps_get_structure (caps, 0);
- GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad));
- guint32 fourcc;
- const GValue *par;
- gint fps_n, fps_d;
-
- gst_structure_get_fourcc (structure, "format", &fourcc);
- gst_structure_get_int (structure, "width", &enc->width);
- gst_structure_get_int (structure, "height", &enc->height);
- gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d);
- par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+ GstVideoInfo info;
th_info_clear (&enc->info);
th_info_init (&enc->info);
+
+ if (!gst_video_info_from_caps (&info, caps))
+ goto invalid_caps;
+
+ enc->vinfo = info;
+
/* Theora has a divisible-by-sixteen restriction for the encoded video size but
* we can define a picture area using pic_width/pic_height */
- enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
- enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
- enc->info.pic_width = enc->width;
- enc->info.pic_height = enc->height;
- switch (fourcc) {
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+ enc->info.frame_width = GST_ROUND_UP_16 (info.width);
+ enc->info.frame_height = GST_ROUND_UP_16 (info.height);
+ enc->info.pic_width = info.width;
+ enc->info.pic_height = info.height;
+
+ switch (GST_VIDEO_INFO_FORMAT (&info)) {
+ case GST_VIDEO_FORMAT_I420:
enc->info.pixel_fmt = TH_PF_420;
break;
- case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
+ case GST_VIDEO_FORMAT_Y42B:
enc->info.pixel_fmt = TH_PF_422;
break;
- case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
+ case GST_VIDEO_FORMAT_Y444:
enc->info.pixel_fmt = TH_PF_444;
break;
default:
g_assert_not_reached ();
}
- enc->info.fps_numerator = enc->fps_n = fps_n;
- enc->info.fps_denominator = enc->fps_d = fps_d;
- if (par) {
- enc->info.aspect_numerator = gst_value_get_fraction_numerator (par);
- enc->par_n = gst_value_get_fraction_numerator (par);
- enc->info.aspect_denominator = gst_value_get_fraction_denominator (par);
- enc->par_d = gst_value_get_fraction_denominator (par);
- } else {
- /* setting them to 0 indicates that the decoder can chose a good aspect
- * ratio, defaulting to 1/1 */
- enc->info.aspect_numerator = 0;
- enc->par_n = 1;
- enc->info.aspect_denominator = 0;
- enc->par_d = 1;
- }
+ enc->info.fps_numerator = info.fps_n;
+ enc->info.fps_denominator = info.fps_d;
+
+ enc->info.aspect_numerator = info.par_n;
+ enc->info.aspect_denominator = info.par_d;
+#if 0
+ /* setting them to 0 indicates that the decoder can chose a good aspect
+ * ratio, defaulting to 1/1 */
+ enc->info.aspect_numerator = 0;
+ enc->par_n = 1;
+ enc->info.aspect_denominator = 0;
+ enc->par_d = 1;
+#endif
enc->info.colorspace = TH_CS_UNSPECIFIED;
theora_enc_reset (enc);
enc->initialised = TRUE;
- gst_object_unref (enc);
-
return TRUE;
+
+ /* ERRORS */
+invalid_caps:
+ {
+ GST_DEBUG_OBJECT (enc, "could not parse caps");
+ return FALSE;
+ }
}
static guint64
goto done;
}
- memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
- gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
+ gst_buffer_fill (buf, 0, packet->packet, packet->bytes);
/* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
* time representation */
GST_BUFFER_OFFSET_END (buf) =
{
GstFlowReturn ret;
- enc->bytes_out += GST_BUFFER_SIZE (buffer);
+ enc->bytes_out += gst_buffer_get_size (buffer);
ret = gst_pad_push (enc->srcpad, buffer);
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 */
theora_enc_reset (enc);
enc->granulepos_offset =
- gst_util_uint64_scale (next_ts, enc->fps_n, GST_SECOND * enc->fps_d);
+ gst_util_uint64_scale (next_ts, enc->vinfo.fps_n,
+ GST_SECOND * enc->vinfo.fps_d);
enc->timestamp_offset = next_ts;
enc->next_ts = 0;
}
static gboolean
-theora_enc_sink_event (GstPad * pad, GstEvent * event)
+theora_enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstTheoraEnc *enc;
ogg_packet op;
gboolean res;
- enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
+ enc = GST_THEORA_ENC (parent);
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_CAPS:
{
- gboolean update;
- gdouble rate, applied_rate;
- GstFormat format;
- gint64 start, stop, time;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
- &format, &start, &stop, &time);
+ GstCaps *caps;
- gst_segment_set_newsegment_full (&enc->segment, update, rate,
- applied_rate, format, start, stop, time);
+ gst_event_parse_caps (event, &caps);
+ res = theora_enc_sink_setcaps (enc, caps);
+ gst_event_unref (event);
+ break;
+ }
+ case GST_EVENT_SEGMENT:
+ {
+ gst_event_copy_segment (event, &enc->segment);
res = gst_pad_push_event (enc->srcpad, event);
break;
}
static gboolean
-theora_enc_src_event (GstPad * pad, GstEvent * event)
+theora_enc_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstTheoraEnc *enc;
gboolean res = TRUE;
- enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
+ enc = GST_THEORA_ENC (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CUSTOM_UPSTREAM:
}
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)
{
- GstVideoFormat format;
+ GstVideoInfo info;
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
* 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 (&info);
+ gst_video_info_set_format (&info, 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 (&info, i);
+ buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
+ buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
+ buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
}
}
while (!done) {
if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
+ GstMapInfo map;
+
cache_buf = gst_buffer_new_and_alloc (512);
+
+ gst_buffer_map (cache_buf, &map, GST_MAP_READ);
stat = g_io_channel_read_chars (enc->multipass_cache_fd,
- (gchar *) GST_BUFFER_DATA (cache_buf), GST_BUFFER_SIZE (cache_buf),
- &bytes_read, NULL);
+ (gchar *) map.data, map.size, &bytes_read, NULL);
if (bytes_read <= 0) {
+ gst_buffer_unmap (cache_buf, &map);
gst_buffer_unref (cache_buf);
break;
} else {
- GST_BUFFER_SIZE (cache_buf) = bytes_read;
-
+ gst_buffer_unmap (cache_buf, &map);
+ gst_buffer_resize (cache_buf, 0, bytes_read);
gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
}
}
bytes_read =
MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
- cache_data = gst_adapter_peek (enc->multipass_cache_adapter, bytes_read);
+ cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
bytes_consumed =
th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
bytes_read);
+ gst_adapter_unmap (enc->multipass_cache_adapter);
+
done = bytes_consumed <= 0;
if (bytes_consumed > 0)
gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
GstBuffer * buffer)
{
GstFlowReturn ret;
+ GstVideoFrame frame;
th_ycbcr_buffer ycbcr;
gint res;
return GST_FLOW_OK;
}
}
- theora_enc_init_buffer (ycbcr, &enc->info, GST_BUFFER_DATA (enc->prevbuf));
- } else
- theora_enc_init_buffer (ycbcr, &enc->info, GST_BUFFER_DATA (buffer));
+ gst_video_frame_map (&frame, &enc->vinfo, enc->prevbuf, GST_MAP_READ);
+ theora_enc_init_buffer (ycbcr, &frame);
+ } else {
+ gst_video_frame_map (&frame, &enc->vinfo, buffer, GST_MAP_READ);
+ theora_enc_init_buffer (ycbcr, &frame);
+ }
/* check for buffer, it can be optional */
if (enc->current_discont && buffer) {
gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
theora_enc_reset (enc);
enc->granulepos_offset =
- gst_util_uint64_scale (running_time, enc->fps_n,
- GST_SECOND * enc->fps_d);
+ gst_util_uint64_scale (running_time, enc->vinfo.fps_n,
+ GST_SECOND * enc->vinfo.fps_d);
enc->timestamp_offset = running_time;
enc->next_ts = 0;
enc->next_discont = TRUE;
}
theora_timefifo_truncate (enc);
+done:
+ gst_video_frame_unmap (&frame);
if (buffer)
gst_buffer_unref (buffer);
enc->current_discont = FALSE;
/* ERRORS */
multipass_read_failed:
{
- gst_buffer_unref (buffer);
- return ret;
+ GST_DEBUG_OBJECT (enc, "multipass read failed");
+ goto done;
}
multipass_write_failed:
{
- gst_buffer_unref (buffer);
- return ret;
+ GST_DEBUG_OBJECT (enc, "multipass write failed");
+ goto done;
}
data_push:
{
- gst_buffer_unref (buffer);
- return ret;
+ GST_DEBUG_OBJECT (enc, "error pushing buffer: %s", gst_flow_get_name (ret));
+ goto done;
}
}
static GstFlowReturn
-theora_enc_chain (GstPad * pad, GstBuffer * buffer)
+theora_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstTheoraEnc *enc;
ogg_packet op;
GstFlowReturn ret;
gboolean force_keyframe;
- enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
+ enc = GST_THEORA_ENC (parent);
/* we keep track of two timelines.
* - The timestamps from the incoming buffers, which we copy to the outgoing
/* mark buffers and put on caps */
caps = gst_caps_new_simple ("video/x-theora",
- "width", G_TYPE_INT, enc->width,
- "height", G_TYPE_INT, enc->height,
- "framerate", GST_TYPE_FRACTION, enc->fps_n, enc->fps_d,
- "pixel-aspect-ratio", GST_TYPE_FRACTION, enc->par_n, enc->par_d, NULL);
+ "width", G_TYPE_INT, enc->vinfo.width,
+ "height", G_TYPE_INT, enc->vinfo.height,
+ "framerate", GST_TYPE_FRACTION, enc->vinfo.fps_n, enc->vinfo.fps_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, enc->vinfo.par_n,
+ enc->vinfo.par_d, NULL);
caps = theora_set_header_on_caps (caps, buffers);
GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
gst_pad_set_caps (enc->srcpad, caps);
-
- g_slist_foreach (buffers, (GFunc) gst_buffer_set_caps, caps);
-
gst_caps_unref (caps);
/* push out the header buffers */
}
enc->granulepos_offset =
- gst_util_uint64_scale (running_time, enc->fps_n,
- GST_SECOND * enc->fps_d);
+ gst_util_uint64_scale (running_time, enc->vinfo.fps_n,
+ GST_SECOND * enc->vinfo.fps_d);
enc->timestamp_offset = running_time;
enc->next_ts = 0;
}
break;
}
- ret = parent_class->change_state (element, transition);
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
GstTheoraEnc *enc = GST_THEORA_ENC (object);
switch (prop_id) {
- case PROP_CENTER:
- case PROP_BORDER:
- case PROP_QUICK:
- case PROP_KEYFRAME_THRESHOLD:
- case PROP_KEYFRAME_MINDISTANCE:
- case PROP_NOISE_SENSITIVITY:
- case PROP_SHARPNESS:
- /* kept for API compat, but ignored */
- GST_WARNING_OBJECT (object, "Obsolete property '%s' ignored",
- pspec->name);
- break;
case PROP_BITRATE:
GST_OBJECT_LOCK (enc);
enc->video_bitrate = g_value_get_int (value) * 1000;
GstTheoraEnc *enc = GST_THEORA_ENC (object);
switch (prop_id) {
- case PROP_CENTER:
- g_value_set_boolean (value, TRUE);
- break;
- case PROP_BORDER:
- g_value_set_enum (value, BORDER_BLACK);
- break;
case PROP_BITRATE:
GST_OBJECT_LOCK (enc);
g_value_set_int (value, enc->video_bitrate / 1000);
g_value_set_int (value, enc->video_quality);
GST_OBJECT_UNLOCK (enc);
break;
- case PROP_QUICK:
- g_value_set_boolean (value, TRUE);
- break;
case PROP_KEYFRAME_AUTO:
g_value_set_boolean (value, enc->keyframe_auto);
break;
case PROP_KEYFRAME_FREQ_FORCE:
g_value_set_int (value, enc->keyframe_force);
break;
- case PROP_KEYFRAME_THRESHOLD:
- g_value_set_int (value, 80);
- break;
- case PROP_KEYFRAME_MINDISTANCE:
- g_value_set_int (value, 8);
- break;
- case PROP_NOISE_SENSITIVITY:
- g_value_set_int (value, 1);
- break;
- case PROP_SHARPNESS:
- g_value_set_int (value, 0);
- break;
case PROP_SPEEDLEVEL:
g_value_set_int (value, enc->speed_level);
break;