summaryrefslogtreecommitdiff
blob: 7fba6144c09529b34af1d501198ec91bb2950ecf (plain)
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)