2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
3 * Copyright (c) 2012 Collabora Ltd.
4 * Author : Edward Hervey <edward@collabora.com>
5 * Author : Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 * SECTION:element-theoraenc
26 * @see_also: theoradec, oggmux
28 * This element encodes raw video into a Theora stream.
29 * [Theora](http://www.theora.org/) is a royalty-free
30 * video codec maintained by the [Xiph.org Foundation](http://www.xiph.org/),
31 * based on the VP3 codec.
33 * The theora codec internally only supports encoding of images that are a
34 * multiple of 16 pixels in both X and Y direction. It is however perfectly
35 * possible to encode images with other dimensions because an arbitrary
36 * rectangular cropping region can be set up. This element will automatically
37 * set up a correct cropping region if the dimensions are not multiples of 16
40 * To control the quality of the encoding, the #GstTheoraEnc:bitrate and
41 * #GstTheoraEnc:quality properties can be used. These two properties are
42 * mutualy exclusive. Setting the bitrate property will produce a constant
43 * bitrate (CBR) stream while setting the quality property will produce a
44 * variable bitrate (VBR) stream.
46 * A videorate element is often required in front of theoraenc, especially
47 * when transcoding and when putting Theora into the Ogg container.
51 * gst-launch-1.0 -v videotestsrc num-buffers=500 ! video/x-raw,width=1280,height=720 ! queue ! progressreport ! theoraenc ! oggmux ! filesink location=videotestsrc.ogg
53 * This example pipeline will encode a test video source to theora muxed in an
54 * ogg container. Refer to the theoradec documentation to decode the create
64 #include <stdlib.h> /* free */
66 #include <gst/tag/tag.h>
67 #include <gst/video/video.h>
68 #include <gst/video/gstvideometa.h>
70 #include "gsttheoraenc.h"
72 #define GST_CAT_DEFAULT theoraenc_debug
73 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
75 #define GST_TYPE_MULTIPASS_MODE (gst_multipass_mode_get_type())
77 gst_multipass_mode_get_type (void)
79 static GType multipass_mode_type = 0;
80 static const GEnumValue multipass_mode[] = {
81 {MULTIPASS_MODE_SINGLE_PASS, "Single pass", "single-pass"},
82 {MULTIPASS_MODE_FIRST_PASS, "First pass", "first-pass"},
83 {MULTIPASS_MODE_SECOND_PASS, "Second pass", "second-pass"},
87 if (!multipass_mode_type) {
89 g_enum_register_static ("GstTheoraEncMultipassMode", multipass_mode);
91 return multipass_mode_type;
94 /* taken from theora/lib/toplevel.c */
96 _ilog (unsigned int v)
107 #define THEORA_DEF_BITRATE 0
108 #define THEORA_DEF_QUALITY 48
109 #define THEORA_DEF_KEYFRAME_AUTO TRUE
110 #define THEORA_DEF_KEYFRAME_FREQ 64
111 #define THEORA_DEF_KEYFRAME_FREQ_FORCE 64
112 #define THEORA_DEF_SPEEDLEVEL 1
113 #define THEORA_DEF_VP3_COMPATIBLE FALSE
114 #define THEORA_DEF_DROP_FRAMES TRUE
115 #define THEORA_DEF_CAP_OVERFLOW TRUE
116 #define THEORA_DEF_CAP_UNDERFLOW FALSE
117 #define THEORA_DEF_RATE_BUFFER 0
118 #define THEORA_DEF_MULTIPASS_CACHE_FILE NULL
119 #define THEORA_DEF_MULTIPASS_MODE MULTIPASS_MODE_SINGLE_PASS
127 PROP_KEYFRAME_FREQ_FORCE,
134 PROP_MULTIPASS_CACHE_FILE,
139 /* this function does a straight granulepos -> timestamp conversion */
141 granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos)
143 guint64 iframe, pframe;
144 int shift = theoraenc->info.keyframe_granule_shift;
147 return GST_CLOCK_TIME_NONE;
149 iframe = granulepos >> shift;
150 pframe = granulepos - (iframe << shift);
152 /* num and den are 32 bit, so we can safely multiply with GST_SECOND */
153 return gst_util_uint64_scale ((guint64) (iframe + pframe),
154 GST_SECOND * theoraenc->info.fps_denominator,
155 theoraenc->info.fps_numerator);
158 static GstStaticPadTemplate theora_enc_sink_factory =
159 GST_STATIC_PAD_TEMPLATE ("sink",
162 GST_STATIC_CAPS ("video/x-raw, "
163 "format = (string) { I420, Y42B, Y444 }, "
164 "framerate = (fraction) [1/MAX, MAX], "
165 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
168 static GstStaticPadTemplate theora_enc_src_factory =
169 GST_STATIC_PAD_TEMPLATE ("src",
172 GST_STATIC_CAPS ("video/x-theora, "
173 "framerate = (fraction) [1/MAX, MAX], "
174 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
177 #define gst_theora_enc_parent_class parent_class
178 G_DEFINE_TYPE (GstTheoraEnc, gst_theora_enc, GST_TYPE_VIDEO_ENCODER);
180 static gboolean theora_enc_start (GstVideoEncoder * enc);
181 static gboolean theora_enc_stop (GstVideoEncoder * enc);
182 static gboolean theora_enc_flush (GstVideoEncoder * enc);
183 static gboolean theora_enc_set_format (GstVideoEncoder * enc,
184 GstVideoCodecState * state);
185 static GstFlowReturn theora_enc_handle_frame (GstVideoEncoder * enc,
186 GstVideoCodecFrame * frame);
187 static GstFlowReturn theora_enc_pre_push (GstVideoEncoder * benc,
188 GstVideoCodecFrame * frame);
189 static GstFlowReturn theora_enc_finish (GstVideoEncoder * enc);
190 static gboolean theora_enc_propose_allocation (GstVideoEncoder * encoder,
193 static GstCaps *theora_enc_getcaps (GstVideoEncoder * encoder,
195 static void theora_enc_get_property (GObject * object, guint prop_id,
196 GValue * value, GParamSpec * pspec);
197 static void theora_enc_set_property (GObject * object, guint prop_id,
198 const GValue * value, GParamSpec * pspec);
199 static void theora_enc_finalize (GObject * object);
201 static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
202 gboolean begin, gboolean eos);
205 gst_theora_enc_class_init (GstTheoraEncClass * klass)
207 GObjectClass *gobject_class = (GObjectClass *) klass;
208 GstElementClass *element_class = (GstElementClass *) klass;
209 GstVideoEncoderClass *gstvideo_encoder_class =
210 GST_VIDEO_ENCODER_CLASS (klass);
212 gobject_class->set_property = theora_enc_set_property;
213 gobject_class->get_property = theora_enc_get_property;
214 gobject_class->finalize = theora_enc_finalize;
216 gst_element_class_add_static_pad_template (element_class,
217 &theora_enc_src_factory);
218 gst_element_class_add_static_pad_template (element_class,
219 &theora_enc_sink_factory);
220 gst_element_class_set_static_metadata (element_class, "Theora video encoder",
221 "Codec/Encoder/Video", "encode raw YUV video to a theora stream",
222 "Wim Taymans <wim@fluendo.com>");
224 gstvideo_encoder_class->start = GST_DEBUG_FUNCPTR (theora_enc_start);
225 gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (theora_enc_stop);
226 gstvideo_encoder_class->flush = GST_DEBUG_FUNCPTR (theora_enc_flush);
227 gstvideo_encoder_class->set_format =
228 GST_DEBUG_FUNCPTR (theora_enc_set_format);
229 gstvideo_encoder_class->handle_frame =
230 GST_DEBUG_FUNCPTR (theora_enc_handle_frame);
231 gstvideo_encoder_class->pre_push = GST_DEBUG_FUNCPTR (theora_enc_pre_push);
232 gstvideo_encoder_class->finish = GST_DEBUG_FUNCPTR (theora_enc_finish);
233 gstvideo_encoder_class->getcaps = GST_DEBUG_FUNCPTR (theora_enc_getcaps);
234 gstvideo_encoder_class->propose_allocation =
235 GST_DEBUG_FUNCPTR (theora_enc_propose_allocation);
237 /* general encoding stream options */
238 g_object_class_install_property (gobject_class, PROP_BITRATE,
239 g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
240 0, (1 << 24) - 1, THEORA_DEF_BITRATE,
241 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
242 GST_PARAM_MUTABLE_PLAYING));
243 g_object_class_install_property (gobject_class, PROP_QUALITY,
244 g_param_spec_int ("quality", "Quality", "Video quality", 0, 63,
246 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
247 GST_PARAM_MUTABLE_PLAYING));
248 g_object_class_install_property (gobject_class, PROP_KEYFRAME_AUTO,
249 g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
250 "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
251 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
252 g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ,
253 g_param_spec_int ("keyframe-freq", "Keyframe frequency",
254 "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
255 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
256 g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ_FORCE,
257 g_param_spec_int ("keyframe-force", "Keyframe force",
258 "Force keyframe every N frames", 1, 32768,
259 THEORA_DEF_KEYFRAME_FREQ_FORCE,
260 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
261 g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL,
262 g_param_spec_int ("speed-level", "Speed level",
263 "Controls the amount of motion vector searching done while encoding",
264 0, 3, THEORA_DEF_SPEEDLEVEL,
265 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
266 g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE,
267 g_param_spec_boolean ("vp3-compatible", "VP3 compatible",
268 "Disables non-VP3 compatible features",
269 THEORA_DEF_VP3_COMPATIBLE,
270 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
271 g_object_class_install_property (gobject_class, PROP_DROP_FRAMES,
272 g_param_spec_boolean ("drop-frames", "Drop frames",
273 "Allow or disallow frame dropping",
274 THEORA_DEF_DROP_FRAMES,
275 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
276 g_object_class_install_property (gobject_class, PROP_CAP_OVERFLOW,
277 g_param_spec_boolean ("cap-overflow", "Cap overflow",
278 "Enable capping of bit reservoir overflows",
279 THEORA_DEF_CAP_OVERFLOW,
280 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
281 g_object_class_install_property (gobject_class, PROP_CAP_UNDERFLOW,
282 g_param_spec_boolean ("cap-underflow", "Cap underflow",
283 "Enable capping of bit reservoir underflows",
284 THEORA_DEF_CAP_UNDERFLOW,
285 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
286 g_object_class_install_property (gobject_class, PROP_RATE_BUFFER,
287 g_param_spec_int ("rate-buffer", "Rate Control Buffer",
288 "Sets the size of the rate control buffer, in units of frames. "
289 "The default value of 0 instructs the encoder to automatically "
290 "select an appropriate value",
291 0, 1000, THEORA_DEF_RATE_BUFFER,
292 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
293 g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
294 g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
295 "Multipass cache file", THEORA_DEF_MULTIPASS_CACHE_FILE,
296 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
297 g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
298 g_param_spec_enum ("multipass-mode", "Multipass mode",
299 "Single pass or first/second pass", GST_TYPE_MULTIPASS_MODE,
300 THEORA_DEF_MULTIPASS_MODE,
301 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
303 GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
305 gst_type_mark_as_plugin_api (GST_TYPE_MULTIPASS_MODE, 0);
309 gst_theora_enc_init (GstTheoraEnc * enc)
311 GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (enc));
313 enc->video_bitrate = THEORA_DEF_BITRATE;
314 enc->video_quality = THEORA_DEF_QUALITY;
315 enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
316 enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
317 enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
319 enc->speed_level = THEORA_DEF_SPEEDLEVEL;
320 enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
321 enc->drop_frames = THEORA_DEF_DROP_FRAMES;
322 enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
323 enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
324 enc->rate_buffer = THEORA_DEF_RATE_BUFFER;
326 enc->multipass_mode = THEORA_DEF_MULTIPASS_MODE;
327 enc->multipass_cache_file = THEORA_DEF_MULTIPASS_CACHE_FILE;
331 theora_enc_clear_multipass_cache (GstTheoraEnc * enc)
333 if (enc->multipass_cache_fd) {
334 g_io_channel_shutdown (enc->multipass_cache_fd, TRUE, NULL);
335 g_io_channel_unref (enc->multipass_cache_fd);
336 enc->multipass_cache_fd = NULL;
339 if (enc->multipass_cache_adapter) {
340 gst_object_unref (enc->multipass_cache_adapter);
341 enc->multipass_cache_adapter = NULL;
346 theora_enc_finalize (GObject * object)
348 GstTheoraEnc *enc = GST_THEORA_ENC (object);
350 GST_DEBUG_OBJECT (enc, "Finalizing");
352 th_encode_free (enc->encoder);
353 th_comment_clear (&enc->comment);
354 th_info_clear (&enc->info);
355 g_free (enc->multipass_cache_file);
357 theora_enc_clear_multipass_cache (enc);
359 if (enc->input_state)
360 gst_video_codec_state_unref (enc->input_state);
362 G_OBJECT_CLASS (parent_class)->finalize (object);
366 theora_enc_flush (GstVideoEncoder * encoder)
368 GstTheoraEnc *enc = GST_THEORA_ENC (encoder);
369 ogg_uint32_t keyframe_force;
373 if (enc->input_state == NULL) {
374 GST_INFO_OBJECT (enc, "Not configured yet, returning FALSE");
379 GST_OBJECT_LOCK (enc);
380 enc->info.target_bitrate = enc->video_bitrate;
381 enc->info.quality = enc->video_quality;
382 enc->bitrate_changed = FALSE;
383 enc->quality_changed = FALSE;
384 GST_OBJECT_UNLOCK (enc);
387 th_encode_free (enc->encoder);
389 enc->encoder = th_encode_alloc (&enc->info);
390 /* We ensure this function cannot fail. */
391 g_assert (enc->encoder != NULL);
392 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
393 sizeof (enc->speed_level));
394 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
395 &enc->vp3_compatible, sizeof (enc->vp3_compatible));
398 if (enc->drop_frames)
399 rate_flags |= TH_RATECTL_DROP_FRAMES;
400 if (enc->drop_frames)
401 rate_flags |= TH_RATECTL_CAP_OVERFLOW;
402 if (enc->drop_frames)
403 rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
404 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
405 &rate_flags, sizeof (rate_flags));
407 if (enc->rate_buffer) {
408 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
409 &enc->rate_buffer, sizeof (enc->rate_buffer));
414 keyframe_force = enc->keyframe_auto ?
415 enc->keyframe_force : enc->keyframe_freq;
416 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
417 &keyframe_force, sizeof (keyframe_force));
419 /* Get placeholder data */
420 if (enc->multipass_cache_fd
421 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
422 theora_enc_write_multipass_cache (enc, TRUE, FALSE);
428 theora_enc_start (GstVideoEncoder * benc)
432 GST_DEBUG_OBJECT (benc, "start: init theora");
433 enc = GST_THEORA_ENC (benc);
435 if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
438 if (!enc->multipass_cache_file) {
439 GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
442 enc->multipass_cache_fd =
443 g_io_channel_new_file (enc->multipass_cache_file,
444 (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"), &err);
446 if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
447 enc->multipass_cache_adapter = gst_adapter_new ();
449 if (!enc->multipass_cache_fd) {
450 GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
451 ("Failed to open multipass cache file: %s", err->message));
456 g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
460 enc->initialised = FALSE;
466 theora_enc_stop (GstVideoEncoder * benc)
470 GST_DEBUG_OBJECT (benc, "stop: clearing theora state");
471 enc = GST_THEORA_ENC (benc);
474 th_encode_free (enc->encoder);
476 th_comment_clear (&enc->comment);
477 th_info_clear (&enc->info);
479 if (enc->input_state)
480 gst_video_codec_state_unref (enc->input_state);
481 enc->input_state = NULL;
483 /* Everything else is handled in reset() */
484 theora_enc_clear_multipass_cache (enc);
490 theora_enc_get_supported_formats (void)
496 th_pixel_fmt pixelformat;
500 TH_PF_420, "I420"}, {
501 TH_PF_422, "Y42B"}, {
504 GString *string = NULL;
507 th_info_init (&info);
508 info.frame_width = 16;
509 info.frame_height = 16;
510 info.fps_numerator = 25;
511 info.fps_denominator = 1;
512 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
513 info.pixel_fmt = formats[i].pixelformat;
515 encoder = th_encode_alloc (&info);
519 GST_LOG ("format %s is supported", formats[i].fourcc);
520 th_encode_free (encoder);
522 if (string == NULL) {
523 string = g_string_new (formats[i].fourcc);
525 g_string_append (string, ", ");
526 g_string_append (string, formats[i].fourcc);
529 th_info_clear (&info);
531 return string == NULL ? NULL : g_string_free (string, FALSE);
535 theora_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
538 char *supported_formats, *caps_string;
540 supported_formats = theora_enc_get_supported_formats ();
541 if (!supported_formats) {
542 GST_WARNING ("no supported formats found. Encoder disabled?");
543 return gst_caps_new_empty ();
546 caps_string = g_strdup_printf ("video/x-raw, "
547 "format = (string) { %s }, "
548 "framerate = (fraction) [1/MAX, MAX], "
549 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
551 caps = gst_caps_from_string (caps_string);
552 g_free (caps_string);
553 g_free (supported_formats);
554 GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
556 ret = gst_video_encoder_proxy_getcaps (encoder, caps, filter);
557 gst_caps_unref (caps);
563 theora_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state)
565 GstTheoraEnc *enc = GST_THEORA_ENC (benc);
566 GstVideoInfo *info = &state->info;
568 enc->width = GST_VIDEO_INFO_WIDTH (info);
569 enc->height = GST_VIDEO_INFO_HEIGHT (info);
571 th_info_clear (&enc->info);
572 th_info_init (&enc->info);
573 /* Theora has a divisible-by-sixteen restriction for the encoded video size but
574 * we can define a picture area using pic_width/pic_height */
575 enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
576 enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
577 enc->info.pic_width = enc->width;
578 enc->info.pic_height = enc->height;
579 switch (GST_VIDEO_INFO_FORMAT (info)) {
580 case GST_VIDEO_FORMAT_I420:
581 enc->info.pixel_fmt = TH_PF_420;
583 case GST_VIDEO_FORMAT_Y42B:
584 enc->info.pixel_fmt = TH_PF_422;
586 case GST_VIDEO_FORMAT_Y444:
587 enc->info.pixel_fmt = TH_PF_444;
590 g_assert_not_reached ();
593 enc->info.fps_numerator = enc->fps_n = GST_VIDEO_INFO_FPS_N (info);
594 enc->info.fps_denominator = enc->fps_d = GST_VIDEO_INFO_FPS_D (info);
595 enc->info.aspect_numerator = GST_VIDEO_INFO_PAR_N (info);
596 enc->info.aspect_denominator = GST_VIDEO_INFO_PAR_D (info);
598 enc->info.colorspace = TH_CS_UNSPECIFIED;
600 /* Save input state */
601 if (enc->input_state)
602 gst_video_codec_state_unref (enc->input_state);
603 enc->input_state = gst_video_codec_state_ref (state);
605 /* as done in theora */
606 enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
607 GST_DEBUG_OBJECT (enc,
608 "keyframe_frequency_force is %d, granule shift is %d",
609 enc->keyframe_force, enc->info.keyframe_granule_shift);
611 theora_enc_flush (benc);
612 enc->initialised = TRUE;
618 theora_enc_pre_push (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
620 GstTheoraEnc *enc = GST_THEORA_ENC (benc);
623 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
624 * time representation */
625 /* granulepos from sync frame */
626 pfn = frame->presentation_frame_number - frame->distance_from_sync;
627 /* correct to correspond to linear running time */
628 pfn -= enc->pfn_offset;
629 pfn += enc->granulepos_offset + 1;
631 GST_BUFFER_OFFSET_END (frame->output_buffer) =
632 (pfn << enc->info.keyframe_granule_shift) + frame->distance_from_sync;
633 GST_BUFFER_OFFSET (frame->output_buffer) = granulepos_to_timestamp (enc,
634 GST_BUFFER_OFFSET_END (frame->output_buffer));
640 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet)
642 GstVideoEncoder *benc;
644 GstVideoCodecFrame *frame;
646 benc = GST_VIDEO_ENCODER (enc);
648 frame = gst_video_encoder_get_oldest_frame (benc);
649 if (gst_video_encoder_allocate_output_frame (benc, frame,
650 packet->bytes) != GST_FLOW_OK) {
651 GST_WARNING_OBJECT (enc, "Could not allocate buffer");
652 gst_video_codec_frame_unref (frame);
653 ret = GST_FLOW_ERROR;
657 if (packet->bytes > 0)
658 gst_buffer_fill (frame->output_buffer, 0, packet->packet, packet->bytes);
660 /* the second most significant bit of the first data byte is cleared
662 if (packet->bytes > 0 && (packet->packet[0] & 0x40) == 0) {
663 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
665 GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
669 ret = gst_video_encoder_finish_frame (benc, frame);
676 theora_set_header_on_caps (GstCaps * caps, GList * buffers)
678 GstStructure *structure;
679 GValue array = { 0 };
680 GValue value = { 0 };
684 caps = gst_caps_make_writable (caps);
685 structure = gst_caps_get_structure (caps, 0);
687 /* put copies of the buffers in a fixed list */
688 g_value_init (&array, GST_TYPE_ARRAY);
690 for (walk = buffers; walk; walk = walk->next) {
692 g_value_init (&value, GST_TYPE_BUFFER);
693 gst_value_set_buffer (&value, buffer);
694 gst_value_array_append_value (&array, &value);
695 g_value_unset (&value);
698 gst_structure_take_value (structure, "streamheader", &array);
704 theora_enc_init_buffer (th_ycbcr_buffer buf, GstVideoFrame * frame)
709 /* According to Theora developer Timothy Terriberry, the Theora
710 * encoder will not use memory outside of pic_width/height, even when
711 * the frame size is bigger. The values outside this region will be encoded
713 * Due to this, setting the frame's width/height as the buffer width/height
714 * is perfectly ok, even though it does not strictly look ok.
717 gst_video_info_init (&vinfo);
718 gst_video_info_set_format (&vinfo, GST_VIDEO_FRAME_FORMAT (frame),
719 GST_ROUND_UP_16 (GST_VIDEO_FRAME_WIDTH (frame)),
720 GST_ROUND_UP_16 (GST_VIDEO_FRAME_HEIGHT (frame)));
722 for (i = 0; i < 3; i++) {
723 buf[i].width = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, i);
724 buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, i);
725 buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
726 buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
731 theora_enc_read_multipass_cache (GstTheoraEnc * enc)
733 GstBuffer *cache_buf;
734 const guint8 *cache_data;
735 gsize bytes_read = 0;
736 gssize bytes_consumed = 0;
737 GIOStatus stat = G_IO_STATUS_NORMAL;
738 gboolean done = FALSE;
741 if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
744 cache_buf = gst_buffer_new_allocate (NULL, 512, NULL);
746 gst_buffer_map (cache_buf, &minfo, GST_MAP_WRITE);
748 stat = g_io_channel_read_chars (enc->multipass_cache_fd,
749 (gchar *) minfo.data, minfo.size, &bytes_read, NULL);
751 if (bytes_read <= 0) {
752 gst_buffer_unmap (cache_buf, &minfo);
753 gst_buffer_unref (cache_buf);
756 gst_buffer_unmap (cache_buf, &minfo);
757 gst_buffer_resize (cache_buf, 0, bytes_read);
759 gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
762 if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
766 MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
768 cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
771 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
773 gst_adapter_unmap (enc->multipass_cache_adapter);
775 done = bytes_consumed <= 0;
776 if (bytes_consumed > 0)
777 gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
780 if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
781 || bytes_consumed < 0) {
782 GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
783 ("Failed to read multipass cache file"));
790 theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
794 GIOStatus stat = G_IO_STATUS_NORMAL;
796 gsize bytes_written = 0;
800 stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
803 if (stat == G_IO_STATUS_ERROR) {
805 GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
806 ("Failed to seek to beginning of multipass cache file: %s",
809 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
810 ("Failed to seek to beginning of multipass cache file: %s",
820 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
822 g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
823 &bytes_written, &err);
824 } while (bytes_read > 0 && bytes_written > 0 && !err);
826 if (bytes_read < 0 || err) {
827 if (bytes_read < 0) {
828 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
829 ("Failed to read multipass cache data: %d", bytes_read));
831 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
832 ("Failed to write multipass cache file: %s", err->message));
844 theora_enc_reset_ts (GstTheoraEnc * enc, GstClockTime running_time, gint pfn)
846 enc->granulepos_offset =
847 gst_util_uint64_scale (running_time, enc->fps_n, GST_SECOND * enc->fps_d);
848 enc->timestamp_offset = running_time;
849 enc->pfn_offset = pfn;
853 theora_enc_buffer_from_header_packet (GstTheoraEnc * enc, ogg_packet * packet)
858 gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (enc),
860 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
861 GST_BUFFER_OFFSET (outbuf) = 0;
862 GST_BUFFER_OFFSET_END (outbuf) = 0;
863 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
864 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
865 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
867 GST_DEBUG ("created header packet buffer, %u bytes",
868 (guint) gst_buffer_get_size (outbuf));
873 theora_enc_handle_frame (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
877 GstClockTime timestamp, running_time;
879 gboolean force_keyframe;
881 enc = GST_THEORA_ENC (benc);
883 /* we keep track of two timelines.
884 * - The timestamps from the incoming buffers, which we copy to the outgoing
885 * encoded buffers as-is. We need to do this as we simply forward the
887 * - The running_time of the buffers, which we use to construct the granulepos
890 timestamp = frame->pts;
892 /* incoming buffers are clipped, so this should be positive */
894 gst_segment_to_running_time (&GST_VIDEO_ENCODER_INPUT_SEGMENT (enc),
895 GST_FORMAT_TIME, timestamp);
897 GST_OBJECT_LOCK (enc);
898 if (enc->bitrate_changed) {
899 long int bitrate = enc->video_bitrate;
901 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
903 enc->bitrate_changed = FALSE;
906 if (enc->quality_changed) {
907 long int quality = enc->video_quality;
909 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
911 enc->quality_changed = FALSE;
914 /* see if we need to schedule a keyframe */
915 force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame);
916 GST_OBJECT_UNLOCK (enc);
918 if (enc->packetno == 0) {
919 /* no packets written yet, setup headers */
922 GList *buffers = NULL;
924 GstVideoCodecState *state;
926 enc->granulepos_offset = 0;
927 enc->timestamp_offset = 0;
929 GST_DEBUG_OBJECT (enc, "output headers");
930 /* Theora streams begin with three headers; the initial header (with
931 most of the codec setup parameters) which is mandated by the Ogg
932 bitstream spec. The second header holds any comment fields. The
933 third header holds the bitstream codebook. We merely need to
934 make the headers, then pass them to libtheora one at a time;
935 libtheora handles the additional Ogg bitstream constraints */
937 /* create the remaining theora headers */
938 th_comment_clear (&enc->comment);
939 th_comment_init (&enc->comment);
942 th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
943 buf = theora_enc_buffer_from_header_packet (enc, &op);
944 buffers = g_list_prepend (buffers, buf);
947 g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
948 g_list_free (buffers);
949 goto encoder_disabled;
952 buffers = g_list_reverse (buffers);
954 /* mark buffers and put on caps */
955 caps = gst_caps_new_empty_simple ("video/x-theora");
956 caps = theora_set_header_on_caps (caps, buffers);
957 state = gst_video_encoder_set_output_state (benc, caps, enc->input_state);
959 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, state->caps);
961 gst_video_codec_state_unref (state);
963 gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc));
965 gst_video_encoder_set_headers (benc, buffers);
967 theora_enc_reset_ts (enc, running_time, frame->presentation_frame_number);
971 th_ycbcr_buffer ycbcr;
972 gint res, keyframe_interval;
973 GstVideoFrame vframe;
975 if (force_keyframe) {
976 /* if we want a keyframe, temporarily reset the max keyframe interval
977 * to 1, which will cause libtheora to emit one. There is no API to
978 * request a keyframe at the moment. */
979 keyframe_interval = 1;
980 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
981 &keyframe_interval, sizeof (keyframe_interval));
984 if (enc->multipass_cache_fd
985 && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
986 if (!theora_enc_read_multipass_cache (enc)) {
987 ret = GST_FLOW_ERROR;
988 goto multipass_read_failed;
992 gst_video_frame_map (&vframe, &enc->input_state->info, frame->input_buffer,
994 theora_enc_init_buffer (ycbcr, &vframe);
996 res = th_encode_ycbcr_in (enc->encoder, ycbcr);
997 gst_video_frame_unmap (&vframe);
999 /* none of the failure cases can happen here */
1000 g_assert (res == 0);
1002 if (enc->multipass_cache_fd
1003 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
1004 if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
1005 ret = GST_FLOW_ERROR;
1006 goto multipass_write_failed;
1011 while (th_encode_packetout (enc->encoder, 0, &op)) {
1012 /* Reset the max keyframe interval to its original state, and reset
1013 * the flag so we don't create more keyframes if we loop */
1014 if (force_keyframe) {
1016 enc->keyframe_auto ? enc->keyframe_force : enc->keyframe_freq;
1017 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
1018 &keyframe_interval, sizeof (keyframe_interval));
1019 force_keyframe = FALSE;
1022 ret = theora_push_packet (enc, &op);
1023 if (ret != GST_FLOW_OK)
1029 gst_video_codec_frame_unref (frame);
1033 multipass_read_failed:
1035 gst_video_codec_frame_unref (frame);
1038 multipass_write_failed:
1040 gst_video_codec_frame_unref (frame);
1045 gst_video_codec_frame_unref (frame);
1046 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1047 ("libtheora has been compiled with the encoder disabled"));
1048 return GST_FLOW_ERROR;
1053 theora_enc_finish (GstVideoEncoder * benc)
1058 enc = GST_THEORA_ENC (benc);
1060 if (enc->initialised) {
1061 /* push last packet with eos flag, should not be called */
1062 while (th_encode_packetout (enc->encoder, 1, &op)) {
1063 theora_push_packet (enc, &op);
1066 if (enc->initialised && enc->multipass_cache_fd
1067 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
1068 theora_enc_write_multipass_cache (enc, TRUE, TRUE);
1070 theora_enc_clear_multipass_cache (enc);
1076 theora_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
1078 gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
1080 return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
1085 theora_enc_set_property (GObject * object, guint prop_id,
1086 const GValue * value, GParamSpec * pspec)
1088 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1092 GST_OBJECT_LOCK (enc);
1093 enc->video_bitrate = g_value_get_int (value) * 1000;
1094 enc->video_quality = 0;
1095 enc->bitrate_changed = TRUE;
1096 GST_OBJECT_UNLOCK (enc);
1099 GST_OBJECT_LOCK (enc);
1100 if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_quality == 0) {
1101 GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
1104 enc->video_quality = g_value_get_int (value);
1105 enc->video_bitrate = 0;
1106 enc->quality_changed = TRUE;
1108 GST_OBJECT_UNLOCK (enc);
1110 case PROP_KEYFRAME_AUTO:
1111 enc->keyframe_auto = g_value_get_boolean (value);
1113 case PROP_KEYFRAME_FREQ:
1114 enc->keyframe_freq = g_value_get_int (value);
1116 case PROP_KEYFRAME_FREQ_FORCE:
1117 enc->keyframe_force = g_value_get_int (value);
1119 case PROP_SPEEDLEVEL:
1120 enc->speed_level = g_value_get_int (value);
1122 case PROP_VP3_COMPATIBLE:
1123 enc->vp3_compatible = g_value_get_boolean (value);
1125 case PROP_DROP_FRAMES:
1126 enc->drop_frames = g_value_get_boolean (value);
1128 case PROP_CAP_OVERFLOW:
1129 enc->cap_overflow = g_value_get_boolean (value);
1131 case PROP_CAP_UNDERFLOW:
1132 enc->cap_underflow = g_value_get_boolean (value);
1134 case PROP_RATE_BUFFER:
1135 enc->rate_buffer = g_value_get_int (value);
1137 case PROP_MULTIPASS_CACHE_FILE:
1138 enc->multipass_cache_file = g_value_dup_string (value);
1140 case PROP_MULTIPASS_MODE:
1141 enc->multipass_mode = g_value_get_enum (value);
1144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1150 theora_enc_get_property (GObject * object, guint prop_id,
1151 GValue * value, GParamSpec * pspec)
1153 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1157 GST_OBJECT_LOCK (enc);
1158 g_value_set_int (value, enc->video_bitrate / 1000);
1159 GST_OBJECT_UNLOCK (enc);
1162 GST_OBJECT_LOCK (enc);
1163 g_value_set_int (value, enc->video_quality);
1164 GST_OBJECT_UNLOCK (enc);
1166 case PROP_KEYFRAME_AUTO:
1167 g_value_set_boolean (value, enc->keyframe_auto);
1169 case PROP_KEYFRAME_FREQ:
1170 g_value_set_int (value, enc->keyframe_freq);
1172 case PROP_KEYFRAME_FREQ_FORCE:
1173 g_value_set_int (value, enc->keyframe_force);
1175 case PROP_SPEEDLEVEL:
1176 g_value_set_int (value, enc->speed_level);
1178 case PROP_VP3_COMPATIBLE:
1179 g_value_set_boolean (value, enc->vp3_compatible);
1181 case PROP_DROP_FRAMES:
1182 g_value_set_boolean (value, enc->drop_frames);
1184 case PROP_CAP_OVERFLOW:
1185 g_value_set_boolean (value, enc->cap_overflow);
1187 case PROP_CAP_UNDERFLOW:
1188 g_value_set_boolean (value, enc->cap_underflow);
1190 case PROP_RATE_BUFFER:
1191 g_value_set_int (value, enc->rate_buffer);
1193 case PROP_MULTIPASS_CACHE_FILE:
1194 g_value_set_string (value, enc->multipass_cache_file);
1196 case PROP_MULTIPASS_MODE:
1197 g_value_set_enum (value, enc->multipass_mode);
1200 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);