[FFmpeg-soc] [soc]: r4223 - in mlp: libavcodec_mlpenc.diff mlpenc.c
ramiro
subversion at mplayerhq.hu
Mon Apr 20 05:00:48 CEST 2009
Author: ramiro
Date: Mon Apr 20 05:00:47 2009
New Revision: 4223
Log:
Add proper channel_meaning.
Modified:
mlp/libavcodec_mlpenc.diff
mlp/mlpenc.c
Modified: mlp/libavcodec_mlpenc.diff
==============================================================================
--- mlp/libavcodec_mlpenc.diff Mon Apr 20 04:46:30 2009 (r4222)
+++ mlp/libavcodec_mlpenc.diff Mon Apr 20 05:00:47 2009 (r4223)
@@ -55,6 +55,31 @@ Index: libavcodec/lpc.h
#ifdef LPC_USE_DOUBLE
#define LPC_TYPE double
+Index: libavcodec/mlp.c
+===================================================================
+--- libavcodec/mlp.c (revision 18631)
++++ libavcodec/mlp.c (working copy)
+@@ -41,6 +41,20 @@
+ }
+ };
+
++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 },
++};
++
+ static int crc_init = 0;
+ static AVCRC crc_63[1024];
+ static AVCRC crc_1D[1024];
Index: libavcodec/Makefile
===================================================================
--- libavcodec/Makefile (revision 18631)
@@ -81,6 +106,48 @@ Index: libavcodec/mlp.h
} FilterParams;
/** sample data coding information */
+@@ -86,6 +89,41 @@
+ */
+ 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 channel information.
++ *
++ * Possible channel arrangements are:
++ *
++ * (Group 1) C
++ * (Group 1) L, R
++ * (Group 1) Lf, Rf / (Group 2) S
++ * (Group 1) Lf, Rf / (Group 2) Ls, Rs
++ * (Group 1) Lf, Rf / (Group 2) LFE
++ * (Group 1) Lf, Rf / (Group 2) LFE, S
++ * (Group 1) Lf, Rf / (Group 2) LFE, Ls, Rs
++ * (Group 1) Lf, Rf / (Group 2) C
++ * (Group 1) Lf, Rf / (Group 2) C, S
++ * (Group 1) Lf, Rf / (Group 2) C, Ls, Rs
++ * (Group 1) Lf, Rf / (Group 2) C, LFE
++ * (Group 1) Lf, Rf / (Group 2) C, LFE, S
++ * (Group 1) Lf, Rf / (Group 2) C, LFE, Ls, Rs
++ * (Group 1) Lf, Rf C / (Group 2) S
++ * (Group 1) Lf, Rf C / (Group 2) Ls, Rs
++ * (Group 1) Lf, Rf C / (Group 2) LFE
++ * (Group 1) Lf, Rf C / (Group 2) LFE, S
++ * (Group 1) Lf, Rf C / (Group 2) LFE, Ls, Rs
++ * (Group 1) Lf, Rf Ls Rs / (Group 2) LFE
++ * (Group 1) Lf, Rf Ls Rs / (Group 2) C
++ * (Group 1) Lf, Rf, Ls, Rs / (Group 2) C, LFE
++ */
++extern ChannelInformation ff_mlp_ch_info[21];
++
+ /** MLP uses checksums that seem to be based on the standard CRC algorithm, but
+ * are not (in implementation terms, the table lookup and XOR are reversed).
+ * We can implement this behavior using a standard av_crc on all but the
Index: libavcodec/flacenc.c
===================================================================
--- libavcodec/flacenc.c (revision 18631)
Modified: mlp/mlpenc.c
==============================================================================
--- mlp/mlpenc.c Mon Apr 20 04:46:30 2009 (r4222)
+++ mlp/mlpenc.c Mon Apr 20 05:00:47 2009 (r4223)
@@ -110,6 +110,13 @@ typedef struct {
int flags; ///< major sync info flags
+ /* channel_meaning */
+ int substream_info;
+ int fs;
+ int wordlength;
+ int channel_occupancy;
+ int summary_info;
+
int32_t *inout_buffer; ///< Pointer to data currently being read from lavc or written to bitstream.
int32_t *major_inout_buffer; ///< Buffer with all in/out data for one entire major frame interval.
int32_t *write_buffer; ///< Pointer to data currently being written to bitstream.
@@ -142,10 +149,6 @@ typedef struct {
uint8_t channel_arrangement; ///< channel arrangement for MLP streams
- uint8_t mlp_channels2; ///< 1 bit for each channel
- uint8_t mlp_channels3; /**< TODO unknown channel-related field
- * These values are correct for mono and stereo. */
-
unsigned int seq_size [MAJOR_HEADER_INTERVAL];
unsigned int seq_offset[MAJOR_HEADER_INTERVAL];
unsigned int sequence_size;
@@ -203,6 +206,11 @@ static BestOffset restart_best_offs
/* FIFO delay must be constant */
#define FLAGS_CONST 0x8000
+#define SUBSTREAM_INFO_MAX_2_CHAN 0x01
+#define SUBSTREAM_INFO_HIGH_RATE 0x02
+#define SUBSTREAM_INFO_ALWAYS_SET 0x04
+#define SUBSTREAM_INFO_2_SUBSTREAMS 0x08
+
/****************************************************************************
************ Functions that copy, clear, or compare parameters *************
****************************************************************************/
@@ -455,21 +463,6 @@ static int inline number_sbits(int numbe
return av_log2(FFABS(number)) + 1 + !!number;
}
-/** Encodes the third type of channel information for the sync headers.
- * TODO This field is not yet fully understood. These values are just copied
- * from some samples out in the wild.
- */
-static uint8_t get_channels3_code(int channels)
-{
- switch (channels) {
- case 1: return 0x1f;
- case 2: return 0x1b;
- case 6: return 0x00;
- default:
- return 0x1b;
- }
-}
-
enum InputBitDepth {
BITS_16,
BITS_20,
@@ -481,21 +474,6 @@ static int mlp_peak_bitrate(int peak_bit
return ((peak_bitrate << 4) - 8) / sample_rate;
}
-/** Returns the coded sample_rate for MLP. */
-static int mlp_sample_rate(int sample_rate)
-{
- switch (sample_rate) {
- case 44100 << 0: return 0x8 + 0;
- case 44100 << 1: return 0x8 + 1;
- case 44100 << 2: return 0x8 + 2;
- case 48000 << 0: return 0x0 + 0;
- case 48000 << 1: return 0x0 + 1;
- case 48000 << 2: return 0x0 + 2;
- default:
- return -1;
- }
-}
-
static av_cold int mlp_encode_init(AVCodecContext *avctx)
{
MLPEncodeContext *ctx = avctx->priv_data;
@@ -514,8 +492,40 @@ static av_cold int mlp_encode_init(AVCod
ctx->avctx = avctx;
- ctx->coded_sample_rate[0] = mlp_sample_rate(avctx->sample_rate);
- if (ctx->coded_sample_rate[0] < 0) {
+ 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);
@@ -533,10 +543,20 @@ static av_cold int mlp_encode_init(AVCod
return -1;
}
+ if (avctx->channels <= 2) {
+ ctx->substream_info |= SUBSTREAM_INFO_MAX_2_CHAN;
+ }
+
switch (avctx->sample_fmt) {
- case SAMPLE_FMT_S16: ctx->coded_sample_fmt[0] = BITS_16; break;
+ case SAMPLE_FMT_S16:
+ ctx->coded_sample_fmt[0] = BITS_16;
+ ctx->wordlength = 16;
+ break;
/* TODO 20 bits: */
- case SAMPLE_FMT_S32: ctx->coded_sample_fmt[0] = BITS_24; break;
+ case SAMPLE_FMT_S32:
+ ctx->coded_sample_fmt[0] = BITS_24;
+ ctx->wordlength = 24;
+ break;
default:
av_log(avctx, AV_LOG_ERROR, "Sample format not supported. "
"Only 16- and 24-bit samples are supported.\n");
@@ -544,7 +564,6 @@ static av_cold int mlp_encode_init(AVCod
}
ctx->coded_sample_fmt[1] = -1 & 0xf;
- avctx->frame_size = 40 << (ctx->coded_sample_rate[0] & 0x7);
avctx->coded_frame = avcodec_alloc_frame();
ctx->dts = -avctx->frame_size;
@@ -600,10 +619,10 @@ static av_cold int mlp_encode_init(AVCod
/* TODO mlp_channels is more complex, but for now
* we only accept mono and stereo. */
ctx->channel_arrangement = avctx->channels - 1;
- ctx->mlp_channels2 = (1 << avctx->channels) - 1;
- ctx->mlp_channels3 = get_channels3_code(avctx->channels);
ctx->num_substreams = 1;
ctx->flags = FLAGS_DVDA;
+ ctx->channel_occupancy = ff_mlp_ch_info[avctx->channels - 1].channel_occupancy;
+ ctx->summary_info = ff_mlp_ch_info[avctx->channels - 1].summary_info ;
size = sizeof(unsigned int) * ctx->max_restart_interval;
@@ -813,15 +832,20 @@ static void write_major_sync(MLPEncodeCo
put_bits(&pb, 15, ctx->coded_peak_bitrate);
put_bits(&pb, 4, 1); /* TODO Support more num_substreams. */
- put_bits(&pb, 20, 0x1054c); /* TODO These values have something to do with
- * the sample rate. The ones used here come
- * from samples that are stereo and have
- * 44100Hz. */
- put_bits(&pb, 8, ctx->mlp_channels2);
- put_bits(&pb, 16, 0x0000);
- put_bits(&pb, 16, 0x8080); /* These values seem */
- put_bits(&pb, 8, 0x00 ); /* to be constants. */
- put_bits(&pb, 8, ctx->mlp_channels3); /* TODO Finish understanding this field. */
+ put_bits(&pb, 4, 0x1 ); /* ignored */
+
+ /* channel_meaning */
+ put_bits(&pb, 8, ctx->substream_info );
+ put_bits(&pb, 5, ctx->fs );
+ put_bits(&pb, 5, ctx->wordlength );
+ put_bits(&pb, 6, ctx->channel_occupancy);
+ put_bits(&pb, 3, 0 ); /* ignored */
+ put_bits(&pb, 10, 0 ); /* speaker_layout */
+ put_bits(&pb, 3, 0 ); /* copy_protection */
+ put_bits(&pb, 16, 0x8080 ); /* ignored */
+ put_bits(&pb, 7, 0 ); /* ignored */
+ put_bits(&pb, 4, 0 ); /* source_format */
+ put_bits(&pb, 5, ctx->summary_info );
flush_put_bits(&pb);
@@ -1415,7 +1439,11 @@ static void set_filter_params(MLPEncodeC
ChannelParams *cp = &ctx->cur_channel_params[channel];
FilterParams *fp = &cp->filter_params[filter];
- if (clear_filter || filter == IIR) {
+ if ((filter == IIR && ctx->substream_info & SUBSTREAM_INFO_HIGH_RATE) ||
+ clear_filter) {
+ fp->order = 0;
+ } else
+ if (filter == IIR) {
fp->order = 0;
} else
if (filter == FIR) {
More information about the FFmpeg-soc
mailing list