mpegtsmux: misc code cleanups and refactoring

This commit is contained in:
Mark Nauwelaerts 2012-06-04 16:03:20 +02:00 committed by Sebastian Dröge
parent d97d49d237
commit 30c782e062

View file

@ -377,130 +377,115 @@ release_buffer_cb (guint8 * data, void *user_data)
}
static GstFlowReturn
mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data, GstPad * pad)
mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
{
GstFlowReturn ret = GST_FLOW_ERROR;
GstCaps *caps = gst_pad_get_negotiated_caps (pad);
GstCaps *caps;
GstStructure *s;
GstPad *pad;
TsMuxStreamType st = TSMUX_ST_RESERVED;
const gchar *mt;
const GValue *value = NULL;
GstBuffer *codec_data = NULL;
if (caps == NULL) {
GST_DEBUG_OBJECT (pad, "Sink pad caps were not set before pushing");
return GST_FLOW_NOT_NEGOTIATED;
}
pad = ts_data->collect.pad;
caps = gst_pad_get_negotiated_caps (pad);
if (caps == NULL)
goto not_negotiated;
GST_DEBUG_OBJECT (pad, "Creating stream with PID 0x%04x for caps %"
GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
g_return_val_if_fail (s != NULL, FALSE);
if (gst_structure_has_name (s, "video/x-dirac")) {
GST_DEBUG_OBJECT (pad, "Creating Dirac stream with PID 0x%04x",
ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_DIRAC,
ts_data->pid);
} else if (gst_structure_has_name (s, "audio/x-ac3")) {
GST_DEBUG_OBJECT (pad, "Creating AC3 stream with PID 0x%04x", ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_AC3,
ts_data->pid);
} else if (gst_structure_has_name (s, "audio/x-dts")) {
GST_DEBUG_OBJECT (pad, "Creating DTS stream with PID 0x%04x", ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_DTS,
ts_data->pid);
} else if (gst_structure_has_name (s, "audio/x-lpcm")) {
GST_DEBUG_OBJECT (pad, "Creating LPCM stream with PID 0x%04x",
ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_LPCM,
ts_data->pid);
} else if (gst_structure_has_name (s, "video/x-h264")) {
const GValue *value;
GST_DEBUG_OBJECT (pad, "Creating H264 stream with PID 0x%04x",
ts_data->pid);
/* Codec data contains SPS/PPS which need to go in stream for valid ES */
mt = gst_structure_get_name (s);
value = gst_structure_get_value (s, "codec_data");
if (value) {
ts_data->codec_data = gst_buffer_ref (gst_value_get_buffer (value));
if (value != NULL)
codec_data = gst_value_get_buffer (value);
if (strcmp (mt, "video/x-dirac") == 0) {
st = TSMUX_ST_VIDEO_DIRAC;
} else if (strcmp (mt, "audio/x-ac3") == 0) {
st = TSMUX_ST_PS_AUDIO_AC3;
} else if (strcmp (mt, "audio/x-dts") == 0) {
st = TSMUX_ST_PS_AUDIO_DTS;
} else if (strcmp (mt, "audio/x-lpcm") == 0) {
st = TSMUX_ST_PS_AUDIO_LPCM;
} else if (strcmp (mt, "video/x-h264") == 0) {
st = TSMUX_ST_VIDEO_H264;
/* Codec data contains SPS/PPS which need to go in stream for valid ES */
if (codec_data) {
GST_DEBUG_OBJECT (pad, "we have additional codec data (%d bytes)",
GST_BUFFER_SIZE (ts_data->codec_data));
GST_BUFFER_SIZE (codec_data));
ts_data->codec_data = gst_buffer_ref (codec_data);
ts_data->prepare_func = mpegtsmux_prepare_h264;
ts_data->free_func = mpegtsmux_free_h264;
} else {
ts_data->codec_data = NULL;
}
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_H264,
ts_data->pid);
} else if (gst_structure_has_name (s, "audio/mpeg")) {
} else if (strcmp (mt, "audio/mpeg") == 0) {
gint mpegversion;
if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) {
GST_ELEMENT_ERROR (pad, STREAM, FORMAT,
("Invalid data format presented"),
("Caps with type audio/mpeg did not have mpegversion"));
goto beach;
GST_ERROR_OBJECT (pad, "caps missing mpegversion");
goto not_negotiated;
}
switch (mpegversion) {
case 1:
GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 1 stream with "
"PID 0x%04x", ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_MPEG1,
ts_data->pid);
st = TSMUX_ST_AUDIO_MPEG1;
break;
case 2:
GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 2 stream with "
"PID 0x%04x", ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_MPEG2,
ts_data->pid);
st = TSMUX_ST_AUDIO_MPEG2;
break;
case 4:
{
const GValue *value;
/* Codec data contains SPS/PPS which need to go in stream for valid ES */
value = gst_structure_get_value (s, "codec_data");
if (value) {
ts_data->codec_data = gst_buffer_ref (gst_value_get_buffer (value));
st = TSMUX_ST_AUDIO_AAC;
if (codec_data) {
GST_DEBUG_OBJECT (pad, "we have additional codec data (%d bytes)",
GST_BUFFER_SIZE (ts_data->codec_data));
GST_BUFFER_SIZE (codec_data));
ts_data->codec_data = gst_buffer_ref (codec_data);
ts_data->prepare_func = mpegtsmux_prepare_aac;
} else {
ts_data->codec_data = NULL;
}
GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 4 stream with "
"PID 0x%04x", ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_AAC,
ts_data->pid);
break;
}
default:
GST_WARNING_OBJECT (pad, "unsupported mpegversion %d", mpegversion);
goto beach;
goto not_negotiated;
}
} else if (gst_structure_has_name (s, "video/mpeg")) {
} else if (strcmp (mt, "video/mpeg") == 0) {
gint mpegversion;
if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) {
GST_ELEMENT_ERROR (mux, STREAM, FORMAT,
("Invalid data format presented"),
("Caps with type video/mpeg did not have mpegversion"));
goto beach;
GST_ERROR_OBJECT (pad, "caps missing mpegversion");
goto not_negotiated;
}
if (mpegversion == 1) {
GST_DEBUG_OBJECT (pad,
"Creating MPEG Video, version 1 stream with PID 0x%04x",
ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG1,
ts_data->pid);
} else if (mpegversion == 2) {
GST_DEBUG_OBJECT (pad,
"Creating MPEG Video, version 2 stream with PID 0x%04x",
ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG2,
ts_data->pid);
} else {
GST_DEBUG_OBJECT (pad,
"Creating MPEG Video, version 4 stream with PID 0x%04x",
ts_data->pid);
ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG4,
ts_data->pid);
switch (mpegversion) {
case 1:
st = TSMUX_ST_VIDEO_MPEG1;
break;
case 2:
st = TSMUX_ST_VIDEO_MPEG2;
break;
case 4:
st = TSMUX_ST_VIDEO_MPEG4;
break;
default:
GST_WARNING_OBJECT (pad, "unsupported mpegversion %d", mpegversion);
goto not_negotiated;
}
}
if (st != TSMUX_ST_RESERVED) {
ts_data->stream = tsmux_create_stream (mux->tsmux, st, ts_data->pid);
} else {
GST_DEBUG_OBJECT (pad, "Failed to determine stream type");
}
if (ts_data->stream != NULL) {
gst_structure_get_int (s, "rate", &ts_data->stream->audio_sampling);
gst_structure_get_int (s, "channels", &ts_data->stream->audio_channels);
@ -512,9 +497,17 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data, GstPad * pad)
ret = GST_FLOW_OK;
}
beach:
gst_caps_unref (caps);
return ret;
/* ERRORS */
not_negotiated:
{
GST_DEBUG_OBJECT (pad, "Sink pad caps were not set before pushing");
if (caps)
gst_caps_unref (caps);
return GST_FLOW_NOT_NEGOTIATED;
}
}
static GstFlowReturn
@ -564,22 +557,28 @@ mpegtsmux_create_streams (MpegTsMux * mux)
}
if (ts_data->stream == NULL) {
ret = mpegtsmux_create_stream (mux, ts_data, c_data->pad);
ret = mpegtsmux_create_stream (mux, ts_data);
if (ret != GST_FLOW_OK)
goto no_stream;
}
}
return GST_FLOW_OK;
/* ERRORS */
no_program:
{
GST_ELEMENT_ERROR (mux, STREAM, MUX,
("Could not create new program"), (NULL));
return GST_FLOW_ERROR;
}
no_stream:
{
GST_ELEMENT_ERROR (mux, STREAM, MUX,
("Could not create handler for stream"), (NULL));
return ret;
}
}
static MpegTsPadData *
mpegtsmux_choose_best_stream (MpegTsMux * mux)
@ -872,13 +871,8 @@ mpegtsmux_collected (GstCollectPads2 * pads, MpegTsMux * mux)
gint64 pts = -1;
gboolean delta = TRUE;
if (prog == NULL) {
GST_ELEMENT_ERROR (mux, STREAM, MUX,
("Stream on pad %" GST_PTR_FORMAT
" is not associated with any program", COLLECT_DATA_PAD (best)),
(NULL));
return GST_FLOW_ERROR;
}
if (prog == NULL)
goto no_program;
if (mux->force_key_unit_event != NULL && best->stream->is_video_stream) {
GstEvent *event;
@ -968,9 +962,21 @@ mpegtsmux_collected (GstCollectPads2 * pads, MpegTsMux * mux)
}
return ret;
/* ERRORS */
write_fail:
{
return mux->last_flow_ret;
}
no_program:
{
GST_ELEMENT_ERROR (mux, STREAM, MUX,
("Stream on pad %" GST_PTR_FORMAT
" is not associated with any program", COLLECT_DATA_PAD (best)),
(NULL));
return GST_FLOW_ERROR;
}
}
static GstPad *
mpegtsmux_request_new_pad (GstElement * element,
@ -1012,22 +1018,29 @@ mpegtsmux_request_new_pad (GstElement * element,
return pad;
/* ERRORS */
stream_exists:
GST_ELEMENT_ERROR (element, STREAM, MUX, ("Duplicate PID requested"), (NULL));
{
GST_ELEMENT_ERROR (element, STREAM, MUX, ("Duplicate PID requested"),
(NULL));
return NULL;
}
could_not_add:
{
GST_ELEMENT_ERROR (element, STREAM, FAILED,
("Internal data stream error."), ("Could not add pad to element"));
gst_collect_pads2_remove_pad (mux->collect, pad);
gst_object_unref (pad);
return NULL;
}
pad_failure:
{
GST_ELEMENT_ERROR (element, STREAM, FAILED,
("Internal data stream error."), ("Could not add pad to collectpads"));
gst_object_unref (pad);
return NULL;
}
}
static void
mpegtsmux_release_pad (GstElement * element, GstPad * pad)