2 * Copyright (C) 2006 David Schleef <ds@schleef.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
25 #include <gst/video/video.h>
28 #define SCHRO_ENABLE_UNSTABLE_API
30 #include <schroedinger/schro.h>
31 #include <schroedinger/schrobitstream.h>
32 #include <schroedinger/schrovirtframe.h>
34 #include "gstbasevideoencoder.h"
35 #include "gstschroutils.h"
37 GST_DEBUG_CATEGORY_EXTERN (schro_debug
);
38 #define GST_CAT_DEFAULT schro_debug
40 #define GST_TYPE_SCHRO_ENC \
41 (gst_schro_enc_get_type())
42 #define GST_SCHRO_ENC(obj) \
43 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SCHRO_ENC,GstSchroEnc))
44 #define GST_SCHRO_ENC_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SCHRO_ENC,GstSchroEncClass))
46 #define GST_IS_SCHRO_ENC(obj) \
47 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SCHRO_ENC))
48 #define GST_IS_SCHRO_ENC_CLASS(obj) \
49 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHRO_ENC))
51 typedef struct _GstSchroEnc GstSchroEnc
;
52 typedef struct _GstSchroEncClass GstSchroEncClass
;
55 GST_SCHRO_ENC_OUTPUT_OGG
,
56 GST_SCHRO_ENC_OUTPUT_QUICKTIME
,
57 GST_SCHRO_ENC_OUTPUT_AVI
,
58 GST_SCHRO_ENC_OUTPUT_MPEG_TS
59 } GstSchroEncOutputType
;
63 GstBaseVideoEncoder base_encoder
;
68 /* video properties */
69 GstSchroEncOutputType output_format
;
72 SchroEncoder
*encoder
;
73 SchroVideoFormat
*video_format
;
74 GstVideoFrame
*eos_frame
;
75 GstBuffer
*seq_header_buffer
;
77 guint64 last_granulepos
;
80 struct _GstSchroEncClass
82 GstBaseVideoEncoderClass parent_class
;
97 static void gst_schro_enc_set_property (GObject
* object
, guint prop_id
,
98 const GValue
* value
, GParamSpec
* pspec
);
99 static void gst_schro_enc_get_property (GObject
* object
, guint prop_id
,
100 GValue
* value
, GParamSpec
* pspec
);
102 static GstFlowReturn
gst_schro_enc_process (GstSchroEnc
*schro_enc
);
104 static gboolean
gst_schro_enc_set_format (GstBaseVideoEncoder
*base_video_encoder
,
105 GstVideoState
*state
);
106 static gboolean
gst_schro_enc_start (GstBaseVideoEncoder
*base_video_encoder
);
107 static gboolean
gst_schro_enc_stop (GstBaseVideoEncoder
*base_video_encoder
);
108 static gboolean
gst_schro_enc_finish (GstBaseVideoEncoder
*base_video_encoder
,
109 GstVideoFrame
*frame
);
110 static gboolean
gst_schro_enc_handle_frame (GstBaseVideoEncoder
*base_video_encoder
,
111 GstVideoFrame
*frame
);
112 static GstFlowReturn
gst_schro_enc_shape_output (GstBaseVideoEncoder
*base_video_encoder
,
113 GstVideoFrame
*frame
);
114 static GstCaps
* gst_schro_enc_get_caps (GstBaseVideoEncoder
*base_video_encoder
);
116 static GstStaticPadTemplate gst_schro_enc_sink_template
=
117 GST_STATIC_PAD_TEMPLATE ("sink",
121 GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }") ";"
125 static GstStaticPadTemplate gst_schro_enc_src_template
=
126 GST_STATIC_PAD_TEMPLATE ("src",
129 GST_STATIC_CAPS ("video/x-dirac;video/x-qt-part")
132 GST_BOILERPLATE (GstSchroEnc
, gst_schro_enc
, GstBaseVideoEncoder
,
133 GST_TYPE_BASE_VIDEO_ENCODER
);
136 gst_schro_enc_base_init (gpointer g_class
)
138 static GstElementDetails schro_enc_details
=
139 GST_ELEMENT_DETAILS ("Dirac Encoder",
140 "Codec/Encoder/Video",
141 "Encode raw video into Dirac stream",
142 "David Schleef <ds@schleef.org>");
143 GstElementClass
*element_class
= GST_ELEMENT_CLASS (g_class
);
145 gst_element_class_add_pad_template (element_class
,
146 gst_static_pad_template_get (&gst_schro_enc_src_template
));
147 gst_element_class_add_pad_template (element_class
,
148 gst_static_pad_template_get (&gst_schro_enc_sink_template
));
150 gst_element_class_set_details (element_class
, &schro_enc_details
);
154 gst_schro_enc_class_init (GstSchroEncClass
* klass
)
156 GObjectClass
*gobject_class
;
157 GstElementClass
*gstelement_class
;
158 GstBaseVideoEncoderClass
*basevideocoder_class
;
161 gobject_class
= G_OBJECT_CLASS (klass
);
162 gstelement_class
= GST_ELEMENT_CLASS (klass
);
163 basevideocoder_class
= GST_BASE_VIDEO_ENCODER_CLASS (klass
);
165 gobject_class
->set_property
= gst_schro_enc_set_property
;
166 gobject_class
->get_property
= gst_schro_enc_get_property
;
168 for(i
=0;i
<schro_encoder_get_n_settings();i
++){
169 const SchroEncoderSetting
*setting
;
171 setting
= schro_encoder_get_setting_info (i
);
173 switch (setting
->type
) {
174 case SCHRO_ENCODER_SETTING_TYPE_BOOLEAN
:
175 g_object_class_install_property (gobject_class
, i
+ 1,
176 g_param_spec_boolean (setting
->name
, setting
->name
, setting
->name
,
177 setting
->default_value
, G_PARAM_READWRITE
));
179 case SCHRO_ENCODER_SETTING_TYPE_INT
:
180 g_object_class_install_property (gobject_class
, i
+ 1,
181 g_param_spec_int (setting
->name
, setting
->name
, setting
->name
,
182 setting
->min
, setting
->max
, setting
->default_value
,
185 case SCHRO_ENCODER_SETTING_TYPE_ENUM
:
186 g_object_class_install_property (gobject_class
, i
+ 1,
187 g_param_spec_int (setting
->name
, setting
->name
, setting
->name
,
188 setting
->min
, setting
->max
, setting
->default_value
,
191 case SCHRO_ENCODER_SETTING_TYPE_DOUBLE
:
192 g_object_class_install_property (gobject_class
, i
+ 1,
193 g_param_spec_double (setting
->name
, setting
->name
, setting
->name
,
194 setting
->min
, setting
->max
, setting
->default_value
,
202 basevideocoder_class
->set_format
= GST_DEBUG_FUNCPTR(gst_schro_enc_set_format
);
203 basevideocoder_class
->start
= GST_DEBUG_FUNCPTR(gst_schro_enc_start
);
204 basevideocoder_class
->stop
= GST_DEBUG_FUNCPTR(gst_schro_enc_stop
);
205 basevideocoder_class
->finish
= GST_DEBUG_FUNCPTR(gst_schro_enc_finish
);
206 basevideocoder_class
->handle_frame
= GST_DEBUG_FUNCPTR(gst_schro_enc_handle_frame
);
207 basevideocoder_class
->shape_output
= GST_DEBUG_FUNCPTR(gst_schro_enc_shape_output
);
208 basevideocoder_class
->get_caps
= GST_DEBUG_FUNCPTR(gst_schro_enc_get_caps
);
212 gst_schro_enc_init (GstSchroEnc
*schro_enc
, GstSchroEncClass
*klass
)
214 GST_DEBUG ("gst_schro_enc_init");
216 /* Normally, we'd create the encoder in ->start(), but we use the
217 * encoder to store object properties. So it needs to be created
219 schro_enc
->encoder
= schro_encoder_new ();
220 schro_encoder_set_packet_assembly (schro_enc
->encoder
, TRUE
);
221 schro_enc
->video_format
=
222 schro_encoder_get_video_format (schro_enc
->encoder
);
228 gst_schro_enc_set_format (GstBaseVideoEncoder
*base_video_encoder
,
229 GstVideoState
*state
)
231 GstSchroEnc
*schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
233 schro_video_format_set_std_video_format (schro_enc
->video_format
,
234 SCHRO_VIDEO_FORMAT_CUSTOM
);
236 switch (state
->format
) {
237 case GST_VIDEO_FORMAT_I420
:
238 case GST_VIDEO_FORMAT_YV12
:
239 schro_enc
->video_format
->chroma_format
= SCHRO_CHROMA_420
;
241 case GST_VIDEO_FORMAT_YUY2
:
242 case GST_VIDEO_FORMAT_UYVY
:
243 schro_enc
->video_format
->chroma_format
= SCHRO_CHROMA_422
;
245 case GST_VIDEO_FORMAT_AYUV
:
246 schro_enc
->video_format
->chroma_format
= SCHRO_CHROMA_444
;
248 case GST_VIDEO_FORMAT_ARGB
:
249 schro_enc
->video_format
->chroma_format
= SCHRO_CHROMA_420
;
252 g_assert_not_reached();
255 schro_enc
->video_format
->frame_rate_numerator
= state
->fps_n
;
256 schro_enc
->video_format
->frame_rate_denominator
= state
->fps_d
;
258 schro_enc
->video_format
->width
= state
->width
;
259 schro_enc
->video_format
->height
= state
->height
;
260 schro_enc
->video_format
->clean_width
= state
->clean_width
;
261 schro_enc
->video_format
->clean_height
= state
->clean_height
;
262 schro_enc
->video_format
->left_offset
= state
->clean_offset_left
;
263 schro_enc
->video_format
->top_offset
= state
->clean_offset_top
;
265 schro_enc
->video_format
->aspect_ratio_numerator
= state
->par_n
;
266 schro_enc
->video_format
->aspect_ratio_denominator
= state
->par_d
;
268 schro_video_format_set_std_signal_range (schro_enc
->video_format
,
269 SCHRO_SIGNAL_RANGE_8BIT_VIDEO
);
270 schro_video_format_set_std_colour_spec (schro_enc
->video_format
,
271 SCHRO_COLOUR_SPEC_HDTV
);
273 schro_encoder_set_video_format (schro_enc
->encoder
, schro_enc
->video_format
);
274 schro_encoder_start (schro_enc
->encoder
);
276 schro_enc
->seq_header_buffer
= gst_schro_wrap_schro_buffer (
277 schro_encoder_encode_sequence_header (schro_enc
->encoder
));
283 gst_schro_enc_set_property (GObject
* object
, guint prop_id
,
284 const GValue
* value
, GParamSpec
* pspec
)
288 g_return_if_fail (GST_IS_SCHRO_ENC (object
));
289 src
= GST_SCHRO_ENC (object
);
291 GST_DEBUG ("gst_schro_enc_set_property");
294 const SchroEncoderSetting
*setting
;
295 setting
= schro_encoder_get_setting_info (prop_id
- 1);
296 switch(G_VALUE_TYPE(value
)) {
298 schro_encoder_setting_set_double (src
->encoder
, setting
->name
,
299 g_value_get_double(value
));
302 schro_encoder_setting_set_double (src
->encoder
, setting
->name
,
303 g_value_get_int(value
));
306 schro_encoder_setting_set_double (src
->encoder
, setting
->name
,
307 g_value_get_boolean(value
));
314 gst_schro_enc_get_property (GObject
* object
, guint prop_id
, GValue
* value
,
319 g_return_if_fail (GST_IS_SCHRO_ENC (object
));
320 src
= GST_SCHRO_ENC (object
);
323 const SchroEncoderSetting
*setting
;
324 setting
= schro_encoder_get_setting_info (prop_id
- 1);
325 switch(G_VALUE_TYPE(value
)) {
327 g_value_set_double (value
,
328 schro_encoder_setting_get_double (src
->encoder
, setting
->name
));
331 g_value_set_int (value
,
332 schro_encoder_setting_get_double (src
->encoder
, setting
->name
));
335 g_value_set_boolean (value
,
336 schro_encoder_setting_get_double (src
->encoder
, setting
->name
));
343 * start is called once the input format is known. This function
344 * must decide on an output format and negotiate it.
347 gst_schro_enc_start (GstBaseVideoEncoder
*base_video_encoder
)
349 GstSchroEnc
*schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
351 GstStructure
*structure
;
353 GST_DEBUG("set_output_caps");
354 caps
= gst_pad_get_allowed_caps (base_video_encoder
->srcpad
);
356 if (gst_caps_is_empty (caps
)) {
357 gst_caps_unref (caps
);
361 structure
= gst_caps_get_structure (caps
, 0);
363 if (gst_structure_has_name (structure
, "video/x-dirac")) {
364 schro_enc
->output_format
= GST_SCHRO_ENC_OUTPUT_OGG
;
365 } else if (gst_structure_has_name (structure
, "video/x-qt-part")) {
366 schro_enc
->output_format
= GST_SCHRO_ENC_OUTPUT_QUICKTIME
;
367 } else if (gst_structure_has_name (structure
, "video/x-avi-part")) {
368 schro_enc
->output_format
= GST_SCHRO_ENC_OUTPUT_AVI
;
373 gst_caps_unref (caps
);
378 gst_schro_enc_stop (GstBaseVideoEncoder
*base_video_encoder
)
380 GstSchroEnc
*schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
382 if (schro_enc
->encoder
) {
383 schro_encoder_free (schro_enc
->encoder
);
384 schro_enc
->encoder
= NULL
;
391 gst_schro_enc_finish (GstBaseVideoEncoder
*base_video_encoder
,
392 GstVideoFrame
*frame
)
394 GstSchroEnc
*schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
398 schro_enc
->eos_frame
= frame
;
400 schro_encoder_end_of_stream (schro_enc
->encoder
);
401 gst_schro_enc_process (schro_enc
);
407 gst_schro_enc_handle_frame (GstBaseVideoEncoder
*base_video_encoder
,
408 GstVideoFrame
*frame
)
410 GstSchroEnc
*schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
411 SchroFrame
*schro_frame
;
413 const GstVideoState
*state
;
415 state
= gst_base_video_encoder_get_state (base_video_encoder
);
417 schro_frame
= gst_schro_buffer_wrap (frame
->sink_buffer
,
418 state
->format
, state
->width
, state
->height
);
420 GST_DEBUG ("pushing frame %p", frame
);
421 schro_encoder_push_frame_full (schro_enc
->encoder
, schro_frame
, frame
);
423 ret
= gst_schro_enc_process (schro_enc
);
430 gst_caps_add_streamheader (GstCaps
*caps
, GList
*list
)
432 GValue array
= { 0 };
433 GValue value
= { 0 };
437 g_value_init (&array
, GST_TYPE_ARRAY
);
439 for(g
=g_list_first (list
); g
; g
= g_list_next (list
)) {
440 g_value_init (&value
, GST_TYPE_BUFFER
);
441 buf
= gst_buffer_copy (GST_BUFFER(g
->data
));
442 gst_value_set_buffer (&value
, buf
);
443 gst_buffer_unref (buf
);
444 gst_value_array_append_value (&array
, &value
);
445 g_value_unset (&value
);
447 gst_structure_set_value (gst_caps_get_structure(caps
,0),
448 "streamheader", &array
);
449 g_value_unset (&array
);
454 gst_schro_enc_get_caps (GstBaseVideoEncoder
*base_video_encoder
)
457 const GstVideoState
*state
;
458 GstSchroEnc
*schro_enc
;
460 schro_enc
= GST_SCHRO_ENC(base_video_encoder
);
462 state
= gst_base_video_encoder_get_state (base_video_encoder
);
464 if (schro_enc
->output_format
== GST_SCHRO_ENC_OUTPUT_OGG
) {
465 caps
= gst_caps_new_simple ("video/x-dirac",
466 "width", G_TYPE_INT
, state
->width
,
467 "height", G_TYPE_INT
, state
->height
,
468 "framerate", GST_TYPE_FRACTION
, state
->fps_n
,
470 "pixel-aspect-ratio", GST_TYPE_FRACTION
, state
->par_n
,
474 GST_BUFFER_FLAG_SET (schro_enc
->seq_header_buffer
, GST_BUFFER_FLAG_IN_CAPS
);
477 GValue array
= { 0 };
478 GValue value
= { 0 };
482 g_value_init (&array
, GST_TYPE_ARRAY
);
483 g_value_init (&value
, GST_TYPE_BUFFER
);
484 size
= GST_BUFFER_SIZE(schro_enc
->seq_header_buffer
);
485 buf
= gst_buffer_new_and_alloc (size
+ SCHRO_PARSE_HEADER_SIZE
);
486 memcpy (GST_BUFFER_DATA(buf
),
487 GST_BUFFER_DATA(schro_enc
->seq_header_buffer
), size
);
488 GST_WRITE_UINT32_BE (GST_BUFFER_DATA(buf
) + size
+ 0, 0x42424344);
489 GST_WRITE_UINT8 (GST_BUFFER_DATA(buf
) + size
+ 4, SCHRO_PARSE_CODE_END_OF_SEQUENCE
);
490 GST_WRITE_UINT32_BE (GST_BUFFER_DATA(buf
) + size
+ 5, 0);
491 GST_WRITE_UINT32_BE (GST_BUFFER_DATA(buf
) + size
+ 9, size
);
492 gst_value_set_buffer (&value
, buf
);
493 gst_buffer_unref (buf
);
494 gst_value_array_append_value (&array
, &value
);
495 gst_structure_set_value (gst_caps_get_structure(caps
,0),
496 "streamheader", &array
);
497 g_value_unset (&value
);
498 g_value_unset (&array
);
500 } else if (schro_enc
->output_format
== GST_SCHRO_ENC_OUTPUT_QUICKTIME
) {
501 caps
= gst_caps_new_simple ("video/x-qt-part",
502 "format", GST_TYPE_FOURCC
, GST_MAKE_FOURCC('d','r','a','c'),
503 "width", G_TYPE_INT
, state
->width
,
504 "height", G_TYPE_INT
, state
->height
,
505 "framerate", GST_TYPE_FRACTION
, state
->fps_n
,
507 "pixel-aspect-ratio", GST_TYPE_FRACTION
, state
->par_n
,
509 } else if (schro_enc
->output_format
== GST_SCHRO_ENC_OUTPUT_AVI
) {
510 caps
= gst_caps_new_simple ("video/x-avi-part",
511 "format", GST_TYPE_FOURCC
, GST_MAKE_FOURCC('d','r','a','c'),
512 "width", G_TYPE_INT
, state
->width
,
513 "height", G_TYPE_INT
, state
->height
,
514 "framerate", GST_TYPE_FRACTION
, state
->fps_n
,
516 "pixel-aspect-ratio", GST_TYPE_FRACTION
, state
->par_n
,
518 } else if (schro_enc
->output_format
== GST_SCHRO_ENC_OUTPUT_MPEG_TS
) {
519 caps
= gst_caps_new_simple ("video/x-mpegts-part",
520 "format", GST_TYPE_FOURCC
, GST_MAKE_FOURCC('d','r','a','c'),
521 "width", G_TYPE_INT
, state
->width
,
522 "height", G_TYPE_INT
, state
->height
,
523 "framerate", GST_TYPE_FRACTION
, state
->fps_n
,
525 "pixel-aspect-ratio", GST_TYPE_FRACTION
, state
->par_n
,
528 g_assert_not_reached ();
538 gst_schro_enc_shape_output_ogg (GstBaseVideoEncoder
*base_video_encoder
,
539 GstVideoFrame
*frame
)
541 GstSchroEnc
*schro_enc
;
547 guint64 granulepos_hi
;
548 guint64 granulepos_low
;
549 GstBuffer
*buf
= frame
->src_buffer
;
551 schro_enc
= GST_SCHRO_ENC (base_video_encoder
);
553 dpn
= frame
->decode_frame_number
;
555 pt
= frame
->presentation_frame_number
* 2;
556 dt
= frame
->decode_frame_number
* 2;
558 dist
= frame
->distance_from_sync
;
560 GST_DEBUG("sys %d dpn %d pt %d dt %d delay %d dist %d",
561 (int)frame
->system_frame_number
,
562 (int)frame
->decode_frame_number
,
563 pt
, dt
, delay
, dist
);
565 granulepos_hi
= (((uint64_t)pt
- delay
)<<9) | ((dist
>>8));
566 granulepos_low
= (delay
<< 9) | (dist
& 0xff);
567 GST_DEBUG("granulepos %lld:%lld", granulepos_hi
, granulepos_low
);
570 GST_BUFFER_OFFSET_END (buf
) = schro_enc
->last_granulepos
;
572 schro_enc
->last_granulepos
= (granulepos_hi
<< 22) | (granulepos_low
);
573 GST_BUFFER_OFFSET_END (buf
) = schro_enc
->last_granulepos
;
576 gst_buffer_set_caps (buf
, base_video_encoder
->caps
);
578 return gst_pad_push (base_video_encoder
->srcpad
, buf
);
582 gst_schro_enc_shape_output_quicktime (GstBaseVideoEncoder
*base_video_encoder
,
583 GstVideoFrame
*frame
)
585 GstBuffer
*buf
= frame
->src_buffer
;
586 const GstVideoState
*state
;
588 state
= gst_base_video_encoder_get_state (base_video_encoder
);
590 GST_BUFFER_TIMESTAMP (buf
) = gst_video_state_get_timestamp (state
,
591 frame
->presentation_frame_number
);
592 GST_BUFFER_DURATION (buf
) = gst_video_state_get_timestamp (state
,
593 frame
->presentation_frame_number
+ 1) - GST_BUFFER_TIMESTAMP (buf
);
594 GST_BUFFER_OFFSET_END (buf
) = gst_video_state_get_timestamp (state
,
595 frame
->decode_frame_number
);
596 GST_BUFFER_OFFSET (buf
) = GST_CLOCK_TIME_NONE
;
598 if (frame
->is_sync_point
&&
599 frame
->presentation_frame_number
== frame
->system_frame_number
) {
600 GST_BUFFER_FLAG_UNSET (buf
, GST_BUFFER_FLAG_DELTA_UNIT
);
601 GST_ERROR("sync point");
603 GST_BUFFER_FLAG_SET (buf
, GST_BUFFER_FLAG_DELTA_UNIT
);
606 gst_buffer_set_caps (buf
, base_video_encoder
->caps
);
608 return gst_pad_push (base_video_encoder
->srcpad
, buf
);
612 gst_schro_enc_shape_output (GstBaseVideoEncoder
*base_video_encoder
,
613 GstVideoFrame
*frame
)
615 GstSchroEnc
*schro_enc
;
617 schro_enc
= GST_SCHRO_ENC (base_video_encoder
);
619 switch (schro_enc
->output_format
) {
620 case GST_SCHRO_ENC_OUTPUT_OGG
:
621 return gst_schro_enc_shape_output_ogg (base_video_encoder
, frame
);
623 case GST_SCHRO_ENC_OUTPUT_QUICKTIME
:
624 return gst_schro_enc_shape_output_quicktime (base_video_encoder
, frame
);
627 g_assert_not_reached ();
631 return GST_FLOW_ERROR
;
635 gst_schro_enc_process (GstSchroEnc
*schro_enc
)
637 SchroBuffer
*encoded_buffer
;
638 GstVideoFrame
*frame
;
640 int presentation_frame
;
642 GstBaseVideoEncoder
*base_video_encoder
= GST_BASE_VIDEO_ENCODER(schro_enc
);
644 GST_DEBUG("process");
647 switch (schro_encoder_wait (schro_enc
->encoder
)) {
648 case SCHRO_STATE_NEED_FRAME
:
650 case SCHRO_STATE_END_OF_STREAM
:
653 case SCHRO_STATE_HAVE_BUFFER
:
655 encoded_buffer
= schro_encoder_pull_full (schro_enc
->encoder
,
656 &presentation_frame
, &voidptr
);
658 if (encoded_buffer
== NULL
) {
659 GST_DEBUG("encoder_pull returned NULL");
660 /* FIXME This shouldn't happen */
661 return GST_FLOW_ERROR
;
664 if (voidptr
== NULL
) {
665 GST_DEBUG("got eos");
666 frame
= schro_enc
->eos_frame
;
669 if (SCHRO_PARSE_CODE_IS_SEQ_HEADER (encoded_buffer
->data
[4])) {
670 frame
->is_sync_point
= TRUE
;
673 frame
->src_buffer
= gst_schro_wrap_schro_buffer (encoded_buffer
);
675 ret
= gst_base_video_encoder_finish_frame (base_video_encoder
, frame
);
677 if (ret
!= GST_FLOW_OK
) {
678 GST_DEBUG("pad_push returned %d", ret
);
682 case SCHRO_STATE_AGAIN
: