diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-22 13:17:53 +0100 |
---|---|---|
committer | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-28 22:01:05 +0100 |
commit | a0eb8de5e01a6401c3b310b5221ab7c3bc485f12 (patch) | |
tree | 4ccc808ebe29dd5102e946195689d0acf0d44e4f | |
parent | 0b378e8aa99e24f5d1b128abaaf1572542ce86f1 (diff) | |
download | ffmpeg-a0eb8de5e01a6401c3b310b5221ab7c3bc485f12.tar.gz |
Merge palette-only header with actual video frame.
This fixes the video frame pts (off by one for each MVIh)
and makes the "key frames" decode stand-alone (MVIh
contains only palette, such a palette-only frame being
marked as key frame is not really correct).
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
-rw-r--r-- | libavcodec/eacmv.c | 5 | ||||
-rw-r--r-- | libavformat/electronicarts.c | 22 |
2 files changed, 22 insertions, 5 deletions
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 8a8d6a9cef..82ec9fc9fc 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -162,8 +162,11 @@ static int cmv_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { + unsigned size = AV_RL32(buf + 4); cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); - return buf_size; + if (size > buf_end - buf - EA_PREAMBLE_SIZE) + return -1; + buf += size; } if (av_image_check_size(s->width, s->height, 0, s->avctx)) diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index c901931dec..55cab7c70f 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -469,11 +469,12 @@ static int ea_read_packet(AVFormatContext *s, AVIOContext *pb = s->pb; int ret = 0; int packet_read = 0; + int partial_packet = 0; unsigned int chunk_type, chunk_size; int key = 0; int av_uninit(num_samples); - while (!packet_read) { + while (!packet_read || partial_packet) { chunk_type = avio_rl32(pb); chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; @@ -496,6 +497,11 @@ static int ea_read_packet(AVFormatContext *s, avio_skip(pb, 8); chunk_size -= 12; } + if (partial_packet) { + av_log_ask_for_sample(s, "video header followed by audio packet not supported.\n"); + av_free_packet(pkt); + partial_packet = 0; + } ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; @@ -558,9 +564,15 @@ static int ea_read_packet(AVFormatContext *s, key = AV_PKT_FLAG_KEY; case MV0F_TAG: get_video_packet: - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; + if (partial_packet) { + ret = av_append_packet(pb, pkt, chunk_size); + } else + ret = av_get_packet(pb, pkt, chunk_size); + if (ret < 0) { + packet_read = 1; + break; + } + partial_packet = chunk_type == MVIh_TAG; pkt->stream_index = ea->video_stream_index; pkt->flags |= key; packet_read = 1; @@ -572,6 +584,8 @@ get_video_packet: } } + if (ret < 0 && partial_packet) + av_free_packet(pkt); return ret; } |