summaryrefslogtreecommitdiff
path: root/libavcodec/dca_exss.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2014-02-11 11:45:27 +0100
committerDiego Biurrun <diego@biurrun.de>2015-03-15 14:51:36 +0100
commit217e4ff4d1f845b76e44634e29371cd09313d1c2 (patch)
treeb2ed55ea486e80a884e463c375204c9b07a73c00 /libavcodec/dca_exss.c
parent4da5aacc7eba274a4f18411120de539d39c5151e (diff)
dca: Support for XLL (lossless extension)
Cleanup and integration by Diego Biurrun. Signed-off-by: Diego Biurrun <diego@biurrun.de>
Diffstat (limited to 'libavcodec/dca_exss.c')
-rw-r--r--libavcodec/dca_exss.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/libavcodec/dca_exss.c b/libavcodec/dca_exss.c
index 0f022e49dd..2895e2096e 100644
--- a/libavcodec/dca_exss.c
+++ b/libavcodec/dca_exss.c
@@ -22,6 +22,7 @@
#include "libavutil/log.h"
#include "dca.h"
+#include "dca_syncwords.h"
#include "get_bits.h"
/* extensions that reside in core substream */
@@ -121,7 +122,8 @@ static int dca_exss_parse_asset_header(DCAContext *s)
skip_bits(&s->gb, 4); // max sample rate code
channels = get_bits(&s->gb, 8) + 1;
- if (get_bits1(&s->gb)) { // 1-to-1 channels to speakers
+ s->one2one_map_chtospkr = get_bits1(&s->gb);
+ if (s->one2one_map_chtospkr) {
int spkr_remap_sets;
int spkr_mask_size = 16;
int num_spkrs[7];
@@ -242,21 +244,27 @@ static int dca_exss_parse_asset_header(DCAContext *s)
*/
void ff_dca_exss_parse_header(DCAContext *s)
{
+ int asset_size[8];
int ss_index;
int blownup;
int num_audiop = 1;
int num_assets = 1;
int active_ss_mask[8];
int i, j;
+ int start_pos;
+ int hdrsize;
+ uint32_t mkr;
if (get_bits_left(&s->gb) < 52)
return;
+ start_pos = get_bits_count(&s->gb) - 32;
+
skip_bits(&s->gb, 8); // user data
ss_index = get_bits(&s->gb, 2);
blownup = get_bits1(&s->gb);
- skip_bits(&s->gb, 8 + 4 * blownup); // header_size
+ hdrsize = get_bits(&s->gb, 8 + 4 * blownup) + 1; // header_size
skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
s->static_fields = get_bits1(&s->gb);
@@ -309,13 +317,52 @@ void ff_dca_exss_parse_header(DCAContext *s)
}
for (i = 0; i < num_assets; i++)
- skip_bits_long(&s->gb, 16 + 4 * blownup); // asset size
+ asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup) + 1;
for (i = 0; i < num_assets; i++) {
if (dca_exss_parse_asset_header(s))
return;
}
- /* not parsed further, we were only interested in the extensions mask
- * from the asset header */
+ if (num_assets > 0) {
+ j = get_bits_count(&s->gb);
+ if (start_pos + hdrsize * 8 > j)
+ skip_bits_long(&s->gb, start_pos + hdrsize * 8 - j);
+
+ for (i = 0; i < num_assets; i++) {
+ int end_pos;
+ start_pos = get_bits_count(&s->gb);
+ end_pos = start_pos + asset_size[i] * 8;
+ mkr = get_bits_long(&s->gb, 32);
+
+ /* parse extensions that we know about */
+ switch (mkr) {
+ case DCA_SYNCWORD_XLL:
+ if (s->xll_disable) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "DTS-XLL: ignoring XLL extension\n");
+ break;
+ }
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "DTS-XLL: decoding XLL extension\n");
+ if (ff_dca_xll_decode_header(s) == 0 &&
+ ff_dca_xll_decode_navi(s, end_pos) == 0)
+ s->exss_ext_mask |= DCA_EXT_EXSS_XLL;
+ break;
+ case DCA_SYNCWORD_XBR:
+ case DCA_SYNCWORD_XXCH:
+ default:
+ av_log(s->avctx, AV_LOG_VERBOSE,
+ "DTS-ExSS: unknown marker = 0x%08"PRIx32"\n", mkr);
+ }
+
+ /* skip to end of block */
+ j = get_bits_count(&s->gb);
+ if (j > end_pos)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "DTS-ExSS: Processed asset too long.\n");
+ if (j < end_pos)
+ skip_bits_long(&s->gb, end_pos - j);
+ }
+ }
}