summaryrefslogtreecommitdiff
path: root/libavformat/smacker.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/smacker.c')
-rw-r--r--libavformat/smacker.c94
1 files changed, 43 insertions, 51 deletions
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index c803ecbec9..4990b7d920 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -48,14 +48,16 @@ typedef struct SmackerContext {
uint32_t *frm_size;
uint8_t *frm_flags;
/* internal variables */
+ int64_t next_frame_pos;
int cur_frame;
/* current frame for demuxing */
+ uint32_t frame_size;
+ int flags;
+ int next_audio_index;
+ int new_palette;
uint8_t pal[768];
int indexes[7];
int videoindex;
- uint8_t *bufs[7];
- int buf_sizes[7];
- int stream_id[7];
int curstream;
int64_t aud_pts[7];
} SmackerContext;
@@ -235,21 +237,19 @@ static int smacker_read_header(AVFormatContext *s)
static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
{
SmackerContext *smk = s->priv_data;
- int64_t next_frame_pos;
int flags;
int ret;
- int i;
- int frame_size = 0;
- int palchange = 0;
if (avio_feof(s->pb) || smk->cur_frame >= smk->frames)
return AVERROR_EOF;
/* if we demuxed all streams, pass another frame */
- if (smk->curstream <= 0) {
- frame_size = smk->frm_size[smk->cur_frame] & (~3);
- next_frame_pos = avio_tell(s->pb) + (unsigned)frame_size;
+ if (!smk->next_audio_index) {
+ smk->frame_size = smk->frm_size[smk->cur_frame] & (~3);
+ smk->next_frame_pos = avio_tell(s->pb) + smk->frame_size;
+ smk->curstream = 0;
flags = smk->frm_flags[smk->cur_frame];
+ smk->flags = flags >> 1;
/* handle palette change event */
if(flags & SMACKER_PAL){
int size, sz, t, off, j, pos;
@@ -258,13 +258,12 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
memcpy(oldpal, pal, 768);
size = avio_r8(s->pb);
- size = size * 4 - 1;
- if (size + 1 > frame_size) {
+ size = size * 4;
+ if (size > smk->frame_size) {
ret = AVERROR_INVALIDDATA;
goto next_frame;
}
- frame_size -= size;
- frame_size--;
+ smk->frame_size -= size--;
sz = 0;
pos = avio_tell(s->pb) + size;
while(sz < 256){
@@ -298,69 +297,65 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
}
}
avio_seek(s->pb, pos, 0);
- palchange |= 1;
+ smk->new_palette = 1;
}
- flags >>= 1;
- smk->curstream = 0;
- /* if audio chunks are present, put them to stack and retrieve later */
- for(i = 0; i < 7; i++) {
- if(flags & 1) {
+ }
+
+ for (int i = smk->next_audio_index; i < 7; i++) {
+ if (smk->flags & (1 << i)) {
uint32_t size;
size = avio_rl32(s->pb);
- if ((int)size < 8 || size > frame_size) {
+ if ((int)size < 8 || size > smk->frame_size) {
av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
ret = AVERROR_INVALIDDATA;
goto next_frame;
}
- frame_size -= size;
+ smk->frame_size -= size;
size -= 4;
- if ((ret = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
- smk->buf_sizes[smk->curstream] = 0;
+
+ if (smk->indexes[i] < 0) {
+ avio_skip(s->pb, size);
+ continue;
+ }
+ if ((ret = av_get_packet(s->pb, pkt, size)) != size) {
+ ret = ret < 0 ? ret : AVERROR_INVALIDDATA;
goto next_frame;
}
- smk->buf_sizes[smk->curstream] = size;
- ret = ffio_read_size(s->pb, smk->bufs[smk->curstream], size);
- if (ret < 0)
- goto next_frame;
- smk->stream_id[smk->curstream] = smk->indexes[i];
+ pkt->stream_index = smk->indexes[i];
+ pkt->pts = smk->aud_pts[smk->curstream];
+ smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
+ smk->next_audio_index = i + 1;
smk->curstream++;
+ return 0;
}
- flags >>= 1;
}
- if (frame_size < 0 || frame_size >= INT_MAX/2) {
+
+ if (smk->frame_size >= INT_MAX/2) {
ret = AVERROR_INVALIDDATA;
goto next_frame;
}
- if ((ret = av_new_packet(pkt, frame_size + 769)) < 0)
+ if ((ret = av_new_packet(pkt, smk->frame_size + 769)) < 0)
goto next_frame;
+ flags = smk->new_palette;
if(smk->frm_size[smk->cur_frame] & 1)
- palchange |= 2;
- pkt->data[0] = palchange;
+ flags |= 2;
+ pkt->data[0] = flags;
memcpy(pkt->data + 1, smk->pal, 768);
- ret = ffio_read_size(s->pb, pkt->data + 769, frame_size);
+ ret = ffio_read_size(s->pb, pkt->data + 769, smk->frame_size);
if (ret < 0)
goto next_frame;
pkt->stream_index = smk->videoindex;
pkt->pts = smk->cur_frame;
pkt->size = ret + 769;
+ smk->next_audio_index = 0;
+ smk->new_palette = 0;
smk->cur_frame++;
- } else {
- smk->curstream--;
- if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream])
- return AVERROR_INVALIDDATA;
- if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0)
- return ret;
- memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);
- pkt->size = smk->buf_sizes[smk->curstream];
- pkt->stream_index = smk->stream_id[smk->curstream];
- pkt->pts = smk->aud_pts[smk->curstream];
- smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
- }
return 0;
next_frame:
- avio_seek(s->pb, next_frame_pos, SEEK_SET);
+ avio_seek(s->pb, smk->next_frame_pos, SEEK_SET);
+ smk->next_audio_index = 0;
smk->cur_frame++;
return ret;
}
@@ -368,10 +363,7 @@ next_frame:
static int smacker_read_close(AVFormatContext *s)
{
SmackerContext *smk = s->priv_data;
- int i;
- for(i = 0; i < 7; i++)
- av_freep(&smk->bufs[i]);
av_freep(&smk->frm_size);
av_freep(&smk->frm_flags);