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:
parent
5e10b74b78
commit
7f4b0fa867
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user