summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/ffmpeg/A01-mpegleak.patch62
-rw-r--r--contrib/ffmpeg/A01-swscale-assert.patch15
-rw-r--r--contrib/ffmpeg/A02-audioconvert.patch13
-rw-r--r--contrib/ffmpeg/A03-png-sequences.patch12
-rw-r--r--contrib/ffmpeg/A04-channel-layout-order.patch103
-rw-r--r--contrib/ffmpeg/A05-asf-seek.patch16
-rw-r--r--contrib/ffmpeg/A06-h264-recovery-point.patch48
-rw-r--r--contrib/ffmpeg/A07-swscale-stack-alignment.patch13
-rw-r--r--contrib/ffmpeg/A08-vc1-decode.patch40
-rw-r--r--contrib/ffmpeg/A09-pgs-pts.patch30
-rw-r--r--contrib/ffmpeg/P01-solaris.patch4
-rw-r--r--contrib/ffmpeg/P02-darwin-pic.patch8
-rw-r--r--contrib/ffmpeg/P04-darwin-memalign.patch4
-rw-r--r--contrib/ffmpeg/module.defs14
-rw-r--r--gtk/src/Makefile.am12
-rw-r--r--libhb/audio_remap.c148
-rw-r--r--libhb/audio_remap.h53
-rw-r--r--libhb/common.h4
-rw-r--r--libhb/deca52.c4
-rw-r--r--libhb/decavcodec.c262
-rw-r--r--libhb/decdca.c4
-rw-r--r--libhb/declpcm.c155
-rw-r--r--libhb/downmix.c1640
-rw-r--r--libhb/downmix.h67
-rw-r--r--libhb/dvd.c1
-rw-r--r--libhb/dvdnav.c1
-rw-r--r--libhb/encavcodec.c20
-rw-r--r--libhb/encavcodecaudio.c213
-rw-r--r--libhb/encfaac.c46
-rw-r--r--libhb/encvorbis.c60
-rw-r--r--libhb/hb.c101
-rw-r--r--libhb/hbffmpeg.h20
-rw-r--r--libhb/mcdeint.c17
-rw-r--r--libhb/mcdeint.h3
-rw-r--r--libhb/module.defs2
-rw-r--r--libhb/platform/macosx/encca_aac.c41
-rw-r--r--libhb/stream.c27
-rw-r--r--libhb/sync.c36
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj6
-rw-r--r--test/module.defs2
40 files changed, 882 insertions, 2445 deletions
diff --git a/contrib/ffmpeg/A01-mpegleak.patch b/contrib/ffmpeg/A01-mpegleak.patch
deleted file mode 100644
index 214e9caf9..000000000
--- a/contrib/ffmpeg/A01-mpegleak.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-diff --git a/libavcodec/h264.c b/libavcodec/h264.c
-index 9889224..041fccf 100644
---- a/libavcodec/h264.c
-+++ b/libavcodec/h264.c
-@@ -3848,7 +3848,7 @@ static int decode_frame(AVCodecContext *avctx,
- if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){
- if (avctx->skip_frame >= AVDISCARD_NONREF)
- return 0;
-- av_log(avctx, AV_LOG_ERROR, "no frame!\n");
-+ av_log(avctx, AV_LOG_DEBUG, "no frame!\n");
- return -1;
- }
-
-diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
-index 1f30916..dce88f3 100644
---- a/libavcodec/h264_refs.c
-+++ b/libavcodec/h264_refs.c
-@@ -634,7 +634,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
- * stream. Need to discard one frame. Prevents overrun of the
- * short_ref and long_ref buffers.
- */
-- av_log(h->s.avctx, AV_LOG_ERROR,
-+ av_log(h->s.avctx, AV_LOG_DEBUG,
- "number of reference frames (%d+%d) exceeds max (%d; probably "
- "corrupt input), discarding one\n",
- h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
-diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
-index e418e95..87cb73c 100644
---- a/libavcodec/mpegvideo.c
-+++ b/libavcodec/mpegvideo.c
-@@ -1004,19 +1004,18 @@ int ff_find_unused_picture(MpegEncContext *s, int shared){
- }
-
- av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n");
-- /* We could return -1, but the codec would crash trying to draw into a
-- * non-existing frame anyway. This is safer than waiting for a random crash.
-- * Also the return of this is never useful, an encoder must only allocate
-- * as much as allowed in the specification. This has no relationship to how
-- * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
-- * enough for such valid streams).
-- * Plus, a decoder has to check stream validity and remove frames if too
-- * many reference frames are around. Waiting for "OOM" is not correct at
-- * all. Similarly, missing reference frames have to be replaced by
-- * interpolated/MC frames, anything else is a bug in the codec ...
-- */
-- abort();
-- return -1;
-+ /* XXX there seems to be a leak caused by h264 in mpeg transport
-+ * streams: Over-the-air streams have a lot of errors. A picture
-+ * may be marked as referenced but the actual references get lost
-+ * so it never gets released. We take care of that here by releasing
-+ * the oldest we have & reusing its slot. */
-+ int oldest=0;
-+ for(i=0; i<MAX_PICTURE_COUNT; i++){
-+ if (s->picture[i].f.coded_picture_number < s->picture[oldest].f.coded_picture_number)
-+ oldest = i;
-+ }
-+ s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[oldest]);
-+ return oldest;
- }
-
- static void update_noise_reduction(MpegEncContext *s){
diff --git a/contrib/ffmpeg/A01-swscale-assert.patch b/contrib/ffmpeg/A01-swscale-assert.patch
new file mode 100644
index 000000000..8136a35b2
--- /dev/null
+++ b/contrib/ffmpeg/A01-swscale-assert.patch
@@ -0,0 +1,15 @@
+diff --git a/libswscale/utils.c b/libswscale/utils.c
+index d8fee58..b96a771 100644
+--- a/libswscale/utils.c
++++ b/libswscale/utils.c
+@@ -508,7 +508,9 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos,
+ // FIXME try to align filterPos if possible
+
+ // fix borders
+- if (is_horizontal) {
++ // This "horizontal" only check causes a subsequent assert when
++ // upscaling.
++ /*if (is_horizontal)*/ {
+ for (i = 0; i < dstW; i++) {
+ int j;
+ if ((*filterPos)[i] < 0) {
diff --git a/contrib/ffmpeg/A02-audioconvert.patch b/contrib/ffmpeg/A02-audioconvert.patch
deleted file mode 100644
index 5248a9fd3..000000000
--- a/contrib/ffmpeg/A02-audioconvert.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/libavcodec/Makefile b/libavcodec/Makefile
-index 3c4e2f8..fe84b8c 100644
---- a/libavcodec/Makefile
-+++ b/libavcodec/Makefile
-@@ -1,7 +1,7 @@
- NAME = avcodec
- FFLIBS = avutil
-
--HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vdpau.h version.h xvmc.h
-+HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vdpau.h version.h xvmc.h audioconvert.h
-
- OBJS = allcodecs.o \
- audioconvert.o \
diff --git a/contrib/ffmpeg/A03-png-sequences.patch b/contrib/ffmpeg/A03-png-sequences.patch
index 66fe1f7c3..6098c3150 100644
--- a/contrib/ffmpeg/A03-png-sequences.patch
+++ b/contrib/ffmpeg/A03-png-sequences.patch
@@ -1,8 +1,8 @@
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
-index a40cebb..26239e2 100644
+index 871f2b2..cba2e90 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
-@@ -599,6 +599,18 @@ static int decode_frame(AVCodecContext *avctx,
+@@ -592,6 +592,24 @@ static int decode_frame(AVCodecContext *avctx,
}
}
exit_loop:
@@ -16,12 +16,18 @@ index a40cebb..26239e2 100644
+ * It offers a similar solution; forces code block to be skipped.
+ *
+ * --kb
++ *
++ * The "fix" in r19079 was a hack placed in avcodec_decode_video.
++ * avcodec_decode_video was obsoleted and no longer exists. The
++ * "fix" disappeared with it.
++ *
++ * --jas
+ */
+#if 0
/* handle p-frames only if a predecessor frame is available */
if(s->last_picture->data[0] != NULL) {
if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
-@@ -615,6 +627,7 @@ static int decode_frame(AVCodecContext *avctx,
+@@ -608,6 +626,7 @@ static int decode_frame(AVCodecContext *avctx,
}
}
}
diff --git a/contrib/ffmpeg/A04-channel-layout-order.patch b/contrib/ffmpeg/A04-channel-layout-order.patch
index 99faa5ddc..2326e7d3e 100644
--- a/contrib/ffmpeg/A04-channel-layout-order.patch
+++ b/contrib/ffmpeg/A04-channel-layout-order.patch
@@ -1,84 +1,39 @@
-diff --git a/libavcodec/Makefile b/libavcodec/Makefile
-index 3c4e2f8..5cfd1bf 100644
---- a/libavcodec/Makefile
-+++ b/libavcodec/Makefile
-@@ -142,7 +142,7 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o
- OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o
- OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o
- OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o
--OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
-+OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o vorbis_data.o
- OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o
- OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
- OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
-diff --git a/libavcodec/flac.c b/libavcodec/flac.c
-index e6a427a..397155e 100644
---- a/libavcodec/flac.c
-+++ b/libavcodec/flac.c
-@@ -22,6 +22,7 @@
- #include "libavutil/crc.h"
- #include "flac.h"
- #include "flacdata.h"
-+#include "vorbis.h"
-
- static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
-
-@@ -54,9 +55,12 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
- fi->ch_mode = get_bits(gb, 4);
- if (fi->ch_mode < FLAC_MAX_CHANNELS) {
- fi->channels = fi->ch_mode + 1;
-+ if (fi->ch_mode <= 5)
-+ avctx->channel_layout = ff_vorbis_channel_layouts[fi->ch_mode];
- fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
- } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) {
- fi->channels = 2;
-+ avctx->channel_layout = AV_CH_LAYOUT_STEREO;
- } else {
- av_log(avctx, AV_LOG_ERROR + log_level_offset,
- "invalid channel mode: %d\n", fi->ch_mode);
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
-index c90285a..58235c8 100644
+index 91efaf3..e6c5c8e 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
-@@ -133,6 +133,9 @@ typedef struct MLPDecodeContext {
- //! Index of the last substream to decode - further substreams are skipped.
- uint8_t max_decoded_substream;
-
-+ //! Stream needs channel reordering to comply with FFmpeg's channel order
-+ uint8_t needs_reordering;
-+
- //! number of PCM samples contained in each frame
- int access_unit_size;
- //! next power of two above the number of samples in each frame
-@@ -326,6 +329,8 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
- for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
- m->substream[substr].restart_seen = 0;
-
-+ m->needs_reordering = mh.channels_mlp >= 18 && mh.channels_mlp <= 20;
-+
- return 0;
- }
-
-@@ -436,6 +441,24 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
+@@ -30,6 +30,7 @@
+ #include "dsputil.h"
+ #include "libavutil/intreadwrite.h"
+ #include "get_bits.h"
++#include "libavutil/audioconvert.h"
+ #include "libavutil/crc.h"
+ #include "parser.h"
+ #include "mlp_parser.h"
+@@ -434,6 +435,28 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
s->ch_assign[ch_assign] = ch;
}
-+ if (m->avctx->codec_id == CODEC_ID_MLP && m->needs_reordering) {
-+ if (m->avctx->channel_layout == (AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY) ||
-+ m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0) {
-+ int i = s->ch_assign[4];
-+ s->ch_assign[4] = s->ch_assign[3];
-+ s->ch_assign[3] = s->ch_assign[2];
-+ s->ch_assign[2] = i;
-+ } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1) {
-+ FFSWAP(int, s->ch_assign[2], s->ch_assign[4]);
-+ FFSWAP(int, s->ch_assign[3], s->ch_assign[5]);
++ if (m->avctx->codec_id == CODEC_ID_TRUEHD) {
++ switch (m->avctx->channel_layout) {
++ case AV_CH_LAYOUT_6POINT1:
++ case (AV_CH_LAYOUT_6POINT1|AV_CH_TOP_CENTER):
++ case (AV_CH_LAYOUT_6POINT1|AV_CH_TOP_FRONT_CENTER):
++ {
++ int i = s->ch_assign[6];
++ s->ch_assign[6] = s->ch_assign[5];
++ s->ch_assign[5] = s->ch_assign[4];
++ s->ch_assign[4] = i;
++ break;
++ }
++ case AV_CH_LAYOUT_7POINT1:
++ case (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER):
++ FFSWAP(int, s->ch_assign[4], s->ch_assign[6]);
++ FFSWAP(int, s->ch_assign[5], s->ch_assign[7]);
++ break;
++ default:
++ break;
+ }
-+ }
-+ if (m->avctx->codec_id == CODEC_ID_TRUEHD &&
-+ m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1) {
-+ FFSWAP(int, s->ch_assign[4], s->ch_assign[6]);
-+ FFSWAP(int, s->ch_assign[5], s->ch_assign[7]);
+ }
+
checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count);
diff --git a/contrib/ffmpeg/A05-asf-seek.patch b/contrib/ffmpeg/A05-asf-seek.patch
deleted file mode 100644
index c19ad496b..000000000
--- a/contrib/ffmpeg/A05-asf-seek.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
-index 0245340..85b2649 100644
---- a/libavformat/asfdec.c
-+++ b/libavformat/asfdec.c
-@@ -1172,7 +1172,10 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
- return AV_NOPTS_VALUE;
- }
-
-- pts= pkt->pts;
-+ if (pkt->pts == AV_NOPTS_VALUE)
-+ pts = pkt->dts;
-+ else
-+ pts = pkt->pts;
-
- av_free_packet(pkt);
- if(pkt->flags&AV_PKT_FLAG_KEY){
diff --git a/contrib/ffmpeg/A06-h264-recovery-point.patch b/contrib/ffmpeg/A06-h264-recovery-point.patch
index 61442bd44..d018dd6b1 100644
--- a/contrib/ffmpeg/A06-h264-recovery-point.patch
+++ b/contrib/ffmpeg/A06-h264-recovery-point.patch
@@ -1,41 +1,41 @@
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
-index 9889224..ae77285 100644
+index 6ed251e..a3242ce 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
-@@ -2229,6 +2229,7 @@ static void flush_dpb(AVCodecContext *avctx){
- h->s.first_field= 0;
+@@ -2627,6 +2627,7 @@ static void flush_dpb(AVCodecContext *avctx)
+ h->s.first_field = 0;
ff_h264_reset_sei(h);
ff_mpeg_flush(avctx);
+ h->recovery_frame= -1;
}
- static int init_poc(H264Context *h){
-@@ -3654,9 +3655,18 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
- if((err = decode_slice_header(hx, h)))
- break;
+ static int init_poc(H264Context *h)
+@@ -4289,9 +4290,18 @@ again:
+ if ((err = decode_slice_header(hx, h)))
+ break;
-+ if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
-+ h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
-+ (1 << h->sps.log2_max_frame_num);
-+ }
++ if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
++ h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
++ (1 << h->sps.log2_max_frame_num);
++ }
+
- s->current_picture_ptr->f.key_frame |=
+ s->current_picture_ptr->f.key_frame |=
- (hx->nal_unit_type == NAL_IDR_SLICE) ||
- (h->sei_recovery_frame_cnt >= 0);
-+ (hx->nal_unit_type == NAL_IDR_SLICE);
++ (hx->nal_unit_type == NAL_IDR_SLICE);
+
-+ if (h->recovery_frame == h->frame_num) {
-+ s->current_picture_ptr->f.key_frame |= 1;
-+ h->recovery_frame = -1;
-+ }
++ if (h->recovery_frame == h->frame_num) {
++ s->current_picture_ptr->f.key_frame |= 1;
++ h->recovery_frame = -1;
++ }
- if (h->current_slice == 1) {
- if(!(s->flags2 & CODEC_FLAG2_CHUNKS)) {
+ if (h->current_slice == 1) {
+ if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
-index 122a54a..cd044b0 100644
+index 570ce2f..454b755 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
-@@ -575,6 +575,13 @@ typedef struct H264Context{
+@@ -569,6 +569,13 @@ typedef struct H264Context {
* frames.
*/
int sei_recovery_frame_cnt;
@@ -47,10 +47,10 @@ index 122a54a..cd044b0 100644
+ */
+ int recovery_frame;
- int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
- int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
+ int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
+ int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
-index 4f52bbe..8d3c40b 100644
+index 2e5fb65..ea33a18 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -38,6 +38,7 @@ static const uint8_t sei_num_clock_ts_table[9]={
diff --git a/contrib/ffmpeg/A07-swscale-stack-alignment.patch b/contrib/ffmpeg/A07-swscale-stack-alignment.patch
deleted file mode 100644
index 6d3bb35ce..000000000
--- a/contrib/ffmpeg/A07-swscale-stack-alignment.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
-index c0161c2..c7e6a28 100644
---- a/libswscale/swscale_unscaled.c
-+++ b/libswscale/swscale_unscaled.c
-@@ -806,7 +806,7 @@ static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt,
- * swscale wrapper, so we don't need to export the SwsContext.
- * Assumes planar YUV to be in YUV order instead of YVU.
- */
--int sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[],
-+int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[],
- const int srcStride[], int srcSliceY, int srcSliceH,
- uint8_t* const dst[], const int dstStride[])
- {
diff --git a/contrib/ffmpeg/A08-vc1-decode.patch b/contrib/ffmpeg/A08-vc1-decode.patch
deleted file mode 100644
index 61c0724a0..000000000
--- a/contrib/ffmpeg/A08-vc1-decode.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
-index 60cca33..1b03215 100644
---- a/libavcodec/vc1dec.c
-+++ b/libavcodec/vc1dec.c
-@@ -3317,7 +3317,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
- i += skip;
- if (i > 63)
- break;
-- if (!v->interlace)
-+ if (!v->fcm)
- idx = v->zz_8x8[0][i++];
- else
- idx = v->zzi_8x8[i++];
-@@ -3345,7 +3345,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
- i += skip;
- if (i > 15)
- break;
-- if (!v->interlace)
-+ if (!v->fcm)
- idx = ff_vc1_simple_progressive_4x4_zz[i++];
- else
- idx = ff_vc1_adv_interlaced_4x4_zz[i++];
-@@ -3372,7 +3372,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
- i += skip;
- if (i > 31)
- break;
-- if (!v->interlace)
-+ if (!v->fcm)
- idx = v->zz_8x4[i++] + off;
- else
- idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
-@@ -3399,7 +3399,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
- i += skip;
- if (i > 31)
- break;
-- if (!v->interlace)
-+ if (!v->fcm)
- idx = v->zz_4x8[i++] + off;
- else
- idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
diff --git a/contrib/ffmpeg/A09-pgs-pts.patch b/contrib/ffmpeg/A09-pgs-pts.patch
index b03f5acce..fe6a6dc93 100644
--- a/contrib/ffmpeg/A09-pgs-pts.patch
+++ b/contrib/ffmpeg/A09-pgs-pts.patch
@@ -1,18 +1,20 @@
-diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/avcodec.h ffmpeg-v0.7-1696-gcae4f4b/libavcodec/avcodec.h
---- ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/avcodec.h 2011-11-03 12:29:48.000000000 +0100
-+++ ffmpeg-v0.7-1696-gcae4f4b/libavcodec/avcodec.h 2012-04-22 10:59:41.122351884 +0200
-@@ -3193,6 +3193,7 @@
+diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
+index 102df3a..aa40c78 100644
+--- a/libavcodec/avcodec.h
++++ b/libavcodec/avcodec.h
+@@ -3093,6 +3093,7 @@ typedef struct AVSubtitle {
unsigned num_rects;
AVSubtitleRect **rects;
int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
+ uint8_t forced;
} AVSubtitle;
- /* packet functions */
-diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-1696-gcae4f4b/libavcodec/pgssubdec.c
---- ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c 2011-11-03 12:29:48.000000000 +0100
-+++ ffmpeg-v0.7-1696-gcae4f4b/libavcodec/pgssubdec.c 2012-04-22 13:09:29.499671541 +0200
-@@ -45,6 +45,8 @@
+ /**
+diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
+index 3335412..3f14a2d 100644
+--- a/libavcodec/pgssubdec.c
++++ b/libavcodec/pgssubdec.c
+@@ -45,6 +45,8 @@ typedef struct PGSSubPresentation {
int y;
int id_number;
int object_number;
@@ -21,7 +23,7 @@ diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-169
} PGSSubPresentation;
typedef struct PGSSubPicture {
-@@ -271,7 +273,8 @@
+@@ -271,7 +273,8 @@ static void parse_palette_segment(AVCodecContext *avctx,
* @todo TODO: Implement forcing of subtitles
*/
static void parse_presentation_segment(AVCodecContext *avctx,
@@ -31,7 +33,7 @@ diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-169
{
PGSSubContext *ctx = avctx->priv_data;
-@@ -280,6 +283,8 @@
+@@ -280,6 +283,8 @@ static void parse_presentation_segment(AVCodecContext *avctx,
int w = bytestream_get_be16(&buf);
int h = bytestream_get_be16(&buf);
@@ -40,7 +42,7 @@ diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-169
av_dlog(avctx, "Video Dimensions %dx%d\n",
w, h);
if (av_image_check_size(w, h, 0, avctx) >= 0)
-@@ -299,16 +304,17 @@
+@@ -299,16 +304,17 @@ static void parse_presentation_segment(AVCodecContext *avctx,
buf += 3;
ctx->presentation.object_number = bytestream_get_byte(&buf);
@@ -61,7 +63,7 @@ diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-169
x = bytestream_get_be16(&buf);
y = bytestream_get_be16(&buf);
-@@ -356,6 +362,9 @@
+@@ -356,6 +362,9 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
*/
memset(sub, 0, sizeof(*sub));
@@ -71,7 +73,7 @@ diff -Naur ffmpeg-v0.7-1696-gcae4f4b.orig/libavcodec/pgssubdec.c ffmpeg-v0.7-169
// Blank if last object_number was 0.
// Note that this may be wrong for more complex subtitles.
if (!ctx->presentation.object_number)
-@@ -441,7 +450,7 @@
+@@ -441,7 +450,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
parse_picture_segment(avctx, buf, segment_length);
break;
case PRESENTATION_SEGMENT:
diff --git a/contrib/ffmpeg/P01-solaris.patch b/contrib/ffmpeg/P01-solaris.patch
index d9bb05be2..8266d0914 100644
--- a/contrib/ffmpeg/P01-solaris.patch
+++ b/contrib/ffmpeg/P01-solaris.patch
@@ -1,5 +1,5 @@
diff --git a/configure b/configure
-index e01d9fd..69ba7ea 100755
+index 07baa2f..4597a0d 100755
--- a/configure
+++ b/configure
@@ -54,6 +54,9 @@ if test "$E1" != 0 || test "$E2" = 0; then
@@ -12,7 +12,7 @@ index e01d9fd..69ba7ea 100755
show_help(){
cat <<EOF
Usage: configure [options]
-@@ -2603,7 +2606,7 @@ EOF
+@@ -2688,7 +2691,7 @@ EOF
check_cc <<EOF || die "endian test failed"
unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
EOF
diff --git a/contrib/ffmpeg/P02-darwin-pic.patch b/contrib/ffmpeg/P02-darwin-pic.patch
index e93180fd3..e9d8dfc00 100644
--- a/contrib/ffmpeg/P02-darwin-pic.patch
+++ b/contrib/ffmpeg/P02-darwin-pic.patch
@@ -1,8 +1,8 @@
diff --git a/configure b/configure
-index e01d9fd..d5d6aec 100755
+index 07baa2f..8a2a581 100755
--- a/configure
+++ b/configure
-@@ -2413,6 +2413,7 @@ case $target_os in
+@@ -2494,6 +2494,7 @@ case $target_os in
AVSERVERLDFLAGS=-Wl,-bind_at_load
objformat="macho"
enabled x86_64 && objformat="macho64"
@@ -10,9 +10,9 @@ index e01d9fd..d5d6aec 100755
enabled_any pic shared ||
{ check_cflags -mdynamic-no-pic && add_asflags -mdynamic-no-pic; }
;;
-@@ -2530,7 +2531,7 @@ esac
+@@ -2614,7 +2615,7 @@ esc(){
- echo "config:$arch:$subarch:$cpu:$target_os:$cc_ident:$LIBAV_CONFIGURATION" >config.fate
+ echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" >config.fate
-check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic
+#check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic
diff --git a/contrib/ffmpeg/P04-darwin-memalign.patch b/contrib/ffmpeg/P04-darwin-memalign.patch
index 7c669b35b..0747dfa3c 100644
--- a/contrib/ffmpeg/P04-darwin-memalign.patch
+++ b/contrib/ffmpeg/P04-darwin-memalign.patch
@@ -1,8 +1,8 @@
diff --git a/libavutil/mem.c b/libavutil/mem.c
-index 27bb30b..6f29363 100644
+index bf1a542..a32d400 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
-@@ -80,6 +80,11 @@ void *av_malloc(size_t size)
+@@ -82,6 +82,11 @@ void *av_malloc(size_t size)
ptr = (char*)ptr + diff;
((char*)ptr)[-1]= diff;
#elif HAVE_POSIX_MEMALIGN
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
index 0d4f4eaac..a6a824fda 100644
--- a/contrib/ffmpeg/module.defs
+++ b/contrib/ffmpeg/module.defs
@@ -1,7 +1,7 @@
$(eval $(call import.MODULE.defs,FFMPEG,ffmpeg,YASM BZIP2 ZLIB))
$(eval $(call import.CONTRIB.defs,FFMPEG))
-FFMPEG.FETCH.url = http://download.handbrake.fr/handbrake/contrib/ffmpeg-v0.7-1696-gcae4f4b.tar.bz2
+FFMPEG.FETCH.url = http://download.handbrake.fr/handbrake/contrib/libav-v0.8-2197-g1a068bf.tar.bz2
FFMPEG.CONFIGURE.deps =
FFMPEG.CONFIGURE.env =
@@ -11,7 +11,8 @@ FFMPEG.CONFIGURE.extra = \
--disable-doc \
--disable-bsfs \
--disable-encoders \
- --disable-ffmpeg \
+ --disable-vda \
+ --disable-vdpau \
--disable-avconv \
--disable-avplay \
--disable-avprobe \
@@ -30,7 +31,6 @@ FFMPEG.CONFIGURE.extra = \
--enable-gpl \
--enable-zlib \
--cc="$(FFMPEG.GCC.gcc)" \
- --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include)" \
--extra-ldflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -L$(call fn.ABSOLUTE,$(CONTRIB.build/)lib)"
## check against tuple: B-SYSTEM where B is { 0 | 1 } for cross-compiling flag
@@ -54,8 +54,16 @@ endif
ifneq (none,$(FFMPEG.GCC.g))
FFMPEG.CONFIGURE.extra += --enable-debug
+
+ifeq (max,$(FFMPEG.GCC.g))
+ FFMPEG.CONFIGURE.extra += --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include) -DDEBUG"
+else
+ FFMPEG.CONFIGURE.extra += --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include) -DNDEBUG"
+endif
+
else
FFMPEG.CONFIGURE.extra += --disable-debug
+ FFMPEG.CONFIGURE.extra += --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include) -DNDEBUG"
endif
ifeq (none,$(FFMPEG.GCC.O))
diff --git a/gtk/src/Makefile.am b/gtk/src/Makefile.am
index 9c1dbd2cd..da65bc926 100644
--- a/gtk/src/Makefile.am
+++ b/gtk/src/Makefile.am
@@ -2,15 +2,15 @@
if MINGW
HB_LIBS= \
- -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdnav -ldvdread \
- -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
- -lx264 -lmp4v2 -lswscale -ltheora -lz \
+ -lhb -la52 -lmkv -lavresample -lavformat -lavcodec -lavutil -ldca \
+ -ldvdnav -ldvdread -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc \
+ -logg -lsamplerate -lx264 -lmp4v2 -lswscale -ltheora -lz \
-lbz2 -liberty -lpthreadGC2 -lbluray -lass -lfontconfig -lfreetype
else
HB_LIBS= \
- -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -ldca -ldvdnav -ldvdread \
- -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
- -lx264 -lmp4v2 -lswscale -ltheora -lz \
+ -lhb -la52 -lmkv -lavresample -lavformat -lavcodec -lavutil -ldca \
+ -ldvdnav -ldvdread -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc \
+ -logg -lsamplerate -lx264 -lmp4v2 -lswscale -ltheora -lz \
-lbz2 -lpthread -lbluray -lass -lfontconfig -lfreetype
endif
diff --git a/libhb/audio_remap.c b/libhb/audio_remap.c
new file mode 100644
index 000000000..6d3877d3d
--- /dev/null
+++ b/libhb/audio_remap.c
@@ -0,0 +1,148 @@
+/* audio_remap.c
+ *
+ * Copyright (c) 2003-2012 HandBrake Team
+ * This file is part of the HandBrake source code
+ * Homepage: <http://handbrake.fr/>
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#include "common.h"
+#include "hbffmpeg.h"
+#include "audio_remap.h"
+
+// source: libavutil/audioconvert.h
+hb_chan_map_t hb_libav_chan_map =
+{
+ {
+ AV_CH_FRONT_LEFT,
+ AV_CH_FRONT_RIGHT,
+ AV_CH_FRONT_CENTER,
+ AV_CH_LOW_FREQUENCY,
+ AV_CH_BACK_LEFT,
+ AV_CH_BACK_RIGHT,
+ AV_CH_FRONT_LEFT_OF_CENTER,
+ AV_CH_FRONT_RIGHT_OF_CENTER,
+ AV_CH_BACK_CENTER,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ 0
+ }
+};
+
+// source: liba52 documentation
+hb_chan_map_t hb_liba52_chan_map =
+{
+ {
+ AV_CH_LOW_FREQUENCY,
+ AV_CH_FRONT_LEFT,
+ AV_CH_FRONT_CENTER,
+ AV_CH_FRONT_RIGHT,
+ AV_CH_BACK_CENTER,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ 0
+ }
+};
+
+// source: libdca documentation and libavcodec/dca.c
+hb_chan_map_t hb_libdca_chan_map =
+{
+ {
+ AV_CH_FRONT_LEFT_OF_CENTER,
+ AV_CH_FRONT_CENTER,
+ AV_CH_FRONT_RIGHT_OF_CENTER,
+ AV_CH_FRONT_LEFT,
+ AV_CH_FRONT_RIGHT,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ AV_CH_LOW_FREQUENCY,
+ 0
+ }
+};
+
+// source: http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9
+hb_chan_map_t hb_vorbis_chan_map =
+{
+ {
+ AV_CH_FRONT_LEFT,
+ AV_CH_FRONT_CENTER,
+ AV_CH_FRONT_RIGHT,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ AV_CH_BACK_LEFT,
+ AV_CH_BACK_CENTER,
+ AV_CH_BACK_RIGHT,
+ AV_CH_LOW_FREQUENCY,
+ 0
+ }
+};
+
+// source: https://developer.apple.com/library/mac/#documentation/musicaudio/reference/CoreAudioDataTypesRef/Reference/reference.html
+hb_chan_map_t hb_aac_chan_map =
+{
+ {
+ AV_CH_FRONT_CENTER,
+ AV_CH_FRONT_LEFT_OF_CENTER,
+ AV_CH_FRONT_RIGHT_OF_CENTER,
+ AV_CH_FRONT_LEFT,
+ AV_CH_FRONT_RIGHT,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ AV_CH_BACK_LEFT,
+ AV_CH_BACK_RIGHT,
+ AV_CH_BACK_CENTER,
+ AV_CH_LOW_FREQUENCY,
+ 0
+ }
+};
+
+int* hb_audio_remap_build_table(uint64_t layout, hb_chan_map_t *map_in, hb_chan_map_t *map_out)
+{
+ int ii, jj, idx, remap_idx, *remap_table;
+ uint64_t *input_order, *output_order;
+
+ remap_table = calloc(HB_AUDIO_REMAP_MAX_CHANNELS, sizeof(int));
+ if (!remap_table)
+ return NULL;
+
+ idx = 0;
+ input_order = map_in->channel_order;
+ output_order = map_out->channel_order;
+ for (ii = 0; output_order[ii]; ii++)
+ {
+ if (layout & output_order[ii])
+ {
+ remap_idx = 0;
+ for (jj = 0; input_order[jj]; jj++)
+ {
+ if (output_order[ii] == input_order[jj])
+ {
+ remap_table[idx++] = remap_idx++;
+ }
+ else if (layout & input_order[jj])
+ {
+ remap_idx++;
+ }
+ }
+ }
+ }
+
+ return remap_table;
+}
+
+void hb_audio_remap(int nchannels, int nsamples, hb_sample_t *samples, int *remap_table)
+{
+ int ii, jj;
+ hb_sample_t tmp[HB_AUDIO_REMAP_MAX_CHANNELS];
+
+ for (ii = 0; ii < nsamples; ii++)
+ {
+ memcpy(tmp, samples, nchannels * sizeof(hb_sample_t));
+ for (jj = 0; jj < nchannels; jj++)
+ {
+ samples[jj] = tmp[remap_table[jj]];
+ }
+ samples += nchannels;
+ }
+} \ No newline at end of file
diff --git a/libhb/audio_remap.h b/libhb/audio_remap.h
new file mode 100644
index 000000000..32ee3e9cb
--- /dev/null
+++ b/libhb/audio_remap.h
@@ -0,0 +1,53 @@
+/* audio_remap.h
+ *
+ * Copyright (c) 2003-2012 HandBrake Team
+ * This file is part of the HandBrake source code
+ * Homepage: <http://handbrake.fr/>
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+/* This file handles the following two scenarios:
+ *
+ * 1) remapping from liba52/libdca order to libav order
+ * - this allows downmixing liba52/libdca sources with libavresample
+ *
+ * 2) remapping from libav order to aac/vorbis order
+ * - this allows encoding audio without libavcodec (faac, ca_aac, libvorbis)
+ *
+ * Thus we only need to support:
+ *
+ * a) channels found in liba52/libdca layouts
+ * b) channels found in HB_AMIXDOWN_* layouts
+ *
+ * Notes:
+ *
+ * Left/Right Surround -> Side Left/Right
+ * Left/Right Rear Surround -> Back Left/Right */
+
+#ifndef AUDIO_REMAP_H
+#define AUDIO_REMAP_H
+
+#include <stdint.h>
+
+// we only need to support the 11 "most common" channels
+#define HB_AUDIO_REMAP_MAX_CHANNELS 11
+
+typedef float hb_sample_t;
+
+typedef struct
+{
+ uint64_t channel_order[HB_AUDIO_REMAP_MAX_CHANNELS+1];
+} hb_chan_map_t;
+
+// used to convert between various channel orders
+extern hb_chan_map_t hb_libav_chan_map;
+extern hb_chan_map_t hb_liba52_chan_map;
+extern hb_chan_map_t hb_libdca_chan_map;
+extern hb_chan_map_t hb_vorbis_chan_map;
+extern hb_chan_map_t hb_aac_chan_map;
+
+int* hb_audio_remap_build_table(uint64_t layout, hb_chan_map_t *map_in, hb_chan_map_t *map_out);
+void hb_audio_remap(int nchannels, int nsamples, hb_sample_t *samples, int *remap_table);
+
+#endif /* AUDIO_REMAP_H */
diff --git a/libhb/common.h b/libhb/common.h
index 16c7acff8..99aae30a1 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -20,7 +20,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
-#include "libavutil/audioconvert.h"
/*
* It seems WinXP doesn't align the stack of new threads to 16 bytes.
@@ -99,7 +98,8 @@ typedef struct hb_lock_s hb_lock_t;
#else
#define PRIVATE const
#endif
-#include "downmix.h"
+#include "audio_remap.h"
+#include "libavutil/audioconvert.h"
hb_list_t * hb_list_init();
int hb_list_count( hb_list_t * );
diff --git a/libhb/deca52.c b/libhb/deca52.c
index 22bfb55da..0c1708de2 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -8,7 +8,7 @@
*/
#include "hb.h"
-#include "downmix.h"
+#include "audio_remap.h"
#include "a52dec/a52.h"
#include "libavutil/crc.h"
@@ -484,7 +484,7 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->channel_layout |= AV_CH_LOW_FREQUENCY;
}
- info->channel_map = &hb_ac3_chan_map;
+ info->channel_map = &hb_liba52_chan_map;
return 1;
}
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index 875a94c67..a32228bf1 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -40,8 +40,7 @@
#include "hb.h"
#include "hbffmpeg.h"
-#include "downmix.h"
-#include "libavcodec/audioconvert.h"
+#include "audio_remap.h"
static void compute_frame_duration( hb_work_private_t *pv );
static void flushDelayQueue( hb_work_private_t *pv );
@@ -98,9 +97,16 @@ struct hb_work_private_s
int sws_width;
int sws_height;
int sws_pix_fmt;
- hb_downmix_t *downmix;
int cadence[12];
int wait_for_keyframe;
+
+ AVAudioResampleContext *avresample;
+ int resample;
+ int out_channels;
+ int stereo_downmix_mode;
+ uint64_t out_channel_layout;
+ uint64_t resample_channel_layout;
+ enum AVSampleFormat resample_sample_fmt;
};
static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size, int64_t pts );
@@ -178,19 +184,19 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
- pv->job = job;
- if ( job )
+ pv->job = job;
+ if (job)
pv->title = job->title;
else
pv->title = w->title;
- pv->list = hb_list_init();
+ pv->list = hb_list_init();
- int codec_id = w->codec_param;
- /*XXX*/
- if ( codec_id == 0 )
- codec_id = CODEC_ID_MP2;
+ // initialize output settings for avresample
+ pv->out_channels = hb_mixdown_get_discrete_channel_count(w->audio->config.out.mixdown);
+ pv->out_channel_layout = hb_ff_mixdown_xlat(w->audio->config.out.mixdown,
+ &pv->stereo_downmix_mode);
- codec = avcodec_find_decoder( codec_id );
+ codec = avcodec_find_decoder( w->codec_param );
if ( pv->title->opaque_priv )
{
AVFormatContext *ic = (AVFormatContext*)pv->title->opaque_priv;
@@ -200,7 +206,7 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
}
else
{
- pv->parser = av_parser_init( codec_id );
+ pv->parser = av_parser_init( w->codec_param );
pv->context = avcodec_alloc_context3(codec);
hb_ff_set_sample_fmt( pv->context, codec );
@@ -211,36 +217,6 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
return 1;
}
- // DTS: work around lack of 6.0/6.1 support in libhb
- if (hb_ff_dts_disable_xch(pv->context))
- {
- hb_deep_log(2, "decavcodecaInit: found DTS-ES, requesting DTS core");
- }
- else if ((!pv->context->channels || !pv->context->channel_layout) &&
- (w->audio->config.in.codec == HB_ACODEC_DCA_HD) &&
- ((w->audio->config.in.channel_layout & ~AV_CH_LOW_FREQUENCY) == AV_CH_LAYOUT_5POINT0))
- {
- /* XXX: when we are demuxing the stream ourselves, it seems we have no
- * channel count/layout info in the context until we decode audio for
- * the first time. If the scan info says the source is 5.0 or 5.1,
- * make sure XCh processing is disabled in Libav before decoding. */
- pv->context->request_channels = pv->context->channels =
- av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout);
- pv->context->channel_layout = w->audio->config.in.channel_layout;
- hb_deep_log(2, "decavcodecaInit: scan detected DTS 5.0/5.1, disabling XCh processing");
- }
-
- if ( w->audio != NULL )
- {
- if ( hb_need_downmix( w->audio->config.in.channel_layout,
- w->audio->config.out.mixdown) )
- {
- pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout,
- w->audio->config.out.mixdown);
- hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map );
- }
- }
-
return 0;
}
@@ -283,14 +259,9 @@ static void closePrivData( hb_work_private_t ** ppv )
{
hb_list_empty( &pv->list );
}
- if ( pv->buffer )
- {
- av_free( pv->buffer );
- pv->buffer = NULL;
- }
- if ( pv->downmix )
+ if ( pv->avresample )
{
- hb_downmix_close( &(pv->downmix) );
+ avresample_free( &pv->avresample );
}
free( pv );
}
@@ -366,10 +337,9 @@ static int decavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
// total samples to per-channel samples. 'sample_rate' converts
// per-channel samples to seconds per sample and the 90000
// is mpeg ticks per second.
- if ( pv->context->sample_rate && pv->context->channels )
+ if ( pv->context->sample_rate )
{
- pv->duration = 90000. /
- (double)( pv->context->sample_rate * pv->context->channels );
+ pv->duration = 90000. / (double)( pv->context->sample_rate );
}
decodeAudio( w->audio, pv, pout, pout_len, cur );
}
@@ -409,11 +379,8 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
{
return decavcodecaInfo( w, info );
}
- // XXX
- // We should parse the bitstream to find its parameters but for right
- // now we just return dummy values if there's a codec that will handle it.
- AVCodec *codec = avcodec_find_decoder( w->codec_param? w->codec_param :
- CODEC_ID_MP2 );
+
+ AVCodec *codec = avcodec_find_decoder( w->codec_param );
if ( ! codec )
{
// there's no ffmpeg codec for this audio type - give up
@@ -430,8 +397,6 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
{
return -1;
}
- uint8_t *buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
- int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
unsigned char *pbuffer;
int pos, pbuffer_size;
@@ -457,21 +422,16 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
pos += len;
if ( pbuffer_size > 0 )
{
+ AVFrame frame;
+ int got_frame;
AVPacket avp;
av_init_packet( &avp );
avp.data = pbuffer;
avp.size = pbuffer_size;
- len = avcodec_decode_audio3( context, (int16_t*)buffer,
- &out_size, &avp );
+ len = avcodec_decode_audio4( context, &frame, &got_frame, &avp );
if ( len > 0 && context->sample_rate > 0 )
{
- // DTS: work around lack of 6.0/6.1 support in libhb
- if( hb_ff_dts_disable_xch( context ) )
- {
- hb_deep_log( 2, "decavcodecaBSInfo: found DTS-ES, requesting DTS core" );
- }
- int isamp = av_get_bytes_per_sample( context->sample_fmt );
info->bitrate = context->bit_rate;
info->rate = context->sample_rate;
info->rate_base = 1;
@@ -479,11 +439,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
hb_ff_layout_xlat(context->channel_layout,
context->channels);
ret = 1;
- if ( context->channels && isamp )
- {
- info->samples_per_frame = out_size /
- (isamp * context->channels);
- }
+ info->samples_per_frame = frame.nb_samples;
break;
}
}
@@ -493,9 +449,8 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
info->profile = context->profile;
info->level = context->level;
- info->channel_map = &hb_smpte_chan_map;
+ info->channel_map = &hb_libav_chan_map;
- av_free( buffer );
if ( parser != NULL )
av_parser_close( parser );
hb_avcodec_close( context );
@@ -1007,6 +962,8 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
pv->title = w->title;
pv->list = hb_list_init();
+ // XXX: A bug in libav prores decoder causes incorrect decoding when
+ // threaded decode is enabled. So disable it till this bug is fixed.
if( pv->job && pv->job->title && !pv->job->title->has_resolution_change &&
w->codec_param != CODEC_ID_PRORES )
{
@@ -1024,8 +981,6 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
pv->context = avcodec_alloc_context3(codec);
avcodec_copy_context( pv->context, ic->streams[pv->title->video_id]->codec);
pv->context->workaround_bugs = FF_BUG_AUTODETECT;
- // Depricated but still used by Libav (twits!)
- pv->context->error_recognition = FF_ER_CAREFUL;
pv->context->err_recognition = AV_EF_CRCCHECK;
pv->context->error_concealment = FF_EC_GUESS_MVS|FF_EC_DEBLOCK;
@@ -1049,8 +1004,6 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
pv->parser = av_parser_init( w->codec_param );
pv->context = avcodec_alloc_context3( codec );
pv->context->workaround_bugs = FF_BUG_AUTODETECT;
- // Depricated but still used by Libav (twits!)
- pv->context->error_recognition = FF_ER_CAREFUL;
pv->context->err_recognition = AV_EF_CRCCHECK;
pv->context->error_concealment = FF_EC_GUESS_MVS|FF_EC_DEBLOCK;
init_video_avcodec_context( pv );
@@ -1451,28 +1404,81 @@ hb_work_object_t hb_decavcodecv =
.bsinfo = decavcodecvBSInfo
};
-static hb_buffer_t * downmixAudio(
- hb_audio_t *audio,
- hb_work_private_t *pv,
- hb_sample_t *buffer,
- int channels,
- int nsamples )
+static hb_buffer_t * downmixAudio(hb_work_private_t *pv,
+ hb_audio_t *audio,
+ AVFrame *frame)
{
- hb_buffer_t * buf = NULL;
+ uint64_t in_layout;
+ int resample_changed;
+
+ in_layout = hb_ff_layout_xlat(pv->context->channel_layout, pv->context->channels);
+ pv->resample = (pv->resample ||
+ pv->out_channel_layout != in_layout ||
+ pv->context->sample_fmt != AV_SAMPLE_FMT_FLT);
+ resample_changed = (pv->resample &&
+ (pv->resample_channel_layout != in_layout ||
+ pv->resample_sample_fmt != pv->context->sample_fmt));
- if ( pv->downmix )
+ if (resample_changed || (pv->resample && pv->avresample == NULL))
{
- int n_ch_samples = nsamples / channels;
- int out_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown );
+ if (pv->avresample == NULL)
+ {
+ pv->avresample = avresample_alloc_context();
+ if (pv->avresample == NULL)
+ {
+ hb_error("Failed to initialize avresample");
+ return NULL;
+ }
+ // output settings only need to be set once
+ av_opt_set_int(pv->avresample, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+ av_opt_set_int(pv->avresample, "out_channel_layout", pv->out_channel_layout, 0);
+ av_opt_set_int(pv->avresample, "matrix_encoding", pv->stereo_downmix_mode, 0);
+ }
+ else if (resample_changed)
+ {
+ avresample_close(pv->avresample);
+ }
- buf = hb_buffer_init( n_ch_samples * out_channels * sizeof(float) );
- hb_sample_t *samples = (hb_sample_t *)buf->data;
- hb_downmix(pv->downmix, samples, buffer, n_ch_samples);
+ av_opt_set_int(pv->avresample, "in_channel_layout", in_layout, 0);
+ av_opt_set_int(pv->avresample, "in_sample_fmt", pv->context->sample_fmt, 0);
+ if (av_get_bytes_per_sample(pv->context->sample_fmt) <= 2)
+ av_opt_set_int(pv->avresample, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
+
+ if (avresample_open(pv->avresample) < 0)
+ {
+ hb_error("Failed to open libavresample");
+ return NULL;
+ }
+
+ pv->resample_channel_layout = in_layout;
+ pv->resample_sample_fmt = pv->context->sample_fmt;
+ }
+
+ hb_buffer_t *buf;
+ int out_size, out_linesize, sample_size;
+ sample_size = av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT);
+ out_size = av_samples_get_buffer_size(&out_linesize, pv->out_channels,
+ frame->nb_samples, AV_SAMPLE_FMT_FLT, !pv->resample);
+ buf = hb_buffer_init(out_size);
+
+ if (pv->resample)
+ {
+ int out_samples;
+ out_samples = avresample_convert(pv->avresample,
+ (void**)&buf->data, out_linesize, frame->nb_samples,
+ (void**)frame->data, frame->linesize[0], frame->nb_samples);
+
+ if (out_samples < 0)
+ {
+ hb_error("avresample_convert() failed");
+ return NULL;
+ }
+ buf->size = out_samples * sample_size * pv->out_channels;
}
else
{
- buf = hb_buffer_init( nsamples * sizeof(float) );
- memcpy( buf->data, buffer, nsamples * sizeof(float) );
+ memcpy(buf->data, frame->data[0], out_size);
+ buf->size = frame->nb_samples * sample_size * pv->out_channels;
}
return buf;
@@ -1490,13 +1496,8 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat
pv->pts_next = pts;
while ( pos < size )
{
- float *buffer = pv->buffer;
- if ( buffer == NULL )
- {
- pv->buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
- buffer = pv->buffer;
- }
-
+ AVFrame frame;
+ int got_frame;
AVPacket avp;
av_init_packet( &avp );
avp.data = data + pos;
@@ -1504,14 +1505,12 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat
avp.pts = pv->pts_next;
avp.dts = AV_NOPTS_VALUE;
- int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
- int nsamples;
- int len = avcodec_decode_audio3( context, (int16_t*)buffer, &out_size, &avp );
+ int len = avcodec_decode_audio4( context, &frame, &got_frame, &avp );
if ( len < 0 )
{
return;
}
- if ( len == 0 )
+ if ( !got_frame )
{
if ( !(loop_limit--) )
return;
@@ -1520,11 +1519,9 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat
loop_limit = 256;
pos += len;
- if( out_size > 0 )
+ if( got_frame )
{
- int isamp = av_get_bytes_per_sample( context->sample_fmt );
- nsamples = out_size / isamp;
- double duration = nsamples * pv->duration;
+ double duration = frame.nb_samples * pv->duration;
double pts_next = pv->pts_next + duration;
// DTS-HD can be passed through to mkv
@@ -1545,50 +1542,15 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat
continue;
}
- // We require floats for the output format. If
- // we got something different convert it.
- if ( context->sample_fmt != AV_SAMPLE_FMT_FLT )
+ hb_buffer_t * buf = downmixAudio( pv, audio, &frame );
+ if ( buf != NULL )
{
- // Note: av_audio_convert seems to be a work-in-progress but
- // looks like it will eventually handle general audio
- // mixdowns which would allow us much more flexibility
- // in handling multichannel audio in HB. If we were doing
- // anything more complicated than a one-for-one format
- // conversion we'd probably want to cache the converter
- // context in the pv.
- AVAudioConvert *ctx;
-
- ctx = av_audio_convert_alloc( AV_SAMPLE_FMT_FLT, 1,
- context->sample_fmt, 1,
- NULL, 0 );
-
- // get output buffer size then malloc a buffer
- buffer = av_malloc( nsamples * sizeof(hb_sample_t) );
-
- // we're doing straight sample format conversion which
- // behaves as if there were only one channel.
- const void * const ibuf[6] = { pv->buffer };
- void * const obuf[6] = { buffer };
- const int istride[6] = { isamp };
- const int ostride[6] = { sizeof(hb_sample_t) };
-
- av_audio_convert( ctx, obuf, ostride, ibuf, istride, nsamples );
- av_audio_convert_free( ctx );
- }
-
- hb_buffer_t * buf;
- buf = downmixAudio( audio, pv, buffer, context->channels, nsamples );
- buf->s.start = pv->pts_next;
- buf->s.duration = duration;
- buf->s.stop = pts_next;
- hb_list_add( pv->list, buf );
-
- pv->pts_next = pts_next;
+ buf->s.start = pv->pts_next;
+ buf->s.duration = duration;
+ buf->s.stop = pts_next;
+ hb_list_add( pv->list, buf );
- // if we allocated a buffer for sample format conversion, free it
- if ( buffer != pv->buffer )
- {
- av_free( buffer );
+ pv->pts_next = pts_next;
}
}
}
diff --git a/libhb/decdca.c b/libhb/decdca.c
index 9f426d6a4..17d0e7755 100644
--- a/libhb/decdca.c
+++ b/libhb/decdca.c
@@ -8,7 +8,7 @@
*/
#include "hb.h"
-#include "downmix.h"
+#include "audio_remap.h"
#include "dca.h"
@@ -425,7 +425,7 @@ static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->channel_layout |= AV_CH_LOW_FREQUENCY;
}
- info->channel_map = &hb_qt_chan_map;
+ info->channel_map = &hb_libdca_chan_map;
dca_free( state );
return 1;
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index 5c6a0e4a1..86dd6e823 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -8,14 +8,14 @@
*/
#include "hb.h"
-#include "downmix.h"
+#include "audio_remap.h"
struct hb_work_private_s
{
hb_job_t *job;
uint32_t size; /* frame size in bytes */
- uint32_t chunks; /* number of samples pairs if paired */
- uint32_t samples; /* frame size in samples */
+ uint32_t nchunks; /* number of samples pairs if paired */
+ uint32_t nsamples; /* frame size in samples */
uint32_t pos; /* buffer offset for next input data */
int64_t next_pts; /* pts for next output frame */
@@ -29,6 +29,15 @@ struct hb_work_private_s
uint8_t sample_size; /* bits per sample */
uint8_t frame[HB_DVD_READ_BUFFER_SIZE*2];
+ uint8_t * data;
+ uint32_t alloc_size;
+
+ AVAudioResampleContext *avresample;
+ int resample;
+ int out_channels;
+ int stereo_downmix_mode;
+ uint64_t out_channel_layout;
+ uint64_t resample_channel_layout;
};
static hb_buffer_t * Decode( hb_work_object_t * w );
@@ -53,12 +62,85 @@ static const int hdr2samplerate[] = { 48000, 96000, 44100, 32000 };
static const int hdr2samplesize[] = { 16, 20, 24, 16 };
static const uint64_t hdr2layout[] =
{
- AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO,
- AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_2_2,
- AV_CH_LAYOUT_5POINT0, AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER,
- AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_QUAD,
+ AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_6POINT0_FRONT,
+ AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO,
};
+static hb_buffer_t * downmixAudio(hb_work_private_t *pv,
+ hb_audio_t *audio)
+{
+ int64_t in_layout;
+ int resample_changed;
+
+ in_layout = hdr2layout[pv->nchannels - 1];
+ pv->resample = pv->resample || (pv->out_channel_layout != in_layout);
+ resample_changed = pv->resample && (pv->resample_channel_layout != in_layout);
+
+ if (resample_changed || (pv->resample && pv->avresample == NULL))
+ {
+ if (pv->avresample == NULL)
+ {
+ pv->avresample = avresample_alloc_context();
+ if (pv->avresample == NULL)
+ {
+ hb_error("Failed to initialize avresample");
+ return NULL;
+ }
+ // some settings only need to be set once
+ av_opt_set_int(pv->avresample, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+ av_opt_set_int(pv->avresample, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+ av_opt_set_int(pv->avresample, "out_channel_layout", pv->out_channel_layout, 0);
+ av_opt_set_int(pv->avresample, "matrix_encoding", pv->stereo_downmix_mode, 0);
+ }
+ else if (resample_changed)
+ {
+ avresample_close(pv->avresample);
+ }
+
+ av_opt_set_int(pv->avresample, "in_channel_layout", in_layout, 0);
+
+ if (avresample_open(pv->avresample) < 0)
+ {
+ hb_error("Failed to open libavresample");
+ return NULL;
+ }
+
+ pv->resample_channel_layout = in_layout;
+ }
+
+ hb_buffer_t *buf;
+ int out_size, out_linesize, sample_size;
+ sample_size = av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT);
+ out_size = av_samples_get_buffer_size(&out_linesize, pv->out_channels,
+ pv->nsamples, AV_SAMPLE_FMT_FLT, !pv->resample);
+ buf = hb_buffer_init(out_size);
+
+ if (pv->resample)
+ {
+ int in_linesize, out_samples;
+ in_linesize = pv->nsamples * pv->nchannels * sample_size;
+ out_samples = avresample_convert(pv->avresample,
+ (void**)&buf->data, out_linesize, pv->nsamples,
+ (void**)&pv->data, in_linesize, pv->nsamples);
+
+ if (out_samples < 0)
+ {
+ hb_error("avresample_convert() failed");
+ return NULL;
+ }
+ buf->size = out_samples * sample_size * pv->out_channels;
+ }
+ else
+ {
+ memcpy(buf->data, pv->data, out_size);
+ buf->size = pv->nsamples * sample_size * pv->out_channels;
+ }
+
+ return buf;
+}
+
static void lpcmInfo( hb_work_object_t *w, hb_buffer_t *in )
{
hb_work_private_t * pv = w->private_data;
@@ -99,8 +181,8 @@ static void lpcmInfo( hb_work_object_t *w, hb_buffer_t *in )
hb_log( "declpcm: illegal frame offset %d", pv->offset );
pv->offset = 2; /*XXX*/
}
- pv->samplerate = hdr2samplerate[ ( in->data[4] >> 4 ) & 0x3 ];
- pv->nchannels = ( in->data[4] & 7 ) + 1;
+ pv->nchannels = ( in->data[4] & 7 ) + 1;
+ pv->samplerate = hdr2samplerate[ ( in->data[4] >> 4 ) & 0x3 ];
pv->sample_size = hdr2samplesize[in->data[4] >> 6];
// 20 and 24 bit lpcm is always encoded in sample pairs. So take this
@@ -142,10 +224,10 @@ static void lpcmInfo( hb_work_object_t *w, hb_buffer_t *in )
149 ) / 150;
pv->duration = frames * 150;
- pv->chunks = ( pv->duration * pv->nchannels * pv->samplerate +
+ pv->nchunks = ( pv->duration * pv->nchannels * pv->samplerate +
samples_per_chunk - 1 ) / ( 90000 * samples_per_chunk );
- pv->samples = ( pv->duration * pv->nchannels * pv->samplerate ) / 90000;
- pv->size = pv->chunks * chunk_size;
+ pv->nsamples = ( pv->duration * pv->samplerate ) / 90000;
+ pv->size = pv->nchunks * chunk_size;
pv->next_pts = in->s.start;
}
@@ -154,7 +236,13 @@ static int declpcmInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
- pv->job = job;
+ pv->job = job;
+
+ // initialize output settings for avresample
+ pv->out_channels = hb_mixdown_get_discrete_channel_count(w->audio->config.out.mixdown);
+ pv->out_channel_layout = hb_ff_mixdown_xlat(w->audio->config.out.mixdown,
+ &pv->stereo_downmix_mode);
+
return 0;
}
@@ -215,20 +303,19 @@ static int declpcmWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
static hb_buffer_t *Decode( hb_work_object_t *w )
{
hb_work_private_t *pv = w->private_data;
- hb_buffer_t *out;
- if (pv->samples == 0)
+ if (pv->nsamples == 0)
return NULL;
- out = hb_buffer_init( pv->samples * sizeof( float ) );
-
- out->s.start = pv->next_pts;
- out->s.duration = pv->duration;
- pv->next_pts += pv->duration;
- out->s.stop = pv->next_pts;
+ int size = pv->nsamples * pv->nchannels * sizeof( float );
+ if (pv->alloc_size != size)
+ {
+ pv->data = realloc( pv->data, size );
+ pv->alloc_size = size;
+ }
- float *odat = (float *)out->data;
- int count = pv->chunks / pv->nchannels;
+ float *odat = (float *)pv->data;
+ int count = pv->nchunks / pv->nchannels;
switch( pv->sample_size )
{
@@ -312,14 +399,30 @@ static hb_buffer_t *Decode( hb_work_object_t *w )
}
} break;
}
+
+ hb_buffer_t *out;
+ out = downmixAudio( pv, w->audio );
+
+ out->s.start = pv->next_pts;
+ out->s.duration = pv->duration;
+ pv->next_pts += pv->duration;
+ out->s.stop = pv->next_pts;
+
return out;
}
static void declpcmClose( hb_work_object_t * w )
{
- if ( w->private_data )
+ hb_work_private_t * pv = w->private_data;
+
+ if ( pv )
{
- free( w->private_data );
+ if ( pv->avresample )
+ {
+ avresample_free( &pv->avresample );
+ }
+ free( pv->data );
+ free( pv );
w->private_data = 0;
}
}
@@ -342,7 +445,7 @@ static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->bitrate = bitrate;
info->flags = ( b->data[3] << 16 ) | ( b->data[4] << 8 ) | b->data[5];
info->channel_layout = hdr2layout[nchannels - 1];
- info->channel_map = &hb_qt_chan_map;
+ info->channel_map = &hb_libav_chan_map;
info->samples_per_frame = ( duration * rate ) / 90000;
return 1;
diff --git a/libhb/downmix.c b/libhb/downmix.c
index e5ed1c599..e69de29bb 100644
--- a/libhb/downmix.c
+++ b/libhb/downmix.c
@@ -1,1640 +0,0 @@
-/* downmix.c
-
- Copyright (c) 2003-2012 HandBrake Team
- This file is part of the HandBrake source code
- Homepage: <http://handbrake.fr/>.
- It may be used under the terms of the GNU General Public License v2.
- For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include "common.h"
-#include "downmix.h"
-
-#define LVL_PLUS6DB 2.0
-#define LVL_PLUS3DB 1.4142135623730951
-#define LVL_3DB 0.7071067811865476
-#define LVL_45DB 0.5946035575013605
-#define LVL_6DB 0.5
-
-#define LVL_SQRT_1_4 0.5
-#define LVL_SQRT_3_4 0.866025404
-
-#define HB_CH_FRONT_LEFT 0x00000001
-#define HB_CH_FRONT_RIGHT 0x00000002
-#define HB_CH_FRONT_CENTER 0x00000004
-#define HB_CH_LOW_FREQUENCY 0x00000008
-#define HB_CH_BACK_LEFT 0x00000010
-#define HB_CH_BACK_RIGHT 0x00000020
-#define HB_CH_BACK_CENTER 0x00000040
-#define HB_CH_SIDE_LEFT 0x00000080
-#define HB_CH_SIDE_RIGHT 0x00000100
-
-#define HB_CH_SURROUND_MASK 0x000001f0
-#define HB_CH_MASK 0x000007ff
-
-#define HB_CH_DOLBY 0x00000800
-#define HB_CH_DPLII 0x00001000
-
-#define DOWNMIX_MONO 0
-#define DOWNMIX_STEREO 1
-#define DOWNMIX_3F 2
-#define DOWNMIX_2F1R 3
-#define DOWNMIX_3F1R 4
-#define DOWNMIX_2F2R 5
-#define DOWNMIX_3F2R 6
-#define DOWNMIX_3F4R 7
-#define DOWNMIX_DOLBY 8
-#define DOWNMIX_DPLII 9
-#define DOWNMIX_NUM_MODES 10
-
-#define DOWNMIX_CHANNEL_MASK 0x0f
-
-#define DOWNMIX_LFE_FLAG 0x10
-#define DOWNMIX_FLAGS_MASK 0x10
-
-hb_sample_t downmix_matrix[DOWNMIX_NUM_MODES][DOWNMIX_NUM_MODES][8][8] =
-{
-// MONO in
-{
- // MONO out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DOLBY out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// STEREO in
-{
- // MONO out
- { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DOLBY out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 3F in
-{
- // MONO out
- { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DOLBY out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 2F1R in
-{
- // MONO out
- { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 0, 1, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 1, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, LVL_3DB, LVL_3DB, 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 1 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 } },
- // DOLBY out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 3F1R in
-{
- // MONO out
- { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 1, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 1, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 1, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, LVL_3DB, LVL_3DB, 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 1 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 },
- { 0, 0, 0, 0, 0, 0, 0 , 0 } },
- // DOLBY out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 2F2R in
-{
- // MONO out
- { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 1, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DOLBY out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_6DB, LVL_6DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_6DB, LVL_6DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_3_4, LVL_SQRT_1_4, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_1_4, LVL_SQRT_3_4, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 3F2R in
-{
- // MONO out
- { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 2F2R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // 3F4R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 1, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DOLBY out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_3_4, LVL_SQRT_1_4, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_1_4, LVL_SQRT_3_4, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
-},
-// 3F4R in
-{
- // MONO out
- { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
- { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 } },
- // STEREO out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 } },
- // 3F out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 } },
- // 2F1R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 } },
- // 3F1R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 } },
- // 2F2R out
- { { 1, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 } },
- // 3F2R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, LVL_3DB, 0, 0, 0 },
- { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
- { 0, 0, 0, 0, LVL_3DB, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 } },
- // 3F4R out
- { { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 1, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 } },
- // DOLBY out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 } },
- // DPLII out
- { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_3_4*LVL_3DB, LVL_SQRT_1_4*LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_1_4*LVL_3DB, LVL_SQRT_3_4*LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_3_4*LVL_3DB, LVL_SQRT_1_4*LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { -LVL_SQRT_1_4*LVL_3DB, LVL_SQRT_3_4*LVL_3DB, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 } }
-},
-};
-
-static int channel_layout_map[DOWNMIX_NUM_MODES] =
-{
- // DOWNMIX_MONO
- (HB_CH_FRONT_CENTER),
- // DOWNMIX_STEREO
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT),
- // DOWNMIX_3F
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER),
- // DOWNMIX_2F1R
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_BACK_CENTER),
- // DOWNMIX_3F1R
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_BACK_CENTER),
- // DOWNMIX_2F2R
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
- // DOWNMIX_3F2R
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
- // DOWNMIX_3F4R
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_SIDE_LEFT|
- HB_CH_SIDE_RIGHT|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
- // DOWNMIX_DOLBY
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT),
- // DOWNMIX_DPLII
- (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT)
-};
-
-int hb_layout_to_mode(uint64_t layout)
-{
- int mode = 0;
- if (layout & AV_CH_LOW_FREQUENCY)
- mode |= DOWNMIX_LFE_FLAG;
- switch (layout & ~AV_CH_LOW_FREQUENCY)
- {
- case AV_CH_LAYOUT_MONO:
- mode |= DOWNMIX_MONO;
- break;
- case AV_CH_LAYOUT_STEREO:
- case AV_CH_LAYOUT_STEREO_DOWNMIX:
- mode |= DOWNMIX_STEREO;
- break;
- case AV_CH_LAYOUT_SURROUND:
- mode |= DOWNMIX_3F;
- break;
- case AV_CH_LAYOUT_2_1:
- mode |= DOWNMIX_2F1R;
- break;
- case AV_CH_LAYOUT_4POINT0:
- mode |= DOWNMIX_3F1R;
- break;
- case AV_CH_LAYOUT_2_2:
- case AV_CH_LAYOUT_QUAD:
- mode |= DOWNMIX_2F2R;
- break;
- case AV_CH_LAYOUT_5POINT0:
- case AV_CH_LAYOUT_5POINT0_BACK:
- mode |= DOWNMIX_3F2R;
- break;
- case AV_CH_LAYOUT_7POINT0:
- mode |= DOWNMIX_3F4R;
- break;
- default:
- {
- switch (av_get_channel_layout_nb_channels(layout))
- {
- case 1:
- mode = DOWNMIX_MONO;
- break;
- case 2:
- mode = DOWNMIX_STEREO;
- break;
- case 3:
- mode = DOWNMIX_3F;
- break;
- case 4:
- mode = DOWNMIX_2F2R;
- break;
- case 5:
- mode = DOWNMIX_3F2R;
- break;
- case 6:
- mode = DOWNMIX_3F2R|DOWNMIX_LFE_FLAG;
- break;
- case 7:
- mode = DOWNMIX_3F4R;
- break;
- case 8:
- mode = DOWNMIX_3F4R|DOWNMIX_LFE_FLAG;
- break;
- default:
- // This will likely not sound very good ;)
- mode = DOWNMIX_STEREO;
- hb_error("hb_layout_to_mode: unsupported layout 0x%"PRIx64" with %d channels",
- layout, av_get_channel_layout_nb_channels(layout));
- break;
- }
- } break;
- }
- return mode;
-}
-
-int hb_mixdown_to_mode(uint32_t mixdown)
-{
- switch (mixdown)
- {
- case HB_AMIXDOWN_MONO:
- return DOWNMIX_MONO;
- case HB_AMIXDOWN_STEREO:
- return DOWNMIX_STEREO;
- case HB_AMIXDOWN_DOLBY:
- return DOWNMIX_DOLBY;
- case HB_AMIXDOWN_DOLBYPLII:
- return DOWNMIX_DPLII;
- case HB_AMIXDOWN_6CH:
- return DOWNMIX_3F2R|DOWNMIX_LFE_FLAG;
- default:
- return DOWNMIX_STEREO;
- }
-}
-
-
-// ffmpeg gives us SMPTE channel layout
-// We could use this layout and remap channels in encfaac,
-// but VLC may have problems with remapping, so lets
-// allow remapping to the default QuickTime order which is:
-//
-// C L R LS RS Rls Rrs LFE
-//
-// This arrangement also makes it possible to use half as
-// many downmix matrices since the matrix with and without
-// LFE are the same.
-//
-// Use hb_layout_remap to accomplish this. For convenience
-// I've provided the necessary maps.
-//
-// SMPTE channel layout
-//
-// DUAL-MONO L R
-// DUAL-MONO-LFE L R LFE
-// MONO M
-// MONO-LFE M LFE
-// STEREO L R
-// STEREO-LFE L R LFE
-// 3F L R C
-// 3F-LFE L R C LFE
-// 2F1 L R S
-// 2F1-LFE L R LFE S
-// 3F1 L R C S
-// 3F1-LFE L R C LFE S
-// 2F2 L R LS RS
-// 2F2-LFE L R LFE LS RS
-// 3F2 L R C LS RS
-// 3F2-LFE L R C LFE LS RS
-// 3F4 L R C Rls Rrs LS RS
-// 3F4-LFE L R C LFE Rls Rrs LS RS
-//
-
-#define CH_C 0
-#define CH_L 1
-#define CH_R 2
-#define CH_CS 3
-#define CH_LS 3
-#define CH_RS 4
-#define CH_Rls 5
-#define CH_Rrs 6
-#define CH_LFE 7
-
-hb_chan_map_t hb_qt_chan_map =
-{
-{
- {{ CH_C, },
- { CH_C, CH_LFE, }}, // MONO
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, CH_LFE, }}, // STEREO
-
- {{ CH_C, CH_L, CH_R, },
- { CH_C, CH_L, CH_R, CH_LFE, }}, // 3F
-
- {{ CH_L, CH_R, CH_CS, },
- { CH_L, CH_R, CH_CS, CH_LFE, }}, // 2F1R
-
- {{ CH_C, CH_L, CH_R, CH_CS, },
- { CH_C, CH_L, CH_R, CH_CS, CH_LFE, }}, // 3F1R
-
- {{ CH_L, CH_R, CH_LS, CH_RS, },
- { CH_L, CH_R, CH_LS, CH_RS, CH_LFE, }}, // 2F2R
-
- {{ CH_C, CH_L, CH_R, CH_LS, CH_RS, },
- { CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_LFE, }}, // 3F2R
-
- {{ CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, },
- { CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, CH_LFE }}, // 3F4R
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }}, // DOLBY
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }} // DPLII
-},
-{
- // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
- {{ 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 }}, // MONO
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 2 }}, // STEREO
-
- {{ 0, 1, 2, 0, 0, 0, 0, 0 },
- { 0, 1, 2, 0, 0, 0, 0, 3 }}, // 3F
-
- {{ 0, 0, 1, 2, 0, 0, 0, 0 },
- { 0, 0, 1, 2, 0, 0, 0, 3 }}, // 2F1R
-
- {{ 0, 1, 2, 3, 0, 0, 0, 0 },
- { 0, 1, 2, 3, 0, 0, 0, 4 }}, // 3F1R
-
- {{ 0, 0, 1, 2, 3, 0, 0, 0 },
- { 0, 0, 1, 2, 3, 0, 0, 4 }}, // 2F2R
-
- {{ 0, 1, 2, 3, 4, 0, 0, 0 },
- { 0, 1, 2, 3, 4, 0, 0, 5 }}, // 3F2R
-
- {{ 0, 1, 2, 3, 4, 5, 6, 0 },
- { 0, 1, 2, 3, 4, 5, 6, 7 }}, // 3F4R
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
-}
-};
-
-hb_chan_map_t hb_smpte_chan_map =
-{
-{
- {{ CH_C, },
- { CH_C, CH_LFE, }}, // MONO
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, CH_LFE, }}, // STEREO
-
- {{ CH_L, CH_R, CH_C, },
- { CH_L, CH_R, CH_C, CH_LFE, }}, // 3F
-
- {{ CH_L, CH_R, CH_CS, },
- { CH_L, CH_R, CH_LFE, CH_CS, }}, // 2F1R
-
- {{ CH_L, CH_R, CH_C, CH_CS, },
- { CH_L, CH_R, CH_LFE, CH_CS, }}, // 3F1R
-
- {{ CH_L, CH_R, CH_LS, CH_RS, },
- { CH_L, CH_R, CH_LFE, CH_LS, CH_RS, }}, // 2F2R
-
- {{ CH_L, CH_R, CH_C, CH_LS, CH_RS, },
- { CH_L, CH_R, CH_C, CH_LFE, CH_LS, CH_RS, }}, // 3F2R
-
- {{ CH_L, CH_R, CH_C, CH_Rls, CH_Rrs, CH_LS, CH_RS },
- { CH_L, CH_R, CH_C, CH_LFE, CH_Rls, CH_Rrs, CH_LS, CH_RS }}, // 3F4R
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }}, // DOLBY
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }} // DPLII
-},
-{
- // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
- {{ 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1 }}, // MONO
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 2 }}, // STEREO
-
- {{ 2, 0, 1, 0, 0, 0, 0, 0 },
- { 2, 0, 1, 0, 0, 0, 0, 3 }}, // 3F
-
- {{ 0, 0, 1, 2, 0, 0, 0, 0 },
- { 0, 0, 1, 3, 0, 0, 0, 2 }}, // 2F1R
-
- {{ 2, 0, 1, 3, 0, 0, 0, 0 },
- { 2, 0, 1, 4, 0, 0, 0, 3 }}, // 3F1R
-
- {{ 0, 0, 1, 2, 3, 0, 0, 0 },
- { 0, 0, 1, 3, 4, 0, 0, 2 }}, // 2F2R
-
- {{ 2, 0, 1, 3, 4, 0, 0, 0 },
- { 2, 0, 1, 4, 5, 0, 0, 3 }}, // 3F2R
-
- {{ 2, 0, 1, 5, 6, 3, 4, 0 },
- { 2, 0, 1, 6, 7, 4, 5, 3 }}, // 3F4R
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
-}
-};
-
-hb_chan_map_t hb_ac3_chan_map =
-{
-{
- {{ CH_C, },
- { CH_LFE, CH_C, }}, // MONO
-
- {{ CH_L, CH_R, },
- { CH_LFE, CH_L, CH_R, }}, // STEREO
-
- {{ CH_L, CH_C, CH_R, },
- { CH_LFE, CH_L, CH_C, CH_R, }}, // 3F
-
- {{ CH_L, CH_R, CH_CS, },
- { CH_LFE, CH_L, CH_R, CH_CS, }}, // 2F1R
-
- {{ CH_L, CH_C, CH_R, CH_CS, },
- { CH_LFE, CH_L, CH_C, CH_R, CH_CS, }}, // 3F1R
-
- {{ CH_L, CH_R, CH_LS, CH_RS, },
- { CH_LFE, CH_L, CH_R, CH_LS, CH_RS, }}, // 2F2R
-
- {{ CH_L, CH_C, CH_R, CH_LS, CH_RS, },
- { CH_LFE, CH_L, CH_C, CH_R, CH_LS, CH_RS, }}, // 3F2R
-
- {{ CH_L, CH_C, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, },
- { CH_LFE, CH_L, CH_C, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs }}, // 3F4R
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }}, // DOLBY
-
- {{ CH_L, CH_R, },
- { CH_L, CH_R, }} // DPLII
-},
-{
- // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
- {{ 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0 }}, // MONO
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 1, 2, 0, 0, 0, 0, 0 }}, // STEREO
-
- {{ 1, 0, 2, 0, 0, 0, 0, 0 },
- { 2, 1, 3, 0, 0, 0, 0, 0 }}, // 3F
-
- {{ 0, 0, 1, 2, 0, 0, 0, 0 },
- { 0, 1, 2, 3, 0, 0, 0, 0 }}, // 2F1R
-
- {{ 1, 0, 2, 3, 0, 0, 0, 0 },
- { 2, 1, 3, 4, 0, 0, 0, 0 }}, // 3F1R
-
- {{ 0, 0, 1, 2, 3, 0, 0, 0 },
- { 0, 1, 2, 3, 4, 0, 0, 0 }}, // 2F2R
-
- {{ 1, 0, 2, 3, 4, 0, 0, 0 },
- { 2, 1, 3, 4, 5, 0, 0, 0 }}, // 3F2R
-
- {{ 1, 0, 2, 3, 4, 5, 6, 0 },
- { 2, 1, 3, 4, 5, 6, 7, 0 }}, // 3F4R
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
-
- {{ 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
-}
-};
-
-static const uint8_t nchans_tbl[] = {1, 2, 3, 3, 4, 4, 5, 7, 2, 2};
-
-// Takes a set of samples and remaps the channel layout
-void hb_layout_remap(hb_chan_map_t *map_in,
- hb_chan_map_t *map_out,
- uint64_t layout,
- hb_sample_t *samples,
- int nsamples)
-{
- int nchans;
- int ii, jj;
- int lfe;
- int * map;
- int * inv_map;
- int mode;
- hb_sample_t tmp[8];
-
- mode = hb_layout_to_mode(layout);
- lfe = ((mode & DOWNMIX_LFE_FLAG) != 0);
- mode = mode & DOWNMIX_CHANNEL_MASK;
- nchans = nchans_tbl[mode] + lfe;
- inv_map = map_in->inv_chan_map[mode][lfe];
- map = map_out->chan_map[mode][lfe];
-
- for (ii = 0; ii < nsamples; ii++)
- {
- for (jj = 0; jj < nchans; jj++)
- {
- tmp[jj] = samples[jj];
- }
- for (jj = 0; jj < nchans; jj++)
- {
- int ord = map[jj];
- samples[jj] = tmp[inv_map[ord]];
- }
- samples += nchans;
- }
-}
-
-static void matrix_mul(
- hb_sample_t * dst,
- hb_sample_t * src,
- int nchans_out,
- int nchans_in,
- int nsamples,
- hb_sample_t (*matrix)[8],
- hb_sample_t bias)
-{
- int nn, ii, jj;
- hb_sample_t val;
-
- for (nn = 0; nn < nsamples; nn++)
- {
- for (ii = 0; ii < nchans_out; ii++)
- {
- val = 0;
- for (jj = 0; jj < nchans_in; jj++)
- {
- val += src[jj] * matrix[jj][ii];
- }
- dst[ii] = val + bias;
- }
- src += nchans_in;
- dst += nchans_out;
- }
-}
-
-static void set_level( hb_downmix_t * downmix )
-{
- int ii, jj;
- int layout_in, layout_out;
- int mode_in;
- int mode_out;
-
- mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
- mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
-
- for (ii = 0; ii < 8; ii++)
- {
- for (jj = 0; jj < 8; jj++)
- {
- downmix->matrix[ii][jj] *= downmix->level;
- }
- }
- if (mode_out >= DOWNMIX_DOLBY)
- return;
-
- layout_in = channel_layout_map[mode_in];
- layout_out = channel_layout_map[mode_out];
-
- if (layout_in & HB_CH_FRONT_CENTER)
- {
- if (!(layout_out & HB_CH_FRONT_CENTER))
- {
- for (jj = 0; jj < 8; jj++)
- {
- downmix->matrix[downmix->center][jj] *= downmix->clev;
- }
- }
- }
- if (layout_in & (HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT|HB_CH_BACK_CENTER|HB_CH_SIDE_LEFT|HB_CH_SIDE_RIGHT))
- {
- if (layout_out & (HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT|HB_CH_BACK_CENTER|HB_CH_SIDE_LEFT|HB_CH_SIDE_RIGHT))
- {
- // Note, slev only gets set if input has surround, and output has none.
- return;
- }
- }
- for (jj = 0; jj < 8; jj++)
- {
- if ( downmix->left_surround >= 0 )
- downmix->matrix[downmix->left_surround][jj] *= downmix->slev;
- if ( downmix->right_surround >= 0 )
- downmix->matrix[downmix->right_surround][jj] *= downmix->slev;
- if ( downmix->rear_left_surround >= 0 )
- downmix->matrix[downmix->rear_left_surround][jj] *= downmix->slev;
- if ( downmix->rear_right_surround >= 0 )
- downmix->matrix[downmix->rear_right_surround][jj] *= downmix->slev;
- }
-}
-
-#define MIXMODE(x,y) (((x)<<4)|(y))
-// The downmix operation can result in new sample values that are
-// outside the original range of sample values. If you wish to
-// guarantee that the levels to not exceed the original range,
-// call this function after initializing downmix and setting
-// your initial levels.
-//
-// Note that this can result in generally lower volume levels
-// in the resulting downmixed audio.
-void hb_downmix_adjust_level( hb_downmix_t * downmix )
-{
- int mode_in, mode_out;
- hb_sample_t level = downmix->level;
- hb_sample_t clev = downmix->clev;
- hb_sample_t slev = downmix->slev;
-
- mode_in = downmix->mode_in & DOWNMIX_CHANNEL_MASK;
- mode_out = downmix->mode_out & DOWNMIX_CHANNEL_MASK;
-
- switch MIXMODE(mode_in, mode_out)
- {
- case MIXMODE(DOWNMIX_STEREO, DOWNMIX_MONO):
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_2F1R):
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_3F1R):
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_3F1R):
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F1R):
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F2R):
- level_3db:
- level /= LVL_PLUS3DB;
- break;
-
- case MIXMODE(DOWNMIX_3F, DOWNMIX_MONO):
- level /= LVL_PLUS3DB + clev * LVL_PLUS3DB;
- break;
-
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_2F1R):
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_2F1R):
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_2F2R):
- if (1 + clev < LVL_PLUS3DB)
- goto level_3db;
- case MIXMODE(DOWNMIX_3F, DOWNMIX_STEREO):
- case MIXMODE(DOWNMIX_3F, DOWNMIX_2F1R):
- case MIXMODE(DOWNMIX_3F, DOWNMIX_2F2R):
- case MIXMODE(DOWNMIX_3F, DOWNMIX_DOLBY):
- case MIXMODE(DOWNMIX_3F, DOWNMIX_DPLII):
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_2F1R):
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_2F2R):
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_2F2R):
- level /= 1 + clev;
- break;
-
-
- case MIXMODE(DOWNMIX_2F1R, DOWNMIX_MONO):
- level /= LVL_PLUS3DB + LVL_3DB * clev;
- break;
-
- case MIXMODE(DOWNMIX_2F1R, DOWNMIX_DOLBY):
- level /= 1 + LVL_3DB;
- break;
-
- case MIXMODE(DOWNMIX_2F1R, DOWNMIX_STEREO):
- case MIXMODE(DOWNMIX_2F1R, DOWNMIX_3F):
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_3F):
- level /= 1 + LVL_3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_MONO):
- level /= LVL_PLUS3DB + LVL_PLUS3DB * clev + LVL_3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_STEREO):
- level /= 1 + clev + LVL_3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_DOLBY):
- case MIXMODE(DOWNMIX_3F1R, DOWNMIX_DPLII):
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_DOLBY):
- level /= 1 + LVL_PLUS3DB;
- break;
-
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_MONO):
- level /= LVL_PLUS3DB + LVL_PLUS3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_STEREO):
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_3F):
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_3F):
- level /= 1 + slev;
- break;
-
- case MIXMODE(DOWNMIX_2F2R, DOWNMIX_DPLII):
- level /= 1 + LVL_SQRT_1_4 + LVL_SQRT_3_4;
- break;
-
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_MONO):
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_MONO):
- level /= LVL_PLUS3DB + LVL_PLUS3DB * clev * LVL_PLUS3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_STEREO):
- level /= 1 + clev + slev;
- break;
-
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_DOLBY):
- level /= 1 + 3 * LVL_3DB;
- break;
-
- case MIXMODE(DOWNMIX_3F2R, DOWNMIX_DPLII):
- level /= 1 + LVL_3DB + LVL_SQRT_1_4 + LVL_SQRT_3_4;
- break;
-
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_STEREO):
- level /= 1 + clev + LVL_PLUS3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F):
- level /= 1 + LVL_PLUS3DB * slev;
- break;
-
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_DOLBY):
- level /= 1 + 5 * LVL_3DB;
- break;
-
- case MIXMODE(DOWNMIX_3F4R, DOWNMIX_DPLII):
- level /= 1 + LVL_3DB + 2 * LVL_SQRT_1_4 + 2 * LVL_SQRT_3_4;
- }
-
- downmix->level = level;
- downmix->matrix_initialized = 0;
-}
-
-void hb_downmix_set_bias( hb_downmix_t * downmix, hb_sample_t bias )
-{
- downmix->bias = bias;
-}
-
-// Changes the downmix mode if it needs changing after initialization
-static void set_mode( hb_downmix_t * downmix )
-{
- int ii, jj;
- int mode_in, mode_out;
- hb_sample_t (*matrix)[8];
-
- mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
- mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
-
- matrix = downmix_matrix[mode_in][mode_out];
-
- for (ii = 0; ii < 8; ii++)
- {
- for (jj = 0; jj < 8; jj++)
- {
- downmix->matrix[ii][jj] = matrix[ii][jj];
- }
- }
-}
-
-// Changes the downmix mode if it needs changing after initialization
-int hb_downmix_set_mode( hb_downmix_t * downmix, int layout, int mixdown )
-{
- int lfe_in, lfe_out;
- int mode_in, mode_out;
-
- if ( downmix == NULL )
- return -1;
-
- mode_in = hb_layout_to_mode(layout);
- mode_out = hb_mixdown_to_mode(mixdown);
- downmix->mode_in = mode_in;
- downmix->mode_out = mode_out;
-
- mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
- mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
-
- if (mode_in >= DOWNMIX_NUM_MODES || mode_out >= DOWNMIX_NUM_MODES)
- return -1;
-
- lfe_in = ((downmix->mode_in & DOWNMIX_LFE_FLAG) != 0);
- lfe_out = ((downmix->mode_out & DOWNMIX_LFE_FLAG) != 0);
-
- downmix->nchans_in = nchans_tbl[mode_in] + lfe_in;
- downmix->nchans_out = nchans_tbl[mode_out] + lfe_out;
-
- downmix->matrix_initialized = 0;
- return 0;
-}
-
-// Changes the downmix levels if they need changing after initialization
-void hb_downmix_set_level( hb_downmix_t * downmix, hb_sample_t clev, hb_sample_t slev, hb_sample_t level )
-{
- if ( downmix == NULL )
- return;
-
- downmix->clev = clev;
- downmix->slev = slev;
- downmix->level = level;
- downmix->matrix_initialized = 0;
-}
-
-static void set_chan_map( hb_downmix_t * downmix )
-{
- int nchans;
- int ii, jj;
- int lfe;
- int * map;
- int * inv_map;
- int mode;
- hb_sample_t matrix[8][8];
-
- // Copy the matrix
- for ( ii = 0; ii < 8; ii++ )
- {
- for ( jj = 0; jj < 8; jj++ )
- {
- matrix[ii][jj] = downmix->matrix[ii][jj];
- }
- }
-
- // Rearrange the rows to correspond to the input channel order
- lfe = ((downmix->mode_in & DOWNMIX_LFE_FLAG) != 0);
- mode = downmix->mode_in & DOWNMIX_CHANNEL_MASK;
- nchans = nchans_tbl[mode] + lfe;
- map = downmix->map_in.chan_map[mode][lfe];
- inv_map = hb_qt_chan_map.inv_chan_map[mode][lfe];
-
- downmix->center = -1;
- downmix->left_surround = -1;
- downmix->right_surround = -1;
- downmix->rear_left_surround = -1;
- downmix->rear_right_surround = -1;
- for ( ii = 0; ii < nchans; ii++ )
- {
- int ord = map[ii];
- int row = inv_map[ord];
- switch (ord)
- {
- case CH_C:
- downmix->center = ii;
- break;
- case CH_LS:
- downmix->left_surround = ii;
- break;
- case CH_RS:
- downmix->right_surround = ii;
- break;
- case CH_Rls:
- downmix->rear_right_surround = ii;
- break;
- case CH_Rrs:
- downmix->rear_left_surround = ii;
- break;
- }
- for ( jj = 0; jj < 8; jj++ )
- {
- downmix->matrix[ii][jj] = matrix[row][jj];
- }
- }
-
- // Copy the matrix
- for ( ii = 0; ii < 8; ii++ )
- {
- for ( jj = 0; jj < 8; jj++ )
- {
- matrix[ii][jj] = downmix->matrix[ii][jj];
- }
- }
-
- // Rearrange the columns to correspond to the output channel order
- lfe = ((downmix->mode_out & DOWNMIX_LFE_FLAG) != 0);
- mode = downmix->mode_out & DOWNMIX_CHANNEL_MASK;
- nchans = nchans_tbl[mode] + lfe;
- map = downmix->map_out.chan_map[mode][lfe];
- inv_map = hb_qt_chan_map.inv_chan_map[mode][lfe];
- for ( ii = 0; ii < nchans; ii++ )
- {
- int ord = map[ii];
- int col = inv_map[ord];
- for ( jj = 0; jj < 8; jj++ )
- {
- downmix->matrix[jj][ii] = matrix[jj][col];
- }
- }
-}
-
-void hb_downmix_set_chan_map(
- hb_downmix_t * downmix,
- hb_chan_map_t * map_in,
- hb_chan_map_t * map_out )
-{
- downmix->map_in = *map_in;
- downmix->map_out = *map_out;
- downmix->matrix_initialized = 0;
-}
-
-hb_downmix_t * hb_downmix_init(int layout, int mixdown)
-{
- hb_downmix_t * downmix = calloc(1, sizeof(hb_downmix_t));
-
- if (downmix == NULL)
- return NULL;
- if ( hb_downmix_set_mode( downmix, layout, mixdown ) < 0 )
- {
- free( downmix );
- return NULL;
- }
- // Set some good default values
- hb_downmix_set_level( downmix, LVL_3DB, LVL_3DB, 1.0 );
- downmix->bias = 0.0;
- downmix->matrix_initialized = 0;
- // The default input and output channel order is QT
- hb_downmix_set_chan_map( downmix, &hb_qt_chan_map, &hb_qt_chan_map );
- return downmix;
-}
-
-void hb_downmix_close( hb_downmix_t **downmix )
-{
- if (*downmix != NULL)
- free(*downmix);
- *downmix = NULL;
-}
-
-static void init_matrix( hb_downmix_t * downmix )
-{
- if ( !downmix->matrix_initialized )
- {
- set_mode( downmix );
- set_chan_map( downmix );
- set_level(downmix);
- downmix->matrix_initialized = 1;
- }
-}
-
-void hb_downmix( hb_downmix_t * downmix, hb_sample_t * dst, hb_sample_t * src, int nsamples)
-{
- init_matrix( downmix );
- matrix_mul( dst, src, downmix->nchans_out, downmix->nchans_in,
- nsamples, downmix->matrix, downmix->bias );
-}
-
-int hb_need_downmix( int layout, int mixdown )
-{
- int mode_in, mode_out;
-
- mode_in = hb_layout_to_mode(layout);
- mode_out = hb_mixdown_to_mode(mixdown);
-
- return (mode_in != mode_out);
-}
diff --git a/libhb/downmix.h b/libhb/downmix.h
index b67889f56..e69de29bb 100644
--- a/libhb/downmix.h
+++ b/libhb/downmix.h
@@ -1,67 +0,0 @@
-/* downmix.h
-
- Copyright (c) 2003-2012 HandBrake Team
- This file is part of the HandBrake source code
- Homepage: <http://handbrake.fr/>.
- It may be used under the terms of the GNU General Public License v2.
- For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
- */
-#ifndef DOWNMIX_H
-#define DOWNMIX_H
-
-typedef float hb_sample_t;
-
-typedef struct
-{
- int chan_map[10][2][8];
- int inv_chan_map[10][2][8];
-} hb_chan_map_t;
-
-typedef struct
-{
- int mode_in;
- int mode_out;
- int nchans_in;
- int nchans_out;
- hb_sample_t matrix[8][8];
- int matrix_initialized;
- hb_sample_t clev;
- hb_sample_t slev;
- hb_sample_t level;
- hb_sample_t bias;
- hb_chan_map_t map_in;
- hb_chan_map_t map_out;
-
- int center;
- int left_surround;
- int right_surround;
- int rear_left_surround;
- int rear_right_surround;
-} hb_downmix_t;
-
-// For convenience, a map to convert smpte channel layout
-// to QuickTime channel layout.
-// Map Indicies are mode, lfe, channel respectively
-extern hb_chan_map_t hb_smpte_chan_map;
-extern hb_chan_map_t hb_ac3_chan_map;
-extern hb_chan_map_t hb_qt_chan_map;
-
-hb_downmix_t * hb_downmix_init(int layout, int mixdown);
-void hb_downmix_close( hb_downmix_t **downmix );
-int hb_downmix_set_mode( hb_downmix_t * downmix, int layout, int mixdown );
-void hb_downmix_set_level( hb_downmix_t * downmix, hb_sample_t clev, hb_sample_t slev, hb_sample_t level );
-void hb_downmix_adjust_level( hb_downmix_t * downmix );
-void hb_downmix_set_bias( hb_downmix_t * downmix, hb_sample_t bias );
-void hb_downmix_set_chan_map(
- hb_downmix_t * downmix,
- hb_chan_map_t * map_in,
- hb_chan_map_t * map_out );
-void hb_downmix( hb_downmix_t * downmix, hb_sample_t * dst, hb_sample_t * src, int nsamples);
-void hb_layout_remap(hb_chan_map_t *map_in,
- hb_chan_map_t *map_out,
- uint64_t layout,
- hb_sample_t *samples,
- int nsamples);
-int hb_need_downmix( int layout, int mixdown );
-
-#endif /* DOWNMIX_H */
diff --git a/libhb/dvd.c b/libhb/dvd.c
index 19325c1d4..6af2e7908 100644
--- a/libhb/dvd.c
+++ b/libhb/dvd.c
@@ -363,6 +363,7 @@ static hb_title_t * hb_dvdread_title_scan( hb_dvd_t * e, int t, uint64_t min_dur
case 0x03:
audio->id = 0xc0 + position;
audio->config.in.codec = HB_ACODEC_FFMPEG;
+ audio->config.in.codec_param = CODEC_ID_MP2;
codec_name = "MPEG";
break;
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index 2e4918095..d6e97c1a5 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -512,6 +512,7 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t, uint64_t min_dura
case 0x03:
audio->id = 0xc0 + position;
audio->config.in.codec = HB_ACODEC_FFMPEG;
+ audio->config.in.codec_param = CODEC_ID_MP2;
codec_name = "MPEG";
break;
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
index 037a7aef2..44453477f 100644
--- a/libhb/encavcodec.c
+++ b/libhb/encavcodec.c
@@ -451,17 +451,25 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
if ( pv->context->codec )
{
+ int ret;
+ AVPacket pkt;
+ int got_packet;
+
+ av_init_packet(&pkt);
/* Should be way too large */
buf = hb_video_buffer_init( job->width, job->height );
- buf->size = avcodec_encode_video( pv->context, buf->data, buf->alloc,
- frame );
- if ( buf->size <= 0 )
+ pkt.data = buf->data;
+ pkt.size = buf->alloc;
+
+ ret = avcodec_encode_video2( pv->context, &pkt, frame, &got_packet );
+ if ( ret < 0 || pkt.size <= 0 || !got_packet )
{
hb_buffer_close( &buf );
}
else
{
- int64_t frameno = pv->context->coded_frame->pts;
+ int64_t frameno = pkt.pts;
+ buf->size = pkt.size;
buf->s.start = get_frame_start( pv, frameno );
buf->s.stop = get_frame_stop( pv, frameno );
buf->s.flags &= ~HB_FRAME_REF;
@@ -492,7 +500,7 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
case AV_PICTURE_TYPE_I:
{
buf->s.flags |= HB_FRAME_REF;
- if ( pv->context->coded_frame->key_frame )
+ if ( pkt.flags & AV_PKT_FLAG_KEY )
{
buf->s.frametype = HB_FRAME_IDR;
}
@@ -504,7 +512,7 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
default:
{
- if ( pv->context->coded_frame->key_frame )
+ if ( pkt.flags & AV_PKT_FLAG_KEY )
{
buf->s.flags |= HB_FRAME_REF;
buf->s.frametype = HB_FRAME_KEY;
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 14df3f317..001000b9a 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -9,8 +9,7 @@
#include "hb.h"
#include "hbffmpeg.h"
-#include "downmix.h"
-#include "libavcodec/audioconvert.h"
+#include "audio_remap.h"
struct hb_work_private_s
{
@@ -23,6 +22,9 @@ struct hb_work_private_s
unsigned long output_bytes;
hb_list_t * list;
uint8_t * buf;
+
+ AVAudioResampleContext *avresample;
+ int *remap_table;
};
static int encavcodecaInit( hb_work_object_t *, hb_job_t * );
@@ -49,8 +51,6 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
pv->job = job;
- pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown );
-
codec = avcodec_find_encoder( w->codec_param );
if( !codec )
{
@@ -60,40 +60,30 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
}
context = avcodec_alloc_context3(codec);
- AVDictionary *av_opts = NULL;
- if ( w->codec_param == CODEC_ID_AAC )
+ int mode;
+ context->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, &mode);
+ pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
+
+ if (pv->out_discrete_channels > 2 &&
+ audio->config.in.channel_map != &hb_libav_chan_map)
{
- av_dict_set( &av_opts, "stereo_mode", "ms_off", 0 );
+ pv->remap_table = hb_audio_remap_build_table(context->channel_layout,
+ audio->config.in.channel_map,
+ &hb_libav_chan_map);
}
- if ( w->codec_param == CODEC_ID_AC3 )
+ else
{
- if( audio->config.out.mixdown == HB_AMIXDOWN_DOLBY ||
- audio->config.out.mixdown == HB_AMIXDOWN_DOLBYPLII )
- {
- av_dict_set( &av_opts, "dsur_mode", "on", 0 );
- }
+ pv->remap_table = NULL;
}
- switch (audio->config.out.mixdown)
+ AVDictionary *av_opts = NULL;
+ if (w->codec_param == CODEC_ID_AAC)
+ {
+ av_dict_set(&av_opts, "stereo_mode", "ms_off", 0);
+ }
+ else if (w->codec_param == CODEC_ID_AC3 && mode != AV_MATRIX_ENCODING_NONE)
{
- case HB_AMIXDOWN_MONO:
- context->channel_layout = AV_CH_LAYOUT_MONO;
- break;
-
- case HB_AMIXDOWN_STEREO:
- case HB_AMIXDOWN_DOLBY:
- case HB_AMIXDOWN_DOLBYPLII:
- context->channel_layout = AV_CH_LAYOUT_STEREO;
- break;
-
- case HB_AMIXDOWN_6CH:
- context->channel_layout = AV_CH_LAYOUT_5POINT1;
- break;
-
- default:
- context->channel_layout = AV_CH_LAYOUT_STEREO;
- hb_log("encavcodecaInit: bad mixdown");
- break;
+ av_dict_set(&av_opts, "dsur_mode", "on", 0);
}
if( audio->config.out.bitrate > 0 )
@@ -146,6 +136,31 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
w->config->extradata.length = context->extradata_size;
}
+ // Check if sample format conversion is necessary
+ if (AV_SAMPLE_FMT_FLT != pv->context->sample_fmt)
+ {
+ // Set up avresample to do conversion
+ pv->avresample = avresample_alloc_context();
+ if (pv->avresample == NULL)
+ {
+ hb_error("Failed to initialize avresample");
+ return 1;
+ }
+
+ uint64_t layout;
+ layout = hb_ff_layout_xlat(context->channel_layout, context->channels);
+ av_opt_set_int(pv->avresample, "in_channel_layout", layout, 0);
+ av_opt_set_int(pv->avresample, "out_channel_layout", layout, 0);
+ av_opt_set_int(pv->avresample, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+ av_opt_set_int(pv->avresample, "out_sample_fmt", context->sample_fmt, 0);
+
+ if (avresample_open(pv->avresample) < 0)
+ {
+ hb_error("Failed to open avresample");
+ avresample_free(&pv->avresample);
+ return 1;
+ }
+ }
return 0;
}
@@ -159,11 +174,20 @@ static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
static void Finalize( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
- hb_buffer_t * buf = hb_buffer_init( pv->output_bytes );
+ hb_buffer_t * buf;
// Finalize with NULL input needed by FLAC to generate md5sum
// in context extradata
- avcodec_encode_audio( pv->context, buf->data, buf->alloc, NULL );
+
+ // Prepare output packet
+ AVPacket pkt;
+ int got_packet;
+ buf = hb_buffer_init( pv->output_bytes );
+ av_init_packet(&pkt);
+ pkt.data = buf->data;
+ pkt.size = buf->alloc;
+
+ avcodec_encode_audio2( pv->context, &pkt, NULL, &got_packet);
hb_buffer_close( &buf );
// Then we need to recopy the header since it was modified
@@ -198,11 +222,36 @@ static void encavcodecaClose( hb_work_object_t * w )
if ( pv->list )
hb_list_empty( &pv->list );
+ if (pv->avresample != NULL)
+ {
+ avresample_free(&pv->avresample);
+ }
+
free( pv );
w->private_data = NULL;
}
}
+static void convertAudioFormat( hb_work_private_t *pv, AVFrame *frame )
+{
+ if (pv->avresample != NULL)
+ {
+ int out_samples, out_linesize;
+
+ av_samples_get_buffer_size(&out_linesize, pv->context->channels,
+ frame->nb_samples, pv->context->sample_fmt, 0);
+
+ out_samples = avresample_convert(pv->avresample,
+ (void **)frame->data, out_linesize, frame->nb_samples,
+ (void **)frame->data, frame->linesize[0], frame->nb_samples);
+
+ if (out_samples < 0)
+ {
+ hb_error("avresample_convert() failed");
+ }
+ }
+}
+
static hb_buffer_t * Encode( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
@@ -217,65 +266,67 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
&pts, &pos);
-
- // XXX: ffaac fails to remap from the internal libav* channel map (SMPTE) to the native AAC channel map
- // do it here - this hack should be removed if Libav fixes the bug
- hb_chan_map_t * out_map = ( w->codec_param == CODEC_ID_AAC ) ? &hb_qt_chan_map : &hb_smpte_chan_map;
-
- if (audio->config.in.channel_map != out_map)
+ if (pv->remap_table != NULL)
{
- hb_layout_remap(audio->config.in.channel_map, out_map,
- pv->context->channel_layout, (float*)pv->buf,
- pv->samples_per_frame);
+ hb_audio_remap(pv->out_discrete_channels, pv->samples_per_frame,
+ (hb_sample_t*)pv->buf, pv->remap_table);
}
+ // Prepare input frame
+ AVFrame frame;
+ frame.nb_samples= pv->samples_per_frame;
+ int size = av_samples_get_buffer_size(NULL, pv->context->channels,
+ frame.nb_samples, pv->context->sample_fmt, 1);
+ avcodec_fill_audio_frame(&frame, pv->context->channels,
+ pv->context->sample_fmt, pv->buf, size, 1);
+ frame.pts = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
+
+ // libav requires that timebase of audio input frames to be
+ // in sample_rate units.
+ frame.pts = av_rescale( frame.pts, pv->context->sample_rate, 90000);
+
// Do we need to convert our internal float format?
- if ( pv->context->sample_fmt != AV_SAMPLE_FMT_FLT )
+ convertAudioFormat(pv, &frame);
+
+ // Prepare output packet
+ AVPacket pkt;
+ int got_packet;
+ buf = hb_buffer_init( pv->output_bytes );
+ av_init_packet(&pkt);
+ pkt.data = buf->data;
+ pkt.size = buf->alloc;
+
+ // Encode
+ int ret = avcodec_encode_audio2( pv->context, &pkt, &frame, &got_packet);
+ if ( ret < 0 )
{
- int isamp, osamp;
- AVAudioConvert *ctx;
-
- isamp = av_get_bytes_per_sample( AV_SAMPLE_FMT_FLT );
- osamp = av_get_bytes_per_sample( pv->context->sample_fmt );
- ctx = av_audio_convert_alloc( pv->context->sample_fmt, 1,
- AV_SAMPLE_FMT_FLT, 1,
- NULL, 0 );
-
- // get output buffer size then malloc a buffer
- //nsamples = out_size / isamp;
- //buffer = av_malloc( nsamples * sizeof(hb_sample_t) );
-
- // we're doing straight sample format conversion which
- // behaves as if there were only one channel.
- const void * const ibuf[6] = { pv->buf };
- void * const obuf[6] = { pv->buf };
- const int istride[6] = { isamp };
- const int ostride[6] = { osamp };
-
- av_audio_convert( ctx, obuf, ostride, ibuf, istride, pv->input_samples );
- av_audio_convert_free( ctx );
+ hb_log( "encavcodeca: avcodec_encode_audio failed" );
+ hb_buffer_close( &buf );
+ return NULL;
}
-
- buf = hb_buffer_init( pv->output_bytes );
- buf->size = avcodec_encode_audio( pv->context, buf->data, buf->alloc,
- (short*)pv->buf );
- buf->s.start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
- buf->s.stop = buf->s.start + 90000 * pv->samples_per_frame / audio->config.out.samplerate;
+ if ( got_packet && pkt.size )
+ {
+ buf->size = pkt.size;
- buf->s.type = AUDIO_BUF;
- buf->s.frametype = HB_FRAME_AUDIO;
+ // The output pts from libav is in context->time_base. Convert
+ // it back to our timebase.
+ //
+ // Also account for the "delay" factor that libav seems to arbitrarily
+ // subtract from the packet. Not sure WTH they think they are doing
+ // by offseting the value in a negative direction.
+ buf->s.start = av_rescale_q( pkt.pts + pv->context->delay,
+ pv->context->time_base, (AVRational){ 1, 90000 });
- if ( !buf->size )
- {
- hb_buffer_close( &buf );
- return Encode( w );
+ buf->s.stop = buf->s.start + 90000 * pv->samples_per_frame / audio->config.out.samplerate;
+
+ buf->s.type = AUDIO_BUF;
+ buf->s.frametype = HB_FRAME_AUDIO;
}
- else if (buf->size < 0)
+ else
{
- hb_log( "encavcodeca: avcodec_encode_audio failed" );
hb_buffer_close( &buf );
- return NULL;
+ return Encode( w );
}
return buf;
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index d01afce8a..6782605e9 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -8,6 +8,7 @@
*/
#include "hb.h"
+#include "audio_remap.h"
#include "faac.h"
@@ -72,7 +73,7 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
pv->job = job;
/* pass the number of channels used into the private work data */
- pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown );
+ pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
/* if the sample rate is 'auto' and that has given us an invalid output */
/* rate, map it to the next highest output rate or 48K if above the highest. */
@@ -109,13 +110,20 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
cfg->aacObjectType = LOW;
cfg->allowMidside = 1;
- if (pv->out_discrete_channels == 6) {
- /* we are preserving 5.1 audio into 6-channel AAC,
- so indicate that we have an lfe channel */
- cfg->useLfe = 1;
- } else {
- cfg->useLfe = 0;
- }
+ // LFE, remapping
+ uint64_t layout;
+ layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
+ cfg->useLfe = !!(layout & AV_CH_LOW_FREQUENCY);
+ if (pv->out_discrete_channels > 2 &&
+ audio->config.in.channel_map != &hb_aac_chan_map)
+ {
+ int *remap_table;
+ remap_table = hb_audio_remap_build_table(layout,
+ audio->config.in.channel_map,
+ &hb_aac_chan_map);
+ // faac does its own remapping
+ memcpy(cfg->channel_map, remap_table, pv->out_discrete_channels * sizeof(int));
+ }
cfg->useTns = 0;
cfg->bitRate = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */
@@ -123,28 +131,6 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
cfg->outputFormat = 0;
cfg->inputFormat = FAAC_INPUT_FLOAT;
- if( ( audio->config.out.mixdown == HB_AMIXDOWN_6CH ) && ( audio->config.in.channel_map != &hb_qt_chan_map ) )
- {
- if( audio->config.in.channel_map == &hb_ac3_chan_map )
- {
- cfg->channel_map[0] = 2;
- cfg->channel_map[1] = 1;
- cfg->channel_map[2] = 3;
- cfg->channel_map[3] = 4;
- cfg->channel_map[4] = 5;
- cfg->channel_map[5] = 0;
- }
- else if( audio->config.in.channel_map == &hb_smpte_chan_map )
- {
- cfg->channel_map[0] = 2;
- cfg->channel_map[1] = 0;
- cfg->channel_map[2] = 1;
- cfg->channel_map[3] = 4;
- cfg->channel_map[4] = 5;
- cfg->channel_map[5] = 3;
- }
- }
-
if( !faacEncSetConfiguration( pv->faac, cfg ) )
{
hb_log( "faacEncSetConfiguration failed" );
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
index b0c7ea0ce..da631592c 100644
--- a/libhb/encvorbis.c
+++ b/libhb/encvorbis.c
@@ -8,6 +8,7 @@
*/
#include "hb.h"
+#include "audio_remap.h"
#include "vorbis/vorbisenc.h"
@@ -40,9 +41,9 @@ struct hb_work_private_s
uint64_t pts;
hb_list_t * list;
- int out_discrete_channels;
- int channel_map[6];
- int64_t prev_blocksize;
+ int out_discrete_channels;
+ int * remap_table;
+ int64_t prev_blocksize;
};
int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
@@ -53,7 +54,7 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
- pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown );
+ pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
pv->job = job;
@@ -134,48 +135,13 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
pv->list = hb_list_init();
- switch (pv->out_discrete_channels) {
- case 1:
- pv->channel_map[0] = 0;
- break;
- case 6:
- // Vorbis uses the following channel map = L C R Ls Rs Lfe
- if( audio->config.in.channel_map == &hb_ac3_chan_map )
- {
- pv->channel_map[0] = 1;
- pv->channel_map[1] = 2;
- pv->channel_map[2] = 3;
- pv->channel_map[3] = 4;
- pv->channel_map[4] = 5;
- pv->channel_map[5] = 0;
- }
- else if( audio->config.in.channel_map == &hb_smpte_chan_map )
- {
- pv->channel_map[0] = 0;
- pv->channel_map[1] = 2;
- pv->channel_map[2] = 1;
- pv->channel_map[3] = 4;
- pv->channel_map[4] = 5;
- pv->channel_map[5] = 3;
- }
- else // &hb_qt_chan_map
- {
- pv->channel_map[0] = 1;
- pv->channel_map[1] = 0;
- pv->channel_map[2] = 2;
- pv->channel_map[3] = 3;
- pv->channel_map[4] = 4;
- pv->channel_map[5] = 5;
- }
- break;
- default:
- hb_log("encvorbis.c: Unable to correctly proccess %d channels, assuming stereo.", pv->out_discrete_channels);
- case 2:
- // Assume stereo
- pv->channel_map[0] = 0;
- pv->channel_map[1] = 1;
- break;
- }
+ // remapping
+ uint64_t layout;
+ layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
+ pv->remap_table = hb_audio_remap_build_table(layout,
+ audio->config.in.channel_map,
+ &hb_vorbis_chan_map);
+
return 0;
}
@@ -273,7 +239,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
{
for( j = 0; j < pv->out_discrete_channels; j++)
{
- buffer[j][i] = ((float *) pv->buf)[(pv->out_discrete_channels * i + pv->channel_map[j])];
+ buffer[j][i] = ((float *) pv->buf)[(pv->out_discrete_channels * i + pv->remap_table[j])];
}
}
diff --git a/libhb/hb.c b/libhb/hb.c
index b5c721953..c6b569caf 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -105,15 +105,16 @@ void hb_avcodec_init()
av_register_all();
}
-int hb_avcodec_open(AVCodecContext *avctx, AVCodec *codec, AVDictionary **av_opts, int thread_count)
+int hb_avcodec_open(AVCodecContext *avctx, AVCodec *codec,
+ AVDictionary **av_opts, int thread_count)
{
int ret;
- if ( ( thread_count == HB_FFMPEG_THREADS_AUTO || thread_count > 0 ) &&
- ( codec->type == AVMEDIA_TYPE_VIDEO ) )
+ if ((thread_count == HB_FFMPEG_THREADS_AUTO || thread_count > 0) &&
+ (codec->type == AVMEDIA_TYPE_VIDEO))
{
- avctx->thread_count = ( thread_count == HB_FFMPEG_THREADS_AUTO ) ?
- hb_get_cpu_count() / 2 + 1 : thread_count;
+ avctx->thread_count = (thread_count == HB_FFMPEG_THREADS_AUTO) ?
+ hb_get_cpu_count() / 2 + 1 : thread_count;
avctx->thread_type = FF_THREAD_FRAME|FF_THREAD_SLICE;
avctx->thread_safe_callbacks = 1;
}
@@ -134,16 +135,16 @@ int hb_avcodec_close(AVCodecContext *avctx)
}
-int hb_avpicture_fill( AVPicture *pic, hb_buffer_t *buf )
+int hb_avpicture_fill(AVPicture *pic, hb_buffer_t *buf)
{
int ret, ii;
- for( ii = 0; ii < 4; ii++ )
+ for (ii = 0; ii < 4; ii++)
pic->linesize[ii] = buf->plane[ii].stride;
- ret = av_image_fill_pointers( pic->data, buf->f.fmt,
- buf->plane[0].height_stride,
- buf->data, pic->linesize );
+ ret = av_image_fill_pointers(pic->data, buf->f.fmt,
+ buf->plane[0].height_stride,
+ buf->data, pic->linesize);
if (ret != buf->size)
{
hb_error("Internal error hb_avpicture_fill expected %d, got %d",
@@ -209,45 +210,61 @@ hb_sws_get_context(int srcW, int srcH, enum PixelFormat srcFormat,
return ctx;
}
+uint64_t hb_ff_mixdown_xlat(int hb_mixdown, int *downmix_mode)
+{
+ uint64_t ff_layout = 0;
+ int mode = AV_MATRIX_ENCODING_NONE;
+ switch (hb_mixdown)
+ {
+ // Passthru
+ case HB_AMIXDOWN_NONE:
+ break;
+
+ case HB_AMIXDOWN_MONO:
+ ff_layout = AV_CH_LAYOUT_MONO;
+ break;
+
+ case HB_AMIXDOWN_DOLBY:
+ ff_layout = AV_CH_LAYOUT_STEREO;
+ mode = AV_MATRIX_ENCODING_DOLBY;
+ break;
+
+ case HB_AMIXDOWN_DOLBYPLII:
+ ff_layout = AV_CH_LAYOUT_STEREO;
+ mode = AV_MATRIX_ENCODING_DPLII;
+ break;
+
+ case HB_AMIXDOWN_STEREO:
+ ff_layout = AV_CH_LAYOUT_STEREO;
+ break;
+
+ case HB_AMIXDOWN_6CH:
+ ff_layout = AV_CH_LAYOUT_5POINT1;
+ break;
+
+ default:
+ ff_layout = AV_CH_LAYOUT_STEREO;
+ hb_log("unrecognized channel layout");
+ break;
+ }
+ if (downmix_mode != NULL)
+ *downmix_mode = mode;
+ return ff_layout;
+}
+
uint64_t hb_ff_layout_xlat(uint64_t ff_channel_layout, int nchannels)
{
uint64_t hb_layout = ff_channel_layout;
if (!hb_layout ||
av_get_channel_layout_nb_channels(hb_layout) != nchannels)
{
- switch (nchannels)
+ hb_layout = av_get_default_channel_layout(nchannels);
+ if (!hb_layout)
{
- // TODO: use av_get_default_channel_layout when available
- case 1:
- hb_layout = AV_CH_LAYOUT_MONO;
- break;
- case 2:
- hb_layout = AV_CH_LAYOUT_STEREO;
- break;
- case 3:
- hb_layout = AV_CH_LAYOUT_SURROUND;
- break;
- case 4:
- hb_layout = AV_CH_LAYOUT_QUAD;
- break;
- case 5:
- hb_layout = AV_CH_LAYOUT_5POINT0;
- break;
- case 6:
- hb_layout = AV_CH_LAYOUT_5POINT1;
- break;
- case 7:
- hb_layout = AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER;
- break;
- case 8:
- hb_layout = AV_CH_LAYOUT_7POINT1;
- break;
- default:
- // This will likely not sound very good ;)
- hb_layout = AV_CH_LAYOUT_STEREO;
- hb_error("hb_ff_layout_xlat: unsupported layout 0x%"PRIx64" with %d channels",
- ff_channel_layout, nchannels);
- break;
+ // This will likely not sound very good ;)
+ hb_layout = AV_CH_LAYOUT_STEREO;
+ hb_error("hb_ff_layout_xlat: unsupported layout 0x%"PRIx64" with %d channels",
+ ff_channel_layout, nchannels);
}
}
return hb_layout;
diff --git a/libhb/hbffmpeg.h b/libhb/hbffmpeg.h
index e4cf63474..138094bc8 100644
--- a/libhb/hbffmpeg.h
+++ b/libhb/hbffmpeg.h
@@ -14,16 +14,20 @@
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libswscale/swscale.h"
+#include "libavresample/avresample.h"
#define HB_FFMPEG_THREADS_AUTO (-1) // let hb_avcodec_open decide thread_count
void hb_avcodec_init(void);
-int hb_avcodec_open( AVCodecContext *, struct AVCodec *, AVDictionary **av_opts, int thread_count );
-int hb_avcodec_close( AVCodecContext * );
+int hb_avcodec_open(AVCodecContext *, AVCodec *, AVDictionary **av_opts, int thread_count);
+int hb_avcodec_close(AVCodecContext *);
+
uint64_t hb_ff_layout_xlat(uint64_t ff_channel_layout, int nchannels);
-struct SwsContext* hb_sws_get_context( int srcW, int srcH,
- enum PixelFormat srcFormat, int dstW, int dstH,
- enum PixelFormat dstFormat, int flags);
-void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec);
-int hb_ff_dts_disable_xch( AVCodecContext *c );
-int hb_avpicture_fill( AVPicture *pic, hb_buffer_t *buf );
+uint64_t hb_ff_mixdown_xlat(int hb_mixdown, int *downmix_mode);
+void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec);
+
+struct SwsContext*
+hb_sws_get_context(int srcW, int srcH, enum PixelFormat srcFormat,
+ int dstW, int dstH, enum PixelFormat dstFormat,
+ int flags);
+int hb_avpicture_fill(AVPicture *pic, hb_buffer_t *buf);
diff --git a/libhb/mcdeint.c b/libhb/mcdeint.c
index 2ffb722f7..4c4c10cef 100644
--- a/libhb/mcdeint.c
+++ b/libhb/mcdeint.c
@@ -58,7 +58,6 @@ void mcdeint_init( mcdeint_private_t * pv,
avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
avctx_enc->global_quality = 1;
- avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
avctx_enc->mb_cmp = FF_CMP_SSE;
@@ -80,8 +79,7 @@ void mcdeint_init( mcdeint_private_t * pv,
}
pv->mcdeint_frame = avcodec_alloc_frame();
- pv->mcdeint_outbuf_size = width * height * 10;
- pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
+ av_new_packet( &pv->mcdeint_pkt, width * height * 10 );
}
}
@@ -96,10 +94,7 @@ void mcdeint_close( mcdeint_private_t * pv )
hb_avcodec_close( pv->mcdeint_avctx_enc );
av_freep( &pv->mcdeint_avctx_enc );
}
- if( pv->mcdeint_outbuf )
- {
- free( pv->mcdeint_outbuf );
- }
+ av_free_packet( &pv->mcdeint_pkt );
}
}
@@ -127,10 +122,10 @@ void mcdeint_filter( uint8_t ** dst,
pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
- avcodec_encode_video( pv->mcdeint_avctx_enc,
- pv->mcdeint_outbuf,
- pv->mcdeint_outbuf_size,
- pv->mcdeint_frame );
+ int got_packet;
+
+ avcodec_encode_video2( pv->mcdeint_avctx_enc,
+ &pv->mcdeint_pkt, pv->mcdeint_frame, &got_packet );
pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
diff --git a/libhb/mcdeint.h b/libhb/mcdeint.h
index 2c47e1ce6..35b5a76fc 100644
--- a/libhb/mcdeint.h
+++ b/libhb/mcdeint.h
@@ -12,8 +12,7 @@ struct mcdeint_private_s
int mcdeint_mode;
int mcdeint_qp;
- int mcdeint_outbuf_size;
- uint8_t * mcdeint_outbuf;
+ AVPacket mcdeint_pkt;
AVCodecContext * mcdeint_avctx_enc;
AVFrame * mcdeint_frame;
AVFrame * mcdeint_frame_dec;
diff --git a/libhb/module.defs b/libhb/module.defs
index 3fefae82d..63acb9b9d 100644
--- a/libhb/module.defs
+++ b/libhb/module.defs
@@ -92,7 +92,7 @@ LIBHB.dll = $(LIBHB.build/)hb.dll
LIBHB.lib = $(LIBHB.build/)hb.lib
LIBHB.dll.libs = $(foreach n, \
- a52 ass avcodec avformat avutil dca dvdnav dvdread faac fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
+ a52 ass avcodec avformat avutil avresample dca dvdnav dvdread faac fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \
$(CONTRIB.build/)lib/lib$(n).a )
diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c
index d67e039b2..7839ed930 100644
--- a/libhb/platform/macosx/encca_aac.c
+++ b/libhb/platform/macosx/encca_aac.c
@@ -8,7 +8,7 @@
*/
#include "hb.h"
-#include "downmix.h"
+#include "audio_remap.h"
#include <AudioToolbox/AudioToolbox.h>
#include <CoreAudio/CoreAudio.h>
@@ -49,8 +49,7 @@ struct hb_work_private_s
uint64_t pts, ibytes;
Float64 osamplerate;
- uint64_t layout;
- hb_chan_map_t *ichanmap;
+ int *remap_table;
};
#define MP4ESDescrTag 0x03
@@ -289,22 +288,17 @@ int encCoreAudioInit(hb_work_object_t *w, hb_job_t *job, enum AAC_MODE mode)
pv->osamplerate = output.mSampleRate;
audio->config.out.samples_per_frame = pv->isamples;
- // set channel map and layout (for remapping)
- pv->ichanmap = audio->config.in.channel_map;
- switch (audio->config.out.mixdown)
+ // channel remapping
+ if (pv->nchannels > 2 && audio->config.in.channel_map != &hb_aac_chan_map)
{
- case HB_AMIXDOWN_MONO:
- pv->layout = AV_CH_LAYOUT_MONO;
- break;
- case HB_AMIXDOWN_STEREO:
- case HB_AMIXDOWN_DOLBY:
- case HB_AMIXDOWN_DOLBYPLII:
- pv->layout = AV_CH_LAYOUT_STEREO;
- break;
- case HB_AMIXDOWN_6CH:
- default:
- pv->layout = AV_CH_LAYOUT_5POINT1;
- break;
+ uint64_t layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
+ pv->remap_table = hb_audio_remap_build_table(layout,
+ audio->config.in.channel_map,
+ &hb_aac_chan_map);
+ }
+ else
+ {
+ pv->remap_table = NULL;
}
// get maximum output size
@@ -350,6 +344,10 @@ void encCoreAudioClose(hb_work_object_t *w)
{
free(pv->buf);
}
+ if (pv->remap_table != NULL)
+ {
+ free(pv->remap_table);
+ }
hb_list_empty(&pv->list);
free(pv);
w->private_data = NULL;
@@ -394,10 +392,11 @@ static OSStatus inInputDataProc(AudioConverterRef converter, UInt32 *npackets,
*npackets = buffers->mBuffers[0].mDataByteSize / pv->isamplesiz;
pv->ibytes -= buffers->mBuffers[0].mDataByteSize;
- if (pv->ichanmap != &hb_qt_chan_map)
+ if (pv->remap_table != NULL)
{
- hb_layout_remap(pv->ichanmap, &hb_qt_chan_map, pv->layout,
- (float*)buffers->mBuffers[0].mData, *npackets);
+ hb_audio_remap(pv->nchannels, *npackets,
+ (hb_sample_t*)buffers->mBuffers[0].mData,
+ pv->remap_table);
}
return noErr;
diff --git a/libhb/stream.c b/libhb/stream.c
index 3e4a682e3..4c9cb347c 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -5085,13 +5085,13 @@ static int ffmpeg_open( hb_stream_t *stream, hb_title_t *title, int scan )
return 1;
fail:
- if ( info_ic ) av_close_input_file( info_ic );
+ if ( info_ic ) avformat_close_input( &info_ic );
return 0;
}
static void ffmpeg_close( hb_stream_t *d )
{
- av_close_input_file( d->ffmpeg_ic );
+ avformat_close_input( &d->ffmpeg_ic );
if ( d->ffmpeg_pkt != NULL )
{
free( d->ffmpeg_pkt );
@@ -5104,23 +5104,9 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
AVStream *st = stream->ffmpeg_ic->streams[id];
AVCodecContext *codec = st->codec;
AVDictionaryEntry *tag;
- int layout;
- // DTS: work around lack of 6.0/6.1 support in libhb
- if( hb_ff_dts_disable_xch( codec ) )
- {
- hb_deep_log( 2, "add_ffmpeg_audio: found DTS-ES, requesting DTS core" );
- }
-
- // scan will ignore any audio without a bitrate. Since we've already
- // typed the audio in order to determine its codec we set up the audio
- // paramters here.
- layout = hb_ff_layout_xlat( codec->channel_layout, codec->channels );
- if ( !layout )
- {
- // Unsupported layout
- return;
- }
+ // scan will ignore any audio without a bitrate. Since we've already typed the
+ // audio in order to determine its codec we set up the audio parameters here.
if ( codec->bit_rate || codec->sample_rate )
{
hb_audio_t *audio = calloc( 1, sizeof(*audio) );;
@@ -5173,8 +5159,9 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
audio->config.in.bitrate = 1;
audio->config.in.samplerate = codec->sample_rate;
audio->config.in.samples_per_frame = codec->frame_size;
- audio->config.in.channel_layout = layout;
- audio->config.in.channel_map = &hb_smpte_chan_map;
+ audio->config.in.channel_map = &hb_libav_chan_map;
+ audio->config.in.channel_layout = hb_ff_layout_xlat(codec->channel_layout,
+ codec->channels);
}
tag = av_dict_get( st->metadata, "language", NULL, 0 );
diff --git a/libhb/sync.c b/libhb/sync.c
index 181d0acb3..fc01c3b12 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -922,7 +922,6 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
gap */
AVCodec * codec;
AVCodecContext * c;
- short * zeros;
switch ( w->audio->config.out.codec )
{
@@ -966,8 +965,18 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
return;
}
- int input_size = c->frame_size * av_get_bytes_per_sample( c->sample_fmt ) * c->channels;
+ // Prepare input frame
+ AVFrame frame;
+ uint8_t * zeros;
+
+ frame.nb_samples= c->frame_size;
+ int input_size = av_samples_get_buffer_size(NULL, c->channels,
+ frame.nb_samples, c->sample_fmt, 1);
zeros = calloc( 1, input_size );
+ avcodec_fill_audio_frame(&frame, c->channels,
+ c->sample_fmt, zeros, input_size, 1);
+ frame.pts = 0;
+
// Allocate enough space for the encoded silence
// The output should be < the input
sync->silence_buf = malloc( input_size );
@@ -977,19 +986,26 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
int ii;
for ( ii = 0; ii < 10; ii++ )
{
- sync->silence_size = avcodec_encode_audio( c, sync->silence_buf,
- input_size, zeros );
+ // Prepare output packet
+ AVPacket pkt;
+ int got_packet;
+ av_init_packet(&pkt);
+ pkt.data = zeros;
+ pkt.size = input_size;
+
+ int ret = avcodec_encode_audio2( c, &pkt, &frame, &got_packet);
+ if ( ret < 0 )
+ {
+ hb_log( "sync: avcodec_encode_audio failed" );
+ break;
+ }
- if (sync->silence_size)
+ if ( got_packet )
{
+ sync->silence_size = pkt.size;
break;
}
}
- if (!sync->silence_size)
- {
- hb_log( "sync: avcodec_encode_audio failed" );
- }
-
free( zeros );
hb_avcodec_close( c );
av_free( c );
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index 073b9448b..a15584b30 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -96,6 +96,8 @@
27D6C74614B102DA00B785E4 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72914B102DA00B785E4 /* libavcodec.a */; };
27D6C74714B102DA00B785E4 /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72A14B102DA00B785E4 /* libavformat.a */; };
27D6C74814B102DA00B785E4 /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72A14B102DA00B785E4 /* libavformat.a */; };
+ 226268E01572CC7300477B4E /* libavresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226268DF1572CC7300477B4E /* libavresample.a */; };
+ 226268E11572CC7300477B4E /* libavresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226268DF1572CC7300477B4E /* libavresample.a */; };
27D6C74914B102DA00B785E4 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72B14B102DA00B785E4 /* libavutil.a */; };
27D6C74A14B102DA00B785E4 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72B14B102DA00B785E4 /* libavutil.a */; };
27D6C74B14B102DA00B785E4 /* libbluray.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C72C14B102DA00B785E4 /* libbluray.a */; };
@@ -288,6 +290,7 @@
27D6C72814B102DA00B785E4 /* libass.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libass.a; path = external/contrib/lib/libass.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C72914B102DA00B785E4 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = external/contrib/lib/libavcodec.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C72A14B102DA00B785E4 /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = external/contrib/lib/libavformat.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 226268DF1572CC7300477B4E /* libavresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavresample.a; path = external/contrib/lib/libavresample.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C72B14B102DA00B785E4 /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = external/contrib/lib/libavutil.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C72C14B102DA00B785E4 /* libbluray.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbluray.a; path = external/contrib/lib/libbluray.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C72D14B102DA00B785E4 /* libdca.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdca.a; path = external/contrib/lib/libdca.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -328,6 +331,7 @@
27D6C74414B102DA00B785E4 /* libass.a in Frameworks */,
27D6C74614B102DA00B785E4 /* libavcodec.a in Frameworks */,
27D6C74814B102DA00B785E4 /* libavformat.a in Frameworks */,
+ 226268E11572CC7300477B4E /* libavresample.a in Frameworks */,
27D6C74A14B102DA00B785E4 /* libavutil.a in Frameworks */,
27D6C74C14B102DA00B785E4 /* libbluray.a in Frameworks */,
27D6C74E14B102DA00B785E4 /* libdca.a in Frameworks */,
@@ -370,6 +374,7 @@
27D6C74314B102DA00B785E4 /* libass.a in Frameworks */,
27D6C74514B102DA00B785E4 /* libavcodec.a in Frameworks */,
27D6C74714B102DA00B785E4 /* libavformat.a in Frameworks */,
+ 226268E01572CC7300477B4E /* libavresample.a in Frameworks */,
27D6C74914B102DA00B785E4 /* libavutil.a in Frameworks */,
27D6C74B14B102DA00B785E4 /* libbluray.a in Frameworks */,
27D6C74D14B102DA00B785E4 /* libdca.a in Frameworks */,
@@ -405,6 +410,7 @@
27D6C72814B102DA00B785E4 /* libass.a */,
27D6C72914B102DA00B785E4 /* libavcodec.a */,
27D6C72A14B102DA00B785E4 /* libavformat.a */,
+ 226268DF1572CC7300477B4E /* libavresample.a */,
27D6C72B14B102DA00B785E4 /* libavutil.a */,
27D6C72C14B102DA00B785E4 /* libbluray.a */,
27D6C72D14B102DA00B785E4 /* libdca.a */,
diff --git a/test/module.defs b/test/module.defs
index 5030e6f29..45f6fea82 100644
--- a/test/module.defs
+++ b/test/module.defs
@@ -10,7 +10,7 @@ TEST.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%.o,$(TEST.c))
TEST.exe = $(BUILD/)$(call TARGET.exe,$(HB.name)CLI)
TEST.libs = $(LIBHB.a) $(foreach n, \
- a52 ass avcodec avformat avutil dca dvdnav dvdread faac fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
+ a52 ass avcodec avformat avutil avresample dca dvdnav dvdread faac fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \
$(CONTRIB.build/)lib/lib$(n).a )