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>
... | ... |
@@ -162,8 +162,11 @@ static int cmv_decode_frame(AVCodecContext *avctx, |
162 | 162 |
return AVERROR_INVALIDDATA; |
163 | 163 |
|
164 | 164 |
if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { |
165 |
+ unsigned size = AV_RL32(buf + 4); |
|
165 | 166 |
cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); |
166 |
- return buf_size; |
|
167 |
+ if (size > buf_end - buf - EA_PREAMBLE_SIZE) |
|
168 |
+ return -1; |
|
169 |
+ buf += size; |
|
167 | 170 |
} |
168 | 171 |
|
169 | 172 |
if (av_image_check_size(s->width, s->height, 0, s->avctx)) |
... | ... |
@@ -469,11 +469,12 @@ static int ea_read_packet(AVFormatContext *s, |
469 | 469 |
AVIOContext *pb = s->pb; |
470 | 470 |
int ret = 0; |
471 | 471 |
int packet_read = 0; |
472 |
+ int partial_packet = 0; |
|
472 | 473 |
unsigned int chunk_type, chunk_size; |
473 | 474 |
int key = 0; |
474 | 475 |
int av_uninit(num_samples); |
475 | 476 |
|
476 |
- while (!packet_read) { |
|
477 |
+ while (!packet_read || partial_packet) { |
|
477 | 478 |
chunk_type = avio_rl32(pb); |
478 | 479 |
chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; |
479 | 480 |
|
... | ... |
@@ -496,6 +497,11 @@ static int ea_read_packet(AVFormatContext *s, |
496 | 496 |
avio_skip(pb, 8); |
497 | 497 |
chunk_size -= 12; |
498 | 498 |
} |
499 |
+ if (partial_packet) { |
|
500 |
+ av_log_ask_for_sample(s, "video header followed by audio packet not supported.\n"); |
|
501 |
+ av_free_packet(pkt); |
|
502 |
+ partial_packet = 0; |
|
503 |
+ } |
|
499 | 504 |
ret = av_get_packet(pb, pkt, chunk_size); |
500 | 505 |
if (ret < 0) |
501 | 506 |
return ret; |
... | ... |
@@ -558,9 +564,15 @@ static int ea_read_packet(AVFormatContext *s, |
558 | 558 |
key = AV_PKT_FLAG_KEY; |
559 | 559 |
case MV0F_TAG: |
560 | 560 |
get_video_packet: |
561 |
- ret = av_get_packet(pb, pkt, chunk_size); |
|
562 |
- if (ret < 0) |
|
563 |
- return ret; |
|
561 |
+ if (partial_packet) { |
|
562 |
+ ret = av_append_packet(pb, pkt, chunk_size); |
|
563 |
+ } else |
|
564 |
+ ret = av_get_packet(pb, pkt, chunk_size); |
|
565 |
+ if (ret < 0) { |
|
566 |
+ packet_read = 1; |
|
567 |
+ break; |
|
568 |
+ } |
|
569 |
+ partial_packet = chunk_type == MVIh_TAG; |
|
564 | 570 |
pkt->stream_index = ea->video_stream_index; |
565 | 571 |
pkt->flags |= key; |
566 | 572 |
packet_read = 1; |
... | ... |
@@ -572,6 +584,8 @@ get_video_packet: |
572 | 572 |
} |
573 | 573 |
} |
574 | 574 |
|
575 |
+ if (ret < 0 && partial_packet) |
|
576 |
+ av_free_packet(pkt); |
|
575 | 577 |
return ret; |
576 | 578 |
} |
577 | 579 |
|