2012-06-21 29 views
6

Tôi muốn chia sẻ một thiết bị Direct3D giữa nhiều chủ đề và đối tượng trong ứng dụng Direct3D của mình. Tôi đã xem qua quản lý thiết bị Direct3D, trông giống như những gì tôi muốn, mặc dù tôi không làm bất kỳ xử lý video hoặc video tăng tốc: http://msdn.microsoft.com/en-us/library/windows/desktop/aa965267(v=vs.85).aspxLàm cách nào để sử dụng Trình Quản Lý Thiết Bị Direct3D?

Trong mã của tôi, tôi làm như sau:

// Create the device manager 
    UINT resetToken = 0; 
    IDirect3DDeviceManager9* deviceManager = NULL; 
    if (FAILED(DXVA2CreateDirect3DDeviceManager9(&resetToken, &deviceManager))) 
    return false; 

    // Add the device to the device manager 
    if (FAILED(deviceManager->ResetDevice(device, resetToken))) 
    return false; 

    deviceManager->AddRef(); 

Câu hỏi của tôi là khi tôi đã tạo trình quản lý thiết bị Direct3D, làm cách nào để chia sẻ trình quản lý thiết bị direct3d với các đối tượng khác mà không cần phải di chuyển con trỏ đến trình quản lý thiết bị? Microsoft đã đặc biệt nói để làm những điều sau đây, nhưng tôi không có đầu mối gì đang thực sự có nghĩa như sau:

Chủ sở hữu thiết bị phải cung cấp một cách cho các đối tượng khác để có được một con trỏ đến giao diện IDirect3DDeviceManager9. Cơ chế tiêu chuẩn là triển khai giao diện IMFGetService. GUID dịch vụ là MR_VIDEO_ACCELERATION_SERVICE.

Ai đó có thể chỉ cho tôi cách chia sẻ trình quản lý thiết bị bằng giao diện IMFGetService không?

Trả lời

4

Nếu bạn không thực hiện bất kỳ xử lý video nào, thì tôi không thấy điểm nào khi triển khai và/hoặc sử dụng giao diện IDirect3DDeviceManager9.

Chỉ cần thực hiện theo cách riêng của bạn để quản lý thời gian sống của thiết bị Direct3D, làm cho con trỏ giao diện có sẵn cho các đối tượng/chủ đề của bạn và đồng bộ hóa. Một thiết bị Direct3D không phải là bất kỳ loại điều kỳ diệu nào mà chỉ có thể được chia sẻ giữa các đối tượng/chủ đề thông qua một số IDirect3DDeviceManager9. Nó giống như bất kỳ tài nguyên nào khác. Và nếu bạn khởi tạo chính xác, bạn thậm chí có thể gọi một số phương thức đồng thời từ các luồng khác nhau (nghĩa là mọi thứ không phụ thuộc vào trạng thái thiết bị có thể bị thay đổi bởi một chuỗi khác).

Làm cho con trỏ giao diện khả dụng có thể đơn giản như có một con trỏ giữ con trỏ. Hoặc, nếu đối tượng/chủ đề của bạn đã cộng tác theo một cách nào đó, họ phải có một số phương tiện trao đổi thông tin. Vì vậy, tôi cho rằng bạn sẽ có thể chỉ cần mở rộng những gì bạn đã có để cung cấp cho các đối tượng/chủ đề truy cập vào các thiết bị Direct3D. Và việc đồng bộ hóa có thể dễ dàng thực hiện bằng cách sử dụng CRITICAL_SECTION.

Nếu bạn thực sự muốn sử dụng IDirect3DDeviceManager9, thì - theo như tôi hiểu - bạn phải triển khai giao diện IMFGetService trên tất cả các đối tượng mà bạn muốn truy cập vào IDirect3DDeviceManager9. Thực hiện chức năng GetService để khi được yêu cầu MR_VIDEO_ACCELERATION_SERVICE/IDirect3DDeviceManager9 nó trả về một con trỏ giao diện cho đối tượng quản lý thiết bị Direct3D của bạn.


EDIT: Về mã mẫu: Tôi hy vọng lời giải thích đưa ra ở đây là đủ. Chia sẻ nội dung giữa nhiều chủ đề là thứ mà tôi không dám giải thích bằng mẫu mã ngắn. Nếu bạn biết cách viết các ứng dụng đa luồng, thì việc sử dụng một thiết bị Direct3D không khác với cách nó được thực hiện với các tài nguyên khác. Và nếu bạn không biết cách viết các ứng dụng đa luồng thì chủ đề đó quá phức tạp cho đến một câu trả lời stackoverflow duy nhất.

Về câu hỏi tại sao MS đề xuất sử dụng IDirect3DDeviceManager9 ... tốt, tôi không biết về đề xuất chung như vậy.Nó chỉ được khuyến khích khi thực hiện xử lý video (sử dụng DXVA, EVR, vv). Hoặc nhiều hơn như bắt buộc; Tôi không chắc liệu bạn có thể chia sẻ thiết bị D3D hay không, ví dụ: Trình kết xuất video nâng cao mà không cần sử dụng trình quản lý thiết bị D3D. Đó là những gì mà người quản lý thiết bị D3D được tạo ra sau khi tất cả. Với việc chia sẻ VMR9 một thiết bị với trình kết xuất chỉ có thể theo hai cách:

Cách được ghi tài liệu: chỉ bao giờ truy cập thiết bị từ cuộc gọi lại "hiện tại" của VMR9. Đó là khá hạn chế - ví dụ bạn bị giới hạn ở tốc độ khung hình của video.

Cách không có giấy tờ: KHÔNG gọi IVMRFilterConfig9::SetNumberOfStreams và chỉ kết nối một luồng đầu vào. Bằng cách đó VMR9 sẽ không chuyển sang "chế độ trộn" và khi không ở chế độ "chế độ trộn" VMR9 sẽ không thay đổi bất kỳ trạng thái thiết bị nào. Vì vậy, nếu thiết bị D3D được khởi tạo đa luồng, thì bạn có thể sử dụng thiết bị D3D một cách tự do trong khi VMR9 đang sử dụng cùng một thiết bị.

Cũng với VMR9, không thể sử dụng thiết bị D3D trong bộ lọc DirectShow khác. Trình quản lý thiết bị D3D được cải thiện dựa trên đó, cho các bộ lọc và mã ứng dụng của riêng bạn khả năng sử dụng thiết bị D3D - bao gồm cả các trạng thái thay đổi. Tuy nhiên, nếu bạn thực hiện mọi thành phần sẽ tự sử dụng thiết bị D3D, thì không có bất kỳ điểm nào trong việc sử dụng trình quản lý thiết bị D3D. Và ngay cả khi bạn đang sử dụng các thành phần của bên thứ ba yêu cầu thiết bị D3D, bạn sẽ chỉ có thể sử dụng trình quản lý thiết bị D3D nếu các thành phần đó hỗ trợ nó. Điều này có thể không phải là trường hợp trừ khi các thành phần đó xảy ra là bộ lọc/thành phần DirectShow hoặc MediaFoundation.

Các vấn đề liên quan