[FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder
* Multichannel support for TrueHD is experimental There should be downmix substreams present for 2+ channel bitstreams, but ffmpeg decoder doesn't need it. Will add support for this soon. * There might be lossless check failures on LFE channels * 32-bit sample support has been removed for now, will add it later While testing, some samples gave lossless check failures when enforcing s32. Probably this will also get solved with other lossless issues. Signed-off-by: Jai Luthra --- libavcodec/Makefile|2 + libavcodec/allcodecs.c |4 +- libavcodec/mlp.c | 21 + libavcodec/mlp.h | 40 + libavcodec/mlpenc.c| 2416 5 files changed, 2481 insertions(+), 2 deletions(-) create mode 100644 libavcodec/mlpenc.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index abef19e..b5a10a0 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -382,6 +382,7 @@ OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o +OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o @@ -544,6 +545,7 @@ OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o ti OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o +OBJS-$(CONFIG_TRUEHD_ENCODER) += mlpenc.o OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o OBJS-$(CONFIG_TRUEMOTION2RT_DECODER) += truemotion2rt.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 951e199..e4ab8b3 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -419,7 +419,7 @@ void avcodec_register_all(void) REGISTER_DECODER(MACE3, mace3); REGISTER_DECODER(MACE6, mace6); REGISTER_DECODER(METASOUND, metasound); -REGISTER_DECODER(MLP, mlp); +REGISTER_ENCDEC (MLP, mlp); REGISTER_DECODER(MP1, mp1); REGISTER_DECODER(MP1FLOAT, mp1float); REGISTER_ENCDEC (MP2, mp2); @@ -448,7 +448,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (SONIC, sonic); REGISTER_ENCODER(SONIC_LS, sonic_ls); REGISTER_DECODER(TAK, tak); -REGISTER_DECODER(TRUEHD,truehd); +REGISTER_ENCDEC (TRUEHD,truehd); REGISTER_DECODER(TRUESPEECH,truespeech); REGISTER_ENCDEC (TTA, tta); REGISTER_DECODER(TWINVQ,twinvq); diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c index 87f7c77..ddbab60 100644 --- a/libavcodec/mlp.c +++ b/libavcodec/mlp.c @@ -41,6 +41,27 @@ const uint8_t ff_mlp_huffman_tables[3][18][2] = { } }; +const ChannelInformation ff_mlp_ch_info[21] = { +{ 0x01, 0x01, 0x00, 0x1f }, { 0x03, 0x02, 0x00, 0x1b }, +{ 0x07, 0x02, 0x01, 0x1f }, { 0x0F, 0x02, 0x02, 0x19 }, +{ 0x07, 0x02, 0x01, 0x03 }, { 0x0F, 0x02, 0x02, 0x1f }, +{ 0x1F, 0x02, 0x03, 0x01 }, { 0x07, 0x02, 0x01, 0x1a }, +{ 0x0F, 0x02, 0x02, 0x1f }, { 0x1F, 0x02, 0x03, 0x18 }, +{ 0x0F, 0x02, 0x02, 0x02 }, { 0x1F, 0x02, 0x03, 0x1f }, +{ 0x3F, 0x02, 0x04, 0x00 }, { 0x0F, 0x03, 0x01, 0x1f }, +{ 0x1F, 0x03, 0x02, 0x18 }, { 0x0F, 0x03, 0x01, 0x02 }, +{ 0x1F, 0x03, 0x02, 0x1f }, { 0x3F, 0x03, 0x03, 0x00 }, +{ 0x1F, 0x04, 0x01, 0x01 }, { 0x1F, 0x04, 0x01, 0x18 }, +{ 0x3F, 0x04, 0x02, 0x00 }, +}; + +const uint64_t ff_mlp_channel_layouts[12] = { +AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_2_1, +AV_CH_LAYOUT_QUAD, AV_CH_LAYOUT_2POINT1, AV_CH_LAYOUT_SURROUND, +AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_3POINT1, +AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0, +}; + static int crc_init = 0; #if CONFIG_SMALL #define CRC_TABLE_SIZE 257 diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h index 05d8dba..41a45a3 100644 --- a/libavcodec/mlp.h +++ b/libavcodec/mlp.h @@ -76,6 +76,9 @@ typedef struct FilterParams { uint8_t shift; ///< Right shift to apply to output of filter. int32_t state[MAX_FIR_ORDER]; + +int coeff_bits; +int coeff_shift; } FilterParams; /** sample data coding information */ @@ -96,6 +99,43 @@ typedef struct ChannelParams { */ extern const uint8_t ff_mlp_huffman_tables[3][18][2]; +typedef struct { +uint8_t channel_occupancy; +uint8_t group1_channels; +uint8_t group2_channels; +uint8_t summary_info; +} ChannelInformation; + +/** Tables defining chan
Re: [FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder
On Tue, Aug 23, 2016 at 02:33:00AM +0530, Jai Luthra wrote: > * Multichannel support for TrueHD is experimental > > There should be downmix substreams present for 2+ channel bitstreams, > but ffmpeg decoder doesn't need it. Will add support for this soon. > > * There might be lossless check failures on LFE channels > > * 32-bit sample support has been removed for now, will add it later > > While testing, some samples gave lossless check failures when enforcing > s32. Probably this will also get solved with other lossless issues. > > Signed-off-by: Jai Luthra > --- > libavcodec/Makefile|2 + > libavcodec/allcodecs.c |4 +- > libavcodec/mlp.c | 21 + > libavcodec/mlp.h | 40 + > libavcodec/mlpenc.c| 2416 > > 5 files changed, 2481 insertions(+), 2 deletions(-) > create mode 100644 libavcodec/mlpenc.c [...] > +static av_cold int mlp_encode_init(AVCodecContext *avctx) > +{ > +MLPEncodeContext *ctx = avctx->priv_data; > +unsigned int substr, index; > +unsigned int sum = 0; > +unsigned int size; > + > +ctx->avctx = avctx; > + > +switch (avctx->sample_rate) { > +case 44100 << 0: > +avctx->frame_size = 40 << 0; > +ctx->coded_sample_rate[0] = 0x08 + 0; > +ctx->fs = 0x08 + 1; > +break; > +case 44100 << 1: > +avctx->frame_size = 40 << 1; > +ctx->coded_sample_rate[0] = 0x08 + 1; > +ctx->fs = 0x0C + 1; > +break; > +case 44100 << 2: > +ctx->substream_info |= SUBSTREAM_INFO_HIGH_RATE; > +avctx->frame_size = 40 << 2; > +ctx->coded_sample_rate[0] = 0x08 + 2; > +ctx->fs = 0x10 + 1; > +break; > +case 48000 << 0: > +avctx->frame_size = 40 << 0; > +ctx->coded_sample_rate[0] = 0x00 + 0; > +ctx->fs = 0x08 + 2; > +break; > +case 48000 << 1: > +avctx->frame_size = 40 << 1; > +ctx->coded_sample_rate[0] = 0x00 + 1; > +ctx->fs = 0x0C + 2; > +break; > +case 48000 << 2: > +ctx->substream_info |= SUBSTREAM_INFO_HIGH_RATE; > +avctx->frame_size = 40 << 2; > +ctx->coded_sample_rate[0] = 0x00 + 2; > +ctx->fs = 0x10 + 2; > +break; > +default: > +av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d. Supported " > +"sample rates are 44100, 88200, 176400, 48000, " > +"96000, and 192000.\n", avctx->sample_rate); > +return -1; > +} > +ctx->coded_sample_rate[1] = -1 & 0xf; > + > +/* TODO Keep count of bitrate and calculate real value. */ > +ctx->coded_peak_bitrate = mlp_peak_bitrate(960, avctx->sample_rate); > + > +/* TODO support more channels. */ > +if (avctx->channels > 2) { > +av_log(avctx, AV_LOG_WARNING, > + "Only mono and stereo are supported at the moment.\n"); > +} > + > +ctx->substream_info |= SUBSTREAM_INFO_ALWAYS_SET; > +if (avctx->channels <= 2) { > +ctx->substream_info |= SUBSTREAM_INFO_MAX_2_CHAN; > +} > + > +switch (avctx->sample_fmt) { > +case AV_SAMPLE_FMT_S16: > +ctx->coded_sample_fmt[0] = BITS_16; > +ctx->wordlength = 16; > +avctx->bits_per_raw_sample = 16; > +break; > +/* TODO 20 bits: */ > +case AV_SAMPLE_FMT_S32: > +ctx->coded_sample_fmt[0] = BITS_24; > +ctx->wordlength = 24; > +avctx->bits_per_raw_sample = 24; > +break; > +default: > +av_log(avctx, AV_LOG_ERROR, "Sample format not supported. " > + "Only 16- and 24-bit samples are supported.\n"); > +return -1; > +} > +ctx->coded_sample_fmt[1] = -1 & 0xf; > + > +ctx->dts = -avctx->frame_size; > + > +ctx->num_channels = avctx->channels + 2; /* +2 noise channels */ > +ctx->one_sample_buffer_size = avctx->frame_size > +* ctx->num_channels; > +/* TODO Let user pass major header interval as parameter. */ > +ctx->max_restart_interval = MAJOR_HEADER_INTERVAL; > + > +ctx->max_codebook_search = 3; > +ctx->min_restart_interval = MAJOR_HEADER_INTERVAL; > +ctx->restart_intervals = ctx->max_restart_interval / > ctx->min_restart_interval; > + > +/* TODO Let user pass parameters for LPC filter. */ > + > +size = sizeof(int32_t) * avctx->frame_size * ctx->max_restart_interval; > + > +ctx->lpc_sample_buffer = av_malloc(size); av_malloc_array() > +if (!ctx->lpc_sample_buffer) { > +av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for buffering samples.\n"); > +return -1; AVERROR(ENOMEM) > +} > + > +size = sizeof(int32_t) > + * ctx->one_sample_buffer_size * ctx->max_r
Re: [FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder
Jai Luthra wrote: * Multichannel support for TrueHD is experimental There should be downmix substreams present for 2+ channel bitstreams, but ffmpeg decoder doesn't need it. Will add support for this soon. Nice work, this is just a sort of related question really from a user who hasn't taken any notice of TrueHD for a few years. Last I looked I couldn't find much in the way of specs for TrueHD and noticed that the Decoder didn't have anything related to dynamic range control. Is there more info about now? IIRC testing decoder - (depending on content) for downmix or 2 channel sub stream the absence of DRC was a bit of a show stopper in that full range can be way too much. The AC3 version of course did have DRC meta and ffmpeg would correctly fully apply it for downmix, so for a stereo listener like me AC3 = good, TrueHD (or DTS) = bad. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder
On Sat, Sep 17, 2016 at 05:07:28PM +0100, Andy Furniss wrote: > Nice work, this is just a sort of related question really from a user > who hasn't taken any notice of TrueHD for a few years. > > Last I looked I couldn't find much in the way of specs for TrueHD and > noticed that the Decoder didn't have anything related to dynamic range > control. > > Is there more info about now? > > IIRC testing decoder - (depending on content) for downmix or 2 channel > sub stream the absence of DRC was a bit of a show stopper in that full > range can be way too much. The AC3 version of course did have DRC meta > and ffmpeg would correctly fully apply it for downmix, so for a stereo > listener like me AC3 = good, TrueHD (or DTS) = bad. The proprietary suite for TrueHD does support dynamic range compression, but I'm unsure if (and where) the metadata for DRC is present in the bitstream. The bitstream isn't fully reversed yet, just enough to get things working. I think this is a very useful feature for downmixed substream to sound good, so I'll try to figure it out in my spare time. Cheers, -- darkapex ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder
Jai Luthra wrote: On Sat, Sep 17, 2016 at 05:07:28PM +0100, Andy Furniss wrote: Nice work, this is just a sort of related question really from a user who hasn't taken any notice of TrueHD for a few years. Last I looked I couldn't find much in the way of specs for TrueHD and noticed that the Decoder didn't have anything related to dynamic range control. Is there more info about now? IIRC testing decoder - (depending on content) for downmix or 2 channel sub stream the absence of DRC was a bit of a show stopper in that full range can be way too much. The AC3 version of course did have DRC meta and ffmpeg would correctly fully apply it for downmix, so for a stereo listener like me AC3 = good, TrueHD (or DTS) = bad. The proprietary suite for TrueHD does support dynamic range compression, but I'm unsure if (and where) the metadata for DRC is present in the bitstream. The bitstream isn't fully reversed yet, just enough to get things working. I think this is a very useful feature for downmixed substream to sound good, so I'll try to figure it out in my spare time. Thanks, it would be really good if the meta could be found even just for the the decoder. I guess it would be a lot more complex for encode anyway. I notice we both use the term downmix, maybe that's not quite the right thing to say WRT substreams. I mean that in the sense that THD substreams are AIUI the base and the higher channel counts are derived. Which means the stereo mix can be different from what a downmix would make. I've got a 7.1 speaker check sample somewhere and the stereo substream has all the speakers at the same level, which is a nice feature. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel