diff options
author | Hein-Pieter van Braam <hp@tmm.cx> | 2017-06-25 21:59:00 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2017-06-27 15:03:51 +0200 |
commit | ba2c385006e3100d6cd506f61c53186ba054a06d (patch) | |
tree | 26ecd9f30b86ae061c72bd7f9dd8ac4bb25af268 /libavformat | |
parent | bbaca6e867999699c026f0de1267f7a5ae06684b (diff) | |
download | ffmpeg-ba2c385006e3100d6cd506f61c53186ba054a06d.tar.gz |
Interplay MVE: Implement MVE SEND_BUFFER operation
Interplay MVE movies have a SEND_BUFFER operation. Only after this
command does the current decoding buffer get displayed. This is required
for the other frame formats. They are fixed-size and can't always encode
a full frame worth of pixeldata.
This code prevents half-finished frames from being emitted.
Signed-off-by: Hein-Pieter van Braam <hp@tmm.cx>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/ipmovie.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 29eeaf6b8b..0705d3381b 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -91,6 +91,7 @@ typedef struct IPMVEContext { uint32_t palette[256]; int has_palette; int changed; + uint8_t send_buffer; unsigned int audio_bits; unsigned int audio_channels; @@ -154,9 +155,9 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, } else if (s->decode_map_chunk_offset) { - /* send both the decode map and the video data together */ + /* send the decode map, the video data, and the send_buffer flag together */ - if (av_new_packet(pkt, 2 + s->decode_map_chunk_size + s->video_chunk_size)) + if (av_new_packet(pkt, 3 + s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; if (s->has_palette) { @@ -178,8 +179,11 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; - AV_WL16(pkt->data, s->decode_map_chunk_size); - if (avio_read(pb, pkt->data + 2, s->decode_map_chunk_size) != + AV_WL8(pkt->data, s->send_buffer); + s->send_buffer = 0; + + AV_WL16(pkt->data + 1, s->decode_map_chunk_size); + if (avio_read(pb, pkt->data + 3, s->decode_map_chunk_size) != s->decode_map_chunk_size) { av_packet_unref(pkt); return CHUNK_EOF; @@ -188,7 +192,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, avio_seek(pb, s->video_chunk_offset, SEEK_SET); s->video_chunk_offset = 0; - if (avio_read(pb, pkt->data + 2 + s->decode_map_chunk_size, + if (avio_read(pb, pkt->data + 3 + s->decode_map_chunk_size, s->video_chunk_size) != s->video_chunk_size) { av_packet_unref(pkt); return CHUNK_EOF; @@ -444,6 +448,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, case OPCODE_SEND_BUFFER: av_log(s->avf, AV_LOG_TRACE, "send buffer\n"); avio_skip(pb, opcode_size); + s->send_buffer = 1; break; case OPCODE_AUDIO_FRAME: @@ -590,6 +595,7 @@ static int ipmovie_read_header(AVFormatContext *s) ipmovie->video_pts = ipmovie->audio_frame_count = 0; ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = ipmovie->decode_map_chunk_offset = 0; + ipmovie->send_buffer = 0; /* on the first read, this will position the stream at the first chunk */ ipmovie->next_chunk_offset = avio_tell(pb) + 4; |