Implemented first version of MediaWriter, which is the bridge between
BMediaFile/BMediaTrack and Writer plugins. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31988 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2009, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _MEDIA_WRITER_H
|
||||
#define _MEDIA_WRITER_H
|
||||
|
||||
|
||||
#include "EncoderPlugin.h"
|
||||
#include "TList.h"
|
||||
#include "WriterPlugin.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace media {
|
||||
|
||||
|
||||
class MediaWriter {
|
||||
public:
|
||||
MediaWriter(BDataIO* target,
|
||||
const media_file_format& fileFormat);
|
||||
~MediaWriter();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
void GetFileFormatInfo(media_file_format* mfi) const;
|
||||
|
||||
status_t SetCopyright(const char* copyright);
|
||||
status_t CommitHeader();
|
||||
status_t Flush();
|
||||
status_t Close();
|
||||
|
||||
status_t AddTrackInfo(void* cookie, uint32 code,
|
||||
const void* data, size_t size,
|
||||
uint32 flags = 0);
|
||||
|
||||
status_t CreateEncoder(Encoder** _encoder,
|
||||
const media_codec_info* codecInfo,
|
||||
uint32 flags = 0);
|
||||
|
||||
status_t WriteChunk(int32 stream,
|
||||
const void* chunkBuffer, size_t chunkSize,
|
||||
uint32 flags);
|
||||
|
||||
private:
|
||||
struct StreamInfo {
|
||||
void* cookie;
|
||||
};
|
||||
|
||||
private:
|
||||
BDataIO* fTarget;
|
||||
Writer* fWriter;
|
||||
|
||||
List<StreamInfo> fStreamInfos;
|
||||
|
||||
media_file_format fFileFormat;
|
||||
};
|
||||
|
||||
|
||||
}; // namespace media
|
||||
}; // namespace BPrivate
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
|
||||
#endif // _MEDIA_WRITER_H
|
||||
@@ -80,6 +80,7 @@ SharedLibrary libmedia.so :
|
||||
EncoderPlugin.cpp
|
||||
MediaExtractor.cpp
|
||||
MediaPlugin.cpp
|
||||
MediaWriter.cpp
|
||||
PluginManager.cpp
|
||||
ReaderPlugin.cpp
|
||||
WriterPlugin.cpp
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2009, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
#include "MediaWriter.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "PluginManager.h"
|
||||
|
||||
|
||||
// should be 0, to disable the chunk cache set it to 1
|
||||
#define DISABLE_CHUNK_CACHE 0
|
||||
|
||||
|
||||
MediaWriter::MediaWriter(BDataIO* target, const media_file_format& fileFormat)
|
||||
:
|
||||
fTarget(target),
|
||||
fWriter(NULL),
|
||||
fStreamInfos(),
|
||||
fFileFormat(fileFormat)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
_plugin_manager.CreateWriter(&fWriter, fFileFormat, fTarget);
|
||||
}
|
||||
|
||||
|
||||
MediaWriter::~MediaWriter()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// free all stream cookies
|
||||
// and chunk caches
|
||||
StreamInfo* info;
|
||||
for (fStreamInfos.Rewind(); fStreamInfos.GetNext(&info);)
|
||||
fWriter->FreeCookie(info->cookie);
|
||||
|
||||
_plugin_manager.DestroyWriter(fWriter);
|
||||
|
||||
// fTarget is owned by the BMediaFile
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaWriter::InitCheck()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
return fWriter != NULL ? B_OK : B_NO_INIT;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MediaWriter::GetFileFormatInfo(media_file_format* _fileFormat) const
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (_fileFormat != NULL)
|
||||
*_fileFormat = fFileFormat;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaWriter::WriteChunk(int32 streamIndex, const void* chunkBuffer,
|
||||
size_t chunkSize, uint32 flags)
|
||||
{
|
||||
if (fWriter == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
StreamInfo* info;
|
||||
if (!fStreamInfos.Get(streamIndex, &info))
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return fWriter->WriteChunk(info->cookie, chunkBuffer, chunkSize, flags);
|
||||
}
|
||||
|
||||
|
||||
class MediaExtractorChunkWriter : public ChunkWriter {
|
||||
public:
|
||||
MediaExtractorChunkWriter(MediaWriter* writer, int32 streamIndex)
|
||||
:
|
||||
fWriter(writer),
|
||||
fStreamIndex(streamIndex)
|
||||
{
|
||||
}
|
||||
|
||||
virtual status_t WriteChunk(const void* chunkBuffer, size_t chunkSize,
|
||||
uint32 flags)
|
||||
{
|
||||
return fWriter->WriteChunk(fStreamIndex, chunkBuffer, chunkSize,
|
||||
flags);
|
||||
}
|
||||
|
||||
private:
|
||||
MediaWriter* fWriter;
|
||||
int32 fStreamIndex;
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
MediaWriter::CreateEncoder(Encoder** _encoder,
|
||||
const media_codec_info* codecInfo, uint32 flags)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// TODO: Here we should work out a way so that if there is a setup
|
||||
// failure we can try the next encoder.
|
||||
Encoder* encoder;
|
||||
status_t ret = _plugin_manager.CreateEncoder(&encoder, codecInfo, flags);
|
||||
if (ret != B_OK) {
|
||||
ERROR("MediaWriter::CreateEncoder _plugin_manager.CreateEncoder "
|
||||
"failed, codec: %s\n", codecInfo->pretty_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
StreamInfo info;
|
||||
ret = fWriter->AllocateCookie(&info.cookie);
|
||||
if (ret != B_OK) {
|
||||
_plugin_manager.DestroyEncoder(encoder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 streamIndex = fStreamInfos.CountItems();
|
||||
|
||||
if (!fStreamInfos.Insert(info)) {
|
||||
_plugin_manager.DestroyEncoder(encoder);
|
||||
ERROR("MediaWriter::CreateEncoder can't create StreamInfo "
|
||||
"for stream %ld\n", streamIndex);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
ChunkWriter* chunkWriter = new(std::nothrow) MediaExtractorChunkWriter(
|
||||
this, streamIndex);
|
||||
if (chunkWriter == NULL) {
|
||||
_plugin_manager.DestroyEncoder(encoder);
|
||||
ERROR("MediaWriter::CreateEncoder can't create ChunkWriter "
|
||||
"for stream %ld\n", streamIndex);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
encoder->SetChunkWriter(chunkWriter);
|
||||
*_encoder = encoder;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user