so.. patches mostly applicable to ffmpeg-4.4 while I slightly edited 'last frame' fix due to other ffmpeg changes
apply 'last frame' and '24-bit' for encoding truehd hopefully lossless apply two mlpdec patches for more correct decoder flush/crc check try to apply mlp.h and libavformat patches for timestamps in demuxer... stop-returning-empty for mlpenc not tested. after all this patching both ffmpeg and cin should work better with truehd streams (still require 'strict -2' in profile) there were other fixes and code movements but i hope those patches can fix real bugs and allow losless re-encoding between pcm and truehd (check crc's!)
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/fea4f953b5c6e04b84ce9c11664c9cbcac171a60..9f420163c6207b9c54badd30056974a6b3450bfd:/libavcodec/mlpenc.c diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c index 8b61fc6b1e..37052d9e38 100644 --- a/libavcodec/mlpenc.c +++ b/libavcodec/mlpenc.c @@ -103,7 +103,7 @@ typedef struct BestOffset { /** Number of possible codebooks (counting "no codebooks") */ #define NUM_CODEBOOKS 4 -typedef struct { +typedef struct MLPEncodeContext { AVCodecContext *avctx; int num_substreams; ///< Number of substreams contained within this stream. @@ -129,7 +129,8 @@ typedef struct { int32_t *write_buffer; ///< Pointer to data currently being written to bitstream. int32_t *sample_buffer; ///< Pointer to current access unit samples. int32_t *major_scratch_buffer; ///< Scratch buffer big enough to fit all data for one entire major frame interval. - int32_t *last_frame; ///< Pointer to last frame with data to encode. + int32_t last_frames; ///< Signal last frames. + int32_t last_index; int32_t *lpc_sample_buffer; @@ -201,6 +202,10 @@ typedef struct { unsigned int max_codebook_search; + int shorten_by; + + int64_t pts; + LPCContext lpc_ctx; } MLPEncodeContext; @@ -1116,9 +1121,13 @@ static uint8_t *write_substrs(MLPEncodeContext *ctx, uint8_t *buf, int buf_size, rh->lossless_check_data ^= *lossless_check_data++; - if (ctx->last_frame == ctx->inout_buffer) { - /* TODO find a sample and implement shorten_by. */ - put_bits(&pb, 32, END_OF_STREAM); + if (ctx->last_frames == 0 && ctx->shorten_by) { + if (ctx->avctx->codec_id == AV_CODEC_ID_TRUEHD) { + put_bits(&pb, 16, END_OF_STREAM & 0xFFFF); + put_bits(&pb, 16, (ctx->shorten_by & 0x1FFF) | 0x2000); + } else { + put_bits(&pb, 32, END_OF_STREAM); + } } /* Data must be flushed for the checksum and parity to be correct; @@ -2216,42 +2225,35 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, int restart_frame, ret; uint8_t *data; + if (!frame && !ctx->last_frames--) + return 0; + if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0) return ret; - /* add current frame to queue */ - if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) - return ret; + if (frame) { + /* add current frame to queue */ + if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) + return ret; + ctx->last_frames = ctx->max_restart_interval; + ctx->last_index = ctx->frame_index; + } - data = frame->data[0]; + data = frame ? frame->data[0] : NULL; ctx->frame_index = avctx->frame_number % ctx->max_restart_interval; ctx->inout_buffer = ctx->major_inout_buffer + ctx->frame_index * ctx->one_sample_buffer_size; - if (ctx->last_frame == ctx->inout_buffer) { - return 0; - } - ctx->sample_buffer = ctx->major_scratch_buffer + ctx->frame_index * ctx->one_sample_buffer_size; ctx->write_buffer = ctx->inout_buffer; if (avctx->frame_number < ctx->max_restart_interval) { - if (data) { + if (data) goto input_and_return; - } else { - /* There are less frames than the requested major header interval. - * Update the context to reflect this. - */ - ctx->max_restart_interval = avctx->frame_number; - ctx->frame_index = 0; - - ctx->sample_buffer = ctx->major_scratch_buffer; - ctx->inout_buffer = ctx->major_inout_buffer; - } } if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) { @@ -2278,14 +2280,13 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, input_and_return: - if (data) { - ctx->frame_size[ctx->frame_index] = avctx->frame_size; - ctx->next_major_frame_size += avctx->frame_size; - ctx->next_major_number_of_frames++; + if (frame) + ctx->shorten_by = avctx->frame_size - frame->nb_samples; + ctx->frame_size[ctx->frame_index] = avctx->frame_size; + ctx->next_major_frame_size += avctx->frame_size; + ctx->next_major_number_of_frames++; + if (data) input_data(ctx, data); - } else if (!ctx->last_frame) { - ctx->last_frame = ctx->inout_buffer; - } restart_frame = (ctx->frame_index + 1) % ctx->min_restart_interval; @@ -2315,10 +2316,11 @@ input_and_return: (ctx->frame_index / ctx->min_restart_interval)*(ctx->sequence_size)*(ctx->num_substreams) + (ctx->seq_offset[seq_index])*(ctx->num_substreams); - for (index = 0; index < ctx->number_of_frames; index++) { + for (index = 0; index < ctx->number_of_frames; index++) number_of_samples += ctx->frame_size[(ctx->starting_frame_index + index) % ctx->max_restart_interval]; - } ctx->number_of_samples = number_of_samples; + if (!ctx->number_of_samples) + break; for (index = 0; index < ctx->seq_size[seq_index]; index++) { clear_channel_params(ctx->seq_channel_params + index * ctx->avctx->channels, ctx->avctx->channels); @@ -2343,8 +2345,16 @@ input_and_return: no_data_left: - ff_af_queue_remove(&ctx->afq, avctx->frame_size, &avpkt->pts, - &avpkt->duration); + if (ctx->afq.frame_count > 0) { + ff_af_queue_remove(&ctx->afq, avctx->frame_size, &avpkt->pts, + &avpkt->duration); + ctx->pts = avpkt->pts + avpkt->duration; + } else { + avpkt->pts = ctx->pts; + ctx->pts += avctx->frame_size; + } + if (!frame) + avctx->frame_number++; avpkt->size = bytes_written; *got_packet = 1; return 0; @@ -2379,7 +2389,7 @@ const AVCodec ff_mlp_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = ff_mlp_channel_layouts, @@ -2396,7 +2406,7 @@ const AVCodec ff_truehd_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0},
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/61c2c9ef8e66920c8ba308e8fa9f36ae602f8245..2bb9d2be5e2e1d971e5b80358098f2a7fce06e0e:/libavcodec/mlpenc.c diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c index 37052d9e38..443cb41cf5 100644 --- a/libavcodec/mlpenc.c +++ b/libavcodec/mlpenc.c @@ -2390,7 +2390,7 @@ const AVCodec ff_mlp_encoder = { .encode2 = mlp_encode_frame, .close = mlp_encode_close, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, + .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = ff_mlp_channel_layouts, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, @@ -2407,7 +2407,7 @@ const AVCodec ff_truehd_encoder = { .encode2 = mlp_encode_frame, .close = mlp_encode_close, .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, + .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0}, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/589cd58c858bb6b5c03cfcdb55cb8aa8acedefd7..036d94da43d09d3e9c312b7c3f6707212de804df:/libavcodec/mlpenc.c diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c index 50662de09c..7db28f518a 100644 --- a/libavcodec/mlpenc.c +++ b/libavcodec/mlpenc.c @@ -1178,8 +1178,8 @@ static void write_frame_headers(MLPEncodeContext *ctx, uint8_t *frame_header, } /** Writes an entire access unit to the bitstream. */ -static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, - int buf_size, int restart_frame) +static int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, + int buf_size, int restart_frame) { uint16_t substream_data_len[MAX_SUBSTREAMS]; uint8_t *buf1, *buf0 = buf; @@ -2183,7 +2183,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet) { MLPEncodeContext *ctx = avctx->priv_data; - unsigned int bytes_written = 0; + int bytes_written = 0; int restart_frame, ret; uint8_t *data; @@ -2316,8 +2316,14 @@ no_data_left: } if (!frame) avctx->frame_number++; - avpkt->size = bytes_written; - *got_packet = 1; + + if (bytes_written > 0) { + avpkt->size = bytes_written; + *got_packet = 1; + } else { + *got_packet = 0; + } + return 0; }
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/9f420163c6207b9c54badd30056974a6b3450bfd..034133a0df5f327aba36ee25db9452cda9e1a62b:/libavcodec/mlpdec.c diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 0fac5ad754..08db5dc63c 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -53,6 +53,8 @@ typedef struct SubStream { /// Set if a valid restart header has been read. Otherwise the substream cannot be decoded. uint8_t restart_seen; + /// Set if end of stream is encountered + uint8_t end_of_stream; //@{ /** restart header data */ @@ -1286,8 +1288,8 @@ static int read_access_unit(AVCodecContext *avctx, void* data, else if (m->avctx->codec_id == AV_CODEC_ID_MLP && shorten_by != 0xD234) return AVERROR_INVALIDDATA; - if (substr == m->max_decoded_substream) - av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n"); + av_log(m->avctx, AV_LOG_DEBUG, "End of stream indicated.\n"); + s->end_of_stream = 1; } if (substream_parity_present[substr]) { @@ -1319,6 +1321,16 @@ next_substr: if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0) return ret; + for (substr = 0; substr <= m->max_decoded_substream; substr++){ + SubStream *s = &m->substream[substr]; + + if (s->end_of_stream) { + s->lossless_check_data = 0xffffffff; + s->end_of_stream = 0; + m->params_valid = 0; + } + } + return length; substream_length_mismatch:
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/5d92b73c6417c87bfd12874dbfbb359b8bfda470..7ebeef6affb5f683febdc86f2dc45a339ac97f6c:/libavformat/mlpdec.c diff --git a/libavformat/mlpdec.c b/libavformat/mlpdec.c index 8f0aabb510..f0996fef31 100644 --- a/libavformat/mlpdec.c +++ b/libavformat/mlpdec.c @@ -22,8 +22,12 @@ */ #include "avformat.h" +#include "avio_internal.h" +#include "internal.h" #include "rawdec.h" #include "libavutil/intreadwrite.h" +#include "libavcodec/mlp.h" +#include "libavcodec/mlp_parse.h" static int av_always_inline mlp_thd_probe(const AVProbeData *p, uint32_t sync) { @@ -50,6 +54,40 @@ static int av_always_inline mlp_thd_probe(const AVProbeData *p, uint32_t sync) return 0; } +static int mlp_read_header(AVFormatContext *s) +{ + int ret = ff_raw_audio_read_header(s); + + if (ret < 0) + return ret; + + ret = ffio_ensure_seekback(s->pb, 10); + if (ret == 0) { + uint8_t buffer[10]; + int read, sample_rate = 0; + + read = avio_read(s->pb, buffer, 10); + if (read == 10) { + switch (buffer[7]) { + case SYNC_TRUEHD: + sample_rate = mlp_samplerate(buffer[8] >> 4); + break; + case SYNC_MLP: + sample_rate = mlp_samplerate(buffer[9] >> 4); + break; + } + + if (sample_rate) + avpriv_set_pts_info(s->streams[0], 64, 1, sample_rate); + } + + if (read > 0) + avio_seek(s->pb, -read, SEEK_CUR); + } + + return 0; +} + #if CONFIG_MLP_DEMUXER static int mlp_probe(const AVProbeData *p) { @@ -60,7 +98,7 @@ const AVInputFormat ff_mlp_demuxer = { .name = "mlp", .long_name = NULL_IF_CONFIG_SMALL("raw MLP"), .read_probe = mlp_probe, - .read_header = ff_raw_audio_read_header, + .read_header = mlp_read_header, .read_packet = ff_raw_read_partial_packet, .flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS, .extensions = "mlp", @@ -80,7 +118,7 @@ const AVInputFormat ff_truehd_demuxer = { .name = "truehd", .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), .read_probe = thd_probe, - .read_header = ff_raw_audio_read_header, + .read_header = mlp_read_header, .read_packet = ff_raw_read_partial_packet, .flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS, .extensions = "thd", @@ -89,4 +127,3 @@ const AVInputFormat ff_truehd_demuxer = { .priv_class = &ff_raw_demuxer_class, }; #endif -
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/a4c98c507ed3c729fc92d641b974385f8aa37b33..5673a4842556b79a92a1ede6e9696506fd4161ad:/libavcodec/mlpdec.c diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index e4992550ee..0fac5ad754 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -1330,6 +1330,18 @@ error: return AVERROR_INVALIDDATA; } +static void mlp_decode_flush(AVCodecContext *avctx) +{ + MLPDecodeContext *m = avctx->priv_data; + + m->params_valid = 0; + for (int substr = 0; substr <= m->max_decoded_substream; substr++){ + SubStream *s = &m->substream[substr]; + + s->lossless_check_data = 0xffffffff; + } +} + #if CONFIG_MLP_DECODER const AVCodec ff_mlp_decoder = { .name = "mlp", @@ -1339,6 +1351,7 @@ const AVCodec ff_mlp_decoder = { .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, + .flush = mlp_decode_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, }; @@ -1352,6 +1365,7 @@ const AVCodec ff_truehd_decoder = { .priv_data_size = sizeof(MLPDecodeContext), .init = mlp_decode_init, .decode = read_access_unit, + .flush = mlp_decode_flush, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };
X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/3ea0171ea3ef374f9468805ec27b37b29f0dd47c..0c87b43c6cd45a66c54134026d2f2cf823df4c7d:/libavcodec/mlp.h diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h index 5b7d8c8cac..e45eba55ae 100644 --- a/libavcodec/mlp.h +++ b/libavcodec/mlp.h @@ -24,6 +24,9 @@ #include <stdint.h> +#define SYNC_MLP 0xbb +#define SYNC_TRUEHD 0xba + /** Last possible matrix channel for each codec */ #define MAX_MATRIX_CHANNEL_MLP 5 #define MAX_MATRIX_CHANNEL_TRUEHD 7
-- Cin mailing list Cin@lists.cinelerra-gg.org https://lists.cinelerra-gg.org/mailman/listinfo/cin