mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-03 05:10:03 +02:00
avformat/aadec: Avoid copying data around
Up until now, the packets have been read in blocks of at most eight bytes at a time; then these blocks have been decrypted and copied into a buffer on the stack (that was double the size needed...). From there they have been copied to the dst packet. This commit changes this: The data is read in one go; and the decryption avoids temporary buffers, too, by making use of the fact that src and dst of av_tea_crypt() can coincide. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
0a76f8217e
commit
a0900a318a
@ -32,7 +32,6 @@
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#define AA_MAGIC 1469084982 /* this identifies an audible .aa file */
|
||||
#define MAX_CODEC_SECOND_SIZE 3982
|
||||
#define MAX_TOC_ENTRIES 16
|
||||
#define MAX_DICTIONARY_ENTRIES 128
|
||||
#define TEA_BLOCK_SIZE 8
|
||||
@ -247,13 +246,9 @@ static int aa_read_header(AVFormatContext *s)
|
||||
|
||||
static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
uint8_t dst[TEA_BLOCK_SIZE];
|
||||
uint8_t src[TEA_BLOCK_SIZE];
|
||||
int i;
|
||||
int trailing_bytes;
|
||||
int blocks;
|
||||
uint8_t buf[MAX_CODEC_SECOND_SIZE * 2];
|
||||
int written = 0;
|
||||
uint8_t *buf;
|
||||
int ret;
|
||||
AADemuxContext *c = s->priv_data;
|
||||
uint64_t pos = avio_tell(s->pb);
|
||||
@ -272,7 +267,6 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
av_log(s, AV_LOG_DEBUG, "Chapter %d (%" PRId64 " bytes)\n", c->chapter_idx, c->current_chapter_size);
|
||||
c->chapter_idx = c->chapter_idx + 1;
|
||||
avio_skip(s->pb, 4); // data start offset
|
||||
pos += 8;
|
||||
c->current_codec_second_size = c->codec_second_size;
|
||||
}
|
||||
|
||||
@ -281,24 +275,18 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
c->current_codec_second_size = c->current_chapter_size % c->current_codec_second_size;
|
||||
}
|
||||
|
||||
ret = av_get_packet(s->pb, pkt, c->current_codec_second_size);
|
||||
if (ret != c->current_codec_second_size)
|
||||
return AVERROR_EOF;
|
||||
|
||||
buf = pkt->data;
|
||||
// decrypt c->current_codec_second_size bytes
|
||||
// trailing bytes are left unencrypted!
|
||||
blocks = c->current_codec_second_size / TEA_BLOCK_SIZE;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
ret = avio_read(s->pb, src, TEA_BLOCK_SIZE);
|
||||
if (ret != TEA_BLOCK_SIZE)
|
||||
return (ret < 0) ? ret : AVERROR_EOF;
|
||||
av_tea_init(c->tea_ctx, c->file_key, 16);
|
||||
av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
|
||||
memcpy(buf + written, dst, TEA_BLOCK_SIZE);
|
||||
written = written + TEA_BLOCK_SIZE;
|
||||
}
|
||||
trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
|
||||
if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
|
||||
ret = avio_read(s->pb, src, trailing_bytes);
|
||||
if (ret != trailing_bytes)
|
||||
return (ret < 0) ? ret : AVERROR_EOF;
|
||||
memcpy(buf + written, src, trailing_bytes);
|
||||
written = written + trailing_bytes;
|
||||
av_tea_crypt(c->tea_ctx, buf, buf, 1, NULL, 1);
|
||||
buf += TEA_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
// update state
|
||||
@ -306,16 +294,12 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
if (c->current_chapter_size <= 0)
|
||||
c->current_chapter_size = 0;
|
||||
|
||||
if (c->seek_offset > written)
|
||||
if (c->seek_offset > c->current_codec_second_size)
|
||||
c->seek_offset = 0; // ignore wrong estimate
|
||||
|
||||
ret = av_new_packet(pkt, written - c->seek_offset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
memcpy(pkt->data, buf + c->seek_offset, written - c->seek_offset);
|
||||
pkt->pos = pos;
|
||||
|
||||
pkt->data += c->seek_offset;
|
||||
pkt->size -= c->seek_offset;
|
||||
c->seek_offset = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user