1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
commit 7d70d28f190e37cfa3a9a827877ddd6bb81408d3
Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date: Mon Dec 28 08:52:56 2009 +0000
Add GMA500 workaround for H.264 DPB. This is disabled by default. Enable with GMA500_WORKAROUND=yes environment variable.
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 9f440c0..0139d64 100644
--- a/ffmpeg/libavcodec/vaapi_h264.c
+++ b/ffmpeg/libavcodec/vaapi_h264.c
@@ -28,6 +28,60 @@
* structures for H.264 decoding.
*/
+/** Parses ENV environment variable expecting "yes" | "no" values. */
+static int getenv_yesno(const char *env, int *pval)
+{
+ int val;
+ const char *env_str;
+
+ env_str = getenv(env);
+ if (!env_str)
+ return -1;
+
+ if (strcmp(env_str, "1") == 0 || strcmp(env_str, "yes") == 0)
+ val = 1;
+ else if (strcmp(env_str, "0") == 0 || strcmp(env_str, "no") == 0)
+ val = 0;
+ else
+ return -1;
+
+ if (pval)
+ *pval = val;
+ return 0;
+}
+
+/**
+ * Use old GMA500 workaround for DPB. It requires other pictures than
+ * those marked as "used for reference".
+ */
+static int get_use_gma500_workaround(struct vaapi_context *vactx)
+{
+ int gma500_workaround_env;
+ const char *vendor_string;
+
+ if (getenv_yesno("GMA500_WORKAROUND", &gma500_workaround_env) < 0)
+ return 0;
+ if (!gma500_workaround_env)
+ return 0;
+
+ vendor_string = vaQueryVendorString(vactx->display);
+ if (vendor_string && strstr(vendor_string, "Intel")) {
+ if (strstr(vendor_string, "GMA500"))
+ return 1;
+ if (strstr(vendor_string, "Embedded Graphics Driver"))
+ return 1;
+ }
+ return 0;
+}
+
+static inline int use_gma500_workaround(struct vaapi_context *vactx)
+{
+ static int gma500_workaround = -1;
+ if (gma500_workaround < 0)
+ gma500_workaround = get_use_gma500_workaround(vactx);
+ return gma500_workaround;
+}
+
/**
* Initializes an empty VA API picture.
*
@@ -123,6 +177,7 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param,
{
DPB dpb;
int i;
+ unsigned int list;
dpb.size = 0;
dpb.max_size = FF_ARRAY_ELEMS(pic_param->ReferenceFrames);
@@ -130,6 +185,17 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param,
for (i = 0; i < dpb.max_size; i++)
init_vaapi_pic(&dpb.va_pics[i]);
+ if (use_gma500_workaround(h->s.avctx->hwaccel_context)) {
+ /* XXX: this is really wrong */
+ for (list = 0; list < h->list_count; list++)
+ for (i = 0; i < (int)h->ref_count[list]; i++) {
+ Picture * const pic = &h->ref_list[list][i];
+ if (pic->reference && dpb_add(&dpb, pic) < 0)
+ return -1;
+ }
+ return 0;
+ }
+
for (i = 0; i < h->short_ref_count; i++) {
Picture * const pic = h->short_ref[i];
if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
|