mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
mpeg2enc: finalize GstVideoEncoder port
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1491>
This commit is contained in:
parent
c9d10e2277
commit
2dfceac9fc
4 changed files with 52 additions and 50 deletions
|
@ -104,6 +104,8 @@ static void gst_mpeg2enc_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
static void gst_mpeg2enc_set_property (GObject * object,
|
static void gst_mpeg2enc_set_property (GObject * object,
|
||||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
|
static gboolean gst_mpeg2enc_src_activate_mode (GstPad * pad, GstObject * parent,
|
||||||
|
GstPadMode mode, gboolean active);
|
||||||
|
|
||||||
#define gst_mpeg2enc_parent_class parent_class
|
#define gst_mpeg2enc_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstMpeg2enc, gst_mpeg2enc, GST_TYPE_VIDEO_ENCODER,
|
G_DEFINE_TYPE_WITH_CODE (GstMpeg2enc, gst_mpeg2enc, GST_TYPE_VIDEO_ENCODER,
|
||||||
|
@ -177,9 +179,38 @@ gst_mpeg2enc_init (GstMpeg2enc * enc)
|
||||||
enc->frames = g_queue_new ();
|
enc->frames = g_queue_new ();
|
||||||
enc->started = FALSE;
|
enc->started = FALSE;
|
||||||
|
|
||||||
|
gst_pad_set_activatemode_function (GST_VIDEO_ENCODER_SRC_PAD (enc),
|
||||||
|
GST_DEBUG_FUNCPTR (gst_mpeg2enc_src_activate_mode));
|
||||||
|
|
||||||
gst_mpeg2enc_reset (enc);
|
gst_mpeg2enc_reset (enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_mpeg2enc_src_activate_mode (GstPad * pad, GstObject * parent,
|
||||||
|
GstPadMode mode, gboolean active)
|
||||||
|
{
|
||||||
|
gboolean result = TRUE;
|
||||||
|
GstMpeg2enc *enc;
|
||||||
|
|
||||||
|
enc = GST_MPEG2ENC (parent);
|
||||||
|
|
||||||
|
if (mode != GST_PAD_MODE_PUSH)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
/* setcaps will start task once encoder is setup */
|
||||||
|
} else {
|
||||||
|
/* can only end the encoding loop by forcing eos */
|
||||||
|
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
||||||
|
enc->eos = TRUE;
|
||||||
|
enc->srcresult = GST_FLOW_FLUSHING;
|
||||||
|
GST_MPEG2ENC_SIGNAL (enc);
|
||||||
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mpeg2enc_reset (GstMpeg2enc * enc)
|
gst_mpeg2enc_reset (GstMpeg2enc * enc)
|
||||||
{
|
{
|
||||||
|
@ -189,8 +220,7 @@ gst_mpeg2enc_reset (GstMpeg2enc * enc)
|
||||||
enc->srcresult = GST_FLOW_OK;
|
enc->srcresult = GST_FLOW_OK;
|
||||||
|
|
||||||
/* in case of error'ed ending */
|
/* in case of error'ed ending */
|
||||||
while ((frame = (GstVideoCodecFrame *) g_queue_pop_head (enc->frames)))
|
while ((frame = (GstVideoCodecFrame *) g_queue_pop_head (enc->frames)));
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
|
|
||||||
if (enc->encoder) {
|
if (enc->encoder) {
|
||||||
delete enc->encoder;
|
delete enc->encoder;
|
||||||
|
@ -307,8 +337,8 @@ gst_mpeg2enc_set_format (GstVideoEncoder * video_encoder, GstVideoCodecState * s
|
||||||
enc->input_state = gst_video_codec_state_ref (state);
|
enc->input_state = gst_video_codec_state_ref (state);
|
||||||
|
|
||||||
/* does not go well to restart stream mid-way */
|
/* does not go well to restart stream mid-way */
|
||||||
//if (enc->srcresult != GST_FLOW_CUSTOM_SUCCESS)
|
if (enc->encoder != NULL)
|
||||||
// goto refuse_renegotiation;
|
goto refuse_renegotiation;
|
||||||
|
|
||||||
|
|
||||||
/* since mpeg encoder does not really check, let's check caps */
|
/* since mpeg encoder does not really check, let's check caps */
|
||||||
|
@ -319,7 +349,6 @@ gst_mpeg2enc_set_format (GstVideoEncoder * video_encoder, GstVideoCodecState * s
|
||||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||||
"mpegversion", G_TYPE_INT, (enc->options->mpeg == 1)?1:2, NULL);
|
"mpegversion", G_TYPE_INT, (enc->options->mpeg == 1)?1:2, NULL);
|
||||||
|
|
||||||
|
|
||||||
output_state =
|
output_state =
|
||||||
gst_video_encoder_set_output_state (video_encoder,
|
gst_video_encoder_set_output_state (video_encoder,
|
||||||
caps, state);
|
caps, state);
|
||||||
|
@ -327,8 +356,6 @@ gst_mpeg2enc_set_format (GstVideoEncoder * video_encoder, GstVideoCodecState * s
|
||||||
|
|
||||||
gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc));
|
gst_video_encoder_negotiate (GST_VIDEO_ENCODER (enc));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
refuse_caps:
|
refuse_caps:
|
||||||
|
@ -337,15 +364,13 @@ refuse_caps:
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
refuse_renegotiation:
|
refuse_renegotiation:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (enc, "refused renegotiation (to %" GST_PTR_FORMAT ")",
|
GST_WARNING_OBJECT (enc, "refused renegotiation (to %" GST_PTR_FORMAT ")",
|
||||||
caps);
|
state->caps);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStructure *
|
static GstStructure *
|
||||||
|
@ -437,7 +462,6 @@ gst_mpeg2enc_getcaps (GstVideoEncoder * video_encoder, GstCaps * filter)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (enc, "returned caps %" GST_PTR_FORMAT, caps);
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,8 +544,6 @@ static void
|
||||||
gst_mpeg2enc_loop (GstVideoEncoder * video_encoder)
|
gst_mpeg2enc_loop (GstVideoEncoder * video_encoder)
|
||||||
{
|
{
|
||||||
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
||||||
GstCaps *othercaps = NULL;
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (enc, "encoding task loop:START");
|
GST_DEBUG_OBJECT (enc, "encoding task loop:START");
|
||||||
/* do not try to resume or start when output problems;
|
/* do not try to resume or start when output problems;
|
||||||
|
@ -556,20 +578,6 @@ gst_mpeg2enc_loop (GstVideoEncoder * video_encoder)
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (enc, "encoding task loop: setup and init DONE");
|
GST_DEBUG_OBJECT (enc, "encoding task loop: setup and init DONE");
|
||||||
|
|
||||||
/* and set caps on other side, which should accept anyway */
|
|
||||||
othercaps = enc->encoder->getFormat ();
|
|
||||||
ret = gst_pad_set_caps (video_encoder->srcpad, othercaps);
|
|
||||||
gst_caps_unref (othercaps);
|
|
||||||
othercaps = NULL;
|
|
||||||
if (!ret) {
|
|
||||||
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
|
||||||
enc->srcresult = GST_FLOW_NOT_NEGOTIATED;
|
|
||||||
GST_MPEG2ENC_SIGNAL (enc);
|
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
|
||||||
goto refuse_caps;
|
|
||||||
}
|
|
||||||
GST_DEBUG_OBJECT (enc, "encoding task loop: caps OK");
|
|
||||||
|
|
||||||
/* note that init performs a pre-fill and therefore needs buffers */
|
/* note that init performs a pre-fill and therefore needs buffers */
|
||||||
/* task will stay in here during all of the encoding */
|
/* task will stay in here during all of the encoding */
|
||||||
enc->encoder->encode ();
|
enc->encoder->encode ();
|
||||||
|
@ -601,12 +609,6 @@ done:
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
refuse_caps:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, enc->input_state->caps);
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
encoder:
|
encoder:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
|
GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
|
||||||
|
@ -638,6 +640,7 @@ gst_mpeg2enc_handle_frame (GstVideoEncoder *video_encoder, GstVideoCodecFrame *f
|
||||||
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (video_encoder, "handle_frame");
|
GST_DEBUG_OBJECT (video_encoder, "handle_frame");
|
||||||
|
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
||||||
|
|
||||||
if (G_UNLIKELY (enc->eos))
|
if (G_UNLIKELY (enc->eos))
|
||||||
goto eos;
|
goto eos;
|
||||||
|
@ -647,7 +650,8 @@ gst_mpeg2enc_handle_frame (GstVideoEncoder *video_encoder, GstVideoCodecFrame *f
|
||||||
goto ignore;
|
goto ignore;
|
||||||
GST_DEBUG_OBJECT (video_encoder, "handle_frame: flow OK");
|
GST_DEBUG_OBJECT (video_encoder, "handle_frame: flow OK");
|
||||||
|
|
||||||
g_queue_push_tail (enc->frames, gst_video_codec_frame_ref (frame));
|
g_queue_push_tail (enc->frames, frame);
|
||||||
|
|
||||||
/* frame will be released by task */
|
/* frame will be released by task */
|
||||||
|
|
||||||
if (g_queue_get_length (enc->frames) > 0 && !enc->started) {
|
if (g_queue_get_length (enc->frames) > 0 && !enc->started) {
|
||||||
|
@ -661,13 +665,16 @@ gst_mpeg2enc_handle_frame (GstVideoEncoder *video_encoder, GstVideoCodecFrame *f
|
||||||
if (enc->started)
|
if (enc->started)
|
||||||
GST_MPEG2ENC_SIGNAL (enc);
|
GST_MPEG2ENC_SIGNAL (enc);
|
||||||
|
|
||||||
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
eos:
|
eos:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (enc, "ignoring frame at end-of-stream");
|
GST_DEBUG_OBJECT (enc, "ignoring frame at end-of-stream");
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_encoder_finish_frame (video_encoder, frame);
|
||||||
|
|
||||||
return GST_FLOW_EOS;
|
return GST_FLOW_EOS;
|
||||||
}
|
}
|
||||||
ignore:
|
ignore:
|
||||||
|
@ -677,13 +684,12 @@ ignore:
|
||||||
GST_DEBUG_OBJECT (enc,
|
GST_DEBUG_OBJECT (enc,
|
||||||
"ignoring frame because encoding task encountered %s",
|
"ignoring frame because encoding task encountered %s",
|
||||||
gst_flow_get_name (enc->srcresult));
|
gst_flow_get_name (enc->srcresult));
|
||||||
|
|
||||||
|
enc->eos = TRUE;
|
||||||
|
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
|
||||||
#if 0
|
gst_video_encoder_finish_frame (video_encoder, frame);
|
||||||
/* encoding loop should have ended now and can be joined */
|
|
||||||
- result = gst_pad_stop_task (video_encoder->srcpad);
|
|
||||||
#endif
|
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,7 +500,6 @@ GstMpeg2EncOptions::initProperties (GObjectClass * klass)
|
||||||
"Dual Prime Motion Estimation Mode for MPEG-2 I/P-frame only "
|
"Dual Prime Motion Estimation Mode for MPEG-2 I/P-frame only "
|
||||||
"streams. Quite some players do not support this.",
|
"streams. Quite some players do not support this.",
|
||||||
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
#endif
|
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_MPEG2ENC_ASPECT, (GstPluginAPIFlags) 0);
|
gst_type_mark_as_plugin_api (GST_TYPE_MPEG2ENC_ASPECT, (GstPluginAPIFlags) 0);
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_MPEG2ENC_FORMAT, (GstPluginAPIFlags) 0);
|
gst_type_mark_as_plugin_api (GST_TYPE_MPEG2ENC_FORMAT, (GstPluginAPIFlags) 0);
|
||||||
|
|
|
@ -110,15 +110,14 @@ bool
|
||||||
guint8 *frame;
|
guint8 *frame;
|
||||||
GstMpeg2enc *enc;
|
GstMpeg2enc *enc;
|
||||||
GstVideoFrame vframe;
|
GstVideoFrame vframe;
|
||||||
GstVideoCodecFrame *inframe;
|
GstVideoCodecFrame *inframe = NULL;
|
||||||
|
|
||||||
enc = GST_MPEG2ENC (element);
|
enc = GST_MPEG2ENC (element);
|
||||||
|
|
||||||
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
||||||
|
|
||||||
inframe = (GstVideoCodecFrame *)g_queue_pop_head (enc->frames);
|
|
||||||
/* hang around until the element provides us with a buffer */
|
/* hang around until the element provides us with a buffer */
|
||||||
while (!inframe) {
|
while (!(inframe = (GstVideoCodecFrame *)g_queue_pop_head (enc->frames))) {
|
||||||
if (enc->eos) {
|
if (enc->eos) {
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
/* inform the mpeg encoding loop that it can give up */
|
/* inform the mpeg encoding loop that it can give up */
|
||||||
|
@ -129,7 +128,6 @@ bool
|
||||||
|
|
||||||
gst_video_frame_map (&vframe, &enc->input_state->info, inframe->input_buffer, GST_MAP_READ);
|
gst_video_frame_map (&vframe, &enc->input_state->info, inframe->input_buffer, GST_MAP_READ);
|
||||||
|
|
||||||
// frame = GST_BUFFER_DATA (enc->buffer);
|
|
||||||
frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
|
frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
|
||||||
s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
|
s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
|
||||||
x = encparams.horizontal_size;
|
x = encparams.horizontal_size;
|
||||||
|
@ -155,8 +153,6 @@ bool
|
||||||
}
|
}
|
||||||
gst_video_frame_unmap (&vframe);
|
gst_video_frame_unmap (&vframe);
|
||||||
|
|
||||||
gst_video_codec_frame_unref (inframe);
|
|
||||||
|
|
||||||
/* inform the element the buffer has been processed */
|
/* inform the element the buffer has been processed */
|
||||||
GST_MPEG2ENC_SIGNAL (enc);
|
GST_MPEG2ENC_SIGNAL (enc);
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
|
|
@ -50,6 +50,7 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
GstMpeg2enc *enc = GST_MPEG2ENC (video_encoder);
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
frame = gst_video_encoder_get_oldest_frame (video_encoder);
|
frame = gst_video_encoder_get_oldest_frame (video_encoder);
|
||||||
g_assert (frame != NULL);
|
g_assert (frame != NULL);
|
||||||
|
@ -59,12 +60,12 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
|
||||||
flushed += flush_upto;
|
flushed += flush_upto;
|
||||||
frame->output_buffer = buf;
|
frame->output_buffer = buf;
|
||||||
|
|
||||||
|
|
||||||
/* this should not block anything else (e.g. handle_frame), but if it does,
|
/* this should not block anything else (e.g. handle_frame), but if it does,
|
||||||
* it's ok as mpeg2enc is not really a loop-based element, but push-based */
|
* it's ok as mpeg2enc is not really a loop-based element, but push-based */
|
||||||
|
ret = gst_video_encoder_finish_frame (video_encoder, frame);
|
||||||
|
gst_video_codec_frame_unref (frame);
|
||||||
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
GST_MPEG2ENC_MUTEX_LOCK (enc);
|
||||||
enc->srcresult = gst_video_encoder_finish_frame (video_encoder, frame);
|
enc->srcresult = ret;
|
||||||
gst_buffer_unref (buf);
|
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue