1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-31 04:02:06 +00:00

demux_mkv: reindent, cosmetics

Reindent the whole handle_realaudio() function, and make the surrouding
if block return early instead.

Also contains some cosmetics to the sipr swapping, which hopefully does
not change the semantics, but is untested (the kind of cosmetic changes
everyone loves so much). May the person responsible for sipr rot in
hell. (It was probably done to obfuscate the codec?)
This commit is contained in:
wm4 2015-02-05 21:54:32 +01:00
parent 5e10b74b78
commit 7f4b0fa867

View File

@ -1950,113 +1950,95 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
uint8_t *buffer = orig->buffer;
uint32_t size = orig->len;
demux_packet_t *dp;
// track->audio_buf allocation size
size_t audiobuf_size = sph * w;
if ((track->a_formattag == MP_FOURCC('2', '8', '_', '8'))
|| (track->a_formattag == MP_FOURCC('c', 'o', 'o', 'k'))
|| (track->a_formattag == MP_FOURCC('a', 't', 'r', 'c'))
|| (track->a_formattag == MP_FOURCC('s', 'i', 'p', 'r')))
{
switch (track->a_formattag) {
case MP_FOURCC('2', '8', '_', '8'):
for (int x = 0; x < sph / 2; x++) {
uint64_t dst_offset = x * 2 * w + spc * (uint64_t)cfs;
if (dst_offset + cfs > audiobuf_size)
goto error;
uint64_t src_offset = x * (uint64_t)cfs;
if (src_offset + cfs > size)
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, cfs);
}
break;
case MP_FOURCC('c', 'o', 'o', 'k'):
case MP_FOURCC('a', 't', 'r', 'c'):
for (int x = 0; x < w / sps; x++) {
uint32_t dst_offset = sps * (sph * x + ((sph + 1) / 2) * (spc & 1)
+ (spc >> 1));
if (dst_offset + sps > audiobuf_size)
goto error;
uint32_t src_offset = sps * x;
if (src_offset + sps > size)
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, sps);
}
break;
case MP_FOURCC('s', 'i', 'p', 'r'):
if (spc * w + w > audiobuf_size || w > size)
switch (track->a_formattag) {
case MP_FOURCC('2', '8', '_', '8'):
for (int x = 0; x < sph / 2; x++) {
uint64_t dst_offset = x * 2 * w + spc * (uint64_t)cfs;
if (dst_offset + cfs > audiobuf_size)
goto error;
memcpy(track->audio_buf + spc * w, buffer, w);
if (spc == sph - 1) {
int n;
int bs = sph * w * 2 / 96; // nibbles per subpacket
// Perform reordering
for (n = 0; n < 38; n++) {
unsigned int i = bs * sipr_swaps[n][0]; // 77 max
unsigned int o = bs * sipr_swaps[n][1]; // 95 max
// swap nibbles of block 'i' with 'o'
for (int j = 0; j < bs; j++) {
if (i / 2 >= audiobuf_size || o / 2 >= audiobuf_size)
goto error;
int x = (i & 1) ?
(track->audio_buf[i / 2] >> 4) :
(track->audio_buf[i / 2] & 0x0F);
int y = (o & 1) ?
(track->audio_buf[o / 2] >> 4) :
(track->audio_buf[o / 2] & 0x0F);
if (o & 1)
track->audio_buf[o / 2] =
(track->audio_buf[o / 2] & 0x0F) | (x << 4);
else
track->audio_buf[o / 2] =
(track->audio_buf[o / 2] & 0xF0) | x;
if (i & 1)
track->audio_buf[i / 2] =
(track->audio_buf[i / 2] & 0x0F) | (y << 4);
else
track->audio_buf[i / 2] =
(track->audio_buf[i / 2] & 0xF0) | y;
++i;
++o;
}
uint64_t src_offset = x * (uint64_t)cfs;
if (src_offset + cfs > size)
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, cfs);
}
break;
case MP_FOURCC('c', 'o', 'o', 'k'):
case MP_FOURCC('a', 't', 'r', 'c'):
for (int x = 0; x < w / sps; x++) {
uint32_t dst_offset =
sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1));
if (dst_offset + sps > audiobuf_size)
goto error;
uint32_t src_offset = sps * x;
if (src_offset + sps > size)
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, sps);
}
break;
case MP_FOURCC('s', 'i', 'p', 'r'):
if (spc * w + w > audiobuf_size || w > size)
goto error;
memcpy(track->audio_buf + spc * w, buffer, w);
if (spc == sph - 1) {
int n;
int bs = sph * w * 2 / 96; // nibbles per subpacket
// Perform reordering
for (n = 0; n < 38; n++) {
unsigned int i = bs * sipr_swaps[n][0]; // 77 max
unsigned int o = bs * sipr_swaps[n][1]; // 95 max
// swap nibbles of block 'i' with 'o'
for (int j = 0; j < bs; j++) {
if (i / 2 >= audiobuf_size || o / 2 >= audiobuf_size)
goto error;
uint8_t iv = track->audio_buf[i / 2];
uint8_t ov = track->audio_buf[o / 2];
int x = (i & 1) ? iv >> 4 : iv & 0x0F;
int y = (o & 1) ? ov >> 4 : ov & 0x0F;
track->audio_buf[o / 2] = ov & 0x0F | (o & 1 ? x << 4 : x);
track->audio_buf[i / 2] = iv & 0x0F | (i & 1 ? y << 4 : y);
i++;
o++;
}
}
break;
}
track->audio_timestamp[track->sub_packet_cnt] =
track->ra_pts == orig->pts ? 0 : orig->pts;
track->ra_pts = orig->pts;
if (++(track->sub_packet_cnt) == sph) {
track->sub_packet_cnt = 0;
// apk_usize has same range as coded_framesize in worst case
uint32_t apk_usize = track->stream->audio->block_align;
if (apk_usize > audiobuf_size)
goto error;
// Release all the audio packets
for (int x = 0; x < sph * w / apk_usize; x++) {
dp = new_demux_packet_from(track->audio_buf + x * apk_usize,
apk_usize);
if (!dp)
goto error;
/* Put timestamp only on packets that correspond to original
* audio packets in file */
dp->pts = (x * apk_usize % w) ? MP_NOPTS_VALUE :
track->audio_timestamp[x * apk_usize / w];
dp->pos = orig->pos;
dp->keyframe = !x; // Mark first packet as keyframe
demux_add_packet(track->stream, dp);
}
}
talloc_free(orig);
return true;
error:
MP_ERR(demuxer, "RealAudio packet extraction or decryption error.\n");
talloc_free(orig);
return true;
} else { // Not a codec that requires reordering
break;
default:
// Not a codec that requires reordering
return false;
}
track->audio_timestamp[track->sub_packet_cnt] =
track->ra_pts == orig->pts ? 0 : orig->pts;
track->ra_pts = orig->pts;
if (++(track->sub_packet_cnt) == sph) {
track->sub_packet_cnt = 0;
// apk_usize has same range as coded_framesize in worst case
uint32_t apk_usize = track->stream->audio->block_align;
if (apk_usize > audiobuf_size)
goto error;
// Release all the audio packets
for (int x = 0; x < sph * w / apk_usize; x++) {
dp = new_demux_packet_from(track->audio_buf + x * apk_usize,
apk_usize);
if (!dp)
goto error;
/* Put timestamp only on packets that correspond to original
* audio packets in file */
dp->pts = (x * apk_usize % w) ? MP_NOPTS_VALUE :
track->audio_timestamp[x * apk_usize / w];
dp->pos = orig->pos;
dp->keyframe = !x; // Mark first packet as keyframe
demux_add_packet(track->stream, dp);
}
}
error:
talloc_free(orig);
return true;
}
static void mkv_seek_reset(demuxer_t *demuxer)