* [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding
@ 2024-01-27 10:38 Gyan Doshi
2024-01-27 10:38 ` [FFmpeg-devel] [PATCH v2 2/2] fate: add tests for dolby_e decoding in s302m Gyan Doshi
2024-02-13 16:40 ` [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
0 siblings, 2 replies; 3+ messages in thread
From: Gyan Doshi @ 2024-01-27 10:38 UTC (permalink / raw)
To: ffmpeg-devel
Set up framework for non-PCM decoding in-place and
add support for Dolby-E decoding.
Useful for direct transcoding of non-PCM audio in live inputs.
---
configure | 1 +
doc/decoders.texi | 40 +++
libavcodec/s302m.c | 596 +++++++++++++++++++++++++++++++++++++--------
3 files changed, 530 insertions(+), 107 deletions(-)
v2:
switch to pointer for non-pcm sync search
use intreadwrite macro for writing frame data
remove unneeded free of non-pcm dec opts
diff --git a/configure b/configure
index 21663000f8..4d7cd83247 100755
--- a/configure
+++ b/configure
@@ -2980,6 +2980,7 @@ rv20_decoder_select="h263_decoder"
rv20_encoder_select="h263_encoder"
rv30_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
rv40_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
+s302m_decoder_select="dolby_e_decoder"
screenpresso_decoder_deps="zlib"
shorten_decoder_select="bswapdsp"
sipr_decoder_select="lsp"
diff --git a/doc/decoders.texi b/doc/decoders.texi
index 293c82c2ba..9f85c876bf 100644
--- a/doc/decoders.texi
+++ b/doc/decoders.texi
@@ -347,6 +347,46 @@ configuration. You need to explicitly configure the build with
An FFmpeg native decoder for Opus exists, so users can decode Opus
without this library.
+@section s302m
+
+SMPTE ST 302 decoder.
+
+SMPTE ST 302 is a method for storing AES3 data format within an MPEG Transport
+Stream. AES3 streams can contain LPCM streams of 2, 4, 6 or 8 channels with a
+bit depth of 16, 20 or 24-bits at a sample rate of 48 kHz.
+They can also contain non-PCM codec streams such as AC-3 or Dolby-E.
+
+Decoding non-PCM streams directly requires that the necessary stream decoder be
+present in the build. At present, only Dolby-E decoding is supported.
+
+@subsection Options
+
+The following options are supported by the s302m decoder.
+
+@table @option
+@item non_pcm_mode @var{mode}
+Specify how to process non-PCM streams
+
+@table @samp
+@item copy
+Treat data as if it were LPCM.
+@item drop
+Discard the stream.
+@item decode_copy
+Decode if possible eise treat the same as @code{copy}.
+@item decode_drop
+Decode if possible eise treat the same as @code{drop}.
+@end table
+
+The default value is @code{decode_drop}. This option does not affect the processing of
+LPCM streams.
+
+@item non_pcm_options @var{options}
+Set options for non-PCM decoder using a list of key=value pairs separated by ":".
+Consult the docs for the non-PCM decoder for its options.
+
+@end table
+
@c man end AUDIO DECODERS
@chapter Subtitles Decoders
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index f1b41608f3..d890b6f117 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -24,21 +24,264 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
#include "libavutil/log.h"
+#include "libavutil/dict.h"
#include "libavutil/reverse.h"
#include "avcodec.h"
#include "codec_internal.h"
+#include "get_bits.h"
#include "decode.h"
#define AES3_HEADER_LEN 4
+#define NONPCMSYNC_16MARKER 0x4E1F0F8720
+#define NONPCMSYNC_20MARKER 0x4E1F60F872A0
+#define NONPCMSYNC_24MARKER 0x7E1F690F872A50
+
+#define NONPCMSYNC_16_IN_20MARKER 0x04E1F00F8720
+#define NONPCMSYNC_20_IN_24MARKER 0x04E1F600F872A0
+
+#define IS_NONPCMSYNC_16(state) ((state & 0xFFFF0FFFF0) == NONPCMSYNC_16MARKER)
+#define IS_NONPCMSYNC_20(state) ((state & 0xFFFFF0FFFFF0) == NONPCMSYNC_20MARKER)
+#define IS_NONPCMSYNC_24(state) ((state & 0xFFFFFF0FFFFFF0) == NONPCMSYNC_24MARKER)
+
+#define IS_NONPCMSYNC_16_IN_20(state) ((state & 0x0FFFF00FFFF0) == NONPCMSYNC_16_IN_20MARKER)
+#define IS_NONPCMSYNC_20_IN_24(state) ((state & 0x0FFFFF00FFFFF0) == NONPCMSYNC_20_IN_24MARKER)
+
+#define IS_NONPCMSYNC(bit,state) ( ((bit == 16) && IS_NONPCMSYNC_16(state)) || \
+ ((bit == 20) && (IS_NONPCMSYNC_20(state) || IS_NONPCMSYNC_16_IN_20(state))) || \
+ ((bit == 24) && (IS_NONPCMSYNC_24(state) || IS_NONPCMSYNC_20_IN_24(state))) \
+ )
+
+enum non_pcm_modes {
+ NON_PCM_COPY,
+ NON_PCM_DROP,
+ NON_PCM_DEC_ELSE_COPY,
+ NON_PCM_DEC_ELSE_DROP,
+};
+
typedef struct S302Context {
AVClass *class;
+
+ int avctx_props_set;
+
+ int channels;
+ int bits;
+
int non_pcm_mode;
+ int non_pcm_data_type;
+ int non_pcm_bits;
+ int non_pcm_dec;
+
+ AVCodecContext *non_pcm_ctx;
+ AVDictionary *non_pcm_opts;
+ AVPacket *packet;
+ AVFrame *frame;
} S302Context;
+static av_cold int s302m_init(AVCodecContext *avctx)
+{
+ S302Context *s = avctx->priv_data;
+
+ s->non_pcm_data_type = -1;
+
+ return 0;
+}
+
+static int s302m_non_pcm_inspect(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
+ int *offset, int *length)
+{
+ S302Context *s = avctx->priv_data;
+ const uint8_t *pos = buf;
+ int ret, aes_frm_size, data_type, length_code = 0, pkt_left = buf_size;
+ uint64_t state = 0;
+ uint32_t size;
+
+ if (s->channels != 2) {
+ goto end;
+ }
+
+ aes_frm_size = (s->bits + 4) * 2 / 8;
+ if (pkt_left < aes_frm_size * 2) // not enough to contain data_type & length_code
+ return AVERROR_INVALIDDATA;
+
+ while (!IS_NONPCMSYNC(s->bits,state) && pkt_left-- >= 1)
+ state = (state << 8) | *pos++;
+
+ if (IS_NONPCMSYNC(s->bits,state)) {
+ GetBitContext gb;
+
+ if (pkt_left < aes_frm_size * 8) {
+ av_log(avctx, AV_LOG_ERROR, "truncated non-pcm frame detected\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = init_get_bits8(&gb, pos, aes_frm_size);
+ if (ret < 0)
+ return ret;
+
+ if (s->bits == 16) {
+ s->non_pcm_bits = 16;
+ } else if (s->bits == 20) {
+ if (IS_NONPCMSYNC_16_IN_20(state))
+ s->non_pcm_bits = 16;
+ else
+ s->non_pcm_bits = 20;
+ } else if (s->bits == 24) {
+ if (IS_NONPCMSYNC_20_IN_24(state))
+ s->non_pcm_bits = 20;
+ else
+ s->non_pcm_bits = 24;
+ }
+
+ skip_bits(&gb, s->bits - 16);
+
+ data_type = ff_reverse[(uint8_t)get_bits(&gb, 5)] >> 3;
+
+ if (s->non_pcm_data_type == -1) {
+ s->non_pcm_data_type = data_type;
+ av_log(avctx, AV_LOG_INFO, "stream has non-pcm data of type %d with %d-bit words in aes3 payload of size %d bits\n", data_type, s->non_pcm_bits, s->bits);
+ } else if (s->non_pcm_data_type != data_type) {
+ av_log(avctx, AV_LOG_DEBUG, "type mismatch of non-pcm type in packet %d vs stream %d. Dropping.\n", data_type, s->non_pcm_data_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->non_pcm_mode == NON_PCM_COPY)
+ return 0;
+ else if (s->non_pcm_mode == NON_PCM_DROP)
+ return AVERROR_INVALIDDATA;
+
+ skip_bits(&gb, 15);
+
+ size = get_bits(&gb, s->bits);
+
+ length_code = ((ff_reverse[(uint8_t)((size & 0xFF) )] << 16) |
+ (ff_reverse[(uint8_t)((size & 0xFF00) >> 8 )] << 8 ) |
+ (ff_reverse[(uint8_t)((size & 0xFF0000) >> 16)] ) ) >> (24 - s->non_pcm_bits);
+
+ skip_bits(&gb, 4);
+
+ *offset = get_bits_count(&gb)/8 + buf_size - pkt_left;
+ *length = length_code;
+
+ av_log(avctx, AV_LOG_TRACE, "located non-pcm packet at offset %d length code %d.\n", AES3_HEADER_LEN + *offset, length_code);
+
+ return data_type;
+ }
+
+end:
+ if (s->non_pcm_data_type == -1) {
+ s->non_pcm_data_type = 32; // indicate stream should be treated as LPCM
+ return 0;
+ } else
+ return AVERROR_INVALIDDATA;
+}
+
+static int s302m_setup_non_pcm_handling(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+ S302Context *s = avctx->priv_data;
+ const AVCodec *codec;
+ enum AVCodecID codec_id;
+ AVDictionary *dec_opts = NULL;
+ int ret;
+
+ if (s->non_pcm_mode > NON_PCM_DROP) {
+ switch (s->non_pcm_data_type) {
+ case 0x1C:
+ codec_id = AV_CODEC_ID_DOLBY_E;
+ break;
+ default:
+ avpriv_report_missing_feature(avctx, "decode of non-pcm data type %d", s->non_pcm_data_type);
+ ret = AVERROR_PATCHWELCOME;
+ goto fail;
+ }
+
+ codec = avcodec_find_decoder(codec_id);
+ if (!codec) {
+ ret = AVERROR_DECODER_NOT_FOUND;
+ goto fail;
+ }
+
+ s->non_pcm_ctx = avcodec_alloc_context3(codec);
+ if (!s->non_pcm_ctx) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ av_dict_copy(&dec_opts, s->non_pcm_opts, 0);
+
+ ret = avcodec_open2(s->non_pcm_ctx, codec, &dec_opts);
+ av_dict_free(&dec_opts);
+ if (ret < 0)
+ goto fail;
+
+ s->packet = av_packet_alloc();
+ if (!s->packet) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ s->frame = av_frame_alloc();
+ if (!s->frame) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ } else
+ return 0;
+
+ s->non_pcm_dec = 1;
+ return 0;
+
+fail:
+ avcodec_free_context(&s->non_pcm_ctx);
+ av_packet_free(&s->packet);
+ av_frame_free(&s->frame);
+
+ if (s->non_pcm_mode == NON_PCM_DEC_ELSE_COPY)
+ s->non_pcm_mode = NON_PCM_COPY;
+ else if (s->non_pcm_mode == NON_PCM_DEC_ELSE_DROP)
+ s->non_pcm_mode = NON_PCM_DROP;
+
+ return ret;
+}
+
+static int s302m_get_non_pcm_pkt_size(AVCodecContext *avctx, int buf_size, int offset,
+ int length_code, int *dec_pkt_size)
+{
+ S302Context *s = avctx->priv_data;
+ int nb_words, word_size, aesframe_size, s302m_read_size;
+
+ if (offset < 0 || offset >= buf_size)
+ return AVERROR_INVALIDDATA;
+
+ switch (s->non_pcm_data_type) {
+ case 0x1C:
+ goto dolby_e;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+
+dolby_e:
+ {
+ nb_words = length_code / s->non_pcm_bits;
+ nb_words += nb_words & 1;
+
+ word_size = s->non_pcm_bits + 7 >> 3;
+ aesframe_size = (s->bits + 4) * 2 / 8; // 2 subframes, each with payload + VUCF bits
+
+ *dec_pkt_size = nb_words * word_size;
+ s302m_read_size = aesframe_size * nb_words/2;
+
+ if (offset + s302m_read_size > buf_size)
+ return AVERROR_INVALIDDATA;
+
+ return s302m_read_size;
+ }
+}
+
static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
int buf_size)
{
+ S302Context *s = avctx->priv_data;
uint32_t h;
int frame_size, channels, bits;
@@ -66,33 +309,15 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
return AVERROR_INVALIDDATA;
}
- /* Set output properties */
- avctx->bits_per_raw_sample = bits;
- if (bits > 16)
- avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- else
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- av_channel_layout_uninit(&avctx->ch_layout);
- switch(channels) {
- case 2:
- avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
- break;
- case 4:
- avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
- break;
- case 6:
- avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
- break;
- case 8:
- av_channel_layout_from_mask(&avctx->ch_layout,
- AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
- break;
- default:
- avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- avctx->ch_layout.nb_channels = channels;
- break;
- }
+ if (!s->channels)
+ s->channels = channels;
+ else if (s->channels != channels)
+ return AVERROR_INVALIDDATA;
+
+ if (!s->bits)
+ s->bits = bits;
+ else if (s->bits != bits)
+ return AVERROR_INVALIDDATA;
return frame_size;
}
@@ -103,119 +328,273 @@ static int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame,
S302Context *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int block_size, ret, channels;
- int i;
- int non_pcm_data_type = -1;
+ int block_size, ret, channels, frame_size;
+ int non_pcm_offset = -1, non_pcm_length = 0;
+ int dec_pkt_size = 0;
- int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
+ if (s->non_pcm_mode == NON_PCM_DROP && s->non_pcm_data_type != -1 && s->non_pcm_data_type != 32)
+ return avpkt->size;
+
+ frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
if (frame_size < 0)
return frame_size;
buf_size -= AES3_HEADER_LEN;
buf += AES3_HEADER_LEN;
- /* get output buffer */
- block_size = (avctx->bits_per_raw_sample + 4) / 4;
- channels = avctx->ch_layout.nb_channels;
- frame->nb_samples = 2 * (buf_size / block_size) / channels;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
+ // set non-pcm status if not determined
+ // else extract offset and length if non-pcm can be decoded
+ if (s->non_pcm_data_type == -1 || s->non_pcm_dec) {
+ ret = s302m_non_pcm_inspect(avctx, buf, buf_size, &non_pcm_offset, &non_pcm_length);
+ if (ret >= 0 && s->non_pcm_data_type != 32 && !s->non_pcm_dec)
+ ret = s302m_setup_non_pcm_handling(avctx, buf, buf_size);
+ else if (ret < 0)
+ return avpkt->size;
+ }
+
+ if (s->non_pcm_data_type == -1)
+ return AVERROR_INVALIDDATA; // we should know data type in order to proceed with output
+
+ if (!s->non_pcm_dec && !s->avctx_props_set) {
+ /* Set output properties */
+ avctx->bits_per_raw_sample = s->non_pcm_bits ? s->non_pcm_bits : s->bits;
+ if (avctx->bits_per_raw_sample > 16)
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- avctx->bit_rate = 48000 * channels * (avctx->bits_per_raw_sample + 4) +
- 32 * 48000 / frame->nb_samples;
- buf_size = (frame->nb_samples * channels / 2) * block_size;
+ av_channel_layout_uninit(&avctx->ch_layout);
+ switch(s->channels) {
+ case 2:
+ avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
+ break;
+ case 4:
+ avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
+ break;
+ case 6:
+ avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
+ break;
+ case 8:
+ av_channel_layout_from_mask(&avctx->ch_layout,
+ AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
+ break;
+ default:
+ avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ avctx->ch_layout.nb_channels = channels;
+ break;
+ }
+
+ avctx->sample_rate = 48000;
+ s->avctx_props_set = 1;
+ }
+
+ if (s->non_pcm_dec) {
+ buf_size = s302m_get_non_pcm_pkt_size(avctx, buf_size, non_pcm_offset, non_pcm_length, &dec_pkt_size);
+ if (buf_size < 0)
+ return AVERROR_INVALIDDATA;
+ buf += non_pcm_offset;
+
+ if (dec_pkt_size > s->packet->size) {
+ ret = av_grow_packet(s->packet, dec_pkt_size - s->packet->size);
+ if (ret < 0)
+ return ret;
+ }
+ ret = av_packet_make_writable(s->packet);
+ if (ret < 0)
+ return ret;
+ memset(s->packet->data, 0, s->packet->size);
+
+ ret = av_packet_copy_props(s->packet, avpkt);
+ if (ret < 0)
+ return ret;
+ } else {
+ /* get output buffer */
+ block_size = (s->bits + 4) / 4;
+ channels = s->channels;
+ frame->nb_samples = 2 * (buf_size / block_size) / channels;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ buf_size = (frame->nb_samples * channels / 2) * block_size;
+
+ avctx->bit_rate = 48000 * s->channels * ((s->non_pcm_bits ? s->non_pcm_bits : s->bits) + 4) +
+ 32 * 48000 / frame->nb_samples;
+ }
+
+ if (s->bits == 24) {
+ uint8_t *p = NULL;
+ uint32_t *f32 = NULL;
+
+ if (s->non_pcm_dec)
+ p = (uint8_t *)s->packet->data;
+ else
+ f32 = (uint32_t *)frame->data[0];
- if (avctx->bits_per_raw_sample == 24) {
- uint32_t *o = (uint32_t *)frame->data[0];
for (; buf_size > 6; buf_size -= 7) {
- *o++ = ((unsigned)ff_reverse[buf[2]] << 24) |
- (ff_reverse[buf[1]] << 16) |
- (ff_reverse[buf[0]] << 8);
- *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) |
- (ff_reverse[buf[5]] << 20) |
- (ff_reverse[buf[4]] << 12) |
- (ff_reverse[buf[3] & 0x0f] << 4);
+ uint8_t b[6];
+
+ b[0] = (ff_reverse[buf[2] ] ) ;
+ b[1] = (ff_reverse[buf[1] ] ) ;
+ b[2] = (ff_reverse[buf[0] ] ) ;
+ b[3] = (ff_reverse[buf[6] & 0xf0] << 4) |
+ (ff_reverse[buf[5] & 0x0f] >> 4) ;
+ b[4] = (ff_reverse[buf[5] & 0xf0] << 4) |
+ (ff_reverse[buf[4] & 0x0f] >> 4) ;
+ b[5] = (ff_reverse[buf[4] & 0xf0] << 4) |
+ (ff_reverse[buf[3] & 0x0f] >> 4) ;
+
+ if (s->non_pcm_bits == 20) {
+ b[2] &= 0xf0;
+ b[5] &= 0xf0;
+ }
+
+ if (s->non_pcm_dec)
+ for (int i = 0; i < 6; i++)
+ *p++ = b[i];
+ else {
+ *f32++ = AV_RB24(&b[0]) << 8;
+ *f32++ = AV_RB24(&b[3]) << 8;
+ }
buf += 7;
}
- o = (uint32_t *)frame->data[0];
- if (channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
- non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
- break;
+ } else if (s->bits == 20) {
+ uint8_t *p = NULL;
+ uint16_t *f16 = NULL;
+ uint32_t *f32 = NULL;
+
+ if (s->non_pcm_dec)
+ p = (uint8_t *)s->packet->data;
+ else if (s->non_pcm_bits == 16)
+ f16 = (uint16_t *)frame->data[0];
+ else
+ f32 = (uint32_t *)frame->data[0];
+
+ for (; buf_size > 5; buf_size -= 6) {
+ uint8_t b[6];
+
+ b[0] = (ff_reverse[buf[2] & 0xf0] << 4) |
+ (ff_reverse[buf[1] & 0x0f] >> 4) ;
+ b[1] = (ff_reverse[buf[1] & 0xf0] << 4) |
+ (ff_reverse[buf[0] & 0x0f] >> 4) ;
+ b[2] = (ff_reverse[buf[0] & 0xf0] << 4) ;
+ b[3] = (ff_reverse[buf[5] & 0xf0] << 4) |
+ (ff_reverse[buf[4] & 0x0f] >> 4) ;
+ b[4] = (ff_reverse[buf[4] & 0xf0] << 4) |
+ (ff_reverse[buf[3] & 0x0f] >> 4) ;
+ b[5] = (ff_reverse[buf[3] & 0xf0] << 4) ;
+
+ if (s->non_pcm_dec) {
+ for (int i = 0; i < 6; i++) {
+ if (s->non_pcm_bits == 16 && (i % 3 == 2))
+ continue;
+ *p++ = b[i];
}
+ } else if (s->non_pcm_bits == 16) {
+ *f16++ = AV_RB16(&b[0]);
+ *f16++ = AV_RB16(&b[3]);
+ } else {
+ *f32++ = AV_RB24(&b[0]) << 8;
+ *f32++ = AV_RB24(&b[3]) << 8;
}
- } else if (avctx->bits_per_raw_sample == 20) {
- uint32_t *o = (uint32_t *)frame->data[0];
- for (; buf_size > 5; buf_size -= 6) {
- *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) |
- (ff_reverse[buf[1]] << 20) |
- (ff_reverse[buf[0]] << 12);
- *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) |
- (ff_reverse[buf[4]] << 20) |
- (ff_reverse[buf[3]] << 12);
buf += 6;
}
- o = (uint32_t *)frame->data[0];
- if (channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
- non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
- break;
- }
- }
} else {
- uint16_t *o = (uint16_t *)frame->data[0];
+ uint8_t *p = NULL;
+ uint16_t *f16 = NULL;
+
+ if (s->non_pcm_dec)
+ p = (uint8_t *)s->packet->data;
+ else
+ f16 = (uint16_t *)frame->data[0];
+
for (; buf_size > 4; buf_size -= 5) {
- *o++ = (ff_reverse[buf[1]] << 8) |
- ff_reverse[buf[0]];
- *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
- (ff_reverse[buf[3]] << 4) |
- (ff_reverse[buf[2]] >> 4);
+ uint8_t b[4];
+
+ b[0] = (ff_reverse[buf[1] ] ) ;
+ b[1] = (ff_reverse[buf[0] ] ) ;
+ b[2] = (ff_reverse[buf[4] & 0xf0] << 4) |
+ (ff_reverse[buf[3] & 0x0f] >> 4) ;
+ b[3] = (ff_reverse[buf[3] & 0xf0] << 4) |
+ (ff_reverse[buf[2] & 0x0f] >> 4) ;
+
+ if (s->non_pcm_dec)
+ for (int i = 0; i < 4; i++)
+ *p++ = b[i];
+ else {
+ *f16++ = AV_RB16(&b[0]);
+ *f16++ = AV_RB16(&b[2]);
+ }
buf += 5;
}
- o = (uint16_t *)frame->data[0];
- if (channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
- non_pcm_data_type = (o[i+6] & 0x1F);
- break;
- }
- }
}
- if (non_pcm_data_type != -1) {
- if (s->non_pcm_mode == 3) {
- av_log(avctx, AV_LOG_ERROR,
- "S302 non PCM mode with data type %d not supported\n",
- non_pcm_data_type);
- return AVERROR_PATCHWELCOME;
+ if (s->non_pcm_dec) {
+ ret = avcodec_send_packet(s->non_pcm_ctx, s->packet);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error %d submitting non-pcm packet with pts %"PRId64" for decoding\n", ret, s->packet->pts);
+ return ret;
}
- if (s->non_pcm_mode & 1) {
- return avpkt->size;
+ ret = avcodec_receive_frame(s->non_pcm_ctx, s->frame);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error %d receiving non-pcm decoded frame for packet with pts %"PRId64"\n", ret, s->packet->pts);
+ return ret;
}
- }
- avctx->sample_rate = 48000;
+ if (!s->avctx_props_set) {
+ avctx->sample_fmt = s->non_pcm_ctx->sample_fmt;
+ avctx->sample_rate = s->non_pcm_ctx->sample_rate;
+
+ av_channel_layout_uninit(&avctx->ch_layout);
+ ret = av_channel_layout_copy(&avctx->ch_layout, &s->non_pcm_ctx->ch_layout);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error %d when copying channel layout from non-pcm decoder context to parent context.\n", ret);
+ return ret;
+ }
+ s->avctx_props_set = 1;
+ }
+
+ frame->nb_samples = s->frame->nb_samples;
+ ret = ff_get_buffer(avctx, frame, 0);
+ if (ret < 0)
+ return ret;
+
+ for (int ch = 0; ch < s->frame->ch_layout.nb_channels; ch++)
+ memcpy(frame->extended_data[ch], s->frame->extended_data[ch],
+ av_get_bytes_per_sample(s->non_pcm_ctx->sample_fmt) * s->frame->nb_samples);
+ }
*got_frame_ptr = 1;
return avpkt->size;
}
+static void s302m_flush(AVCodecContext *avctx)
+{
+ S302Context *s = avctx->priv_data;
+
+ if (s->non_pcm_dec && s->non_pcm_ctx)
+ avcodec_flush_buffers(s->non_pcm_ctx);
+}
+
+static av_cold int s302m_close(AVCodecContext *avctx)
+{
+ S302Context *s = avctx->priv_data;
+
+ avcodec_free_context(&s->non_pcm_ctx);
+ av_packet_free(&s->packet);
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
static const AVOption s302m_options[] = {
- {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
- {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"},
- {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"},
- {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"},
- {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = NON_PCM_DEC_ELSE_DROP}, NON_PCM_COPY, NON_PCM_DEC_ELSE_DROP, FLAGS, "non_pcm_mode"},
+ {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_COPY}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DROP}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_COPY}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_DROP}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"non_pcm_options", "Set options for non-pcm decoder", offsetof(S302Context, non_pcm_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
{NULL}
};
@@ -231,6 +610,9 @@ const FFCodec ff_s302m_decoder = {
CODEC_LONG_NAME("SMPTE 302M"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_S302M,
+ .init = s302m_init,
+ .close = s302m_close,
+ .flush = s302m_flush,
.p.priv_class = &s302m_class,
.priv_data_size = sizeof(S302Context),
FF_CODEC_DECODE_CB(s302m_decode_frame),
--
2.39.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
* [FFmpeg-devel] [PATCH v2 2/2] fate: add tests for dolby_e decoding in s302m
2024-01-27 10:38 [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
@ 2024-01-27 10:38 ` Gyan Doshi
2024-02-13 16:40 ` [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
1 sibling, 0 replies; 3+ messages in thread
From: Gyan Doshi @ 2024-01-27 10:38 UTC (permalink / raw)
To: ffmpeg-devel
Three tests, one each for
1) 16-bit Dolby-E words in 20-bits AES3 words
2) 20-bit Dolby-E words in 20-bits AES3 words
3) 20-bit Dolby-E words in 24-bits AES3 words
---
tests/fate/acodec.mak | 15 ++
tests/ref/acodec/s302m-20-dolbye-16 | 221 ++++++++++++++++++++++++++++
tests/ref/acodec/s302m-20-dolbye-20 | 127 ++++++++++++++++
tests/ref/acodec/s302m-24-dolbye-20 | 170 +++++++++++++++++++++
4 files changed, 533 insertions(+)
create mode 100644 tests/ref/acodec/s302m-20-dolbye-16
create mode 100644 tests/ref/acodec/s302m-20-dolbye-20
create mode 100644 tests/ref/acodec/s302m-24-dolbye-20
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index 7b09e3bd63..60d3b8515b 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -165,6 +165,21 @@ fate-acodec-s302m: CODEC = s302m
fate-acodec-s302m: ENCOPTS = -af aresample=48000:tsf=s16p -strict -2
fate-acodec-s302m: DECOPTS = -af aresample=44100:tsf=s16p
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-20-dolbye-16
+fate-acodec-s302m-20-dolbye-16: CMD = framecrc -auto_conversion_filters \
+ -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_20bits_DolbyE_16bits.ts \
+ -vn -c:a pcm_s16le
+
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-20-dolbye-20
+fate-acodec-s302m-20-dolbye-20: CMD = framecrc -auto_conversion_filters \
+ -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_20bits_DolbyE_20bits.ts \
+ -vn -c:a pcm_s16le
+
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-24-dolbye-20
+fate-acodec-s302m-24-dolbye-20: CMD = framecrc -auto_conversion_filters \
+ -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_24bits_DolbyE_20bits.ts \
+ -vn -c:a pcm_s16le
+
FATE_ACODEC-$(call ENCDEC, WAVPACK, WV, ARESAMPLE_FILTER) += fate-acodec-wavpack
fate-acodec-wavpack: FMT = wv
fate-acodec-wavpack: CODEC = wavpack -compression_level 1
diff --git a/tests/ref/acodec/s302m-20-dolbye-16 b/tests/ref/acodec/s302m-20-dolbye-16
new file mode 100644
index 0000000000..e0c7b9e13b
--- /dev/null
+++ b/tests/ref/acodec/s302m-20-dolbye-16
@@ -0,0 +1,221 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 5.1(side)
+0, 0, 0, 1792, 21504, 0x9136aa8a
+0, 1792, 1792, 1792, 21504, 0x6b8b42f0
+0, 3584, 3584, 1792, 21504, 0xc73c0342
+0, 5376, 5376, 1792, 21504, 0x9d777e2a
+0, 7168, 7168, 1792, 21504, 0x2ee86c97
+0, 8960, 8960, 1792, 21504, 0xfdd41829
+0, 10752, 10752, 1792, 21504, 0x58ea1b12
+0, 12544, 12544, 1792, 21504, 0xa81a35f4
+0, 14336, 14336, 1792, 21504, 0x2bd9bb62
+0, 16128, 16128, 1792, 21504, 0x0648940e
+0, 17920, 17920, 1792, 21504, 0x377452f9
+0, 19712, 19712, 1792, 21504, 0xf50f26b9
+0, 21504, 21504, 1792, 21504, 0x935e7c69
+0, 23296, 23296, 1792, 21504, 0x99363659
+0, 25088, 25088, 1792, 21504, 0x78212dd2
+0, 26880, 26880, 1792, 21504, 0x687f5776
+0, 28672, 28672, 1792, 21504, 0xd6d3320c
+0, 30464, 30464, 1792, 21504, 0x96e1b731
+0, 32256, 32256, 1792, 21504, 0xbb0b9cd9
+0, 34048, 34048, 1792, 21504, 0x819db403
+0, 35840, 35840, 1792, 21504, 0xa95c859a
+0, 37632, 37632, 1792, 21504, 0xd9cd11cc
+0, 39424, 39424, 1792, 21504, 0xe7a3abbf
+0, 41216, 41216, 1792, 21504, 0x975e4ddc
+0, 43008, 43008, 1792, 21504, 0x329af143
+0, 44800, 44800, 1792, 21504, 0x9bb6281b
+0, 46592, 46592, 1792, 21504, 0x96cc0fa8
+0, 48384, 48384, 1792, 21504, 0xaae03a7d
+0, 50176, 50176, 1792, 21504, 0x2a5d6225
+0, 51968, 51968, 1792, 21504, 0xf7cc19f5
+0, 53760, 53760, 1792, 21504, 0x89e85e67
+0, 55552, 55552, 1792, 21504, 0x607ab65e
+0, 57344, 57344, 1792, 21504, 0x95c0ad8f
+0, 59136, 59136, 1792, 21504, 0x6b9e8b96
+0, 60928, 60928, 1792, 21504, 0x7b83696c
+0, 62720, 62720, 1792, 21504, 0xac0b6fbf
+0, 64512, 64512, 1792, 21504, 0xfa249f22
+0, 66304, 66304, 1792, 21504, 0x51acbb93
+0, 68096, 68096, 1792, 21504, 0xd77b34be
+0, 69888, 69888, 1792, 21504, 0xd5494a86
+0, 71680, 71680, 1792, 21504, 0xd83c3d91
+0, 73472, 73472, 1792, 21504, 0xa476ccd8
+0, 75264, 75264, 1792, 21504, 0x2aafc337
+0, 77056, 77056, 1792, 21504, 0xeee70084
+0, 78848, 78848, 1792, 21504, 0xd60a3c93
+0, 80640, 80640, 1792, 21504, 0x43ac0f84
+0, 82432, 82432, 1792, 21504, 0x8aeb9355
+0, 84224, 84224, 1792, 21504, 0xe548d9ec
+0, 86016, 86016, 1792, 21504, 0x13c71471
+0, 87808, 87808, 1792, 21504, 0x328bde19
+0, 89600, 89600, 1792, 21504, 0xe21f9541
+0, 91392, 91392, 1792, 21504, 0xf01f7709
+0, 93184, 93184, 1792, 21504, 0x7eed888b
+0, 94976, 94976, 1792, 21504, 0x93ce6bd6
+0, 96768, 96768, 1792, 21504, 0x25a00dce
+0, 98560, 98560, 1792, 21504, 0xf3b782e5
+0, 100352, 100352, 1792, 21504, 0x50cfeff9
+0, 102144, 102144, 1792, 21504, 0x8a49dc66
+0, 103936, 103936, 1792, 21504, 0x992102d0
+0, 105728, 105728, 1792, 21504, 0x948cf82a
+0, 107520, 107520, 1792, 21504, 0x8d21d0f4
+0, 109312, 109312, 1792, 21504, 0x4c3075a2
+0, 111104, 111104, 1792, 21504, 0xdd958734
+0, 112896, 112896, 1792, 21504, 0xdd98493b
+0, 114688, 114688, 1792, 21504, 0x65273440
+0, 116480, 116480, 1792, 21504, 0xefa1df42
+0, 118272, 118272, 1792, 21504, 0x60c90e3f
+0, 120064, 120064, 1792, 21504, 0x31500c0b
+0, 121856, 121856, 1792, 21504, 0xb5cfee25
+0, 123648, 123648, 1792, 21504, 0xb7377ca2
+0, 125440, 125440, 1792, 21504, 0x2cec434f
+0, 127232, 127232, 1792, 21504, 0x5a42a510
+0, 129024, 129024, 1792, 21504, 0xa3a27927
+0, 130816, 130816, 1792, 21504, 0x9faf946f
+0, 132608, 132608, 1792, 21504, 0x05c9ce85
+0, 134400, 134400, 1792, 21504, 0xdd2d2579
+0, 136192, 136192, 1792, 21504, 0x422b6910
+0, 137984, 137984, 1792, 21504, 0xbd87a267
+0, 139776, 139776, 1792, 21504, 0x8ff262b6
+0, 141568, 141568, 1792, 21504, 0x2c134aea
+0, 143360, 143360, 1792, 21504, 0x4b756eef
+0, 145152, 145152, 1792, 21504, 0xe871ccba
+0, 146944, 146944, 1792, 21504, 0x048f2364
+0, 148736, 148736, 1792, 21504, 0x2fbc747d
+0, 150528, 150528, 1792, 21504, 0x1c4ad508
+0, 152320, 152320, 1792, 21504, 0xdc3d010e
+0, 154112, 154112, 1792, 21504, 0xf0bee87a
+0, 155904, 155904, 1792, 21504, 0xc4c53799
+0, 157696, 157696, 1792, 21504, 0xa815039c
+0, 159488, 159488, 1792, 21504, 0x70e02a19
+0, 161280, 161280, 1792, 21504, 0x25f640d4
+0, 163072, 163072, 1792, 21504, 0xeb34e7d1
+0, 164864, 164864, 1792, 21504, 0x98fb0d91
+0, 166656, 166656, 1792, 21504, 0xac0c2d8c
+0, 168448, 168448, 1792, 21504, 0x6292368a
+0, 170240, 170240, 1792, 21504, 0x2f78c7a8
+0, 172032, 172032, 1792, 21504, 0x43268663
+0, 173824, 173824, 1792, 21504, 0x5834f0f9
+0, 175616, 175616, 1792, 21504, 0x7bab1336
+0, 177408, 177408, 1792, 21504, 0xb6736af6
+0, 179200, 179200, 1792, 21504, 0xd4681bfa
+0, 180992, 180992, 1792, 21504, 0xc2199d49
+0, 182784, 182784, 1792, 21504, 0x366a1ae0
+0, 184576, 184576, 1792, 21504, 0x7fde6d4b
+0, 186368, 186368, 1792, 21504, 0x8ac70491
+0, 188160, 188160, 1792, 21504, 0x08bbf02e
+0, 189952, 189952, 1792, 21504, 0x9fbd8944
+0, 191744, 191744, 1792, 21504, 0x04b12848
+0, 193536, 193536, 1792, 21504, 0xcb23ae72
+0, 195328, 195328, 1792, 21504, 0xd5571f70
+0, 197120, 197120, 1792, 21504, 0x820cb277
+0, 198912, 198912, 1792, 21504, 0x1352bb72
+0, 200704, 200704, 1792, 21504, 0x008aa81c
+0, 202496, 202496, 1792, 21504, 0x14cc97e2
+0, 204288, 204288, 1792, 21504, 0x1599fdd7
+0, 206080, 206080, 1792, 21504, 0x8e5fcec5
+0, 207872, 207872, 1792, 21504, 0x8fa3f712
+0, 209664, 209664, 1792, 21504, 0xee373f8a
+0, 211456, 211456, 1792, 21504, 0x78d5d931
+0, 213248, 213248, 1792, 21504, 0x48132510
+0, 215040, 215040, 1792, 21504, 0x3bddeb6a
+0, 216832, 216832, 1792, 21504, 0xe4b7dade
+0, 218624, 218624, 1792, 21504, 0x39660d3b
+0, 220416, 220416, 1792, 21504, 0x57e5529e
+0, 222208, 222208, 1792, 21504, 0xe7047887
+0, 224000, 224000, 1792, 21504, 0x58b47398
+0, 225792, 225792, 1792, 21504, 0x1c209a7a
+0, 227584, 227584, 1792, 21504, 0x9880d68e
+0, 229376, 229376, 1792, 21504, 0xe529880f
+0, 231168, 231168, 1792, 21504, 0xc5a3a5ff
+0, 232960, 232960, 1792, 21504, 0x9b344d76
+0, 234752, 234752, 1792, 21504, 0xeb73e24c
+0, 236544, 236544, 1792, 21504, 0xeae26f88
+0, 238336, 238336, 1792, 21504, 0xdc02c37a
+0, 240128, 240128, 1792, 21504, 0xd7102ba8
+0, 241920, 241920, 1792, 21504, 0x40ecab7e
+0, 243712, 243712, 1792, 21504, 0x57bdf0ba
+0, 245504, 245504, 1792, 21504, 0xc5961f22
+0, 247296, 247296, 1792, 21504, 0x3649ea62
+0, 249088, 249088, 1792, 21504, 0x47960ac6
+0, 250880, 250880, 1792, 21504, 0xd19597be
+0, 252672, 252672, 1792, 21504, 0xa3b2f62b
+0, 254464, 254464, 1792, 21504, 0x99abea1e
+0, 256256, 256256, 1792, 21504, 0xcee9f230
+0, 258048, 258048, 1792, 21504, 0xdc0ce362
+0, 259840, 259840, 1792, 21504, 0xc6da4814
+0, 261632, 261632, 1792, 21504, 0x2fe37803
+0, 263424, 263424, 1792, 21504, 0x2a6e4f0c
+0, 265216, 265216, 1792, 21504, 0x0b8d59b3
+0, 267008, 267008, 1792, 21504, 0xebcdbc2e
+0, 268800, 268800, 1792, 21504, 0xe236b4c4
+0, 270592, 270592, 1792, 21504, 0x631726e6
+0, 272384, 272384, 1792, 21504, 0xf00db632
+0, 274176, 274176, 1792, 21504, 0x2f679a9b
+0, 275968, 275968, 1792, 21504, 0xaa74d412
+0, 277760, 277760, 1792, 21504, 0x64abf8f3
+0, 279552, 279552, 1792, 21504, 0x352b8366
+0, 281344, 281344, 1792, 21504, 0x35addc2c
+0, 283136, 283136, 1792, 21504, 0x20093740
+0, 284928, 284928, 1792, 21504, 0x5ac2c7cd
+0, 286720, 286720, 1792, 21504, 0xb12329a4
+0, 288512, 288512, 1792, 21504, 0xe4cdfece
+0, 290304, 290304, 1792, 21504, 0xb5477f3b
+0, 292096, 292096, 1792, 21504, 0x68f0b7fc
+0, 293888, 293888, 1792, 21504, 0x7ddbff47
+0, 295680, 295680, 1792, 21504, 0xd4048c58
+0, 297472, 297472, 1792, 21504, 0x582a008d
+0, 299264, 299264, 1792, 21504, 0xacc3e45d
+0, 301056, 301056, 1792, 21504, 0xa41dc633
+0, 302848, 302848, 1792, 21504, 0x700345de
+0, 304640, 304640, 1792, 21504, 0xd8f5c071
+0, 306432, 306432, 1792, 21504, 0x671d777e
+0, 308224, 308224, 1792, 21504, 0x7bc98c57
+0, 310016, 310016, 1792, 21504, 0xebb4dd91
+0, 311808, 311808, 1792, 21504, 0xaffbcc2e
+0, 313600, 313600, 1792, 21504, 0xd97328ea
+0, 315392, 315392, 1792, 21504, 0xa40a3495
+0, 317184, 317184, 1792, 21504, 0x86a82b6f
+0, 318976, 318976, 1792, 21504, 0x1009f9fa
+0, 320768, 320768, 1792, 21504, 0x4bb3b64a
+0, 322560, 322560, 1792, 21504, 0x4ea9ebd3
+0, 324352, 324352, 1792, 21504, 0x4bb33092
+0, 326144, 326144, 1792, 21504, 0x27b8ce5f
+0, 327936, 327936, 1792, 21504, 0x7a7192e7
+0, 329728, 329728, 1792, 21504, 0x49972389
+0, 331520, 331520, 1792, 21504, 0x707a8d22
+0, 333312, 333312, 1792, 21504, 0x21ee3ee7
+0, 335104, 335104, 1792, 21504, 0xe01a4599
+0, 336896, 336896, 1792, 21504, 0x4282e560
+0, 338688, 338688, 1792, 21504, 0x44539c70
+0, 340480, 340480, 1792, 21504, 0xac084971
+0, 342272, 342272, 1792, 21504, 0xc0dafcb4
+0, 344064, 344064, 1792, 21504, 0x3248760d
+0, 345856, 345856, 1792, 21504, 0x18a4f9e5
+0, 347648, 347648, 1792, 21504, 0x71f8e059
+0, 349440, 349440, 1792, 21504, 0xea7282ea
+0, 351232, 351232, 1792, 21504, 0x25c0919c
+0, 353024, 353024, 1792, 21504, 0x5b0886cf
+0, 354816, 354816, 1792, 21504, 0x909f2352
+0, 356608, 356608, 1792, 21504, 0x37458b4a
+0, 358400, 358400, 1792, 21504, 0x678ac27a
+0, 360192, 360192, 1792, 21504, 0x2a25cabb
+0, 361984, 361984, 1792, 21504, 0xa0bcd6d8
+0, 363776, 363776, 1792, 21504, 0x39366653
+0, 365568, 365568, 1792, 21504, 0xa173abac
+0, 367360, 367360, 1792, 21504, 0x737a1781
+0, 369152, 369152, 1792, 21504, 0xa2ba122e
+0, 370944, 370944, 1792, 21504, 0x63135aef
+0, 372736, 372736, 1792, 21504, 0xc9bd4ccc
+0, 374528, 374528, 1792, 21504, 0xd8aab65d
+0, 376320, 376320, 1792, 21504, 0x1f35ca2e
+0, 378112, 378112, 1792, 21504, 0x002ea8b9
+0, 379904, 379904, 1792, 21504, 0xa5e1b4d0
+0, 381696, 381696, 1792, 21504, 0xd2fa9e4a
+0, 383488, 383488, 1792, 21504, 0xcfd58c02
+0, 385280, 385280, 1792, 21504, 0x0fa5edf4
diff --git a/tests/ref/acodec/s302m-20-dolbye-20 b/tests/ref/acodec/s302m-20-dolbye-20
new file mode 100644
index 0000000000..f19d0f0b19
--- /dev/null
+++ b/tests/ref/acodec/s302m-20-dolbye-20
@@ -0,0 +1,127 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 7.1
+0, 0, 0, 1792, 28672, 0xafcc7cdc
+0, 1792, 1792, 1792, 28672, 0x6779af9c
+0, 3584, 3584, 1792, 28672, 0x85383174
+0, 5376, 5376, 1792, 28672, 0xf31ac9ba
+0, 7168, 7168, 1792, 28672, 0x6d38995e
+0, 8960, 8960, 1792, 28672, 0x0ea74b36
+0, 10752, 10752, 1792, 28672, 0x5b599a77
+0, 12544, 12544, 1792, 28672, 0x697aa42c
+0, 14336, 14336, 1792, 28672, 0x0a2812a5
+0, 16128, 16128, 1792, 28672, 0x738239fc
+0, 17920, 17920, 1792, 28672, 0x0a091522
+0, 19712, 19712, 1792, 28672, 0x926829c7
+0, 21504, 21504, 1792, 28672, 0x1e02c825
+0, 23296, 23296, 1792, 28672, 0x00b969df
+0, 25088, 25088, 1792, 28672, 0x8864a003
+0, 26880, 26880, 1792, 28672, 0x5e48b960
+0, 28672, 28672, 1792, 28672, 0xd6bc9752
+0, 30464, 30464, 1792, 28672, 0x6ddc6c53
+0, 32256, 32256, 1792, 28672, 0x4779e77e
+0, 34048, 34048, 1792, 28672, 0x42cf2f9d
+0, 35840, 35840, 1792, 28672, 0x8b9ba6bd
+0, 37632, 37632, 1792, 28672, 0x5947fe3d
+0, 39424, 39424, 1792, 28672, 0x13b13fb9
+0, 41216, 41216, 1792, 28672, 0x8f707e79
+0, 43008, 43008, 1792, 28672, 0x2da453c2
+0, 44800, 44800, 1792, 28672, 0x71b53009
+0, 46592, 46592, 1792, 28672, 0x261aee06
+0, 48384, 48384, 1792, 28672, 0xf17e2267
+0, 50176, 50176, 1792, 28672, 0xb050e6ad
+0, 51968, 51968, 1792, 28672, 0x5bac3a6e
+0, 53760, 53760, 1792, 28672, 0x8864fd2a
+0, 55552, 55552, 1792, 28672, 0x76e3e5c2
+0, 57344, 57344, 1792, 28672, 0xb0dfb4eb
+0, 59136, 59136, 1792, 28672, 0x759ccffd
+0, 60928, 60928, 1792, 28672, 0xc05465ff
+0, 62720, 62720, 1792, 28672, 0x6cdb97ce
+0, 64512, 64512, 1792, 28672, 0x6d095222
+0, 66304, 66304, 1792, 28672, 0xb73a46a9
+0, 68096, 68096, 1792, 28672, 0xe7972758
+0, 69888, 69888, 1792, 28672, 0x13957aec
+0, 71680, 71680, 1792, 28672, 0xd98da4be
+0, 73472, 73472, 1792, 28672, 0x5b71520b
+0, 75264, 75264, 1792, 28672, 0x7f2b5780
+0, 77056, 77056, 1792, 28672, 0x998dfb6d
+0, 78848, 78848, 1792, 28672, 0x74cdcf9d
+0, 80640, 80640, 1792, 28672, 0x0d0561e5
+0, 82432, 82432, 1792, 28672, 0x3d52043c
+0, 84224, 84224, 1792, 28672, 0x91292607
+0, 86016, 86016, 1792, 28672, 0x09ce094f
+0, 87808, 87808, 1792, 28672, 0xb4f535a7
+0, 89600, 89600, 1792, 28672, 0xade53075
+0, 91392, 91392, 1792, 28672, 0xd2180e7a
+0, 93184, 93184, 1792, 28672, 0x93383890
+0, 94976, 94976, 1792, 28672, 0xe9885e95
+0, 96768, 96768, 1792, 28672, 0x95a7648c
+0, 98560, 98560, 1792, 28672, 0xc92504d0
+0, 100352, 100352, 1792, 28672, 0xe68650cb
+0, 102144, 102144, 1792, 28672, 0x8f0fe748
+0, 103936, 103936, 1792, 28672, 0xed292e2c
+0, 105728, 105728, 1792, 28672, 0xf3f2e270
+0, 107520, 107520, 1792, 28672, 0x52156585
+0, 109312, 109312, 1792, 28672, 0x2b4e6f80
+0, 111104, 111104, 1792, 28672, 0x20c3e16f
+0, 112896, 112896, 1792, 28672, 0xc5684fa4
+0, 114688, 114688, 1792, 28672, 0xc583d3f7
+0, 116480, 116480, 1792, 28672, 0xfac32c30
+0, 118272, 118272, 1792, 28672, 0x4bbb4646
+0, 120064, 120064, 1792, 28672, 0x119f0385
+0, 121856, 121856, 1792, 28672, 0x934bce21
+0, 123648, 123648, 1792, 28672, 0x9c7414fb
+0, 125440, 125440, 1792, 28672, 0xdfc81ba0
+0, 127232, 127232, 1792, 28672, 0x319cd9d7
+0, 129024, 129024, 1792, 28672, 0x5cb03e9e
+0, 130816, 130816, 1792, 28672, 0xc6b466b5
+0, 132608, 132608, 1792, 28672, 0x34ded4e4
+0, 134400, 134400, 1792, 28672, 0xa882395b
+0, 136192, 136192, 1792, 28672, 0x4181cd56
+0, 137984, 137984, 1792, 28672, 0x7fd2ef9b
+0, 139776, 139776, 1792, 28672, 0xcedcdfd0
+0, 141568, 141568, 1792, 28672, 0xaa74647b
+0, 143360, 143360, 1792, 28672, 0xf7159e6e
+0, 145152, 145152, 1792, 28672, 0x629a2808
+0, 146944, 146944, 1792, 28672, 0x98c5f445
+0, 148736, 148736, 1792, 28672, 0xe6f59ec4
+0, 150528, 150528, 1792, 28672, 0xbbe36f6c
+0, 152320, 152320, 1792, 28672, 0xd4798e38
+0, 154112, 154112, 1792, 28672, 0x6bfd5400
+0, 155904, 155904, 1792, 28672, 0x8b5f72e9
+0, 157696, 157696, 1792, 28672, 0x847e5637
+0, 159488, 159488, 1792, 28672, 0xe4cb8f75
+0, 161280, 161280, 1792, 28672, 0x005b69fc
+0, 163072, 163072, 1792, 28672, 0x5626bd05
+0, 164864, 164864, 1792, 28672, 0x1b3d7d91
+0, 166656, 166656, 1792, 28672, 0x41bb9890
+0, 168448, 168448, 1792, 28672, 0x2867c152
+0, 170240, 170240, 1792, 28672, 0xd34cb130
+0, 172032, 172032, 1792, 28672, 0x8e0231e0
+0, 173824, 173824, 1792, 28672, 0x44091a11
+0, 175616, 175616, 1792, 28672, 0x38a76d79
+0, 177408, 177408, 1792, 28672, 0xa9bf2434
+0, 179200, 179200, 1792, 28672, 0xefd1aa69
+0, 180992, 180992, 1792, 28672, 0x02676349
+0, 182784, 182784, 1792, 28672, 0x5000fa7e
+0, 184576, 184576, 1792, 28672, 0x9ed251d6
+0, 186368, 186368, 1792, 28672, 0x80e8740a
+0, 188160, 188160, 1792, 28672, 0x17af21c8
+0, 189952, 189952, 1792, 28672, 0x60d53ee2
+0, 191744, 191744, 1792, 28672, 0x25c7e866
+0, 193536, 193536, 1792, 28672, 0xe058a7a5
+0, 195328, 195328, 1792, 28672, 0xc23b7195
+0, 197120, 197120, 1792, 28672, 0x1c5e4edf
+0, 198912, 198912, 1792, 28672, 0x6daba516
+0, 200704, 200704, 1792, 28672, 0x9e9434ea
+0, 202496, 202496, 1792, 28672, 0x72be8da3
+0, 204288, 204288, 1792, 28672, 0x0172327d
+0, 206080, 206080, 1792, 28672, 0xc7b6006f
+0, 207872, 207872, 1792, 28672, 0x4378142c
+0, 209664, 209664, 1792, 28672, 0x5ec9bb1a
+0, 211456, 211456, 1792, 28672, 0x74bce720
+0, 213248, 213248, 1792, 28672, 0xbf7cc959
+0, 215040, 215040, 1792, 28672, 0x545ef21b
+0, 216832, 216832, 1792, 28672, 0x8fc6d2c0
diff --git a/tests/ref/acodec/s302m-24-dolbye-20 b/tests/ref/acodec/s302m-24-dolbye-20
new file mode 100644
index 0000000000..e77cf24ded
--- /dev/null
+++ b/tests/ref/acodec/s302m-24-dolbye-20
@@ -0,0 +1,170 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 7.1
+0, 0, 0, 1792, 28672, 0x95445465
+0, 1792, 1792, 1792, 28672, 0x87b4bf1e
+0, 3584, 3584, 1792, 28672, 0x1a29c210
+0, 5376, 5376, 1792, 28672, 0xf616964a
+0, 7168, 7168, 1792, 28672, 0x5d61da52
+0, 8960, 8960, 1792, 28672, 0xa4caee00
+0, 10752, 10752, 1792, 28672, 0x070796bf
+0, 12544, 12544, 1792, 28672, 0x93dc7e75
+0, 14336, 14336, 1792, 28672, 0x2a0b29d9
+0, 16128, 16128, 1792, 28672, 0x2d5fc18b
+0, 17920, 17920, 1792, 28672, 0xc4ffda50
+0, 19712, 19712, 1792, 28672, 0x569cad29
+0, 21504, 21504, 1792, 28672, 0x8ee9be26
+0, 23296, 23296, 1792, 28672, 0x1311c083
+0, 25088, 25088, 1792, 28672, 0x052edc47
+0, 26880, 26880, 1792, 28672, 0xa1c818d7
+0, 28672, 28672, 1792, 28672, 0x9af8a5ad
+0, 30464, 30464, 1792, 28672, 0x721f2943
+0, 32256, 32256, 1792, 28672, 0xb11f5696
+0, 34048, 34048, 1792, 28672, 0xf1687bc0
+0, 35840, 35840, 1792, 28672, 0x65b0b51d
+0, 37632, 37632, 1792, 28672, 0x0b0c03ed
+0, 39424, 39424, 1792, 28672, 0xfcdae7d3
+0, 41216, 41216, 1792, 28672, 0x185cd05f
+0, 43008, 43008, 1792, 28672, 0xc68effa3
+0, 44800, 44800, 1792, 28672, 0x7e049d24
+0, 46592, 46592, 1792, 28672, 0x6de1075f
+0, 48384, 48384, 1792, 28672, 0x3d05cca4
+0, 50176, 50176, 1792, 28672, 0x0f69105b
+0, 51968, 51968, 1792, 28672, 0xa74fa091
+0, 53760, 53760, 1792, 28672, 0xdf7133b8
+0, 55552, 55552, 1792, 28672, 0x926b9501
+0, 57344, 57344, 1792, 28672, 0x3030e01f
+0, 59136, 59136, 1792, 28672, 0xc6972cc4
+0, 60928, 60928, 1792, 28672, 0xae728cbc
+0, 62720, 62720, 1792, 28672, 0x9c67b48b
+0, 64512, 64512, 1792, 28672, 0xc5a959fd
+0, 66304, 66304, 1792, 28672, 0xfdce63e6
+0, 68096, 68096, 1792, 28672, 0x76d4b7ee
+0, 69888, 69888, 1792, 28672, 0xb434cdb9
+0, 71680, 71680, 1792, 28672, 0xf5acbe03
+0, 73472, 73472, 1792, 28672, 0xfc0cd3f3
+0, 75264, 75264, 1792, 28672, 0x8fc77f0e
+0, 77056, 77056, 1792, 28672, 0x696a4e65
+0, 78848, 78848, 1792, 28672, 0x7ba12041
+0, 80640, 80640, 1792, 28672, 0x361cf723
+0, 82432, 82432, 1792, 28672, 0x39e5b0e0
+0, 84224, 84224, 1792, 28672, 0x9ada3053
+0, 86016, 86016, 1792, 28672, 0x0e2b1e6a
+0, 87808, 87808, 1792, 28672, 0xbaee59ab
+0, 89600, 89600, 1792, 28672, 0xb3a4d79a
+0, 91392, 91392, 1792, 28672, 0x27c8c10b
+0, 93184, 93184, 1792, 28672, 0xac80c8b6
+0, 94976, 94976, 1792, 28672, 0x81fdab74
+0, 96768, 96768, 1792, 28672, 0x61616f5b
+0, 98560, 98560, 1792, 28672, 0x52fc6929
+0, 100352, 100352, 1792, 28672, 0x00b3c31f
+0, 102144, 102144, 1792, 28672, 0x42167448
+0, 103936, 103936, 1792, 28672, 0x837e83b7
+0, 105728, 105728, 1792, 28672, 0x85b44868
+0, 107520, 107520, 1792, 28672, 0xadff8622
+0, 109312, 109312, 1792, 28672, 0x431a4e70
+0, 111104, 111104, 1792, 28672, 0x741610e5
+0, 112896, 112896, 1792, 28672, 0x6d028788
+0, 114688, 114688, 1792, 28672, 0xdf965bf7
+0, 116480, 116480, 1792, 28672, 0xaddfb6af
+0, 118272, 118272, 1792, 28672, 0xcb92def7
+0, 120064, 120064, 1792, 28672, 0xd1554d02
+0, 121856, 121856, 1792, 28672, 0x73f4c559
+0, 123648, 123648, 1792, 28672, 0x6f21f1cf
+0, 125440, 125440, 1792, 28672, 0x4db4b98a
+0, 127232, 127232, 1792, 28672, 0x5421dd30
+0, 129024, 129024, 1792, 28672, 0x115c79dc
+0, 130816, 130816, 1792, 28672, 0x8ea20a47
+0, 132608, 132608, 1792, 28672, 0x5cc7442b
+0, 134400, 134400, 1792, 28672, 0x1a56b340
+0, 136192, 136192, 1792, 28672, 0x824b4c80
+0, 137984, 137984, 1792, 28672, 0x1f836508
+0, 139776, 139776, 1792, 28672, 0xf858b763
+0, 141568, 141568, 1792, 28672, 0x06b8e360
+0, 143360, 143360, 1792, 28672, 0xec69151b
+0, 145152, 145152, 1792, 28672, 0x85393407
+0, 146944, 146944, 1792, 28672, 0x67185428
+0, 148736, 148736, 1792, 28672, 0xc949590d
+0, 150528, 150528, 1792, 28672, 0xb51a60c5
+0, 152320, 152320, 1792, 28672, 0x16d97145
+0, 154112, 154112, 1792, 28672, 0xf2e424e8
+0, 155904, 155904, 1792, 28672, 0x966df23d
+0, 157696, 157696, 1792, 28672, 0x4b76484e
+0, 159488, 159488, 1792, 28672, 0x09123aee
+0, 161280, 161280, 1792, 28672, 0xf982c429
+0, 163072, 163072, 1792, 28672, 0x402909fd
+0, 164864, 164864, 1792, 28672, 0xf660b6e7
+0, 166656, 166656, 1792, 28672, 0x4ff88563
+0, 168448, 168448, 1792, 28672, 0xe8390c49
+0, 170240, 170240, 1792, 28672, 0x29c5f5e2
+0, 172032, 172032, 1792, 28672, 0x1728b69c
+0, 173824, 173824, 1792, 28672, 0xb44e116d
+0, 175616, 175616, 1792, 28672, 0x0eef525f
+0, 177408, 177408, 1792, 28672, 0xaaed3647
+0, 179200, 179200, 1792, 28672, 0x5142208e
+0, 180992, 180992, 1792, 28672, 0x0e508d98
+0, 182784, 182784, 1792, 28672, 0xa53bacea
+0, 184576, 184576, 1792, 28672, 0xe0458b56
+0, 186368, 186368, 1792, 28672, 0xf9d854b3
+0, 188160, 188160, 1792, 28672, 0x5cae832d
+0, 189952, 189952, 1792, 28672, 0x6622952f
+0, 191744, 191744, 1792, 28672, 0x6b123bb3
+0, 193536, 193536, 1792, 28672, 0x947bc6a8
+0, 195328, 195328, 1792, 28672, 0x1d49e016
+0, 197120, 197120, 1792, 28672, 0xd7166c77
+0, 198912, 198912, 1792, 28672, 0x079623b0
+0, 200704, 200704, 1792, 28672, 0x00bb8bae
+0, 202496, 202496, 1792, 28672, 0x14f639f0
+0, 204288, 204288, 1792, 28672, 0xeb469a8d
+0, 206080, 206080, 1792, 28672, 0xf6702b9d
+0, 207872, 207872, 1792, 28672, 0x4996a3b4
+0, 209664, 209664, 1792, 28672, 0x8041d137
+0, 211456, 211456, 1792, 28672, 0x2e44983c
+0, 213248, 213248, 1792, 28672, 0x2065a2c9
+0, 215040, 215040, 1792, 28672, 0x90be25e7
+0, 216832, 216832, 1792, 28672, 0x5d31a6c4
+0, 218624, 218624, 1792, 28672, 0x6b6e452c
+0, 220416, 220416, 1792, 28672, 0xc836bd59
+0, 222208, 222208, 1792, 28672, 0x13575340
+0, 224000, 224000, 1792, 28672, 0x0f42a7cb
+0, 225792, 225792, 1792, 28672, 0xba0bbb76
+0, 227584, 227584, 1792, 28672, 0x7d251bd6
+0, 229376, 229376, 1792, 28672, 0x4c0d7d4e
+0, 231168, 231168, 1792, 28672, 0x9f812c3d
+0, 232960, 232960, 1792, 28672, 0xf48e7e24
+0, 234752, 234752, 1792, 28672, 0x89cc47c4
+0, 236544, 236544, 1792, 28672, 0xbe6c913a
+0, 238336, 238336, 1792, 28672, 0x3783546e
+0, 240128, 240128, 1792, 28672, 0xd73d62d2
+0, 241920, 241920, 1792, 28672, 0x8473ffd1
+0, 243712, 243712, 1792, 28672, 0x353ae430
+0, 245504, 245504, 1792, 28672, 0xbc74d0d6
+0, 247296, 247296, 1792, 28672, 0x67dd42ba
+0, 249088, 249088, 1792, 28672, 0x32c28b0f
+0, 250880, 250880, 1792, 28672, 0x6798ba73
+0, 252672, 252672, 1792, 28672, 0x2342e18e
+0, 254464, 254464, 1792, 28672, 0x93c30e5b
+0, 256256, 256256, 1792, 28672, 0x521b4c34
+0, 258048, 258048, 1792, 28672, 0x4ff173fb
+0, 259840, 259840, 1792, 28672, 0x144cd84d
+0, 261632, 261632, 1792, 28672, 0x0b79131a
+0, 263424, 263424, 1792, 28672, 0x8136d27a
+0, 265216, 265216, 1792, 28672, 0xcc62b7d5
+0, 267008, 267008, 1792, 28672, 0xbdab12f7
+0, 268800, 268800, 1792, 28672, 0x71455124
+0, 270592, 270592, 1792, 28672, 0x0d05b187
+0, 272384, 272384, 1792, 28672, 0xa734c089
+0, 274176, 274176, 1792, 28672, 0xb18695ca
+0, 275968, 275968, 1792, 28672, 0x9401890d
+0, 277760, 277760, 1792, 28672, 0x0d719e68
+0, 279552, 279552, 1792, 28672, 0x0415a6aa
+0, 281344, 281344, 1792, 28672, 0x23cfd606
+0, 283136, 283136, 1792, 28672, 0x37fd4513
+0, 284928, 284928, 1792, 28672, 0xcbcc645c
+0, 286720, 286720, 1792, 28672, 0x478d37fe
+0, 288512, 288512, 1792, 28672, 0xb354ea3b
+0, 290304, 290304, 1792, 28672, 0x8d769c69
+0, 292096, 292096, 1792, 28672, 0x60068eed
+0, 293888, 293888, 1792, 28672, 0x1fd254b4
--
2.39.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding
2024-01-27 10:38 [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
2024-01-27 10:38 ` [FFmpeg-devel] [PATCH v2 2/2] fate: add tests for dolby_e decoding in s302m Gyan Doshi
@ 2024-02-13 16:40 ` Gyan Doshi
1 sibling, 0 replies; 3+ messages in thread
From: Gyan Doshi @ 2024-02-13 16:40 UTC (permalink / raw)
To: ffmpeg-devel
On 2024-01-27 04:08 pm, Gyan Doshi wrote:
> Set up framework for non-PCM decoding in-place and
> add support for Dolby-E decoding.
>
> Useful for direct transcoding of non-PCM audio in live inputs.
Plan to push in 3 days, barring objections.
Regards,
Gyan
> ---
> configure | 1 +
> doc/decoders.texi | 40 +++
> libavcodec/s302m.c | 596 +++++++++++++++++++++++++++++++++++++--------
> 3 files changed, 530 insertions(+), 107 deletions(-)
>
> v2:
> switch to pointer for non-pcm sync search
> use intreadwrite macro for writing frame data
> remove unneeded free of non-pcm dec opts
>
> diff --git a/configure b/configure
> index 21663000f8..4d7cd83247 100755
> --- a/configure
> +++ b/configure
> @@ -2980,6 +2980,7 @@ rv20_decoder_select="h263_decoder"
> rv20_encoder_select="h263_encoder"
> rv30_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
> rv40_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
> +s302m_decoder_select="dolby_e_decoder"
> screenpresso_decoder_deps="zlib"
> shorten_decoder_select="bswapdsp"
> sipr_decoder_select="lsp"
> diff --git a/doc/decoders.texi b/doc/decoders.texi
> index 293c82c2ba..9f85c876bf 100644
> --- a/doc/decoders.texi
> +++ b/doc/decoders.texi
> @@ -347,6 +347,46 @@ configuration. You need to explicitly configure the build with
> An FFmpeg native decoder for Opus exists, so users can decode Opus
> without this library.
>
> +@section s302m
> +
> +SMPTE ST 302 decoder.
> +
> +SMPTE ST 302 is a method for storing AES3 data format within an MPEG Transport
> +Stream. AES3 streams can contain LPCM streams of 2, 4, 6 or 8 channels with a
> +bit depth of 16, 20 or 24-bits at a sample rate of 48 kHz.
> +They can also contain non-PCM codec streams such as AC-3 or Dolby-E.
> +
> +Decoding non-PCM streams directly requires that the necessary stream decoder be
> +present in the build. At present, only Dolby-E decoding is supported.
> +
> +@subsection Options
> +
> +The following options are supported by the s302m decoder.
> +
> +@table @option
> +@item non_pcm_mode @var{mode}
> +Specify how to process non-PCM streams
> +
> +@table @samp
> +@item copy
> +Treat data as if it were LPCM.
> +@item drop
> +Discard the stream.
> +@item decode_copy
> +Decode if possible eise treat the same as @code{copy}.
> +@item decode_drop
> +Decode if possible eise treat the same as @code{drop}.
> +@end table
> +
> +The default value is @code{decode_drop}. This option does not affect the processing of
> +LPCM streams.
> +
> +@item non_pcm_options @var{options}
> +Set options for non-PCM decoder using a list of key=value pairs separated by ":".
> +Consult the docs for the non-PCM decoder for its options.
> +
> +@end table
> +
> @c man end AUDIO DECODERS
>
> @chapter Subtitles Decoders
> diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
> index f1b41608f3..d890b6f117 100644
> --- a/libavcodec/s302m.c
> +++ b/libavcodec/s302m.c
> @@ -24,21 +24,264 @@
> #include "libavutil/intreadwrite.h"
> #include "libavutil/opt.h"
> #include "libavutil/log.h"
> +#include "libavutil/dict.h"
> #include "libavutil/reverse.h"
> #include "avcodec.h"
> #include "codec_internal.h"
> +#include "get_bits.h"
> #include "decode.h"
>
> #define AES3_HEADER_LEN 4
>
> +#define NONPCMSYNC_16MARKER 0x4E1F0F8720
> +#define NONPCMSYNC_20MARKER 0x4E1F60F872A0
> +#define NONPCMSYNC_24MARKER 0x7E1F690F872A50
> +
> +#define NONPCMSYNC_16_IN_20MARKER 0x04E1F00F8720
> +#define NONPCMSYNC_20_IN_24MARKER 0x04E1F600F872A0
> +
> +#define IS_NONPCMSYNC_16(state) ((state & 0xFFFF0FFFF0) == NONPCMSYNC_16MARKER)
> +#define IS_NONPCMSYNC_20(state) ((state & 0xFFFFF0FFFFF0) == NONPCMSYNC_20MARKER)
> +#define IS_NONPCMSYNC_24(state) ((state & 0xFFFFFF0FFFFFF0) == NONPCMSYNC_24MARKER)
> +
> +#define IS_NONPCMSYNC_16_IN_20(state) ((state & 0x0FFFF00FFFF0) == NONPCMSYNC_16_IN_20MARKER)
> +#define IS_NONPCMSYNC_20_IN_24(state) ((state & 0x0FFFFF00FFFFF0) == NONPCMSYNC_20_IN_24MARKER)
> +
> +#define IS_NONPCMSYNC(bit,state) ( ((bit == 16) && IS_NONPCMSYNC_16(state)) || \
> + ((bit == 20) && (IS_NONPCMSYNC_20(state) || IS_NONPCMSYNC_16_IN_20(state))) || \
> + ((bit == 24) && (IS_NONPCMSYNC_24(state) || IS_NONPCMSYNC_20_IN_24(state))) \
> + )
> +
> +enum non_pcm_modes {
> + NON_PCM_COPY,
> + NON_PCM_DROP,
> + NON_PCM_DEC_ELSE_COPY,
> + NON_PCM_DEC_ELSE_DROP,
> +};
> +
> typedef struct S302Context {
> AVClass *class;
> +
> + int avctx_props_set;
> +
> + int channels;
> + int bits;
> +
> int non_pcm_mode;
> + int non_pcm_data_type;
> + int non_pcm_bits;
> + int non_pcm_dec;
> +
> + AVCodecContext *non_pcm_ctx;
> + AVDictionary *non_pcm_opts;
> + AVPacket *packet;
> + AVFrame *frame;
> } S302Context;
>
> +static av_cold int s302m_init(AVCodecContext *avctx)
> +{
> + S302Context *s = avctx->priv_data;
> +
> + s->non_pcm_data_type = -1;
> +
> + return 0;
> +}
> +
> +static int s302m_non_pcm_inspect(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
> + int *offset, int *length)
> +{
> + S302Context *s = avctx->priv_data;
> + const uint8_t *pos = buf;
> + int ret, aes_frm_size, data_type, length_code = 0, pkt_left = buf_size;
> + uint64_t state = 0;
> + uint32_t size;
> +
> + if (s->channels != 2) {
> + goto end;
> + }
> +
> + aes_frm_size = (s->bits + 4) * 2 / 8;
> + if (pkt_left < aes_frm_size * 2) // not enough to contain data_type & length_code
> + return AVERROR_INVALIDDATA;
> +
> + while (!IS_NONPCMSYNC(s->bits,state) && pkt_left-- >= 1)
> + state = (state << 8) | *pos++;
> +
> + if (IS_NONPCMSYNC(s->bits,state)) {
> + GetBitContext gb;
> +
> + if (pkt_left < aes_frm_size * 8) {
> + av_log(avctx, AV_LOG_ERROR, "truncated non-pcm frame detected\n");
> + return AVERROR_INVALIDDATA;
> + }
> +
> + ret = init_get_bits8(&gb, pos, aes_frm_size);
> + if (ret < 0)
> + return ret;
> +
> + if (s->bits == 16) {
> + s->non_pcm_bits = 16;
> + } else if (s->bits == 20) {
> + if (IS_NONPCMSYNC_16_IN_20(state))
> + s->non_pcm_bits = 16;
> + else
> + s->non_pcm_bits = 20;
> + } else if (s->bits == 24) {
> + if (IS_NONPCMSYNC_20_IN_24(state))
> + s->non_pcm_bits = 20;
> + else
> + s->non_pcm_bits = 24;
> + }
> +
> + skip_bits(&gb, s->bits - 16);
> +
> + data_type = ff_reverse[(uint8_t)get_bits(&gb, 5)] >> 3;
> +
> + if (s->non_pcm_data_type == -1) {
> + s->non_pcm_data_type = data_type;
> + av_log(avctx, AV_LOG_INFO, "stream has non-pcm data of type %d with %d-bit words in aes3 payload of size %d bits\n", data_type, s->non_pcm_bits, s->bits);
> + } else if (s->non_pcm_data_type != data_type) {
> + av_log(avctx, AV_LOG_DEBUG, "type mismatch of non-pcm type in packet %d vs stream %d. Dropping.\n", data_type, s->non_pcm_data_type);
> + return AVERROR_INVALIDDATA;
> + }
> +
> + if (s->non_pcm_mode == NON_PCM_COPY)
> + return 0;
> + else if (s->non_pcm_mode == NON_PCM_DROP)
> + return AVERROR_INVALIDDATA;
> +
> + skip_bits(&gb, 15);
> +
> + size = get_bits(&gb, s->bits);
> +
> + length_code = ((ff_reverse[(uint8_t)((size & 0xFF) )] << 16) |
> + (ff_reverse[(uint8_t)((size & 0xFF00) >> 8 )] << 8 ) |
> + (ff_reverse[(uint8_t)((size & 0xFF0000) >> 16)] ) ) >> (24 - s->non_pcm_bits);
> +
> + skip_bits(&gb, 4);
> +
> + *offset = get_bits_count(&gb)/8 + buf_size - pkt_left;
> + *length = length_code;
> +
> + av_log(avctx, AV_LOG_TRACE, "located non-pcm packet at offset %d length code %d.\n", AES3_HEADER_LEN + *offset, length_code);
> +
> + return data_type;
> + }
> +
> +end:
> + if (s->non_pcm_data_type == -1) {
> + s->non_pcm_data_type = 32; // indicate stream should be treated as LPCM
> + return 0;
> + } else
> + return AVERROR_INVALIDDATA;
> +}
> +
> +static int s302m_setup_non_pcm_handling(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
> +{
> + S302Context *s = avctx->priv_data;
> + const AVCodec *codec;
> + enum AVCodecID codec_id;
> + AVDictionary *dec_opts = NULL;
> + int ret;
> +
> + if (s->non_pcm_mode > NON_PCM_DROP) {
> + switch (s->non_pcm_data_type) {
> + case 0x1C:
> + codec_id = AV_CODEC_ID_DOLBY_E;
> + break;
> + default:
> + avpriv_report_missing_feature(avctx, "decode of non-pcm data type %d", s->non_pcm_data_type);
> + ret = AVERROR_PATCHWELCOME;
> + goto fail;
> + }
> +
> + codec = avcodec_find_decoder(codec_id);
> + if (!codec) {
> + ret = AVERROR_DECODER_NOT_FOUND;
> + goto fail;
> + }
> +
> + s->non_pcm_ctx = avcodec_alloc_context3(codec);
> + if (!s->non_pcm_ctx) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> +
> + av_dict_copy(&dec_opts, s->non_pcm_opts, 0);
> +
> + ret = avcodec_open2(s->non_pcm_ctx, codec, &dec_opts);
> + av_dict_free(&dec_opts);
> + if (ret < 0)
> + goto fail;
> +
> + s->packet = av_packet_alloc();
> + if (!s->packet) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> +
> + s->frame = av_frame_alloc();
> + if (!s->frame) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + } else
> + return 0;
> +
> + s->non_pcm_dec = 1;
> + return 0;
> +
> +fail:
> + avcodec_free_context(&s->non_pcm_ctx);
> + av_packet_free(&s->packet);
> + av_frame_free(&s->frame);
> +
> + if (s->non_pcm_mode == NON_PCM_DEC_ELSE_COPY)
> + s->non_pcm_mode = NON_PCM_COPY;
> + else if (s->non_pcm_mode == NON_PCM_DEC_ELSE_DROP)
> + s->non_pcm_mode = NON_PCM_DROP;
> +
> + return ret;
> +}
> +
> +static int s302m_get_non_pcm_pkt_size(AVCodecContext *avctx, int buf_size, int offset,
> + int length_code, int *dec_pkt_size)
> +{
> + S302Context *s = avctx->priv_data;
> + int nb_words, word_size, aesframe_size, s302m_read_size;
> +
> + if (offset < 0 || offset >= buf_size)
> + return AVERROR_INVALIDDATA;
> +
> + switch (s->non_pcm_data_type) {
> + case 0x1C:
> + goto dolby_e;
> + default:
> + return AVERROR_INVALIDDATA;
> + }
> +
> +dolby_e:
> + {
> + nb_words = length_code / s->non_pcm_bits;
> + nb_words += nb_words & 1;
> +
> + word_size = s->non_pcm_bits + 7 >> 3;
> + aesframe_size = (s->bits + 4) * 2 / 8; // 2 subframes, each with payload + VUCF bits
> +
> + *dec_pkt_size = nb_words * word_size;
> + s302m_read_size = aesframe_size * nb_words/2;
> +
> + if (offset + s302m_read_size > buf_size)
> + return AVERROR_INVALIDDATA;
> +
> + return s302m_read_size;
> + }
> +}
> +
> static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
> int buf_size)
> {
> + S302Context *s = avctx->priv_data;
> uint32_t h;
> int frame_size, channels, bits;
>
> @@ -66,33 +309,15 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
> return AVERROR_INVALIDDATA;
> }
>
> - /* Set output properties */
> - avctx->bits_per_raw_sample = bits;
> - if (bits > 16)
> - avctx->sample_fmt = AV_SAMPLE_FMT_S32;
> - else
> - avctx->sample_fmt = AV_SAMPLE_FMT_S16;
> -
> - av_channel_layout_uninit(&avctx->ch_layout);
> - switch(channels) {
> - case 2:
> - avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
> - break;
> - case 4:
> - avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
> - break;
> - case 6:
> - avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
> - break;
> - case 8:
> - av_channel_layout_from_mask(&avctx->ch_layout,
> - AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
> - break;
> - default:
> - avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
> - avctx->ch_layout.nb_channels = channels;
> - break;
> - }
> + if (!s->channels)
> + s->channels = channels;
> + else if (s->channels != channels)
> + return AVERROR_INVALIDDATA;
> +
> + if (!s->bits)
> + s->bits = bits;
> + else if (s->bits != bits)
> + return AVERROR_INVALIDDATA;
>
> return frame_size;
> }
> @@ -103,119 +328,273 @@ static int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame,
> S302Context *s = avctx->priv_data;
> const uint8_t *buf = avpkt->data;
> int buf_size = avpkt->size;
> - int block_size, ret, channels;
> - int i;
> - int non_pcm_data_type = -1;
> + int block_size, ret, channels, frame_size;
> + int non_pcm_offset = -1, non_pcm_length = 0;
> + int dec_pkt_size = 0;
>
> - int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
> + if (s->non_pcm_mode == NON_PCM_DROP && s->non_pcm_data_type != -1 && s->non_pcm_data_type != 32)
> + return avpkt->size;
> +
> + frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
> if (frame_size < 0)
> return frame_size;
>
> buf_size -= AES3_HEADER_LEN;
> buf += AES3_HEADER_LEN;
>
> - /* get output buffer */
> - block_size = (avctx->bits_per_raw_sample + 4) / 4;
> - channels = avctx->ch_layout.nb_channels;
> - frame->nb_samples = 2 * (buf_size / block_size) / channels;
> - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
> - return ret;
> + // set non-pcm status if not determined
> + // else extract offset and length if non-pcm can be decoded
> + if (s->non_pcm_data_type == -1 || s->non_pcm_dec) {
> + ret = s302m_non_pcm_inspect(avctx, buf, buf_size, &non_pcm_offset, &non_pcm_length);
> + if (ret >= 0 && s->non_pcm_data_type != 32 && !s->non_pcm_dec)
> + ret = s302m_setup_non_pcm_handling(avctx, buf, buf_size);
> + else if (ret < 0)
> + return avpkt->size;
> + }
> +
> + if (s->non_pcm_data_type == -1)
> + return AVERROR_INVALIDDATA; // we should know data type in order to proceed with output
> +
> + if (!s->non_pcm_dec && !s->avctx_props_set) {
> + /* Set output properties */
> + avctx->bits_per_raw_sample = s->non_pcm_bits ? s->non_pcm_bits : s->bits;
> + if (avctx->bits_per_raw_sample > 16)
> + avctx->sample_fmt = AV_SAMPLE_FMT_S32;
> + else
> + avctx->sample_fmt = AV_SAMPLE_FMT_S16;
>
> - avctx->bit_rate = 48000 * channels * (avctx->bits_per_raw_sample + 4) +
> - 32 * 48000 / frame->nb_samples;
> - buf_size = (frame->nb_samples * channels / 2) * block_size;
> + av_channel_layout_uninit(&avctx->ch_layout);
> + switch(s->channels) {
> + case 2:
> + avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
> + break;
> + case 4:
> + avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
> + break;
> + case 6:
> + avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
> + break;
> + case 8:
> + av_channel_layout_from_mask(&avctx->ch_layout,
> + AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
> + break;
> + default:
> + avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
> + avctx->ch_layout.nb_channels = channels;
> + break;
> + }
> +
> + avctx->sample_rate = 48000;
> + s->avctx_props_set = 1;
> + }
> +
> + if (s->non_pcm_dec) {
> + buf_size = s302m_get_non_pcm_pkt_size(avctx, buf_size, non_pcm_offset, non_pcm_length, &dec_pkt_size);
> + if (buf_size < 0)
> + return AVERROR_INVALIDDATA;
> + buf += non_pcm_offset;
> +
> + if (dec_pkt_size > s->packet->size) {
> + ret = av_grow_packet(s->packet, dec_pkt_size - s->packet->size);
> + if (ret < 0)
> + return ret;
> + }
> + ret = av_packet_make_writable(s->packet);
> + if (ret < 0)
> + return ret;
> + memset(s->packet->data, 0, s->packet->size);
> +
> + ret = av_packet_copy_props(s->packet, avpkt);
> + if (ret < 0)
> + return ret;
> + } else {
> + /* get output buffer */
> + block_size = (s->bits + 4) / 4;
> + channels = s->channels;
> + frame->nb_samples = 2 * (buf_size / block_size) / channels;
> + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
> + return ret;
> +
> + buf_size = (frame->nb_samples * channels / 2) * block_size;
> +
> + avctx->bit_rate = 48000 * s->channels * ((s->non_pcm_bits ? s->non_pcm_bits : s->bits) + 4) +
> + 32 * 48000 / frame->nb_samples;
> + }
> +
> + if (s->bits == 24) {
> + uint8_t *p = NULL;
> + uint32_t *f32 = NULL;
> +
> + if (s->non_pcm_dec)
> + p = (uint8_t *)s->packet->data;
> + else
> + f32 = (uint32_t *)frame->data[0];
>
> - if (avctx->bits_per_raw_sample == 24) {
> - uint32_t *o = (uint32_t *)frame->data[0];
> for (; buf_size > 6; buf_size -= 7) {
> - *o++ = ((unsigned)ff_reverse[buf[2]] << 24) |
> - (ff_reverse[buf[1]] << 16) |
> - (ff_reverse[buf[0]] << 8);
> - *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) |
> - (ff_reverse[buf[5]] << 20) |
> - (ff_reverse[buf[4]] << 12) |
> - (ff_reverse[buf[3] & 0x0f] << 4);
> + uint8_t b[6];
> +
> + b[0] = (ff_reverse[buf[2] ] ) ;
> + b[1] = (ff_reverse[buf[1] ] ) ;
> + b[2] = (ff_reverse[buf[0] ] ) ;
> + b[3] = (ff_reverse[buf[6] & 0xf0] << 4) |
> + (ff_reverse[buf[5] & 0x0f] >> 4) ;
> + b[4] = (ff_reverse[buf[5] & 0xf0] << 4) |
> + (ff_reverse[buf[4] & 0x0f] >> 4) ;
> + b[5] = (ff_reverse[buf[4] & 0xf0] << 4) |
> + (ff_reverse[buf[3] & 0x0f] >> 4) ;
> +
> + if (s->non_pcm_bits == 20) {
> + b[2] &= 0xf0;
> + b[5] &= 0xf0;
> + }
> +
> + if (s->non_pcm_dec)
> + for (int i = 0; i < 6; i++)
> + *p++ = b[i];
> + else {
> + *f32++ = AV_RB24(&b[0]) << 8;
> + *f32++ = AV_RB24(&b[3]) << 8;
> + }
> buf += 7;
> }
> - o = (uint32_t *)frame->data[0];
> - if (channels == 2)
> - for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
> - if (o[i] || o[i+1] || o[i+2] || o[i+3])
> - break;
> - if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
> - non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
> - break;
> + } else if (s->bits == 20) {
> + uint8_t *p = NULL;
> + uint16_t *f16 = NULL;
> + uint32_t *f32 = NULL;
> +
> + if (s->non_pcm_dec)
> + p = (uint8_t *)s->packet->data;
> + else if (s->non_pcm_bits == 16)
> + f16 = (uint16_t *)frame->data[0];
> + else
> + f32 = (uint32_t *)frame->data[0];
> +
> + for (; buf_size > 5; buf_size -= 6) {
> + uint8_t b[6];
> +
> + b[0] = (ff_reverse[buf[2] & 0xf0] << 4) |
> + (ff_reverse[buf[1] & 0x0f] >> 4) ;
> + b[1] = (ff_reverse[buf[1] & 0xf0] << 4) |
> + (ff_reverse[buf[0] & 0x0f] >> 4) ;
> + b[2] = (ff_reverse[buf[0] & 0xf0] << 4) ;
> + b[3] = (ff_reverse[buf[5] & 0xf0] << 4) |
> + (ff_reverse[buf[4] & 0x0f] >> 4) ;
> + b[4] = (ff_reverse[buf[4] & 0xf0] << 4) |
> + (ff_reverse[buf[3] & 0x0f] >> 4) ;
> + b[5] = (ff_reverse[buf[3] & 0xf0] << 4) ;
> +
> + if (s->non_pcm_dec) {
> + for (int i = 0; i < 6; i++) {
> + if (s->non_pcm_bits == 16 && (i % 3 == 2))
> + continue;
> + *p++ = b[i];
> }
> + } else if (s->non_pcm_bits == 16) {
> + *f16++ = AV_RB16(&b[0]);
> + *f16++ = AV_RB16(&b[3]);
> + } else {
> + *f32++ = AV_RB24(&b[0]) << 8;
> + *f32++ = AV_RB24(&b[3]) << 8;
> }
> - } else if (avctx->bits_per_raw_sample == 20) {
> - uint32_t *o = (uint32_t *)frame->data[0];
> - for (; buf_size > 5; buf_size -= 6) {
> - *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) |
> - (ff_reverse[buf[1]] << 20) |
> - (ff_reverse[buf[0]] << 12);
> - *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) |
> - (ff_reverse[buf[4]] << 20) |
> - (ff_reverse[buf[3]] << 12);
> buf += 6;
> }
> - o = (uint32_t *)frame->data[0];
> - if (channels == 2)
> - for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
> - if (o[i] || o[i+1] || o[i+2] || o[i+3])
> - break;
> - if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
> - non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
> - break;
> - }
> - }
> } else {
> - uint16_t *o = (uint16_t *)frame->data[0];
> + uint8_t *p = NULL;
> + uint16_t *f16 = NULL;
> +
> + if (s->non_pcm_dec)
> + p = (uint8_t *)s->packet->data;
> + else
> + f16 = (uint16_t *)frame->data[0];
> +
> for (; buf_size > 4; buf_size -= 5) {
> - *o++ = (ff_reverse[buf[1]] << 8) |
> - ff_reverse[buf[0]];
> - *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
> - (ff_reverse[buf[3]] << 4) |
> - (ff_reverse[buf[2]] >> 4);
> + uint8_t b[4];
> +
> + b[0] = (ff_reverse[buf[1] ] ) ;
> + b[1] = (ff_reverse[buf[0] ] ) ;
> + b[2] = (ff_reverse[buf[4] & 0xf0] << 4) |
> + (ff_reverse[buf[3] & 0x0f] >> 4) ;
> + b[3] = (ff_reverse[buf[3] & 0xf0] << 4) |
> + (ff_reverse[buf[2] & 0x0f] >> 4) ;
> +
> + if (s->non_pcm_dec)
> + for (int i = 0; i < 4; i++)
> + *p++ = b[i];
> + else {
> + *f16++ = AV_RB16(&b[0]);
> + *f16++ = AV_RB16(&b[2]);
> + }
> buf += 5;
> }
> - o = (uint16_t *)frame->data[0];
> - if (channels == 2)
> - for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
> - if (o[i] || o[i+1] || o[i+2] || o[i+3])
> - break;
> - if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
> - non_pcm_data_type = (o[i+6] & 0x1F);
> - break;
> - }
> - }
> }
>
> - if (non_pcm_data_type != -1) {
> - if (s->non_pcm_mode == 3) {
> - av_log(avctx, AV_LOG_ERROR,
> - "S302 non PCM mode with data type %d not supported\n",
> - non_pcm_data_type);
> - return AVERROR_PATCHWELCOME;
> + if (s->non_pcm_dec) {
> + ret = avcodec_send_packet(s->non_pcm_ctx, s->packet);
> + if (ret < 0) {
> + av_log(avctx, AV_LOG_ERROR, "error %d submitting non-pcm packet with pts %"PRId64" for decoding\n", ret, s->packet->pts);
> + return ret;
> }
> - if (s->non_pcm_mode & 1) {
> - return avpkt->size;
> + ret = avcodec_receive_frame(s->non_pcm_ctx, s->frame);
> + if (ret < 0) {
> + av_log(avctx, AV_LOG_ERROR, "error %d receiving non-pcm decoded frame for packet with pts %"PRId64"\n", ret, s->packet->pts);
> + return ret;
> }
> - }
>
> - avctx->sample_rate = 48000;
> + if (!s->avctx_props_set) {
> + avctx->sample_fmt = s->non_pcm_ctx->sample_fmt;
> + avctx->sample_rate = s->non_pcm_ctx->sample_rate;
> +
> + av_channel_layout_uninit(&avctx->ch_layout);
> + ret = av_channel_layout_copy(&avctx->ch_layout, &s->non_pcm_ctx->ch_layout);
> + if (ret < 0) {
> + av_log(avctx, AV_LOG_ERROR, "error %d when copying channel layout from non-pcm decoder context to parent context.\n", ret);
> + return ret;
> + }
> + s->avctx_props_set = 1;
> + }
> +
> + frame->nb_samples = s->frame->nb_samples;
> + ret = ff_get_buffer(avctx, frame, 0);
> + if (ret < 0)
> + return ret;
> +
> + for (int ch = 0; ch < s->frame->ch_layout.nb_channels; ch++)
> + memcpy(frame->extended_data[ch], s->frame->extended_data[ch],
> + av_get_bytes_per_sample(s->non_pcm_ctx->sample_fmt) * s->frame->nb_samples);
> + }
>
> *got_frame_ptr = 1;
>
> return avpkt->size;
> }
>
> +static void s302m_flush(AVCodecContext *avctx)
> +{
> + S302Context *s = avctx->priv_data;
> +
> + if (s->non_pcm_dec && s->non_pcm_ctx)
> + avcodec_flush_buffers(s->non_pcm_ctx);
> +}
> +
> +static av_cold int s302m_close(AVCodecContext *avctx)
> +{
> + S302Context *s = avctx->priv_data;
> +
> + avcodec_free_context(&s->non_pcm_ctx);
> + av_packet_free(&s->packet);
> + av_frame_free(&s->frame);
> +
> + return 0;
> +}
> +
> #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
> static const AVOption s302m_options[] = {
> - {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
> - {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"},
> - {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"},
> - {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"},
> - {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
> + {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = NON_PCM_DEC_ELSE_DROP}, NON_PCM_COPY, NON_PCM_DEC_ELSE_DROP, FLAGS, "non_pcm_mode"},
> + {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_COPY}, 0, 3, FLAGS, "non_pcm_mode"},
> + {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DROP}, 0, 3, FLAGS, "non_pcm_mode"},
> + {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_COPY}, 0, 3, FLAGS, "non_pcm_mode"},
> + {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_DROP}, 0, 3, FLAGS, "non_pcm_mode"},
> + {"non_pcm_options", "Set options for non-pcm decoder", offsetof(S302Context, non_pcm_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
> {NULL}
> };
>
> @@ -231,6 +610,9 @@ const FFCodec ff_s302m_decoder = {
> CODEC_LONG_NAME("SMPTE 302M"),
> .p.type = AVMEDIA_TYPE_AUDIO,
> .p.id = AV_CODEC_ID_S302M,
> + .init = s302m_init,
> + .close = s302m_close,
> + .flush = s302m_flush,
> .p.priv_class = &s302m_class,
> .priv_data_size = sizeof(S302Context),
> FF_CODEC_DECODE_CB(s302m_decode_frame),
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-02-13 16:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-27 10:38 [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
2024-01-27 10:38 ` [FFmpeg-devel] [PATCH v2 2/2] fate: add tests for dolby_e decoding in s302m Gyan Doshi
2024-02-13 16:40 ` [FFmpeg-devel] [PATCH v2 1/2] avcodec/s302m: enable non-PCM decoding Gyan Doshi
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git