hardware/intel/libva
Revisão | 6cb2cd5b8b74844ce2f36449b14d2043b3a683a6 (tree) |
---|---|
Hora | 2010-07-12 14:26:39 |
Autor | Gwenole Beauchesne <gbeauchesne@spli...> |
Commiter | Xiang, Haihao |
Implement vaGetImage().
@@ -1446,6 +1446,66 @@ i965_SetImagePalette(VADriverContextP ctx, | ||
1446 | 1446 | return VA_STATUS_SUCCESS; |
1447 | 1447 | } |
1448 | 1448 | |
1449 | +static void | |
1450 | +get_image_yv12(struct object_image *obj_image, uint8_t *image_data, | |
1451 | + struct object_surface *obj_surface, | |
1452 | + const VARectangle *rect) | |
1453 | +{ | |
1454 | + uint8_t *dst[3], *src[3]; | |
1455 | + int i, x, y, w, h; | |
1456 | + | |
1457 | + if (!obj_surface->bo) | |
1458 | + return; | |
1459 | + | |
1460 | + dri_bo_map(obj_surface->bo, 0); | |
1461 | + | |
1462 | + if (!obj_surface->bo->virtual) | |
1463 | + return; | |
1464 | + | |
1465 | + x = rect->x; | |
1466 | + y = rect->y; | |
1467 | + w = rect->width; | |
1468 | + h = rect->height; | |
1469 | + | |
1470 | + dst[0] = image_data + obj_image->image.offsets[0]; | |
1471 | + src[0] = (uint8_t *)obj_surface->bo->virtual; | |
1472 | + dst[1] = image_data + obj_image->image.offsets[1]; | |
1473 | + src[1] = src[0] + obj_surface->width * obj_surface->height; | |
1474 | + dst[2] = image_data + obj_image->image.offsets[2]; | |
1475 | + src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2); | |
1476 | + | |
1477 | + dst[0] += y * obj_image->image.pitches[0] + x; | |
1478 | + src[0] += y * obj_surface->width + x; | |
1479 | + for (i = 0; i < h; i++) { | |
1480 | + memcpy(dst[0], src[0], w); | |
1481 | + dst[0] += obj_image->image.pitches[0]; | |
1482 | + src[0] += obj_surface->width; | |
1483 | + } | |
1484 | + | |
1485 | + x /= 2; | |
1486 | + y /= 2; | |
1487 | + w /= 2; | |
1488 | + h /= 2; | |
1489 | + | |
1490 | + dst[1] += y * obj_image->image.pitches[1] + x; | |
1491 | + src[1] += y * obj_surface->width / 2 + x; | |
1492 | + for (i = 0; i < h; i++) { | |
1493 | + memcpy(dst[1], src[1], w); | |
1494 | + dst[1] += obj_image->image.pitches[1]; | |
1495 | + src[1] += obj_surface->width / 2; | |
1496 | + } | |
1497 | + | |
1498 | + dst[2] += y * obj_image->image.pitches[2] + y; | |
1499 | + src[2] += y * obj_surface->width / 2 + x; | |
1500 | + for (i = 0; i < h; i++) { | |
1501 | + memcpy(dst[2], src[2], w); | |
1502 | + dst[2] += obj_image->image.pitches[2]; | |
1503 | + src[2] += obj_surface->width / 2; | |
1504 | + } | |
1505 | + | |
1506 | + dri_bo_unmap(obj_surface->bo); | |
1507 | +} | |
1508 | + | |
1449 | 1509 | VAStatus |
1450 | 1510 | i965_GetImage(VADriverContextP ctx, |
1451 | 1511 | VASurfaceID surface, |
@@ -1455,7 +1515,51 @@ i965_GetImage(VADriverContextP ctx, | ||
1455 | 1515 | unsigned int height, |
1456 | 1516 | VAImageID image) |
1457 | 1517 | { |
1458 | - return VA_STATUS_SUCCESS; | |
1518 | + struct i965_driver_data *i965 = i965_driver_data(ctx); | |
1519 | + struct i965_render_state *render_state = &i965->render_state; | |
1520 | + | |
1521 | + struct object_surface *obj_surface = SURFACE(surface); | |
1522 | + if (!obj_surface) | |
1523 | + return VA_STATUS_ERROR_INVALID_SURFACE; | |
1524 | + | |
1525 | + struct object_image *obj_image = IMAGE(image); | |
1526 | + if (!obj_image) | |
1527 | + return VA_STATUS_ERROR_INVALID_IMAGE; | |
1528 | + | |
1529 | + if (x < 0 || y < 0) | |
1530 | + return VA_STATUS_ERROR_INVALID_PARAMETER; | |
1531 | + if (width > obj_surface->width || height > obj_surface->height) | |
1532 | + return VA_STATUS_ERROR_INVALID_PARAMETER; | |
1533 | + if (width > obj_image->image.width || height > obj_image->image.height) | |
1534 | + return VA_STATUS_ERROR_INVALID_PARAMETER; | |
1535 | + | |
1536 | + VAStatus va_status; | |
1537 | + void *image_data = NULL; | |
1538 | + | |
1539 | + va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data); | |
1540 | + if (va_status != VA_STATUS_SUCCESS) | |
1541 | + return va_status; | |
1542 | + | |
1543 | + VARectangle rect; | |
1544 | + rect.x = x; | |
1545 | + rect.y = y; | |
1546 | + rect.width = width; | |
1547 | + rect.height = height; | |
1548 | + | |
1549 | + switch (obj_image->image.format.fourcc) { | |
1550 | + case VA_FOURCC('Y','V','1','2'): /* YV12 is native format here */ | |
1551 | + if (render_state->interleaved_uv) | |
1552 | + goto operation_failed; | |
1553 | + get_image_yv12(obj_image, image_data, obj_surface, &rect); | |
1554 | + break; | |
1555 | + default: | |
1556 | + operation_failed: | |
1557 | + va_status = VA_STATUS_ERROR_OPERATION_FAILED; | |
1558 | + break; | |
1559 | + } | |
1560 | + | |
1561 | + i965_UnmapBuffer(ctx, obj_image->image.buf); | |
1562 | + return va_status; | |
1459 | 1563 | } |
1460 | 1564 | |
1461 | 1565 | VAStatus |