summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog1
-rw-r--r--libavcodec/vc1dec.c41
-rw-r--r--libavcodec/version.h2
3 files changed, 41 insertions, 3 deletions
diff --git a/Changelog b/Changelog
index 8456022ad0..2778304539 100644
--- a/Changelog
+++ b/Changelog
@@ -43,6 +43,7 @@ version 3.2:
- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
- sidedata video and asidedata audio filter
- Changed mapping of rtp MIME type G726 to codec g726le.
+- spec compliant VAAPI/DXVA2 VC-1 decoding of slices in frame-coded images
version 3.1:
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 4f78aa8e33..75d336583c 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -634,6 +634,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
uint8_t *buf;
GetBitContext gb;
int mby_start;
+ const uint8_t *rawbuf;
+ int raw_size;
} *slices = NULL, *tmp;
v->second_field = 0;
@@ -716,6 +718,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
/* 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].rawbuf = start;
+ slices[n_slices].raw_size = size + 4;
n_slices1 = n_slices - 1; // index of the last slice of the first field
n_slices++;
break;
@@ -743,6 +747,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);
+ slices[n_slices].rawbuf = start;
+ slices[n_slices].raw_size = size + 4;
n_slices++;
break;
}
@@ -779,6 +785,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
slices[n_slices].mby_start = s->mb_height + 1 >> 1;
+ slices[n_slices].rawbuf = divider;
+ slices[n_slices].raw_size = buf + buf_size - divider;
n_slices1 = n_slices - 1;
n_slices++;
}
@@ -921,6 +929,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
} else
#endif
if (avctx->hwaccel) {
+ s->mb_y = 0;
if (v->field_mode && buf_start_second_field) {
// decode first field
s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
@@ -953,8 +962,36 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
s->picture_structure = PICT_FRAME;
if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
goto err;
- if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
- goto err;
+
+ if (n_slices == 0) {
+ // no slices, decode the frame as-is
+ if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
+ goto err;
+ } else {
+ // decode the frame part as the first slice
+ if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0)
+ goto err;
+
+ // and process the slices as additional slices afterwards
+ for (i = 0 ; 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;
}
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 5a7e4804eb..c28867a1ff 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 66
-#define LIBAVCODEC_VERSION_MICRO 107
+#define LIBAVCODEC_VERSION_MICRO 108
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \