summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2013-10-04 15:29:30 +0200
committerTorsten Jager <t.jager@gmx.de>2013-10-04 15:29:30 +0200
commit40abca76de2f331b569fe194d16158c0b5917b0a (patch)
tree1229744b4a52f53752865e7ef4891e1ea30ab605
parent59ea3725a7eea1bc0e5c649b58c6bbe43c937ea5 (diff)
downloadxine-lib-40abca76de2f331b569fe194d16158c0b5917b0a.tar.gz
xine-lib-40abca76de2f331b569fe194d16158c0b5917b0a.tar.bz2
ff_audio_decoder: add ATRAC 3 support, and fix some COOK audio trouble.
I dont wanna lose my early 2000's videoteque. Maybe this needs my upcoming demux_real audio fix for full functionality.
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c159
-rw-r--r--src/combined/ffmpeg/xine_audio.list1
2 files changed, 91 insertions, 69 deletions
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index d5f62f7e2..a066141d2 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -275,85 +275,106 @@ static void ff_handle_header_buffer(ff_audio_decoder_t *this, buf_element_t *buf
}
}
} else {
- short *ptr;
+ switch (codec_type) {
- switch(codec_type) {
- case BUF_AUDIO_14_4:
- this->ff_sample_rate = 8000;
- this->ff_channels = 1;
+ case BUF_AUDIO_14_4:
+ this->ff_sample_rate = 8000;
+ this->ff_channels = 1;
- this->context->block_align = 240;
- break;
- case BUF_AUDIO_28_8:
- this->ff_sample_rate = _X_BE_16(&this->buf[0x30]);
- this->ff_channels = this->buf[0x37];
- /* this->ff_bits = buf->content[0x35] */
+ this->context->block_align = 240;
+ break;
- this->context->block_align = _X_BE_32(&this->buf[0x18]);
+ case BUF_AUDIO_28_8:
+ {
+ uint16_t *ptr;
- this->context->extradata_size = 5*sizeof(short);
- this->context->extradata = malloc(this->context->extradata_size);
+ this->ff_sample_rate = _X_BE_16 (&this->buf[0x30]);
+ this->ff_channels = this->buf[0x37];
+ /* this->ff_bits = buf->content[0x35] */
- ptr = (short *) this->context->extradata;
+ this->context->block_align = _X_BE_32 (&this->buf[0x18]);
- ptr[0] = _X_BE_16(&this->buf[0x2C]); /* subpacket size */
- ptr[1] = _X_BE_16(&this->buf[0x28]); /* subpacket height */
- ptr[2] = _X_BE_16(&this->buf[0x16]); /* subpacket flavour */
- ptr[3] = _X_BE_32(&this->buf[0x18]); /* coded frame size */
- ptr[4] = 0; /* codec's data length */
+ this->context->extradata_size = 5 * sizeof (uint16_t);
+ this->context->extradata = malloc (this->context->extradata_size);
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "ffmpeg_audio_dec: 28_8 audio channels %d bits %d sample rate %d block align %d\n",
- this->ff_channels, this->ff_bits, this->ff_sample_rate,
- this->context->block_align);
- break;
- case BUF_AUDIO_COOK:
- {
- int version;
- int data_len;
- int extradata;
-
- version = _X_BE_16 (this->buf+4);
- if (version == 4) {
- this->ff_sample_rate = _X_BE_16 (this->buf+48);
- this->ff_bits = _X_BE_16 (this->buf+52);
- this->ff_channels = _X_BE_16 (this->buf+54);
- data_len = _X_BE_32 (this->buf+67);
- extradata = 71;
- } else {
- this->ff_sample_rate = _X_BE_16 (this->buf+54);
- this->ff_bits = _X_BE_16 (this->buf+58);
- this->ff_channels = _X_BE_16 (this->buf+60);
- data_len = _X_BE_32 (this->buf+74);
- extradata = 78;
+ ptr = (uint16_t *)this->context->extradata;
+
+ ptr[0] = _X_BE_16 (&this->buf[0x2C]); /* subpacket size */
+ ptr[1] = _X_BE_16 (&this->buf[0x28]); /* subpacket height */
+ ptr[2] = _X_BE_16 (&this->buf[0x16]); /* subpacket flavour */
+ ptr[3] = _X_BE_32 (&this->buf[0x18]); /* coded frame size */
+ ptr[4] = 0; /* codec's data length */
+
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: 28_8 audio channels %d bits %d sample rate %d block align %d\n",
+ this->ff_channels, this->ff_bits, this->ff_sample_rate, this->context->block_align);
+ break;
}
- this->context->block_align = _X_BE_16 (this->buf+44);
-
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "ffmpeg_audio_dec: cook audio channels %d bits %d sample rate %d block align %d\n",
- this->ff_channels, this->ff_bits, this->ff_sample_rate,
- this->context->block_align);
-
- if (extradata + data_len > this->size)
- break; /* abort early - extradata length is bad */
- if (extradata > INT_MAX - data_len)
- break;/*integer overflow*/
-
- this->context->extradata_size = data_len;
- this->context->extradata = malloc(this->context->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
- xine_fast_memcpy (this->context->extradata, this->buf + extradata,
- this->context->extradata_size);
- break;
- }
- case BUF_AUDIO_EAC3:
- break;
+ case BUF_AUDIO_COOK:
+ case BUF_AUDIO_ATRK:
+ {
+ int version, subpacket_size = 0, coded_frame_size = 0, intl = 0;
+ int data_len;
+ uint8_t *p, *e;
+ p = this->buf;
+ e = p + this->size;
+ if (p + 6 > e) break;
+ version = p[5];
+ if (version == 3) {
+ this->ff_sample_rate = 8000;
+ this->ff_bits = 16;
+ this->ff_channels = 1;
+ data_len = 0;
+ } else if (version == 4) {
+ if (p + 73 > e) break;
+ coded_frame_size = _X_BE_32 (p + 24);
+ subpacket_size = _X_BE_16 (p + 44);
+ this->ff_sample_rate = _X_BE_16 (p + 48);
+ this->ff_bits = _X_BE_16 (p + 52);
+ this->ff_channels = _X_BE_16 (p + 54);
+ if (p[56] != 4) break;
+ intl = 57;
+ if (p[61] != 4) break;
+ data_len = _X_BE_32 (p + 69);
+ p += 73;
+ } else {
+ if (p + 78 > e) break;
+ coded_frame_size = _X_BE_32 (p + 24);
+ subpacket_size = _X_BE_16 (p + 44);
+ this->ff_sample_rate = _X_BE_16 (p + 54);
+ this->ff_bits = _X_BE_16 (p + 58);
+ this->ff_channels = _X_BE_16 (p + 60);
+ intl = 62;
+ data_len = _X_BE_32 (p + 74);
+ p += 78;
+ }
+ this->context->block_align = intl && !memcmp (this->buf + intl, "genr", 4) ?
+ subpacket_size : coded_frame_size;
+ if (p + data_len > e) break;
+ if (p > e - data_len) break;
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: %s audio channels %d bits %d sample rate %d block align %d\n",
+ codec_type == BUF_AUDIO_COOK ? "cook" : "atrac 3",
+ this->ff_channels, this->ff_bits, this->ff_sample_rate,
+ this->context->block_align);
+ if (!data_len) break;
+ e = malloc (data_len + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!e) break;
+ xine_fast_memcpy (e, p, data_len);
+ memset (e + data_len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ this->context->extradata = e;
+ this->context->extradata_size = data_len;
+ break;
+ }
- default:
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type);
- break;
+ case BUF_AUDIO_EAC3:
+ break;
+
+ default:
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type);
+ break;
}
}
diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list
index 2002dd7fb..ea905c200 100644
--- a/src/combined/ffmpeg/xine_audio.list
+++ b/src/combined/ffmpeg/xine_audio.list
@@ -33,6 +33,7 @@ SHORTEN SHORTEN Shorten
ALAC ALAC ALAC
QDESIGN2 QDM2 QDesign
COOK COOK RealAudio Cooker
+ATRK ATRAC3 ATRAC 3
TRUESPEECH TRUESPEECH TrueSpeech
TTA TTA True Audio Lossless
SMACKER SMACKAUDIO Smacker