mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 09:41:07 +00:00
libav: Integrate FFmpeg's DSD support with GstDsd caps
Code is partially based on the DSD of Robert Tiemann <rtie@gmx.de>: https://gitlab.freedesktop.org/rtiemann/gstreamer/-/tree/dsd Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3901>
This commit is contained in:
parent
8febc4102a
commit
34238e251d
3 changed files with 95 additions and 25 deletions
|
@ -6659,7 +6659,7 @@
|
|||
"long-name": "libav DSD (Direct Stream Digital), least significant bit first decoder",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "audio/x-dsd:\n lsbf: true\n planar: false\n",
|
||||
"caps": "audio/x-dsd:\n format: DSDU8\n reversed-bytes: true\n layout: interleaved\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
},
|
||||
|
@ -6687,7 +6687,7 @@
|
|||
"long-name": "libav DSD (Direct Stream Digital), least significant bit first, planar decoder",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "audio/x-dsd:\n lsbf: true\n planar: true\n",
|
||||
"caps": "audio/x-dsd:\n format: DSDU8\n reversed-bytes: true\n layout: non-interleaved\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
},
|
||||
|
@ -6715,7 +6715,7 @@
|
|||
"long-name": "libav DSD (Direct Stream Digital), most significant bit first decoder",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "audio/x-dsd:\n lsbf: false\n planar: false\n",
|
||||
"caps": "audio/x-dsd:\n format: DSDU8\n reversed-bytes: false\n layout: interleaved\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
},
|
||||
|
@ -6743,7 +6743,7 @@
|
|||
"long-name": "libav DSD (Direct Stream Digital), most significant bit first, planar decoder",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "audio/x-dsd:\n lsbf: false\n planar: true\n",
|
||||
"caps": "audio/x-dsd:\n format: DSDU8\n reversed-bytes: false\n layout: non-interleaved\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
},
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/audio/audio.h>
|
||||
#include <gst/audio/gstdsd.h>
|
||||
#include <gst/pbutils/codec-utils.h>
|
||||
|
||||
/* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
|
||||
|
@ -640,6 +641,36 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
|||
rates = l_rates;
|
||||
break;
|
||||
}
|
||||
case AV_CODEC_ID_DSD_LSBF:
|
||||
case AV_CODEC_ID_DSD_MSBF:
|
||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||
{
|
||||
const static gint l_rates[] = {
|
||||
GST_DSD_MAKE_DSD_RATE_44x (64),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (64),
|
||||
GST_DSD_MAKE_DSD_RATE_44x (128),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (128),
|
||||
GST_DSD_MAKE_DSD_RATE_44x (256),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (256),
|
||||
GST_DSD_MAKE_DSD_RATE_44x (512),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (512),
|
||||
GST_DSD_MAKE_DSD_RATE_44x (1024),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (1024),
|
||||
GST_DSD_MAKE_DSD_RATE_44x (2048),
|
||||
GST_DSD_MAKE_DSD_RATE_48x (2048),
|
||||
};
|
||||
/* There is no clearly defined maximum number of channels in DSD.
|
||||
* The DSF spec mentions a maximum of 6 channels, while the DSDIFF
|
||||
* spec mentions up to 65535 channels. DSDIFF stores DSD in an
|
||||
* interleaved, DSF in a planar fashion. But there is no reason
|
||||
* why some other format couldn't have more than 6 interleaved
|
||||
* channels for example. */
|
||||
maxchannels = 65535;
|
||||
n_rates = G_N_ELEMENTS (l_rates);
|
||||
rates = l_rates;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2318,33 +2349,45 @@ gst_ffmpeg_codecid_to_caps (enum AVCodecID codec_id,
|
|||
NULL);
|
||||
break;
|
||||
case AV_CODEC_ID_DSD_LSBF:
|
||||
caps =
|
||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
||||
NULL);
|
||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
||||
TRUE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
case AV_CODEC_ID_DSD_MSBF:
|
||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||
{
|
||||
gboolean reversed_bytes;
|
||||
gboolean interleaved;
|
||||
|
||||
switch (codec_id) {
|
||||
case AV_CODEC_ID_DSD_LSBF:
|
||||
reversed_bytes = TRUE;
|
||||
interleaved = TRUE;
|
||||
break;
|
||||
case AV_CODEC_ID_DSD_MSBF:
|
||||
caps =
|
||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
||||
NULL);
|
||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
||||
FALSE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
reversed_bytes = FALSE;
|
||||
interleaved = TRUE;
|
||||
break;
|
||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||
caps =
|
||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
||||
NULL);
|
||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
||||
TRUE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
reversed_bytes = TRUE;
|
||||
interleaved = FALSE;
|
||||
break;
|
||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||
reversed_bytes = FALSE;
|
||||
interleaved = FALSE;
|
||||
break;
|
||||
default:
|
||||
reversed_bytes = FALSE;
|
||||
interleaved = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
caps =
|
||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
||||
NULL);
|
||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
||||
FALSE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
"format", G_TYPE_STRING, "DSDU8",
|
||||
"reversed-bytes", G_TYPE_BOOLEAN, reversed_bytes,
|
||||
"layout", G_TYPE_STRING,
|
||||
(interleaved) ? "interleaved" : "non-interleaved", NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
case AV_CODEC_ID_APTX:
|
||||
caps =
|
||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/aptx",
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
/* #include <ffmpeg/avi.h> */
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstflowcombiner.h>
|
||||
#include <gst/audio/gstdsd.h>
|
||||
|
||||
#include "gstav.h"
|
||||
#include "gstavcodecmap.h"
|
||||
|
@ -1576,6 +1577,32 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
|||
stream->discont = FALSE;
|
||||
}
|
||||
|
||||
/* If we are demuxing planar DSD data, add the necessary
|
||||
* meta to inform downstream about the planar layout. */
|
||||
switch (avstream->codecpar->codec_id) {
|
||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||
{
|
||||
int channel_idx;
|
||||
int num_channels = avstream->codecpar->channels;
|
||||
int num_bytes_per_channel = pkt.size / num_channels;
|
||||
GstDsdPlaneOffsetMeta *plane_ofs_meta;
|
||||
|
||||
plane_ofs_meta = gst_buffer_add_dsd_plane_offset_meta (outbuf,
|
||||
avstream->codecpar->channels, num_bytes_per_channel, NULL);
|
||||
|
||||
for (channel_idx = 0; channel_idx < num_channels; ++channel_idx) {
|
||||
plane_ofs_meta->offsets[channel_idx] =
|
||||
num_bytes_per_channel * channel_idx;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Sending out buffer time:%" GST_TIME_FORMAT " size:%" G_GSIZE_FORMAT,
|
||||
GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
|
||||
|
|
Loading…
Reference in a new issue