Changed the way Encoders are published by EncoderPlugins. Encoder retrieval
in PluginManager is reenabled. We use the media_codec_info.id to reference a specific plugin, while the sub_id will be used to reference individual Encoders that the plugin supports. No idea if that's how it was intented, but some comments hint in this direction. I failed to mention this before, but comments are of course very welcome on any of these commits, as always. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -133,7 +133,7 @@ enum {
|
|||||||
SERVER_GET_DECODER_FOR_FORMAT,
|
SERVER_GET_DECODER_FOR_FORMAT,
|
||||||
SERVER_GET_WRITER_FOR_FORMAT_FAMILY,
|
SERVER_GET_WRITER_FOR_FORMAT_FAMILY,
|
||||||
SERVER_GET_FILE_FORMAT_FOR_COOKIE,
|
SERVER_GET_FILE_FORMAT_FOR_COOKIE,
|
||||||
SERVER_GET_ENCODER_FOR_FORMAT,
|
SERVER_GET_ENCODER_FOR_CODEC_INFO,
|
||||||
SERVER_MESSAGE_END,
|
SERVER_MESSAGE_END,
|
||||||
NODE_MESSAGE_START = 0x200,
|
NODE_MESSAGE_START = 0x200,
|
||||||
|
|
||||||
@@ -808,11 +808,11 @@ struct server_get_decoder_for_format_reply : reply_data {
|
|||||||
// a ref to the decoder
|
// a ref to the decoder
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server_get_encoder_for_format_request : request_data {
|
struct server_get_encoder_for_codec_info_request : request_data {
|
||||||
media_format format;
|
int32 id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server_get_encoder_for_format_reply : reply_data {
|
struct server_get_encoder_for_codec_info_reply : reply_data {
|
||||||
xfer_entry_ref ref;
|
xfer_entry_ref ref;
|
||||||
// a ref to the encoder
|
// a ref to the encoder
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
#ifndef _ENCODER_PLUGIN_H
|
#ifndef _ENCODER_PLUGIN_H
|
||||||
#define _ENCODER_PLUGIN_H
|
#define _ENCODER_PLUGIN_H
|
||||||
|
|
||||||
|
|
||||||
#include <MediaTrack.h>
|
#include <MediaTrack.h>
|
||||||
#include <MediaFormats.h>
|
#include <MediaFormats.h>
|
||||||
#include "MediaPlugin.h"
|
#include "MediaPlugin.h"
|
||||||
|
|
||||||
|
|
||||||
class AddOnManager;
|
class AddOnManager;
|
||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
@@ -18,15 +24,14 @@ public:
|
|||||||
size_t chunkSize, uint32 flags) = 0;
|
size_t chunkSize, uint32 flags) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Encoder {
|
class Encoder {
|
||||||
public:
|
public:
|
||||||
Encoder();
|
Encoder();
|
||||||
virtual ~Encoder();
|
virtual ~Encoder();
|
||||||
|
|
||||||
virtual void GetCodecInfo(media_codec_info* codecInfo) = 0;
|
|
||||||
|
|
||||||
virtual status_t SetFormat(const media_file_format& fileFormat,
|
virtual status_t SetFormat(const media_file_format& fileFormat,
|
||||||
const media_format& encodedFormat) = 0;
|
media_format* _inOutEncodedFormat) = 0;
|
||||||
|
|
||||||
virtual status_t AddTrackInfo(uint32 code, const void* data,
|
virtual status_t AddTrackInfo(uint32 code, const void* data,
|
||||||
size_t size, uint32 flags = 0) = 0;
|
size_t size, uint32 flags = 0) = 0;
|
||||||
@@ -67,8 +72,19 @@ class EncoderPlugin : public virtual MediaPlugin {
|
|||||||
public:
|
public:
|
||||||
EncoderPlugin();
|
EncoderPlugin();
|
||||||
|
|
||||||
virtual Encoder* NewEncoder(uint index) = 0;
|
virtual Encoder* NewEncoder(
|
||||||
virtual status_t GetSupportedFormats(media_format** formats,
|
const media_codec_info& codecInfo) = 0;
|
||||||
|
|
||||||
|
// TODO: Maybe this also needs to return a media_format with wild cards
|
||||||
|
// so that we can support the respective get_next_encoder() functions
|
||||||
|
// that take media_formats with wild cards and specialize them.
|
||||||
|
// Then this interface could be turned into an iterator like interface:
|
||||||
|
//
|
||||||
|
// status_t GetNextSupportedCodec(int32* cookie,
|
||||||
|
// const media_codec_info* codecInfo,
|
||||||
|
// const media_format* format) = 0;
|
||||||
|
virtual status_t GetSupportedCodecs(
|
||||||
|
const media_codec_info** codecInfos,
|
||||||
size_t* count) = 0;
|
size_t* count) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ public:
|
|||||||
status_t CreateEncoder(Encoder** encoder,
|
status_t CreateEncoder(Encoder** encoder,
|
||||||
const media_codec_info* codecInfo,
|
const media_codec_info* codecInfo,
|
||||||
uint32 flags);
|
uint32 flags);
|
||||||
status_t GetEncoderInfo(Encoder* encoder,
|
|
||||||
media_codec_info* _info) const;
|
|
||||||
void DestroyEncoder(Encoder* encoder);
|
void DestroyEncoder(Encoder* encoder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -257,16 +257,15 @@ PluginManager::CreateEncoder(Encoder** _encoder,
|
|||||||
{
|
{
|
||||||
TRACE("PluginManager::CreateEncoder enter\n");
|
TRACE("PluginManager::CreateEncoder enter\n");
|
||||||
|
|
||||||
#if 0
|
// Get encoder for this codec info from the server
|
||||||
// get decoder for this format from the server
|
server_get_encoder_for_codec_info_request request;
|
||||||
server_get_encoder_for_format_request request;
|
server_get_encoder_for_codec_info_reply reply;
|
||||||
server_get_encoder_for_format_reply reply;
|
request.id = codecInfo->id;
|
||||||
request.format = format;
|
status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_CODEC_INFO, &request,
|
||||||
status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_FORMAT, &request,
|
|
||||||
sizeof(request), &reply, sizeof(reply));
|
sizeof(request), &reply, sizeof(reply));
|
||||||
if (ret != B_OK) {
|
if (ret != B_OK) {
|
||||||
printf("PluginManager::CreateEncoder: can't get encoder for format: "
|
printf("PluginManager::CreateEncoder: can't get encoder for codec %s: "
|
||||||
"%s\n", strerror(ret));
|
"%s\n", codecInfo->pretty_name, strerror(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,9 +282,7 @@ PluginManager::CreateEncoder(Encoder** _encoder,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: In theory, one EncoderPlugin could support multiple Encoders,
|
*_encoder = encoderPlugin->NewEncoder(*codecInfo);
|
||||||
// but this is not yet handled (passing "0" as index/ID).
|
|
||||||
*_encoder = encoderPlugin->NewEncoder(0);
|
|
||||||
if (*_encoder == NULL) {
|
if (*_encoder == NULL) {
|
||||||
printf("PluginManager::CreateEncoder: NewEncoder() failed\n");
|
printf("PluginManager::CreateEncoder: NewEncoder() failed\n");
|
||||||
PutPlugin(plugin);
|
PutPlugin(plugin);
|
||||||
@@ -296,24 +293,6 @@ PluginManager::CreateEncoder(Encoder** _encoder,
|
|||||||
|
|
||||||
TRACE("PluginManager::CreateEncoder leave\n");
|
TRACE("PluginManager::CreateEncoder leave\n");
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
#else
|
|
||||||
TRACE("PluginManager::CreateEncoder leave\n");
|
|
||||||
return B_NOT_SUPPORTED;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
PluginManager::GetEncoderInfo(Encoder* encoder, media_codec_info* _info) const
|
|
||||||
{
|
|
||||||
if (encoder == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
encoder->GetCodecInfo(_info);
|
|
||||||
// TODO:
|
|
||||||
// out_info->id =
|
|
||||||
// out_info->sub_id =
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ private:
|
|||||||
AddOnManager::AddOnManager()
|
AddOnManager::AddOnManager()
|
||||||
:
|
:
|
||||||
fLock("add-on manager"),
|
fLock("add-on manager"),
|
||||||
fNextWriterFormatFamilyID(0)
|
fNextWriterFormatFamilyID(0),
|
||||||
|
fNextEncoderCodecInfoID(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,38 +142,25 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
AddOnManager::GetEncoderForFormat(xfer_entry_ref* _encoderRef,
|
AddOnManager::GetEncoder(xfer_entry_ref* _encoderRef, int32 id)
|
||||||
const media_format& format)
|
|
||||||
{
|
{
|
||||||
if ((format.type == B_MEDIA_ENCODED_VIDEO
|
|
||||||
|| format.type == B_MEDIA_ENCODED_AUDIO
|
|
||||||
|| format.type == B_MEDIA_MULTISTREAM)
|
|
||||||
&& format.Encoding() == 0) {
|
|
||||||
return B_MEDIA_BAD_FORMAT;
|
|
||||||
}
|
|
||||||
if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE)
|
|
||||||
return B_MEDIA_BAD_FORMAT;
|
|
||||||
|
|
||||||
BAutolock locker(fLock);
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
printf("AddOnManager::GetEncoderForFormat: searching encoder for encoding "
|
|
||||||
"%ld\n", format.Encoding());
|
|
||||||
|
|
||||||
encoder_info* info;
|
encoder_info* info;
|
||||||
for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
|
for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
|
||||||
media_format* encoderFormat;
|
|
||||||
for (info->formats.Rewind(); info->formats.GetNext(&encoderFormat);) {
|
|
||||||
// check if the encoder matches the supplied format
|
// check if the encoder matches the supplied format
|
||||||
if (!encoderFormat->Matches(&format))
|
if (info->internalID == id) {
|
||||||
continue;
|
|
||||||
|
|
||||||
printf("AddOnManager::GetEncoderForFormat: found encoder %s for "
|
printf("AddOnManager::GetEncoderForFormat: found encoder %s for "
|
||||||
"encoding %ld\n", info->ref.name, encoderFormat->Encoding());
|
"id %ld\n", info->ref.name, id);
|
||||||
|
|
||||||
*_encoderRef = info->ref;
|
*_encoderRef = info->ref;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("AddOnManager::GetEncoderForFormat: failed to find encoder for id "
|
||||||
|
"%ld\n", id);
|
||||||
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +191,7 @@ AddOnManager::GetFileFormat(media_file_format* _fileFormat, int32 cookie)
|
|||||||
BAutolock locker(fLock);
|
BAutolock locker(fLock);
|
||||||
|
|
||||||
media_file_format* fileFormat;
|
media_file_format* fileFormat;
|
||||||
if (fFileFormats.Get(cookie, &fileFormat)) {
|
if (fWriterFileFormats.Get(cookie, &fileFormat)) {
|
||||||
*_fileFormat = *fileFormat;
|
*_fileFormat = *fileFormat;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -436,7 +424,7 @@ AddOnManager::_RegisterWriter(WriterPlugin* writer, const entry_ref& ref)
|
|||||||
fileFormat.id.device = ref.device;
|
fileFormat.id.device = ref.device;
|
||||||
fileFormat.id.internal_id = info.internalID;
|
fileFormat.id.internal_id = info.internalID;
|
||||||
|
|
||||||
fFileFormats.Insert(fileFormat);
|
fWriterFileFormats.Insert(fileFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
fWriterList.Insert(info);
|
fWriterList.Insert(info);
|
||||||
@@ -460,17 +448,23 @@ AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref)
|
|||||||
|
|
||||||
encoder_info info;
|
encoder_info info;
|
||||||
info.ref = ref;
|
info.ref = ref;
|
||||||
|
info.internalID = fNextEncoderCodecInfoID++;
|
||||||
|
|
||||||
// Get list of support media_formats...
|
// Get list of supported codecs...
|
||||||
media_format* formats = NULL;
|
const media_codec_info* codecInfos = NULL;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
if (plugin->GetSupportedFormats(&formats, &count) != B_OK) {
|
if (plugin->GetSupportedCodecs(&codecInfos, &count) != B_OK) {
|
||||||
printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedFormats"
|
printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedCodecs"
|
||||||
"(...) failed!\n");
|
"(...) failed!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uint i = 0 ; i < count ; i++)
|
|
||||||
info.formats.Insert(formats[i]);
|
for (uint32 i = 0 ; i < count ; i++) {
|
||||||
|
media_codec_info codecInfo = codecInfos[i];
|
||||||
|
codecInfo.id = info.internalID;
|
||||||
|
codecInfo.sub_id = i;
|
||||||
|
info.codecInfos.Insert(codecInfo);
|
||||||
|
}
|
||||||
|
|
||||||
fEncoderList.Insert(info);
|
fEncoderList.Insert(info);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,7 @@ public:
|
|||||||
status_t GetReaders(xfer_entry_ref* _ref,
|
status_t GetReaders(xfer_entry_ref* _ref,
|
||||||
int32* _count, int32 maxCount);
|
int32* _count, int32 maxCount);
|
||||||
|
|
||||||
status_t GetEncoderForFormat(xfer_entry_ref* _ref,
|
status_t GetEncoder(xfer_entry_ref* _ref, int32 id);
|
||||||
const media_format& format);
|
|
||||||
|
|
||||||
status_t GetWriter(xfer_entry_ref* _ref,
|
status_t GetWriter(xfer_entry_ref* _ref,
|
||||||
uint32 internalID);
|
uint32 internalID);
|
||||||
@@ -78,7 +77,8 @@ private:
|
|||||||
};
|
};
|
||||||
struct encoder_info {
|
struct encoder_info {
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
List<media_format> formats;
|
uint32 internalID;
|
||||||
|
List<media_codec_info> codecInfos;
|
||||||
};
|
};
|
||||||
|
|
||||||
BLocker fLock;
|
BLocker fLock;
|
||||||
@@ -87,9 +87,10 @@ private:
|
|||||||
List<decoder_info> fDecoderList;
|
List<decoder_info> fDecoderList;
|
||||||
List<encoder_info> fEncoderList;
|
List<encoder_info> fEncoderList;
|
||||||
|
|
||||||
List<media_file_format> fFileFormats;
|
List<media_file_format> fWriterFileFormats;
|
||||||
|
|
||||||
uint32 fNextWriterFormatFamilyID;
|
uint32 fNextWriterFormatFamilyID;
|
||||||
|
uint32 fNextEncoderCodecInfoID;
|
||||||
|
|
||||||
AddOnMonitorHandler* fHandler;
|
AddOnMonitorHandler* fHandler;
|
||||||
AddOnMonitor* fAddOnMonitor;
|
AddOnMonitor* fAddOnMonitor;
|
||||||
|
|||||||
@@ -908,14 +908,13 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SERVER_GET_ENCODER_FOR_FORMAT:
|
case SERVER_GET_ENCODER_FOR_CODEC_INFO:
|
||||||
{
|
{
|
||||||
const server_get_encoder_for_format_request *request
|
const server_get_encoder_for_codec_info_request *request
|
||||||
= reinterpret_cast<
|
= reinterpret_cast<
|
||||||
const server_get_encoder_for_format_request *>(data);
|
const server_get_encoder_for_codec_info_request *>(data);
|
||||||
server_get_encoder_for_format_reply reply;
|
server_get_encoder_for_codec_info_reply reply;
|
||||||
rv = gAddOnManager->GetEncoderForFormat(&reply.ref,
|
rv = gAddOnManager->GetEncoder(&reply.ref, request->id);
|
||||||
request->format);
|
|
||||||
request->SendReply(rv, &reply, sizeof(reply));
|
request->SendReply(rv, &reply, sizeof(reply));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user