diff options
author | Ilia Mirkin <[email protected]> | 2014-02-08 15:22:46 -0500 |
---|---|---|
committer | Maarten Lankhorst <[email protected]> | 2014-02-10 14:00:17 +0100 |
commit | 40dd777b3307301e6580c5757c322a2ec99b5b37 (patch) | |
tree | 5d756fa07072768b3f8fcbe5a755a9140bcacf4e /src/gallium/drivers/nouveau/nv50 | |
parent | a487ef87fe4aa8c4b8e5c0d888bfb18727c8e570 (diff) |
nouveau/video: make sure that firmware is present when checking caps
Apparently some players are ill-prepared for us claiming that a decoder
exists only to have creating it fail, and express this poor preparation
with crashes (e.g. flash). Check that firmware is there to increase the
chances of there being a high correlation between reported capabilities
and ability to create a decoder.
Signed-off-by: Ilia Mirkin <[email protected]>
Cc: 10.0 10.1 <[email protected]>
Tested-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv84_video.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c index 3fee6d95f66..a39f572f708 100644 --- a/src/gallium/drivers/nouveau/nv50/nv84_video.c +++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c @@ -741,16 +741,80 @@ error: return NULL; } +#define FIRMWARE_BSP_KERN 0x01 +#define FIRMWARE_VP_KERN 0x02 +#define FIRMWARE_BSP_H264 0x04 +#define FIRMWARE_VP_MPEG2 0x08 +#define FIRMWARE_VP_H264_1 0x10 +#define FIRMWARE_VP_H264_2 0x20 +#define FIRMWARE_PRESENT(val, fw) (val & FIRMWARE_ ## fw) + +static int +firmware_present(struct pipe_screen *pscreen, enum pipe_video_format codec) +{ + struct nouveau_screen *screen = nouveau_screen(pscreen); + struct nouveau_object *obj = NULL; + struct stat s; + int checked = screen->firmware_info.profiles_checked; + int present, ret; + + if (!FIRMWARE_PRESENT(checked, VP_KERN)) { + nouveau_object_new(screen->channel, 0, 0x7476, NULL, 0, &obj); + if (obj) + screen->firmware_info.profiles_present |= FIRMWARE_VP_KERN; + nouveau_object_del(&obj); + screen->firmware_info.profiles_checked |= FIRMWARE_VP_KERN; + } + + if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (!FIRMWARE_PRESENT(checked, BSP_KERN)) { + nouveau_object_new(screen->channel, 0, 0x74b0, NULL, 0, &obj); + if (obj) + screen->firmware_info.profiles_present |= FIRMWARE_BSP_KERN; + nouveau_object_del(&obj); + screen->firmware_info.profiles_checked |= FIRMWARE_BSP_KERN; + } + + if (!FIRMWARE_PRESENT(checked, VP_H264_1)) { + ret = stat("/lib/firmware/nouveau/nv84_vp-h264-1", &s); + if (!ret && s.st_size > 1000) + screen->firmware_info.profiles_present |= FIRMWARE_VP_H264_1; + screen->firmware_info.profiles_checked |= FIRMWARE_VP_H264_1; + } + + /* should probably check the others, but assume that 1 means all */ + + present = screen->firmware_info.profiles_present; + return FIRMWARE_PRESENT(present, VP_KERN) && + FIRMWARE_PRESENT(present, BSP_KERN) && + FIRMWARE_PRESENT(present, VP_H264_1); + } else { + if (!FIRMWARE_PRESENT(checked, VP_MPEG2)) { + ret = stat("/lib/firmware/nouveau/nv84_vp-mpeg12", &s); + if (!ret && s.st_size > 1000) + screen->firmware_info.profiles_present |= FIRMWARE_VP_MPEG2; + screen->firmware_info.profiles_checked |= FIRMWARE_VP_MPEG2; + } + present = screen->firmware_info.profiles_present; + return FIRMWARE_PRESENT(present, VP_KERN) && + FIRMWARE_PRESENT(present, VP_MPEG2); + } +} + int nv84_screen_get_video_param(struct pipe_screen *pscreen, enum pipe_video_profile profile, enum pipe_video_entrypoint entrypoint, enum pipe_video_cap param) { + enum pipe_video_format codec; + switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: - return u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC || - u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_MPEG12; + codec = u_reduce_video_profile(profile); + return (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC || + codec == PIPE_VIDEO_FORMAT_MPEG12) && + firmware_present(pscreen, codec); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: |