summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2014-02-07 16:47:10 +0100
committerTorsten Jager <t.jager@gmx.de>2014-02-07 16:47:10 +0100
commit9443b4022c85a02811ba07785c0286d2f8bfaaae (patch)
tree4dc984057a84a7a2e198c04a4d6d159b8b972001
parent35892b7e199400a1202717da2db1acfec425989c (diff)
downloadxine-lib-9443b4022c85a02811ba07785c0286d2f8bfaaae.tar.gz
xine-lib-9443b4022c85a02811ba07785c0286d2f8bfaaae.tar.bz2
demux_qt: Enable Purevoice audio decoding via ffmpeg.
-rw-r--r--src/combined/ffmpeg/xine_audio.list1
-rw-r--r--src/demuxers/demux_qt.c35
2 files changed, 34 insertions, 2 deletions
diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list
index ea905c200..df43b1d53 100644
--- a/src/combined/ffmpeg/xine_audio.list
+++ b/src/combined/ffmpeg/xine_audio.list
@@ -45,6 +45,7 @@ EAC3 EAC3 E-AC-3
AAC AAC MPEG4
AAC_LATM AAC_LATM AAC LATM
ADPCM_G726 ADPCM_G726 ADPCM G726
+QCLP QCELP QualComm Purevoice
# disabled codecs (ref. configure.ac)
! AC3
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index 599d0103b..ebb039daf 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -113,6 +113,7 @@ typedef unsigned int qt_atom;
#define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1')
#define AC_3_FOURCC ME_FOURCC('a', 'c', '-', '3')
#define EAC3_FOURCC ME_FOURCC('e', 'c', '-', '3')
+#define QCLP_FOURCC ME_FOURCC('Q', 'c', 'l', 'p')
#define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a')
#define META_ATOM QT_ATOM('m', 'e', 't', 'a')
@@ -1327,6 +1328,9 @@ static qt_error parse_trak_atom (qt_trak *trak,
memcpy (p->audio.properties_atom, &atom[atom_pos + 0x20], p->audio.properties_atom_size);
}
+ if (p->audio.codec_fourcc == QCLP_FOURCC)
+ p->audio.vbr = 1;
+
if (p->audio.codec_fourcc == DRMS_FOURCC) {
last_error = QT_DRM_NOT_SUPPORTED;
goto free_trak;
@@ -1674,6 +1678,7 @@ static qt_error build_frame_table(qt_trak *trak,
unsigned char *o, *p, *q, *s;
unsigned int chunk_start, chunk_end;
unsigned int samples_per_chunk;
+ unsigned int samples_per_frame;
unsigned int size_left, size_value;
unsigned int offset_left;
uint64_t offset_value;
@@ -1702,22 +1707,36 @@ static qt_error build_frame_table(qt_trak *trak,
if ((trak->type == MEDIA_VIDEO) ||
(trak->properties->audio.vbr)) {
+ /* test for legacy compressed audio */
+ if ((trak->type == MEDIA_AUDIO) &&
+ (trak->properties->audio.samples_per_frame > 1) &&
+ (trak->time_to_sample_count == 1) &&
+ (_X_BE_32 (&trak->time_to_sample_table[4]) == 1))
+ /* Oh dear. Old style. */
+ samples_per_frame = trak->properties->audio.samples_per_frame;
+ else
+ samples_per_frame = 1;
+
/* figure out # of samples */
trak->frame_count = 0;
n = trak->chunk_offset_count;
if (!n)
return QT_OK;
for (i = 0; i < trak->sample_to_chunk_count - 1; i++) {
+ int s = trak->sample_to_chunk_table[i].samples_per_chunk;
+ if ((samples_per_frame != 1) && (s % samples_per_frame))
+ return QT_OK; /* unaligned chunk, should not happen */
j = trak->sample_to_chunk_table[i + 1].first_chunk -
trak->sample_to_chunk_table[i].first_chunk;
if (j < 0)
continue;
if (j > n)
j = n;
- trak->frame_count += j * trak->sample_to_chunk_table[i].samples_per_chunk;
+ trak->frame_count += j * s;
n -= j;
}
trak->frame_count += n * trak->sample_to_chunk_table[i].samples_per_chunk;
+ trak->frame_count = (trak->frame_count + samples_per_frame - 1) / samples_per_frame;
if (!trak->frame_count)
return QT_OK;
@@ -1749,6 +1768,18 @@ static qt_error build_frame_table(qt_trak *trak,
q = trak->timeoffs_to_sample_table;
ptsoffs_countdown = ptsoffs_value = 0;
+ if (samples_per_frame != 1) {
+ /* Old style demuxing. Tweak our frame builder.
+ Treating whole chunks as frames would be faster, but unfortunately
+ some ffmpeg decoders dont like multiple frames in one go. */
+ size_left = 0;
+ size_value = trak->properties->audio.bytes_per_frame;
+ duration_left = 0;
+ duration_value = samples_per_frame;
+ ptsoffs_left = 0;
+ trak->samples = _X_BE_32 (trak->time_to_sample_table) / samples_per_frame;
+ }
+
media_id_counts = xine_xcalloc(trak->stsd_atoms_count, sizeof(int));
if (!media_id_counts)
return QT_NO_MEMORY;
@@ -1832,7 +1863,7 @@ static qt_error build_frame_table(qt_trak *trak,
frame->ptsoffs = ptsoffs_value;
ptsoffs_countdown--;
- samples_per_chunk--;
+ samples_per_chunk -= samples_per_frame;
frame++;
}
}