mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +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",
|
"long-name": "libav DSD (Direct Stream Digital), least significant bit first decoder",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink": {
|
"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",
|
"direction": "sink",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
|
@ -6687,7 +6687,7 @@
|
||||||
"long-name": "libav DSD (Direct Stream Digital), least significant bit first, planar decoder",
|
"long-name": "libav DSD (Direct Stream Digital), least significant bit first, planar decoder",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink": {
|
"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",
|
"direction": "sink",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
|
@ -6715,7 +6715,7 @@
|
||||||
"long-name": "libav DSD (Direct Stream Digital), most significant bit first decoder",
|
"long-name": "libav DSD (Direct Stream Digital), most significant bit first decoder",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink": {
|
"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",
|
"direction": "sink",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
|
@ -6743,7 +6743,7 @@
|
||||||
"long-name": "libav DSD (Direct Stream Digital), most significant bit first, planar decoder",
|
"long-name": "libav DSD (Direct Stream Digital), most significant bit first, planar decoder",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink": {
|
"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",
|
"direction": "sink",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/audio/audio.h>
|
#include <gst/audio/audio.h>
|
||||||
|
#include <gst/audio/gstdsd.h>
|
||||||
#include <gst/pbutils/codec-utils.h>
|
#include <gst/pbutils/codec-utils.h>
|
||||||
|
|
||||||
/* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
|
/* 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;
|
rates = l_rates;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2318,33 +2349,45 @@ gst_ffmpeg_codecid_to_caps (enum AVCodecID codec_id,
|
||||||
NULL);
|
NULL);
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_DSD_LSBF:
|
case AV_CODEC_ID_DSD_LSBF:
|
||||||
caps =
|
case AV_CODEC_ID_DSD_MSBF:
|
||||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||||
NULL);
|
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
{
|
||||||
TRUE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
|
gboolean reversed_bytes;
|
||||||
|
gboolean interleaved;
|
||||||
|
|
||||||
|
switch (codec_id) {
|
||||||
|
case AV_CODEC_ID_DSD_LSBF:
|
||||||
|
reversed_bytes = TRUE;
|
||||||
|
interleaved = TRUE;
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_DSD_MSBF:
|
case AV_CODEC_ID_DSD_MSBF:
|
||||||
caps =
|
reversed_bytes = FALSE;
|
||||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
interleaved = TRUE;
|
||||||
NULL);
|
|
||||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
|
||||||
FALSE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
|
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||||
caps =
|
reversed_bytes = TRUE;
|
||||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
interleaved = FALSE;
|
||||||
NULL);
|
|
||||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
|
||||||
TRUE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
|
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||||
|
reversed_bytes = FALSE;
|
||||||
|
interleaved = FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reversed_bytes = FALSE;
|
||||||
|
interleaved = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
caps =
|
caps =
|
||||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
|
||||||
NULL);
|
"format", G_TYPE_STRING, "DSDU8",
|
||||||
gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
|
"reversed-bytes", G_TYPE_BOOLEAN, reversed_bytes,
|
||||||
FALSE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
|
"layout", G_TYPE_STRING,
|
||||||
|
(interleaved) ? "interleaved" : "non-interleaved", NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case AV_CODEC_ID_APTX:
|
case AV_CODEC_ID_APTX:
|
||||||
caps =
|
caps =
|
||||||
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/aptx",
|
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/aptx",
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
/* #include <ffmpeg/avi.h> */
|
/* #include <ffmpeg/avi.h> */
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstflowcombiner.h>
|
#include <gst/base/gstflowcombiner.h>
|
||||||
|
#include <gst/audio/gstdsd.h>
|
||||||
|
|
||||||
#include "gstav.h"
|
#include "gstav.h"
|
||||||
#include "gstavcodecmap.h"
|
#include "gstavcodecmap.h"
|
||||||
|
@ -1576,6 +1577,32 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||||
stream->discont = FALSE;
|
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,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Sending out buffer time:%" GST_TIME_FORMAT " size:%" G_GSIZE_FORMAT,
|
"Sending out buffer time:%" GST_TIME_FORMAT " size:%" G_GSIZE_FORMAT,
|
||||||
GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
|
GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
|
||||||
|
|
Loading…
Reference in a new issue