* [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