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 * <ulink url="http://www.theora.org/">Theora</ulink> is a royalty-free
30 * video codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
31 * Foundation</ulink>, 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");
307 gst_theora_enc_init (GstTheoraEnc * enc)
309 GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (enc));
311 enc->video_bitrate = THEORA_DEF_BITRATE;
312 enc->video_quality = THEORA_DEF_QUALITY;
313 enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
314 enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
315 enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
317 enc->speed_level = THEORA_DEF_SPEEDLEVEL;
318 enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
319 enc->drop_frames = THEORA_DEF_DROP_FRAMES;
320 enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
321 enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
322 enc->rate_buffer = THEORA_DEF_RATE_BUFFER;
324 enc->multipass_mode = THEORA_DEF_MULTIPASS_MODE;
325 enc->multipass_cache_file = THEORA_DEF_MULTIPASS_CACHE_FILE;
329 theora_enc_clear_multipass_cache (GstTheoraEnc * enc)
331 if (enc->multipass_cache_fd) {
332 g_io_channel_shutdown (enc->multipass_cache_fd, TRUE, NULL);
333 g_io_channel_unref (enc->multipass_cache_fd);
334 enc->multipass_cache_fd = NULL;
337 if (enc->multipass_cache_adapter) {
338 gst_object_unref (enc->multipass_cache_adapter);
339 enc->multipass_cache_adapter = NULL;
344 theora_enc_finalize (GObject * object)
346 GstTheoraEnc *enc = GST_THEORA_ENC (object);
348 GST_DEBUG_OBJECT (enc, "Finalizing");
350 th_encode_free (enc->encoder);
351 th_comment_clear (&enc->comment);
352 th_info_clear (&enc->info);
353 g_free (enc->multipass_cache_file);
355 theora_enc_clear_multipass_cache (enc);
357 if (enc->input_state)
358 gst_video_codec_state_unref (enc->input_state);
360 G_OBJECT_CLASS (parent_class)->finalize (object);
364 theora_enc_flush (GstVideoEncoder * encoder)
366 GstTheoraEnc *enc = GST_THEORA_ENC (encoder);
367 ogg_uint32_t keyframe_force;
371 if (enc->input_state == NULL) {
372 GST_INFO_OBJECT (enc, "Not configured yet, returning FALSE");
377 GST_OBJECT_LOCK (enc);
378 enc->info.target_bitrate = enc->video_bitrate;
379 enc->info.quality = enc->video_quality;
380 enc->bitrate_changed = FALSE;
381 enc->quality_changed = FALSE;
382 GST_OBJECT_UNLOCK (enc);
385 th_encode_free (enc->encoder);
387 enc->encoder = th_encode_alloc (&enc->info);
388 /* We ensure this function cannot fail. */
389 g_assert (enc->encoder != NULL);
390 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
391 sizeof (enc->speed_level));
392 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
393 &enc->vp3_compatible, sizeof (enc->vp3_compatible));
396 if (enc->drop_frames)
397 rate_flags |= TH_RATECTL_DROP_FRAMES;
398 if (enc->drop_frames)
399 rate_flags |= TH_RATECTL_CAP_OVERFLOW;
400 if (enc->drop_frames)
401 rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
402 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
403 &rate_flags, sizeof (rate_flags));
405 if (enc->rate_buffer) {
406 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
407 &enc->rate_buffer, sizeof (enc->rate_buffer));
412 keyframe_force = enc->keyframe_auto ?
413 enc->keyframe_force : enc->keyframe_freq;
414 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
415 &keyframe_force, sizeof (keyframe_force));
417 /* Get placeholder data */
418 if (enc->multipass_cache_fd
419 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
420 theora_enc_write_multipass_cache (enc, TRUE, FALSE);
426 theora_enc_start (GstVideoEncoder * benc)
430 GST_DEBUG_OBJECT (benc, "start: init theora");
431 enc = GST_THEORA_ENC (benc);
433 if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
436 if (!enc->multipass_cache_file) {
437 GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
440 enc->multipass_cache_fd =
441 g_io_channel_new_file (enc->multipass_cache_file,
442 (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"), &err);
444 if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
445 enc->multipass_cache_adapter = gst_adapter_new ();
447 if (!enc->multipass_cache_fd) {
448 GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
449 ("Failed to open multipass cache file: %s", err->message));
454 g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
458 enc->initialised = FALSE;
464 theora_enc_stop (GstVideoEncoder * benc)
468 GST_DEBUG_OBJECT (benc, "stop: clearing theora state");
469 enc = GST_THEORA_ENC (benc);
472 th_encode_free (enc->encoder);
474 th_comment_clear (&enc->comment);
475 th_info_clear (&enc->info);
477 if (enc->input_state)
478 gst_video_codec_state_unref (enc->input_state);
479 enc->input_state = NULL;
481 /* Everything else is handled in reset() */
482 theora_enc_clear_multipass_cache (enc);
488 theora_enc_get_supported_formats (void)
494 th_pixel_fmt pixelformat;
498 TH_PF_420, "I420"}, {
499 TH_PF_422, "Y42B"}, {
502 GString *string = NULL;
505 th_info_init (&info);
506 info.frame_width = 16;
507 info.frame_height = 16;
508 info.fps_numerator = 25;
509 info.fps_denominator = 1;
510 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
511 info.pixel_fmt = formats[i].pixelformat;
513 encoder = th_encode_alloc (&info);
517 GST_LOG ("format %s is supported", formats[i].fourcc);
518 th_encode_free (encoder);
520 if (string == NULL) {
521 string = g_string_new (formats[i].fourcc);
523 g_string_append (string, ", ");
524 g_string_append (string, formats[i].fourcc);
527 th_info_clear (&info);
529 return string == NULL ? NULL : g_string_free (string, FALSE);
533 theora_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
536 char *supported_formats, *caps_string;
538 supported_formats = theora_enc_get_supported_formats ();
539 if (!supported_formats) {
540 GST_WARNING ("no supported formats found. Encoder disabled?");
541 return gst_caps_new_empty ();
544 caps_string = g_strdup_printf ("video/x-raw, "
545 "format = (string) { %s }, "
546 "framerate = (fraction) [1/MAX, MAX], "
547 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
549 caps = gst_caps_from_string (caps_string);
550 g_free (caps_string);
551 g_free (supported_formats);
552 GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
554 ret = gst_video_encoder_proxy_getcaps (encoder, caps, filter);
555 gst_caps_unref (caps);
561 theora_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state)
563 GstTheoraEnc *enc = GST_THEORA_ENC (benc);
564 GstVideoInfo *info = &state->info;
566 enc->width = GST_VIDEO_INFO_WIDTH (info);
567 enc->height = GST_VIDEO_INFO_HEIGHT (info);
569 th_info_clear (&enc->info);
570 th_info_init (&enc->info);
571 /* Theora has a divisible-by-sixteen restriction for the encoded video size but
572 * we can define a picture area using pic_width/pic_height */
573 enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
574 enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
575 enc->info.pic_width = enc->width;
576 enc->info.pic_height = enc->height;
577 switch (GST_VIDEO_INFO_FORMAT (info)) {
578 case GST_VIDEO_FORMAT_I420:
579 enc->info.pixel_fmt = TH_PF_420;
581 case GST_VIDEO_FORMAT_Y42B:
582 enc->info.pixel_fmt = TH_PF_422;
584 case GST_VIDEO_FORMAT_Y444:
585 enc->info.pixel_fmt = TH_PF_444;
588 g_assert_not_reached ();
591 enc->info.fps_numerator = enc->fps_n = GST_VIDEO_INFO_FPS_N (info);
592 enc->info.fps_denominator = enc->fps_d = GST_VIDEO_INFO_FPS_D (info);
593 enc->info.aspect_numerator = GST_VIDEO_INFO_PAR_N (info);
594 enc->info.aspect_denominator = GST_VIDEO_INFO_PAR_D (info);
596 enc->info.colorspace = TH_CS_UNSPECIFIED;
598 /* Save input state */
599 if (enc->input_state)
600 gst_video_codec_state_unref (enc->input_state);
601 enc->input_state = gst_video_codec_state_ref (state);
603 /* as done in theora */
604 enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
605 GST_DEBUG_OBJECT (enc,
606 "keyframe_frequency_force is %d, granule shift is %d",
607 enc->keyframe_force, enc->info.keyframe_granule_shift);
609 theora_enc_flush (benc);
610 enc->initialised = TRUE;
616 theora_enc_pre_push (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
618 GstTheoraEnc *enc = GST_THEORA_ENC (benc);
621 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
622 * time representation */
623 /* granulepos from sync frame */
624 pfn = frame->presentation_frame_number - frame->distance_from_sync;
625 /* correct to correspond to linear running time */
626 pfn -= enc->pfn_offset;
627 pfn += enc->granulepos_offset + 1;
629 GST_BUFFER_OFFSET_END (frame->output_buffer) =
630 (pfn << enc->info.keyframe_granule_shift) + frame->distance_from_sync;
631 GST_BUFFER_OFFSET (frame->output_buffer) = granulepos_to_timestamp (enc,
632 GST_BUFFER_OFFSET_END (frame->output_buffer));
638 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet)
640 GstVideoEncoder *benc;
642 GstVideoCodecFrame *frame;
644 benc = GST_VIDEO_ENCODER (enc);
646 frame = gst_video_encoder_get_oldest_frame (benc);
647 if (gst_video_encoder_allocate_output_frame (benc, frame,
648 packet->bytes) != GST_FLOW_OK) {
649 GST_WARNING_OBJECT (enc, "Could not allocate buffer");
650 gst_video_codec_frame_unref (frame);
651 ret = GST_FLOW_ERROR;
655 if (packet->bytes > 0)
656 gst_buffer_fill (frame->output_buffer, 0, packet->packet, packet->bytes);
658 /* the second most significant bit of the first data byte is cleared
660 if (packet->bytes > 0 && (packet->packet[0] & 0x40) == 0) {
661 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
663 GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
667 ret = gst_video_encoder_finish_frame (benc, frame);
674 theora_set_header_on_caps (GstCaps * caps, GList * buffers)
676 GstStructure *structure;
677 GValue array = { 0 };
678 GValue value = { 0 };
682 caps = gst_caps_make_writable (caps);
683 structure = gst_caps_get_structure (caps, 0);
685 /* put copies of the buffers in a fixed list */
686 g_value_init (&array, GST_TYPE_ARRAY);
688 for (walk = buffers; walk; walk = walk->next) {
690 g_value_init (&value, GST_TYPE_BUFFER);
691 gst_value_set_buffer (&value, buffer);
692 gst_value_array_append_value (&array, &value);
693 g_value_unset (&value);
696 gst_structure_take_value (structure, "streamheader", &array);
702 theora_enc_init_buffer (th_ycbcr_buffer buf, GstVideoFrame * frame)
707 /* According to Theora developer Timothy Terriberry, the Theora
708 * encoder will not use memory outside of pic_width/height, even when
709 * the frame size is bigger. The values outside this region will be encoded
711 * Due to this, setting the frame's width/height as the buffer width/height
712 * is perfectly ok, even though it does not strictly look ok.
715 gst_video_info_init (&vinfo);
716 gst_video_info_set_format (&vinfo, GST_VIDEO_FRAME_FORMAT (frame),
717 GST_ROUND_UP_16 (GST_VIDEO_FRAME_WIDTH (frame)),
718 GST_ROUND_UP_16 (GST_VIDEO_FRAME_HEIGHT (frame)));
720 for (i = 0; i < 3; i++) {
721 buf[i].width = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, i);
722 buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, i);
723 buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
724 buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
729 theora_enc_read_multipass_cache (GstTheoraEnc * enc)
731 GstBuffer *cache_buf;
732 const guint8 *cache_data;
733 gsize bytes_read = 0;
734 gssize bytes_consumed = 0;
735 GIOStatus stat = G_IO_STATUS_NORMAL;
736 gboolean done = FALSE;
739 if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
742 cache_buf = gst_buffer_new_allocate (NULL, 512, NULL);
744 gst_buffer_map (cache_buf, &minfo, GST_MAP_WRITE);
746 stat = g_io_channel_read_chars (enc->multipass_cache_fd,
747 (gchar *) minfo.data, minfo.size, &bytes_read, NULL);
749 if (bytes_read <= 0) {
750 gst_buffer_unmap (cache_buf, &minfo);
751 gst_buffer_unref (cache_buf);
754 gst_buffer_unmap (cache_buf, &minfo);
755 gst_buffer_resize (cache_buf, 0, bytes_read);
757 gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
760 if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
764 MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
766 cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
769 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
771 gst_adapter_unmap (enc->multipass_cache_adapter);
773 done = bytes_consumed <= 0;
774 if (bytes_consumed > 0)
775 gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
778 if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
779 || bytes_consumed < 0) {
780 GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
781 ("Failed to read multipass cache file"));
788 theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
792 GIOStatus stat = G_IO_STATUS_NORMAL;
794 gsize bytes_written = 0;
798 stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
801 if (stat == G_IO_STATUS_ERROR) {
803 GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
804 ("Failed to seek to beginning of multipass cache file: %s",
807 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
808 ("Failed to seek to beginning of multipass cache file: %s",
818 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
820 g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
821 &bytes_written, &err);
822 } while (bytes_read > 0 && bytes_written > 0 && !err);
824 if (bytes_read < 0 || err) {
825 if (bytes_read < 0) {
826 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
827 ("Failed to read multipass cache data: %d", bytes_read));
829 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
830 ("Failed to write multipass cache file: %s", err->message));
842 theora_enc_reset_ts (GstTheoraEnc * enc, GstClockTime running_time, gint pfn)
844 enc->granulepos_offset =
845 gst_util_uint64_scale (running_time, enc->fps_n, GST_SECOND * enc->fps_d);
846 enc->timestamp_offset = running_time;
847 enc->pfn_offset = pfn;
851 theora_enc_buffer_from_header_packet (GstTheoraEnc * enc, ogg_packet * packet)
856 gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (enc),
858 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
859 GST_BUFFER_OFFSET (outbuf) = 0;
860 GST_BUFFER_OFFSET_END (outbuf) = 0;
861 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
862 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
863 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
865 GST_DEBUG ("created header packet buffer, %u bytes",
866 (guint) gst_buffer_get_size (outbuf));
871 theora_enc_handle_frame (GstVideoEncoder * benc, GstVideoCodecFrame * frame)
875 GstClockTime timestamp, running_time;
877 gboolean force_keyframe;
879 enc = GST_THEORA_ENC (benc);
881 /* we keep track of two timelines.
882 * - The timestamps from the incomming buffers, which we copy to the outgoing
883 * encoded buffers as-is. We need to do this as we simply forward the
885 * - The running_time of the buffers, which we use to construct the granulepos
888 timestamp = frame->pts;
890 /* incoming buffers are clipped, so this should be positive */
892 gst_segment_to_running_time (&GST_VIDEO_ENCODER_INPUT_SEGMENT (enc),
893 GST_FORMAT_TIME, timestamp);
895 GST_OBJECT_LOCK (enc);
896 if (enc->bitrate_changed) {
897 long int bitrate = enc->video_bitrate;
899 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
901 enc->bitrate_changed = FALSE;
904 if (enc->quality_changed) {
905 long int quality = enc->video_quality;
907 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
909 enc->quality_changed = FALSE;
912 /* see if we need to schedule a keyframe */
913 force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame);
914 GST_OBJECT_UNLOCK (enc);
916 if (enc->packetno == 0) {
917 /* no packets written yet, setup headers */
920 GList *buffers = NULL;
922 GstVideoCodecState *state;
924 enc->granulepos_offset = 0;
925 enc->timestamp_offset = 0;
927 GST_DEBUG_OBJECT (enc, "output headers");
928 /* Theora streams begin with three headers; the initial header (with
929 most of the codec setup parameters) which is mandated by the Ogg
930 bitstream spec. The second header holds any comment fields. The
931 third header holds the bitstream codebook. We merely need to
932 make the headers, then pass them to libtheora one at a time;
933 libtheora handles the additional Ogg bitstream constraints */
935 /* create the remaining theora headers */
936 th_comment_clear (&enc->comment);
937 th_comment_init (&enc->comment);
940 th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
941 buf = theora_enc_buffer_from_header_packet (enc, &op);
942 buffers = g_list_prepend (buffers, buf);
945 g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
946 g_list_free (buffers);
947 goto encoder_disabled;
950 buffers = g_list_reverse (buffers);
952 /* mark buffers and put on caps */
953 caps = gst_caps_new_empty_simple ("video/x-theora");
954 caps = theora_set_header_on_caps (caps, buffers);
955 state = gst_video_encoder_set_output_state (benc, caps, enc->input_state);
957 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, state->caps);
959 gst_video_codec_state_unref (state);
961 gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc));
963 gst_video_encoder_set_headers (benc, buffers);
965 theora_enc_reset_ts (enc, running_time, frame->presentation_frame_number);
969 th_ycbcr_buffer ycbcr;
970 gint res, keyframe_interval;
971 GstVideoFrame vframe;
973 if (force_keyframe) {
974 /* if we want a keyframe, temporarily reset the max keyframe interval
975 * to 1, which will cause libtheora to emit one. There is no API to
976 * request a keyframe at the moment. */
977 keyframe_interval = 1;
978 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
979 &keyframe_interval, sizeof (keyframe_interval));
982 if (enc->multipass_cache_fd
983 && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
984 if (!theora_enc_read_multipass_cache (enc)) {
985 ret = GST_FLOW_ERROR;
986 goto multipass_read_failed;
990 gst_video_frame_map (&vframe, &enc->input_state->info, frame->input_buffer,
992 theora_enc_init_buffer (ycbcr, &vframe);
994 res = th_encode_ycbcr_in (enc->encoder, ycbcr);
995 gst_video_frame_unmap (&vframe);
997 /* none of the failure cases can happen here */
1000 if (enc->multipass_cache_fd
1001 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
1002 if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
1003 ret = GST_FLOW_ERROR;
1004 goto multipass_write_failed;
1009 while (th_encode_packetout (enc->encoder, 0, &op)) {
1010 /* Reset the max keyframe interval to its original state, and reset
1011 * the flag so we don't create more keyframes if we loop */
1012 if (force_keyframe) {
1014 enc->keyframe_auto ? enc->keyframe_force : enc->keyframe_freq;
1015 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
1016 &keyframe_interval, sizeof (keyframe_interval));
1017 force_keyframe = FALSE;
1020 ret = theora_push_packet (enc, &op);
1021 if (ret != GST_FLOW_OK)
1027 gst_video_codec_frame_unref (frame);
1031 multipass_read_failed:
1033 gst_video_codec_frame_unref (frame);
1036 multipass_write_failed:
1038 gst_video_codec_frame_unref (frame);
1043 gst_video_codec_frame_unref (frame);
1044 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1045 ("libtheora has been compiled with the encoder disabled"));
1046 return GST_FLOW_ERROR;
1051 theora_enc_finish (GstVideoEncoder * benc)
1056 enc = GST_THEORA_ENC (benc);
1058 if (enc->initialised) {
1059 /* push last packet with eos flag, should not be called */
1060 while (th_encode_packetout (enc->encoder, 1, &op)) {
1061 theora_push_packet (enc, &op);
1064 if (enc->initialised && enc->multipass_cache_fd
1065 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
1066 theora_enc_write_multipass_cache (enc, TRUE, TRUE);
1068 theora_enc_clear_multipass_cache (enc);
1074 theora_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
1076 gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
1078 return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
1083 theora_enc_set_property (GObject * object, guint prop_id,
1084 const GValue * value, GParamSpec * pspec)
1086 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1090 GST_OBJECT_LOCK (enc);
1091 enc->video_bitrate = g_value_get_int (value) * 1000;
1092 enc->video_quality = 0;
1093 enc->bitrate_changed = TRUE;
1094 GST_OBJECT_UNLOCK (enc);
1097 GST_OBJECT_LOCK (enc);
1098 if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_quality == 0) {
1099 GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
1102 enc->video_quality = g_value_get_int (value);
1103 enc->video_bitrate = 0;
1104 enc->quality_changed = TRUE;
1106 GST_OBJECT_UNLOCK (enc);
1108 case PROP_KEYFRAME_AUTO:
1109 enc->keyframe_auto = g_value_get_boolean (value);
1111 case PROP_KEYFRAME_FREQ:
1112 enc->keyframe_freq = g_value_get_int (value);
1114 case PROP_KEYFRAME_FREQ_FORCE:
1115 enc->keyframe_force = g_value_get_int (value);
1117 case PROP_SPEEDLEVEL:
1118 enc->speed_level = g_value_get_int (value);
1120 case PROP_VP3_COMPATIBLE:
1121 enc->vp3_compatible = g_value_get_boolean (value);
1123 case PROP_DROP_FRAMES:
1124 enc->drop_frames = g_value_get_boolean (value);
1126 case PROP_CAP_OVERFLOW:
1127 enc->cap_overflow = g_value_get_boolean (value);
1129 case PROP_CAP_UNDERFLOW:
1130 enc->cap_underflow = g_value_get_boolean (value);
1132 case PROP_RATE_BUFFER:
1133 enc->rate_buffer = g_value_get_int (value);
1135 case PROP_MULTIPASS_CACHE_FILE:
1136 enc->multipass_cache_file = g_value_dup_string (value);
1138 case PROP_MULTIPASS_MODE:
1139 enc->multipass_mode = g_value_get_enum (value);
1142 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1148 theora_enc_get_property (GObject * object, guint prop_id,
1149 GValue * value, GParamSpec * pspec)
1151 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1155 GST_OBJECT_LOCK (enc);
1156 g_value_set_int (value, enc->video_bitrate / 1000);
1157 GST_OBJECT_UNLOCK (enc);
1160 GST_OBJECT_LOCK (enc);
1161 g_value_set_int (value, enc->video_quality);
1162 GST_OBJECT_UNLOCK (enc);
1164 case PROP_KEYFRAME_AUTO:
1165 g_value_set_boolean (value, enc->keyframe_auto);
1167 case PROP_KEYFRAME_FREQ:
1168 g_value_set_int (value, enc->keyframe_freq);
1170 case PROP_KEYFRAME_FREQ_FORCE:
1171 g_value_set_int (value, enc->keyframe_force);
1173 case PROP_SPEEDLEVEL:
1174 g_value_set_int (value, enc->speed_level);
1176 case PROP_VP3_COMPATIBLE:
1177 g_value_set_boolean (value, enc->vp3_compatible);
1179 case PROP_DROP_FRAMES:
1180 g_value_set_boolean (value, enc->drop_frames);
1182 case PROP_CAP_OVERFLOW:
1183 g_value_set_boolean (value, enc->cap_overflow);
1185 case PROP_CAP_UNDERFLOW:
1186 g_value_set_boolean (value, enc->cap_underflow);
1188 case PROP_RATE_BUFFER:
1189 g_value_set_int (value, enc->rate_buffer);
1191 case PROP_MULTIPASS_CACHE_FILE:
1192 g_value_set_string (value, enc->multipass_cache_file);
1194 case PROP_MULTIPASS_MODE:
1195 g_value_set_enum (value, enc->multipass_mode);
1198 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);