|
|
|
@@ -698,9 +698,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
slices[n_slices].buf); |
|
|
|
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, |
|
|
|
buf_size3 << 3); |
|
|
|
/* assuming that the field marker is at the exact middle, |
|
|
|
hope it's correct */ |
|
|
|
slices[n_slices].mby_start = s->mb_height + 1 >> 1; |
|
|
|
slices[n_slices].mby_start = avctx->coded_height + 31 >> 5; |
|
|
|
slices[n_slices].rawbuf = start; |
|
|
|
slices[n_slices].raw_size = size + 4; |
|
|
|
n_slices1 = n_slices - 1; // index of the last slice of the first field |
|
|
|
@@ -903,13 +901,41 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
s->picture_structure = PICT_BOTTOM_FIELD - v->tff; |
|
|
|
if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, buf_start_second_field - buf_start)) < 0) |
|
|
|
goto err; |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
if (n_slices1 == -1) { |
|
|
|
// no slices, decode the field as-is |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start)) < 0) |
|
|
|
goto err; |
|
|
|
} else { |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
for (i = 0 ; i < n_slices1 + 1; i++) { |
|
|
|
s->gb = slices[i].gb; |
|
|
|
s->mb_y = slices[i].mby_start; |
|
|
|
|
|
|
|
v->pic_header_flag = get_bits1(&s->gb); |
|
|
|
if (v->pic_header_flag) { |
|
|
|
if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { |
|
|
|
av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
if (avctx->err_recognition & AV_EF_EXPLODE) |
|
|
|
goto err; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) |
|
|
|
goto err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
// decode second field |
|
|
|
s->gb = slices[n_slices1 + 1].gb; |
|
|
|
s->mb_y = slices[n_slices1 + 1].mby_start; |
|
|
|
s->picture_structure = PICT_TOP_FIELD + v->tff; |
|
|
|
v->second_field = 1; |
|
|
|
v->pic_header_flag = 0; |
|
|
|
@@ -922,8 +948,35 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
if ((ret = avctx->hwaccel->start_frame(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) |
|
|
|
goto err; |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
if (n_slices - n_slices1 == 2) { |
|
|
|
// no slices, decode the field as-is |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) |
|
|
|
goto err; |
|
|
|
} else { |
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, slices[n_slices1 + 2].rawbuf - buf_start_second_field)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
for (i = n_slices1 + 2; i < n_slices; i++) { |
|
|
|
s->gb = slices[i].gb; |
|
|
|
s->mb_y = slices[i].mby_start; |
|
|
|
|
|
|
|
v->pic_header_flag = get_bits1(&s->gb); |
|
|
|
if (v->pic_header_flag) { |
|
|
|
if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { |
|
|
|
av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
if (avctx->err_recognition & AV_EF_EXPLODE) |
|
|
|
goto err; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) |
|
|
|
goto err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) |
|
|
|
goto err; |
|
|
|
} else { |
|
|
|
|