Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ TAGS
/src/intel_version.h
/src/wayland-drm-client-protocol.h
.VERSION*

.idea
63 changes: 35 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
[![Stories in Ready](https://badge.waffle.io/intel/intel-vaapi-driver.png?label=ready&title=Ready)](http://waffle.io/intel/intel-vaapi-driver)
[![Build Status](https://travis-ci.org/intel/intel-vaapi-driver.svg?branch=master)](https://travis-ci.org/intel/intel-vaapi-driver)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/11612/badge.svg)](https://scan.coverity.com/projects/intel-intel-vaapi-driver)
# Fork of `intel-vaapi-driver` with h264 G45 support

# Intel-vaapi-driver Project
## The issue

VA-API (Video Acceleration API) user mode driver for Intel GEN Graphics family
Some Gen-4 intel GPUs (GMA X4500HD, GMA 4500MHD, X4700MHD) support hardware acceleration of h264 video decoding, but the user-space driver from Intel doesn't offer it.

VA-API is an open-source library and API specification, which
provides access to graphics hardware acceleration capabilities
for video processing. It consists of a main library and
driver-specific acceleration backends for each supported hardware
vendor.
Related issue https://github.com/intel/intel-vaapi-driver/issues/544

The current video driver backend provides a bridge to the GEN GPUs through the packaging of buffers and
commands to be sent to the i915 driver for exercising both hardware and shader functionality for video
decode, encode, and processing.
## Upstream

If you would like to contribute to intel-vaapi-driver, check our [Contributing
guide](https://github.com/intel/intel-vaapi-driver/blob/master/CONTRIBUTING.md).
The video acceleration user-space driver was maintained at:
- https://cgit.freedesktop.org/vaapi/intel-driver (until 2017.02.18)
- https://github.com/intel/intel-vaapi-driver previously https://github.com/01org/intel-vaapi-driver (2024.10.29)

We also recommend taking a look at the ['janitorial'
bugs](https://github.com/intel/intel-vaapi-driver/issues?q=is%3Aopen+is%3Aissue+label%3AJanitorial)
in our list of open issues as these bugs can be solved without an
extensive knowledge of intel-vaapi-driver.
The driver is no longer maintained by Intel with `intel-vaapi-driver` successor https://github.com/intel/media-driver supporting Gen-8 and up.

We would love to help you start contributing!
## Patches

The intel vaapi media development team can be reached via our [mailing
list](https://lists.01.org/mailman/listinfo/intel-vaapi-media) and on IRC
in channel ##intel-media on [Freenode](https://freenode.net/kb/answer/chat).
Patches that enable h264 in G45 are available at https://bitbucket.org/alium/g45-h264/downloads.
I am not aware who is the author of the code, it might be the user called `alium` or someone else.
Please open the issue if you know the details where this code came from.

We also use [#Slack](https://slack.com) and host [VAAPI Media Slack
Team](https://intel-media.slack.com). You can signup by submitting your email
address to our [Slack Team invite page](https://slack-join-intel-media.herokuapp.com).
## This project

Slack complements our other means of communication. Pick the one that works
best for you!
This project is a fork of https://github.com/intel/intel-vaapi-driver `v2.4-branch` and `master` branches with applied patches from https://bitbucket.org/alium/g45-h264/downloads.

I created this repository to preserve the patches in a transparent way. Tar-balls that are available from Bitbucket feel like a black-box without a real option for further contribution.

## Packaging

Packages are available in:
- [Debian](https://packages.debian.org/search?keywords=i965-va-driver) called `i965-va-driver`.
- [Ubuntu](https://launchpad.net/ubuntu/+source/intel-vaapi-driver) called `i965-va-driver`.
- [Arch Linux](https://archlinux.org/packages/extra/x86_64/libva-intel-driver) called `libva-intel-driver`.

Patched driver (h264 G45) is available in:
- [Arch Linux AUR](https://aur.archlinux.org/packages/libva-intel-driver-g45-h264) called `libva-intel-driver-g45-h264`.

## Development

To avoid unnecessary changes to line endings

```sh
git config core.whitespace cr-at-eol
```
154 changes: 139 additions & 15 deletions src/i965_avc_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,6 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
i965_h264_context->weight128_chroma_l0 = 0;
i965_h264_context->weight128_chroma_l1 = 0;

i965_h264_context->weight128_offset0_flag = 0;
i965_h264_context->weight128_offset0 = 0;

if (present_flag & PRESENT_WEIGHT_OFFSET_L0) {
for (j = 0; j < 32; j++) {
weightoffsets[j * 6 + 0] = slice_param->luma_offset_l0[j];
Expand All @@ -327,11 +324,17 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
slice_param->chroma_weight_l0[j][1] == 128)
i965_h264_context->weight128_chroma_l0 |= (1 << j);
} else {
/* FIXME: workaround for weight 128 */
if (slice_param->luma_weight_l0[j] == 128 ||
slice_param->chroma_weight_l0[j][0] == 128 ||
slice_param->chroma_weight_l0[j][1] == 128)
i965_h264_context->weight128_offset0_flag = 1;
if (slice_param->luma_weight_l0[j] == 128) {
weightoffsets[j * 6 + 1] = i965_h264_context->weight128_offset0;
}

if (slice_param->chroma_weight_l0[j][0] == 128) {
weightoffsets[j * 6 + 3] = i965_h264_context->weight128_offset0;
}

if (slice_param->chroma_weight_l0[j][1] == 128) {
weightoffsets[j * 6 + 5] = i965_h264_context->weight128_offset0;
}
}
}
}
Expand All @@ -357,10 +360,17 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
slice_param->chroma_weight_l1[j][1] == 128)
i965_h264_context->weight128_chroma_l1 |= (1 << j);
} else {
if (slice_param->luma_weight_l0[j] == 128 ||
slice_param->chroma_weight_l0[j][0] == 128 ||
slice_param->chroma_weight_l0[j][1] == 128)
i965_h264_context->weight128_offset0_flag = 1;
if (slice_param->luma_weight_l1[j] == 128) {
weightoffsets[j * 6 + 1] = i965_h264_context->weight128_offset0;
}

if (slice_param->chroma_weight_l1[j][0] == 128) {
weightoffsets[j * 6 + 3] = i965_h264_context->weight128_offset0;
}

if (slice_param->chroma_weight_l1[j][1] == 128) {
weightoffsets[j * 6 + 5] = i965_h264_context->weight128_offset0;
}
}
}
}
Expand Down Expand Up @@ -610,7 +620,7 @@ g4x_avc_bsd_object(VADriverContextP ctx,
OUT_BCS_BATCH(batch, CMD_AVC_BSD_OBJECT | (8 - 2));
OUT_BCS_BATCH(batch, 0); /* indirect data length for phantom slice is 0 */
OUT_BCS_BATCH(batch, 0); /* indirect data start address for phantom slice is 0 */
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, slice_index);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag));
Expand Down Expand Up @@ -781,9 +791,120 @@ static void
i965_avc_bsd_phantom_slice(VADriverContextP ctx,
struct decode_state *decode_state,
VAPictureParameterBufferH264 *pic_param,
int prev_slice_type,
struct i965_h264_context *i965_h264_context)
{
i965_avc_bsd_object(ctx, decode_state, pic_param, NULL, 0, i965_h264_context);
i965_avc_bsd_object(ctx, decode_state, pic_param, NULL, prev_slice_type, i965_h264_context);
}

static int
i965_list_find_weight(short *list, int size, short value)
{
int i;

for (i = 0; i < size; i++) {
if (list[i] == value)
return 1;
}

return 0;
}

static void
i965_weight128_workaround(VADriverContextP ctx, struct decode_state *decode_state, void *h264_context)
{
struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)h264_context;
VAPictureParameterBufferH264 *pic_param;
VASliceParameterBufferH264 *slice_param;
short weight128_offset0 = 0;
int i, j;

i965_h264_context->weight128_offset0_flag = 0;
i965_h264_context->weight128_offset0 = 0;

if (i965_h264_context->use_hw_w128)
return;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;

for (j = 0; j < decode_state->num_slice_params; j++) {
assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer;

for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {

if ((slice_param->slice_type == SLICE_TYPE_P ||
slice_param->slice_type == SLICE_TYPE_SP) &&
(pic_param->pic_fields.bits.weighted_pred_flag == 1)) {
i965_h264_context->weight128_offset0_flag =
i965_list_find_weight(&slice_param->luma_weight_l0[0], 32, 128) ||
i965_list_find_weight(&slice_param->chroma_weight_l0[0][0], 64, 128);
}

if ((slice_param->slice_type == SLICE_TYPE_B) &&
(pic_param->pic_fields.bits.weighted_bipred_idc == 1)) {
i965_h264_context->weight128_offset0_flag =
i965_list_find_weight(&slice_param->luma_weight_l0[0], 32, 128) ||
i965_list_find_weight(&slice_param->chroma_weight_l0[0][0], 64, 128) ||
i965_list_find_weight(&slice_param->luma_weight_l1[0], 32, 128) ||
i965_list_find_weight(&slice_param->chroma_weight_l1[0][0], 64, 128);
}

if (i965_h264_context->weight128_offset0_flag)
break;

slice_param++;
}

if (i965_h264_context->weight128_offset0_flag)
break;
}

if (!i965_h264_context->weight128_offset0_flag)
return;

for (weight128_offset0 = 0; weight128_offset0 < 128; weight128_offset0++) {
int bfound = 0;

for (j = 0; j < decode_state->num_slice_params; j++) {
assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer;

for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {

if ((slice_param->slice_type == SLICE_TYPE_P ||
slice_param->slice_type == SLICE_TYPE_SP) &&
(pic_param->pic_fields.bits.weighted_pred_flag == 1)) {
bfound =
i965_list_find_weight(&slice_param->luma_weight_l0[0], 32, weight128_offset0) ||
i965_list_find_weight(&slice_param->chroma_weight_l0[0][0], 64, weight128_offset0);
}

if ((slice_param->slice_type == SLICE_TYPE_B) &&
(pic_param->pic_fields.bits.weighted_bipred_idc == 1)) {
bfound =
i965_list_find_weight(&slice_param->luma_weight_l0[0], 32, weight128_offset0) ||
i965_list_find_weight(&slice_param->chroma_weight_l0[0][0], 64, weight128_offset0) ||
i965_list_find_weight(&slice_param->luma_weight_l1[0], 32, weight128_offset0) ||
i965_list_find_weight(&slice_param->chroma_weight_l1[0][0], 64, weight128_offset0);
}

if (bfound)
break;

slice_param++;
}

if (bfound)
break;
}

if (!bfound) {
i965_h264_context->weight128_offset0 = weight128_offset0;
break;
}
}
}

void
Expand All @@ -794,11 +915,13 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
VAPictureParameterBufferH264 *pic_param;
VASliceParameterBufferH264 *slice_param;
int i, j;
int prev_slice_type = SLICE_TYPE_I;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
intel_update_avc_frame_store_index(ctx, decode_state, pic_param,
i965_h264_context->fsid_list, &i965_h264_context->fs_ctx);
i965_weight128_workaround(ctx,decode_state, h264_context);

i965_h264_context->enable_avc_ildb = 0;
i965_h264_context->picture.i_flag = 1;
Expand Down Expand Up @@ -851,11 +974,12 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
i965_avc_bsd_slice_state(ctx, pic_param, slice_param, i965_h264_context);
i965_avc_bsd_buf_base_state(ctx, decode_state, pic_param, slice_param, i965_h264_context);
i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param, j, i965_h264_context);
prev_slice_type = slice_param->slice_type;
slice_param++;
}
}

i965_avc_bsd_phantom_slice(ctx, decode_state, pic_param, i965_h264_context);
i965_avc_bsd_phantom_slice(ctx, decode_state, pic_param, prev_slice_type, i965_h264_context);
intel_batchbuffer_emit_mi_flush(batch);
intel_batchbuffer_end_atomic(batch);
intel_batchbuffer_flush(batch);
Expand Down
4 changes: 2 additions & 2 deletions src/i965_avc_ildb.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,8 @@ i965_avc_ildb_decode_init(VADriverContextP ctx, void *h264_context)
avc_ildb_context->urb.vfe_start = 0;
avc_ildb_context->urb.cs_start = avc_ildb_context->urb.vfe_start +
avc_ildb_context->urb.num_vfe_entries * avc_ildb_context->urb.size_vfe_entry;
assert(avc_ildb_context->urb.cs_start +
avc_ildb_context->urb.num_cs_entries * avc_ildb_context->urb.size_cs_entry <= i965->intel.device_info->urb_size);
// assert(avc_ildb_context->urb.cs_start +
// avc_ildb_context->urb.num_cs_entries * avc_ildb_context->urb.size_cs_entry <= i965->intel.device_info->urb_size);

for (i = 0; i < NUM_AVC_ILDB_SURFACES; i++) {
dri_bo_unreference(avc_ildb_context->surface[i].s_bo);
Expand Down
1 change: 1 addition & 0 deletions src/i965_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD CMD(2, 0, 2)
#define CMD_MEDIA_GATEWAY_STATE CMD(2, 0, 3)
#define CMD_MEDIA_STATE_FLUSH CMD(2, 0, 4)
#define CMD_MEDIA_OBJECT_PRT CMD(2, 1, 2)
#define CMD_MEDIA_OBJECT_WALKER CMD(2, 1, 3)

#define CMD_PIPELINED_POINTERS CMD(3, 0, 0)
Expand Down
1 change: 1 addition & 0 deletions src/i965_device_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static struct hw_codec_info g4x_hw_codec_info = {
.min_linear_hpitch = 4,

.has_mpeg2_decoding = 1,
.has_h264_decoding = 1,

.num_filters = 0,
};
Expand Down
34 changes: 3 additions & 31 deletions src/i965_drv_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -5866,15 +5866,7 @@ i965_GetSurfaceAttributes(
attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;

if (attrib_list[i].value.value.i == 0) {
if (IS_G4X(i965->intel.device_info)) {
if (obj_config->profile == VAProfileMPEG2Simple ||
obj_config->profile == VAProfileMPEG2Main) {
attrib_list[i].value.value.i = VA_FOURCC_I420;
} else {
assert(0);
attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
}
} else if (IS_IRONLAKE(i965->intel.device_info)) {
if (IS_G4X(i965->intel.device_info) || IS_IRONLAKE(i965->intel.device_info)) {
if (obj_config->profile == VAProfileMPEG2Simple ||
obj_config->profile == VAProfileMPEG2Main) {
attrib_list[i].value.value.i = VA_FOURCC_I420;
Expand All @@ -5900,18 +5892,7 @@ i965_GetSurfaceAttributes(
attrib_list[i].value.value.i = VA_FOURCC_NV12;
}
} else {
if (IS_G4X(i965->intel.device_info)) {
if (obj_config->profile == VAProfileMPEG2Simple ||
obj_config->profile == VAProfileMPEG2Main) {
if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
attrib_list[i].value.value.i = 0;
attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
}
} else {
assert(0);
attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
}
} else if (IS_IRONLAKE(i965->intel.device_info)) {
if (IS_G4X(i965->intel.device_info) || IS_IRONLAKE(i965->intel.device_info)) {
if (obj_config->profile == VAProfileMPEG2Simple ||
obj_config->profile == VAProfileMPEG2Main) {
if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
Expand Down Expand Up @@ -6064,16 +6045,7 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
if (attribs == NULL)
return VA_STATUS_ERROR_ALLOCATION_FAILED;

if (IS_G4X(i965->intel.device_info)) {
if (obj_config->profile == VAProfileMPEG2Simple ||
obj_config->profile == VAProfileMPEG2Main) {
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].value.value.i = VA_FOURCC_I420;
i++;
}
} else if (IS_IRONLAKE(i965->intel.device_info)) {
if (IS_G4X(i965->intel.device_info) || IS_IRONLAKE(i965->intel.device_info)) {
switch (obj_config->profile) {
case VAProfileMPEG2Simple:
case VAProfileMPEG2Main:
Expand Down
3 changes: 3 additions & 0 deletions src/i965_media.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ g4x_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
case VAProfileH264ConstrainedBaseline:
case VAProfileH264Main:
case VAProfileH264High:
i965_media_h264_dec_context_init(ctx, media_context);
break;

case VAProfileVC1Simple:
case VAProfileVC1Main:
case VAProfileVC1Advanced:
Expand Down
2 changes: 1 addition & 1 deletion src/i965_media.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

#include "i965_structs.h"

#define MAX_INTERFACE_DESC 16
#define MAX_INTERFACE_DESC 32
#define MAX_MEDIA_SURFACES 34

struct decode_state;
Expand Down
Loading