#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
enum
{
PROP_0,
- PROP_CROP,
PROP_TELEMETRY_MV,
PROP_TELEMETRY_MBMODE,
PROP_TELEMETRY_QI,
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 ]")
);
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);
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)
{
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",
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);
}
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;
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);
/* 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;
/* make sure we don't read too much */
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 */
if (offset == 2)
data += psize;
offset += psize;
}
+
+ gst_buffer_unmap (buffer, &minfo);
}
GST_DEBUG_OBJECT (dec, "Done");
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 *) "\201theora", 7,
- &encoder);
-
- gst_buffer_unref (buf);
+ gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes,
+ (guint8 *) "\201theora", 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,
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);
/* 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;
}
int i, plane;
guint8 *dest, *src;
GstBuffer *out;
+ GstMapInfo minfo;
result = gst_video_decoder_alloc_output_frame (decoder, frame);
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 ==
}
}
+ gst_buffer_unmap (out, &minfo);
+
return GST_FLOW_OK;
}
{
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;
}
done:
+ gst_buffer_unmap (buf, &minfo);
+
return result;
}
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;
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;
#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 ]")
);
-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);
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,
gboolean begin, gboolean eos);
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_static_pad_template_get (&theora_enc_src_factory));
"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);
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)",
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 motion vector searching done while "
}
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;
}
static GstCaps *
-theora_enc_sink_getcaps (GstPad * pad)
+theora_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
{
- GstCaps *caps;
+ GstCaps *caps, *ret;
char *supported_formats, *caps_string;
supported_formats = theora_enc_get_supported_formats ();
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);
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
benc = GST_VIDEO_ENCODER (enc);
- buf = gst_buffer_new_and_alloc (packet->bytes);
+ buf = gst_buffer_new_allocate (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;
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 */
}
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 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
* 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);
}
}
{
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) {
- cache_buf = gst_buffer_new_and_alloc (512);
+ GstMapInfo minfo;
+
+ cache_buf = gst_buffer_new_allocate (NULL, 512, NULL);
+
+ gst_buffer_map (cache_buf, &minfo, GST_MAP_WRITE);
+
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 *) minfo.data, minfo.size, &bytes_read, NULL);
if (bytes_read <= 0) {
+ gst_buffer_unmap (cache_buf, &minfo);
gst_buffer_unref (cache_buf);
break;
} else {
- GST_BUFFER_SIZE (cache_buf) = bytes_read;
+ gst_buffer_unmap (cache_buf, &minfo);
+ 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);
}
- if (stat == G_IO_STATUS_ERROR || bytes_read < 0 || bytes_written < 0) {
+ if (stat == G_IO_STATUS_ERROR || bytes_read < 0) {
if (begin) {
if (eos)
GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
{
GstBuffer *outbuf;
- outbuf = gst_buffer_new_and_alloc (packet->bytes);
- memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
+ outbuf = gst_buffer_new_allocate (NULL, packet->bytes, NULL);
+ gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
GST_BUFFER_OFFSET (outbuf) = 0;
GST_BUFFER_OFFSET_END (outbuf) = 0;
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
GST_DEBUG ("created header packet buffer, %d bytes",
- GST_BUFFER_SIZE (outbuf));
+ gst_buffer_get_size (outbuf));
return outbuf;
}
buffers = g_list_reverse (buffers);
/* mark buffers and put on caps */
- caps = gst_caps_new_simple ("video/x-theora", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-theora");
caps = theora_set_header_on_caps (caps, buffers);
state = gst_video_encoder_set_output_state (benc, caps, enc->input_state);
{
th_ycbcr_buffer ycbcr;
gint res;
-
- theora_enc_init_buffer (ycbcr, &enc->info,
- GST_BUFFER_DATA (frame->input_buffer));
+ GstVideoFrame vframe;
if (force_keyframe) {
theora_enc_reset (enc);
}
}
+ gst_video_frame_map (&vframe, &enc->input_state->info, frame->input_buffer,
+ GST_MAP_READ);
+ theora_enc_init_buffer (ycbcr, &vframe);
+
res = th_encode_ycbcr_in (enc->encoder, ycbcr);
+ gst_video_frame_unmap (&vframe);
+
/* none of the failure cases can happen here */
g_assert (res == 0);
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 */
- 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;