You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
vc1dec: support multiple slices in frame coded images with hwaccel
Based on a patch by Jun Zhao <mypopydev@gmail.com>
This commit is contained in:
@@ -43,6 +43,7 @@ version 3.2:
|
|||||||
- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
|
- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
|
||||||
- sidedata video and asidedata audio filter
|
- sidedata video and asidedata audio filter
|
||||||
- Changed mapping of rtp MIME type G726 to codec g726le.
|
- 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:
|
version 3.1:
|
||||||
|
@@ -634,6 +634,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
int mby_start;
|
int mby_start;
|
||||||
|
const uint8_t *rawbuf;
|
||||||
|
int raw_size;
|
||||||
} *slices = NULL, *tmp;
|
} *slices = NULL, *tmp;
|
||||||
|
|
||||||
v->second_field = 0;
|
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,
|
/* assuming that the field marker is at the exact middle,
|
||||||
hope it's correct */
|
hope it's correct */
|
||||||
slices[n_slices].mby_start = s->mb_height + 1 >> 1;
|
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_slices1 = n_slices - 1; // index of the last slice of the first field
|
||||||
n_slices++;
|
n_slices++;
|
||||||
break;
|
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,
|
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
|
||||||
buf_size3 << 3);
|
buf_size3 << 3);
|
||||||
slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);
|
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++;
|
n_slices++;
|
||||||
break;
|
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,
|
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
|
||||||
buf_size3 << 3);
|
buf_size3 << 3);
|
||||||
slices[n_slices].mby_start = s->mb_height + 1 >> 1;
|
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_slices1 = n_slices - 1;
|
||||||
n_slices++;
|
n_slices++;
|
||||||
}
|
}
|
||||||
@@ -921,6 +929,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (avctx->hwaccel) {
|
if (avctx->hwaccel) {
|
||||||
|
s->mb_y = 0;
|
||||||
if (v->field_mode && buf_start_second_field) {
|
if (v->field_mode && buf_start_second_field) {
|
||||||
// decode first field
|
// decode first field
|
||||||
s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
|
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;
|
s->picture_structure = PICT_FRAME;
|
||||||
if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
|
if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
|
||||||
goto err;
|
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)
|
if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0)
|
||||||
goto err;
|
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)
|
if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 57
|
#define LIBAVCODEC_VERSION_MAJOR 57
|
||||||
#define LIBAVCODEC_VERSION_MINOR 66
|
#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, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
Reference in New Issue
Block a user