mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
vc1: implement vc1 field interlaced dxva2 decoding
Tested-by: Gwenole Beauchesne <gb.devel@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
8fb8d539a4
commit
b87ff34496
@ -68,7 +68,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
|
||||
pp->bPicStructure |= 0x01;
|
||||
if (s->picture_structure & PICT_BOTTOM_FIELD)
|
||||
pp->bPicStructure |= 0x02;
|
||||
pp->bSecondField = v->interlace && v->fcm != ILACE_FIELD && !s->first_field;
|
||||
pp->bSecondField = v->interlace && v->fcm == ILACE_FIELD && v->second_field;
|
||||
pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type;
|
||||
pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type;
|
||||
pp->bBidirectionalAveragingMode = (1 << 7) |
|
||||
@ -183,8 +183,11 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
|
||||
|
||||
result = data_size <= dxva_size ? 0 : -1;
|
||||
if (!result) {
|
||||
if (start_code_size > 0)
|
||||
if (start_code_size > 0) {
|
||||
memcpy(dxva_data, start_code, start_code_size);
|
||||
if (v->second_field)
|
||||
dxva_data[3] = 0x0c;
|
||||
}
|
||||
memcpy(dxva_data + start_code_size,
|
||||
ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
|
||||
if (padding > 0)
|
||||
|
@ -5318,7 +5318,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
MpegEncContext *s = &v->s;
|
||||
AVFrame *pict = data;
|
||||
uint8_t *buf2 = NULL;
|
||||
const uint8_t *buf_start = buf;
|
||||
const uint8_t *buf_start = buf, *buf_start_second_field = NULL;
|
||||
int mb_height, n_slices1=-1;
|
||||
struct {
|
||||
uint8_t *buf;
|
||||
@ -5326,6 +5326,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int mby_start;
|
||||
} *slices = NULL, *tmp;
|
||||
|
||||
v->second_field = 0;
|
||||
|
||||
if(s->flags & CODEC_FLAG_LOW_DELAY)
|
||||
s->low_delay = 1;
|
||||
|
||||
@ -5372,6 +5374,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
break;
|
||||
case VC1_CODE_FIELD: {
|
||||
int buf_size3;
|
||||
if (avctx->hwaccel ||
|
||||
s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
|
||||
buf_start_second_field = start;
|
||||
tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
|
||||
if (!tmp)
|
||||
goto err;
|
||||
@ -5423,6 +5428,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");
|
||||
goto err;
|
||||
} else { // found field marker, unescape second field
|
||||
if (avctx->hwaccel ||
|
||||
s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
|
||||
buf_start_second_field = divider;
|
||||
tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
|
||||
if (!tmp)
|
||||
goto err;
|
||||
@ -5558,12 +5566,42 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
&&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
|
||||
ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
|
||||
else if (avctx->hwaccel) {
|
||||
if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->end_frame(avctx) < 0)
|
||||
goto err;
|
||||
if (v->field_mode && buf_start_second_field) {
|
||||
// decode first field
|
||||
s->picture_structure = PICT_BOTTOM_FIELD - v->tff;
|
||||
if (avctx->hwaccel->start_frame(avctx, buf_start, buf_start_second_field - buf_start) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->end_frame(avctx) < 0)
|
||||
goto err;
|
||||
|
||||
// decode second field
|
||||
s->gb = slices[n_slices1 + 1].gb;
|
||||
s->picture_structure = PICT_TOP_FIELD + v->tff;
|
||||
v->second_field = 1;
|
||||
v->pic_header_flag = 0;
|
||||
if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "parsing header for second field failed");
|
||||
goto err;
|
||||
}
|
||||
v->s.current_picture_ptr->f.pict_type = v->s.pict_type;
|
||||
|
||||
if (avctx->hwaccel->start_frame(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->end_frame(avctx) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
s->picture_structure = PICT_FRAME;
|
||||
if (avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
|
||||
goto err;
|
||||
if (avctx->hwaccel->end_frame(avctx) < 0)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
ff_er_frame_start(s);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user