static GstFlowReturn gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf) { GstBaseVideoEncoder *base_video_encoder; GstBaseVideoEncoderClass *klass; GstVideoFrame *frame; if (!gst_pad_is_negotiated (pad)) { return GST_FLOW_NOT_NEGOTIATED; } base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); klass = GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder); if (base_video_encoder->a.at_eos) { return GST_FLOW_UNEXPECTED; } if (base_video_encoder->sink_clipping) { gint64 start = GST_BUFFER_TIMESTAMP (buf); gint64 stop = start + GST_BUFFER_DURATION (buf); gint64 clip_start; gint64 clip_stop; if (!gst_segment_clip (&GST_BASE_VIDEO_CODEC (base_video_encoder)->segment, GST_FORMAT_TIME, start, stop, &clip_start, &clip_stop)) { GST_DEBUG ("clipping to segment dropped frame"); goto done; } } frame = gst_base_video_codec_new_frame (GST_BASE_VIDEO_CODEC (base_video_encoder)); frame->sink_buffer = buf; frame->presentation_timestamp = GST_BUFFER_TIMESTAMP (buf); frame->presentation_duration = GST_BUFFER_DURATION (buf); frame->presentation_frame_number = base_video_encoder->presentation_frame_number; base_video_encoder->presentation_frame_number++; GST_BASE_VIDEO_CODEC (base_video_encoder)->frames = g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame); klass->handle_frame (base_video_encoder, frame); done: g_object_unref (base_video_encoder); return GST_FLOW_OK; }
static GstFlowReturn gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf) { GstBaseVideoEncoder *base_video_encoder; GstBaseVideoEncoderClass *klass; GstVideoFrame *frame; GstFlowReturn ret = GST_FLOW_OK; base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); klass = GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder); g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR); GST_BASE_VIDEO_CODEC_STREAM_LOCK (base_video_encoder); if (!GST_PAD_CAPS (pad)) { ret = GST_FLOW_NOT_NEGOTIATED; goto done; } GST_LOG_OBJECT (base_video_encoder, "received buffer of size %d with ts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); if (base_video_encoder->a.at_eos) { ret = GST_FLOW_UNEXPECTED; goto done; } if (base_video_encoder->sink_clipping) { gint64 start = GST_BUFFER_TIMESTAMP (buf); gint64 stop = start + GST_BUFFER_DURATION (buf); gint64 clip_start; gint64 clip_stop; if (!gst_segment_clip (&GST_BASE_VIDEO_CODEC (base_video_encoder)->segment, GST_FORMAT_TIME, start, stop, &clip_start, &clip_stop)) { GST_DEBUG_OBJECT (base_video_encoder, "clipping to segment dropped frame"); goto done; } } if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { GST_LOG_OBJECT (base_video_encoder, "marked discont"); GST_BASE_VIDEO_CODEC (base_video_encoder)->discont = TRUE; } frame = gst_base_video_codec_new_frame (GST_BASE_VIDEO_CODEC (base_video_encoder)); frame->events = base_video_encoder->current_frame_events; base_video_encoder->current_frame_events = NULL; frame->sink_buffer = buf; frame->presentation_timestamp = GST_BUFFER_TIMESTAMP (buf); frame->presentation_duration = GST_BUFFER_DURATION (buf); frame->presentation_frame_number = base_video_encoder->presentation_frame_number; base_video_encoder->presentation_frame_number++; frame->force_keyframe = base_video_encoder->force_keyframe; base_video_encoder->force_keyframe = FALSE; GST_BASE_VIDEO_CODEC (base_video_encoder)->frames = g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame); /* new data, more finish needed */ base_video_encoder->drained = FALSE; GST_LOG_OBJECT (base_video_encoder, "passing frame pfn %d to subclass", frame->presentation_frame_number); ret = klass->handle_frame (base_video_encoder, frame); done: GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (base_video_encoder); g_object_unref (base_video_encoder); return ret; }