From b6f0f884326256fa8a22d61eaff9691f7014b367 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Fri, 10 Jul 2015 18:43:35 +0200 Subject: [PATCH] Implement BMediaRoster::GetFileFormatsFor --- headers/private/media/ServerInterface.h | 9 ++++++ src/kits/media/FileInterface.cpp | 29 +++++++++++++++++++ src/kits/media/MediaRoster.cpp | 38 +++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h index e2c9fe3d3d..6c126dbc9f 100644 --- a/headers/private/media/ServerInterface.h +++ b/headers/private/media/ServerInterface.h @@ -135,6 +135,7 @@ enum { FILEINTERFACE_SET_REF, FILEINTERFACE_GET_REF, FILEINTERFACE_SNIFF_REF, + FILEINTERFACE_GET_FORMATS, FILEINTERFACE_MESSAGE_END, CONTROLLABLE_MESSAGE_START = 0x600, @@ -1004,6 +1005,14 @@ struct fileinterface_sniff_ref_reply : reply_data { float capability; }; +struct fileinterface_get_formats_request : request_data { + int32 num_formats; + area_id data_area; +}; + +struct fileinterface_get_formats_reply : reply_data { + int32 filled_slots; +}; // #pragma mark - controllable commands diff --git a/src/kits/media/FileInterface.cpp b/src/kits/media/FileInterface.cpp index 891169f7bb..c3c8d3d0ac 100644 --- a/src/kits/media/FileInterface.cpp +++ b/src/kits/media/FileInterface.cpp @@ -97,6 +97,35 @@ BFileInterface::HandleMessage(int32 message, return B_OK; } + case FILEINTERFACE_GET_FORMATS: + { + const fileinterface_get_formats_request *request = + (const fileinterface_get_formats_request*) data; + fileinterface_get_formats_reply reply; + + media_file_format* formats; + area_id area = clone_area("client formats area", + (void**)&formats, B_ANY_ADDRESS, B_WRITE_AREA, + request->data_area); + + if (area < 0) { + ERROR("BBufferConsumer::FILEINTERFACE_GET_FORMATS:" + " can't clone area\n"); + break; + } + + int32 cookie = 0; + while (GetNextFileFormat(&cookie, formats) == B_OK) { + if (cookie >= request->num_formats) + break; + formats += sizeof(media_format); + } + reply.filled_slots = cookie; + request->SendReply(B_OK, &reply, sizeof(reply)); + + delete_area(area); + return B_OK; + } default: return B_ERROR; } diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index ae368218f2..52bc59af26 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -2819,8 +2819,42 @@ status_t BMediaRoster::GetFileFormatsFor(const media_node& fileInterface, media_file_format* _formats, int32* _numFormats) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + + if (IS_INVALID_NODE(fileInterface) + || (fileInterface.kind & B_FILE_INTERFACE) == 0) + return B_MEDIA_BAD_NODE; + + if (_numFormats == NULL || *_numFormats < 1) + return B_BAD_VALUE; + + fileinterface_get_formats_request request; + fileinterface_get_formats_reply reply; + + media_file_format* formats; + size_t needSize = sizeof(media_file_format) * *_numFormats; + size_t size = (needSize + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1); + + area_id area = create_area("formats area", (void**)&formats, + B_ANY_ADDRESS, size, B_NO_LOCK, + B_READ_AREA | B_WRITE_AREA); + + if (area < 0) + return B_NO_MEMORY; + + request.num_formats = *_numFormats; + request.data_area = area; + + status_t status = QueryPort(fileInterface.port, + FILEINTERFACE_GET_FORMATS, &request, + sizeof(request), &reply, sizeof(reply)); + + if (status == B_OK) { + memcpy(_formats, formats, sizeof(media_file_format)*reply.filled_slots); + *_numFormats = reply.filled_slots; + } + delete_area(area); + return status; }