mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
rmdemux: descramble SIPR before pushing out
Collect and descramble the SIPR packets before pushing. Descramble ATRAC audio. Fixes #618098
This commit is contained in:
parent
0b73505c61
commit
a68951f0bb
1 changed files with 80 additions and 7 deletions
|
@ -42,6 +42,8 @@
|
||||||
|
|
||||||
#define MAX_FRAGS 256
|
#define MAX_FRAGS 256
|
||||||
|
|
||||||
|
static const guint8 sipr_subpk_size[4] = { 29, 19, 37, 20 };
|
||||||
|
|
||||||
typedef struct _GstRMDemuxIndex GstRMDemuxIndex;
|
typedef struct _GstRMDemuxIndex GstRMDemuxIndex;
|
||||||
|
|
||||||
struct _GstRMDemuxStream
|
struct _GstRMDemuxStream
|
||||||
|
@ -1387,6 +1389,9 @@ gst_rmdemux_add_stream (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
||||||
case GST_RM_AUD_ATRC:
|
case GST_RM_AUD_ATRC:
|
||||||
codec_name = "Sony ATRAC3";
|
codec_name = "Sony ATRAC3";
|
||||||
stream_caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
|
stream_caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
|
||||||
|
stream->needs_descrambling = TRUE;
|
||||||
|
stream->subpackets_needed = stream->height;
|
||||||
|
stream->subpackets = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* RealAudio G2 audio */
|
/* RealAudio G2 audio */
|
||||||
|
@ -1400,15 +1405,28 @@ gst_rmdemux_add_stream (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
||||||
|
|
||||||
/* RALF is lossless */
|
/* RALF is lossless */
|
||||||
case GST_RM_AUD_RALF:
|
case GST_RM_AUD_RALF:
|
||||||
/* FIXME: codec_name = */
|
codec_name = "Real Audio Lossless (RALF)";
|
||||||
GST_DEBUG_OBJECT (rmdemux, "RALF");
|
GST_DEBUG_OBJECT (rmdemux, "RALF");
|
||||||
stream_caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
|
stream_caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Sipro/ACELP.NET Voice Codec (MIME unknown) */
|
|
||||||
case GST_RM_AUD_SIPR:
|
case GST_RM_AUD_SIPR:
|
||||||
/* FIXME: codec_name = */
|
|
||||||
|
if (stream->flavor > 3) {
|
||||||
|
GST_WARNING_OBJECT (rmdemux, "bad SIPR flavor %d, freeing it",
|
||||||
|
stream->flavor);
|
||||||
|
g_free (stream);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
codec_name = "Sipro/ACELP.NET Voice";
|
||||||
|
GST_DEBUG_OBJECT (rmdemux, "SIPR");
|
||||||
stream_caps = gst_caps_new_simple ("audio/x-sipro", NULL);
|
stream_caps = gst_caps_new_simple ("audio/x-sipro", NULL);
|
||||||
|
stream->needs_descrambling = TRUE;
|
||||||
|
stream->subpackets_needed = stream->height;
|
||||||
|
stream->subpackets = NULL;
|
||||||
|
stream->leaf_size = sipr_subpk_size[stream->flavor];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1730,7 +1748,6 @@ gst_rmdemux_parse_mdpr (GstRMDemux * rmdemux, const guint8 * data, int length)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 14_4, 28_8, cook, dnet, sipr, raac, racp, ralf, atrc */
|
/* 14_4, 28_8, cook, dnet, sipr, raac, racp, ralf, atrc */
|
||||||
GST_DEBUG_OBJECT (rmdemux,
|
GST_DEBUG_OBJECT (rmdemux,
|
||||||
"Audio stream with rate=%d sample_width=%d n_channels=%d",
|
"Audio stream with rate=%d sample_width=%d n_channels=%d",
|
||||||
|
@ -1905,8 +1922,7 @@ gst_rmdemux_stream_clear_cached_subpackets (GstRMDemux * rmdemux,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rmdemux_descramble_cook_audio (GstRMDemux * rmdemux,
|
gst_rmdemux_descramble_audio (GstRMDemux * rmdemux, GstRMDemuxStream * stream)
|
||||||
GstRMDemuxStream * stream)
|
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
@ -2036,6 +2052,59 @@ gst_rmdemux_descramble_mp4a_audio (GstRMDemux * rmdemux,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_rmdemux_descramble_sipr_audio (GstRMDemux * rmdemux,
|
||||||
|
GstRMDemuxStream * stream)
|
||||||
|
{
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GstBuffer *outbuf;
|
||||||
|
guint packet_size = stream->packet_size;
|
||||||
|
guint height = stream->subpackets->len;
|
||||||
|
guint leaf_size = stream->leaf_size;
|
||||||
|
guint p;
|
||||||
|
|
||||||
|
g_assert (stream->height == height);
|
||||||
|
|
||||||
|
GST_LOG ("packet_size = %u, leaf_size = %u, height= %u", packet_size,
|
||||||
|
leaf_size, height);
|
||||||
|
|
||||||
|
ret = gst_pad_alloc_buffer_and_set_caps (stream->pad,
|
||||||
|
GST_BUFFER_OFFSET_NONE, height * packet_size,
|
||||||
|
GST_PAD_CAPS (stream->pad), &outbuf);
|
||||||
|
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
for (p = 0; p < height; ++p) {
|
||||||
|
GstBuffer *b = g_ptr_array_index (stream->subpackets, p);
|
||||||
|
guint8 *b_data = GST_BUFFER_DATA (b);
|
||||||
|
|
||||||
|
if (p == 0)
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (b);
|
||||||
|
|
||||||
|
memcpy (GST_BUFFER_DATA (outbuf) + packet_size * p, b_data, packet_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
|
||||||
|
|
||||||
|
if (stream->discont) {
|
||||||
|
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
|
||||||
|
stream->discont = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
outbuf = gst_rm_utils_descramble_sipr_buffer (outbuf);
|
||||||
|
|
||||||
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (stream->pad));
|
||||||
|
ret = gst_pad_push (stream->pad, outbuf);
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
gst_rmdemux_stream_clear_cached_subpackets (rmdemux, stream);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rmdemux_handle_scrambled_packet (GstRMDemux * rmdemux,
|
gst_rmdemux_handle_scrambled_packet (GstRMDemux * rmdemux,
|
||||||
GstRMDemuxStream * stream, GstBuffer * buf, gboolean keyframe)
|
GstRMDemuxStream * stream, GstBuffer * buf, gboolean keyframe)
|
||||||
|
@ -2064,12 +2133,16 @@ gst_rmdemux_handle_scrambled_packet (GstRMDemux * rmdemux,
|
||||||
ret = gst_rmdemux_descramble_dnet_audio (rmdemux, stream);
|
ret = gst_rmdemux_descramble_dnet_audio (rmdemux, stream);
|
||||||
break;
|
break;
|
||||||
case GST_RM_AUD_COOK:
|
case GST_RM_AUD_COOK:
|
||||||
ret = gst_rmdemux_descramble_cook_audio (rmdemux, stream);
|
case GST_RM_AUD_ATRC:
|
||||||
|
ret = gst_rmdemux_descramble_audio (rmdemux, stream);
|
||||||
break;
|
break;
|
||||||
case GST_RM_AUD_RAAC:
|
case GST_RM_AUD_RAAC:
|
||||||
case GST_RM_AUD_RACP:
|
case GST_RM_AUD_RACP:
|
||||||
ret = gst_rmdemux_descramble_mp4a_audio (rmdemux, stream);
|
ret = gst_rmdemux_descramble_mp4a_audio (rmdemux, stream);
|
||||||
break;
|
break;
|
||||||
|
case GST_RM_AUD_SIPR:
|
||||||
|
ret = gst_rmdemux_descramble_sipr_audio (rmdemux, stream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue