* Also pass the media_codec_info to the Writer::AllocateCookie(), since that
info is not part of the media_format otherwise. * Finished enough in the AVFormatWriter and AVCodecEncoder that we can now actually create AVIs and MPGs and encode MPEG1, MPEG2 and MPEG4 video. But no audio as of yet. Also, there is no bit-rate/quality setup, so it seems libavformat is using the least possible bit-rate/quality. * Enable some more muxers and encoders in the FFmpeg libs. * Uses pixel format conversion from libswsscale, need to read the documentation again, but I think it makes the plugin GPL. * Fixed includes in libswscale/swscale.h, this is now an unmodified FFmpeg 0.5 header again (AFAICT). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32043 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a0bfe3ab9d
commit
54897d5c06
@ -21,7 +21,8 @@ public:
|
||||
virtual status_t Close() = 0;
|
||||
|
||||
virtual status_t AllocateCookie(void** cookie,
|
||||
const media_format* format) = 0;
|
||||
const media_format* format,
|
||||
const media_codec_info* codecInfo) = 0;
|
||||
virtual status_t FreeCookie(void* cookie) = 0;
|
||||
|
||||
virtual status_t SetCopyright(void* cookie,
|
||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
static const size_t kDefaultChunkBufferSize = FF_MIN_BUFFER_SIZE;
|
||||
static const size_t kDefaultChunkBufferSize = 2 * 1024 * 1024;
|
||||
|
||||
|
||||
AVCodecEncoder::AVCodecEncoder(uint32 codecID)
|
||||
@ -32,8 +32,8 @@ AVCodecEncoder::AVCodecEncoder(uint32 codecID)
|
||||
Encoder(),
|
||||
fCodec(NULL),
|
||||
fContext(avcodec_alloc_context()),
|
||||
fInputPicture(avcodec_alloc_frame()),
|
||||
// fOutputPicture(avcodec_alloc_frame()),
|
||||
fFrame(avcodec_alloc_frame()),
|
||||
fSwsContext(NULL),
|
||||
fCodecInitDone(false),
|
||||
fChunkBuffer(new(std::nothrow) uint8[kDefaultChunkBufferSize])
|
||||
{
|
||||
@ -53,8 +53,25 @@ AVCodecEncoder::~AVCodecEncoder()
|
||||
if (fCodecInitDone)
|
||||
avcodec_close(fContext);
|
||||
|
||||
// free(fOutputPicture);
|
||||
free(fInputPicture);
|
||||
sws_freeContext(fSwsContext);
|
||||
|
||||
avpicture_free(&fDstFrame);
|
||||
// NOTE: Do not use avpicture_free() on fSrcFrame!! We fill the picture
|
||||
// data on the file with the media buffer data passed to Encode().
|
||||
|
||||
if (fFrame != NULL) {
|
||||
fFrame->data[0] = NULL;
|
||||
fFrame->data[1] = NULL;
|
||||
fFrame->data[2] = NULL;
|
||||
fFrame->data[3] = NULL;
|
||||
|
||||
fFrame->linesize[0] = 0;
|
||||
fFrame->linesize[1] = 0;
|
||||
fFrame->linesize[2] = 0;
|
||||
fFrame->linesize[3] = 0;
|
||||
free(fFrame);
|
||||
}
|
||||
|
||||
free(fContext);
|
||||
|
||||
delete[] fChunkBuffer;
|
||||
@ -94,10 +111,15 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
fInputFormat = *inputFormat;
|
||||
|
||||
if (fInputFormat.type == B_MEDIA_RAW_VIDEO) {
|
||||
// frame rate
|
||||
fContext->time_base.den = (int)fInputFormat.u.raw_video.field_rate;
|
||||
fContext->time_base.num = 1;
|
||||
// video size
|
||||
fContext->width = fInputFormat.u.raw_video.display.line_width;
|
||||
fContext->height = fInputFormat.u.raw_video.display.line_count;
|
||||
// fContext->gop_size = 12;
|
||||
fContext->pix_fmt = PIX_FMT_BGR32;
|
||||
// TODO: Fix pixel format or setup conversion method...
|
||||
fContext->pix_fmt = PIX_FMT_YUV420P;
|
||||
// fContext->rate_emu = 0;
|
||||
// TODO: Setup rate control:
|
||||
// fContext->rc_eq = NULL;
|
||||
@ -111,11 +133,38 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
|
||||
|| fContext->sample_aspect_ratio.den == 0) {
|
||||
av_reduce(&fContext->sample_aspect_ratio.num,
|
||||
&fContext->sample_aspect_ratio.den, fContext->width,
|
||||
fContext->height, 256);
|
||||
fContext->height, 255);
|
||||
}
|
||||
|
||||
// TODO: This should already happen in AcceptFormat()
|
||||
fInputFormat.u.raw_video.display.bytes_per_row = fContext->width * 4;
|
||||
if (fInputFormat.u.raw_video.display.bytes_per_row == 0) {
|
||||
fInputFormat.u.raw_video.display.bytes_per_row
|
||||
= fContext->width * 4;
|
||||
}
|
||||
|
||||
fFrame->pts = 0;
|
||||
|
||||
// Allocate space for colorspace converted AVPicture
|
||||
// TODO: Check allocations...
|
||||
avpicture_alloc(&fDstFrame, fContext->pix_fmt, fContext->width,
|
||||
fContext->height);
|
||||
|
||||
// Make the frame point to the data in the converted AVPicture
|
||||
fFrame->data[0] = fDstFrame.data[0];
|
||||
fFrame->data[1] = fDstFrame.data[1];
|
||||
fFrame->data[2] = fDstFrame.data[2];
|
||||
fFrame->data[3] = fDstFrame.data[3];
|
||||
|
||||
fFrame->linesize[0] = fDstFrame.linesize[0];
|
||||
fFrame->linesize[1] = fDstFrame.linesize[1];
|
||||
fFrame->linesize[2] = fDstFrame.linesize[2];
|
||||
fFrame->linesize[3] = fDstFrame.linesize[3];
|
||||
|
||||
// TODO: Use actual pixel format from media_format!
|
||||
fSwsContext = sws_getContext(fContext->width, fContext->height,
|
||||
PIX_FMT_RGB32, fContext->width, fContext->height,
|
||||
fContext->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
|
||||
|
||||
} else {
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
@ -154,6 +203,9 @@ AVCodecEncoder::Encode(const void* buffer, int64 frameCount,
|
||||
{
|
||||
TRACE("AVCodecEncoder::Encode(%p, %lld, %p)\n", buffer, frameCount, info);
|
||||
|
||||
if (!fCodecInitDone)
|
||||
return B_NO_INIT;
|
||||
|
||||
if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
|
||||
return _EncodeAudio(buffer, frameCount, info);
|
||||
else if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
|
||||
@ -192,12 +244,23 @@ AVCodecEncoder::_EncodeVideo(const void* buffer, int64 frameCount,
|
||||
while (frameCount > 0) {
|
||||
size_t bpr = fInputFormat.u.raw_video.display.bytes_per_row;
|
||||
size_t bufferSize = fInputFormat.u.raw_video.display.line_count * bpr;
|
||||
TRACE(" bytes per row: %ld, buffer size: %ld\n", bpr, bufferSize);
|
||||
|
||||
fInputPicture->data[0] = (uint8_t*)buffer;
|
||||
fInputPicture->linesize[0] = bpr;
|
||||
// We should always get chunky bitmaps, so this code should be safe.
|
||||
fSrcFrame.data[0] = (uint8_t*)buffer;
|
||||
fSrcFrame.linesize[0] = bpr;
|
||||
|
||||
// Run the pixel format conversion
|
||||
sws_scale(fSwsContext, fSrcFrame.data, fSrcFrame.linesize, 0,
|
||||
fInputFormat.u.raw_video.display.line_count, fDstFrame.data,
|
||||
fDstFrame.linesize);
|
||||
|
||||
// TODO: Look into this... avcodec.h says we need to set it.
|
||||
fFrame->pts++;
|
||||
|
||||
// Encode one video chunk/frame.
|
||||
int usedBytes = avcodec_encode_video(fContext, fChunkBuffer,
|
||||
kDefaultChunkBufferSize, fInputPicture);
|
||||
kDefaultChunkBufferSize, fFrame);
|
||||
|
||||
if (usedBytes < 0) {
|
||||
TRACE(" avcodec_encode_video() failed: %d\n", usedBytes);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
extern "C" {
|
||||
#include "avcodec.h"
|
||||
#include "swscale.h"
|
||||
}
|
||||
|
||||
#include "EncoderPlugin.h"
|
||||
@ -51,8 +52,10 @@ private:
|
||||
// TODO: Refactor common base class from AVCodec[De|En]Coder!
|
||||
AVCodec* fCodec;
|
||||
AVCodecContext* fContext;
|
||||
AVFrame* fInputPicture;
|
||||
// AVFrame* fOutputPicture;
|
||||
AVPicture fSrcFrame;
|
||||
AVPicture fDstFrame;
|
||||
AVFrame* fFrame;
|
||||
SwsContext* fSwsContext;
|
||||
|
||||
uint32 fAVCodecID;
|
||||
|
||||
|
@ -26,7 +26,7 @@ extern "C" {
|
||||
#include "gfx_util.h"
|
||||
|
||||
|
||||
#define TRACE_AVFORMAT_READER
|
||||
//#define TRACE_AVFORMAT_READER
|
||||
#ifdef TRACE_AVFORMAT_READER
|
||||
# define TRACE printf
|
||||
# define TRACE_IO(a...)
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
BLocker* streamLock);
|
||||
virtual ~StreamCookie();
|
||||
|
||||
status_t Init(const media_format* format);
|
||||
status_t Init(const media_format* format,
|
||||
const media_codec_info* codecInfo);
|
||||
|
||||
status_t WriteChunk(const void* chunkBuffer,
|
||||
size_t chunkSize,
|
||||
@ -70,7 +71,8 @@ public:
|
||||
private:
|
||||
AVFormatContext* fContext;
|
||||
AVStream* fStream;
|
||||
// Since different threads may read from the source,
|
||||
AVPacket fPacket;
|
||||
// Since different threads may write to the target,
|
||||
// we need to protect the file position and I/O by a lock.
|
||||
BLocker* fStreamLock;
|
||||
};
|
||||
@ -84,29 +86,64 @@ AVFormatWriter::StreamCookie::StreamCookie(AVFormatContext* context,
|
||||
fStream(NULL),
|
||||
fStreamLock(streamLock)
|
||||
{
|
||||
av_new_packet(&fPacket, 0);
|
||||
}
|
||||
|
||||
|
||||
AVFormatWriter::StreamCookie::~StreamCookie()
|
||||
{
|
||||
av_free_packet(&fPacket);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AVFormatWriter::StreamCookie::Init(const media_format* format)
|
||||
AVFormatWriter::StreamCookie::Init(const media_format* format,
|
||||
const media_codec_info* codecInfo)
|
||||
{
|
||||
TRACE("AVFormatWriter::StreamCookie::Init()\n");
|
||||
|
||||
BAutolock _(fStreamLock);
|
||||
|
||||
fStream = av_new_stream(fContext, fContext->nb_streams);
|
||||
fPacket.stream_index = fContext->nb_streams;
|
||||
fStream = av_new_stream(fContext, fPacket.stream_index);
|
||||
|
||||
if (fStream == NULL) {
|
||||
TRACE(" failed to add new stream\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Setup the stream according to the media format...
|
||||
// Setup the stream according to the media format...
|
||||
if (format->type == B_MEDIA_RAW_VIDEO) {
|
||||
avcodec_get_context_defaults2(fStream->codec, CODEC_TYPE_VIDEO);
|
||||
// frame rate
|
||||
fStream->codec->time_base.den = (int)format->u.raw_video.field_rate;
|
||||
fStream->codec->time_base.num = 1;
|
||||
// video size
|
||||
fStream->codec->width = format->u.raw_video.display.line_width;
|
||||
fStream->codec->height = format->u.raw_video.display.line_count;
|
||||
// pixel aspect ratio
|
||||
fStream->sample_aspect_ratio.num
|
||||
= format->u.raw_video.pixel_width_aspect;
|
||||
fStream->sample_aspect_ratio.den
|
||||
= format->u.raw_video.pixel_height_aspect;
|
||||
if (fStream->sample_aspect_ratio.num == 0
|
||||
|| fStream->sample_aspect_ratio.den == 0) {
|
||||
av_reduce(&fStream->sample_aspect_ratio.num,
|
||||
&fStream->sample_aspect_ratio.den, fStream->codec->width,
|
||||
fStream->codec->height, 255);
|
||||
}
|
||||
|
||||
fStream->codec->sample_aspect_ratio = fStream->sample_aspect_ratio;
|
||||
// TODO: Don't hard code this...
|
||||
fStream->codec->pix_fmt = PIX_FMT_YUV420P;
|
||||
} else if (format->type == B_MEDIA_RAW_AUDIO) {
|
||||
avcodec_get_context_defaults2(fStream->codec, CODEC_TYPE_AUDIO);
|
||||
// TODO: ...
|
||||
}
|
||||
|
||||
// TODO: This is a hack for now! Use avcodec_find_encoder_by_name()
|
||||
// or something similar...
|
||||
fStream->codec->codec_id = (CodecID)codecInfo->sub_id;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -116,12 +153,33 @@ status_t
|
||||
AVFormatWriter::StreamCookie::WriteChunk(const void* chunkBuffer,
|
||||
size_t chunkSize, media_encode_info* encodeInfo)
|
||||
{
|
||||
TRACE("AVFormatWriter::StreamCookie::WriteChunk(%p, %ld)\n",
|
||||
TRACE_PACKET("AVFormatWriter::StreamCookie::WriteChunk(%p, %ld)\n",
|
||||
chunkBuffer, chunkSize);
|
||||
|
||||
BAutolock _(fStreamLock);
|
||||
|
||||
return B_ERROR;
|
||||
// TODO: Probably the AVCodecEncoder needs to pass packet data
|
||||
// in encodeInfo...
|
||||
|
||||
fPacket.data = const_cast<uint8_t*>((const uint8_t*)chunkBuffer);
|
||||
fPacket.size = chunkSize;
|
||||
|
||||
#if 0
|
||||
// TODO: Eventually, we need to write interleaved packets, but
|
||||
// maybe we are only supposed to use this if we have actually
|
||||
// more than one stream. For the moment, this crashes in AVPacket
|
||||
// shuffling inside libavformat. Maybe if we want to use this, we
|
||||
// need to allocate a separate AVPacket and copy the chunk buffer.
|
||||
int result = av_interleaved_write_frame(fContext, &fPacket);
|
||||
if (result < 0)
|
||||
TRACE(" av_interleaved_write_frame(): %d\n", result);
|
||||
#else
|
||||
int result = av_write_frame(fContext, &fPacket);
|
||||
if (result < 0)
|
||||
TRACE(" av_write_frame(): %d\n", result);
|
||||
#endif
|
||||
|
||||
return result == 0 ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -183,12 +241,10 @@ AVFormatWriter::Init(const media_file_format* fileFormat)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Is this how it works?
|
||||
// TODO: Is the cookie stored in ByteIOContext? Or does it need to be
|
||||
// stored in fContext->priv_data?
|
||||
// Setup I/O hooks. This seems to be enough.
|
||||
fContext->pb = &fIOContext;
|
||||
|
||||
// TODO: Set the AVOutputFormat according to fileFormat...
|
||||
// Set the AVOutputFormat according to fileFormat...
|
||||
fContext->oformat = guess_format(fileFormat->short_name,
|
||||
fileFormat->file_extension, fileFormat->mime_type);
|
||||
if (fContext->oformat == NULL) {
|
||||
@ -263,7 +319,8 @@ AVFormatWriter::Close()
|
||||
|
||||
|
||||
status_t
|
||||
AVFormatWriter::AllocateCookie(void** _cookie, const media_format* format)
|
||||
AVFormatWriter::AllocateCookie(void** _cookie, const media_format* format,
|
||||
const media_codec_info* codecInfo)
|
||||
{
|
||||
TRACE("AVFormatWriter::AllocateCookie()\n");
|
||||
|
||||
@ -275,7 +332,14 @@ AVFormatWriter::AllocateCookie(void** _cookie, const media_format* format)
|
||||
StreamCookie* cookie = new(std::nothrow) StreamCookie(fContext,
|
||||
&fStreamLock);
|
||||
|
||||
return cookie->Init(format);
|
||||
status_t ret = cookie->Init(format, codecInfo);
|
||||
if (ret != B_OK) {
|
||||
delete cookie;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*_cookie = cookie;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -327,7 +391,7 @@ AVFormatWriter::WriteChunk(void* _cookie, const void* chunkBuffer,
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// #pragma mark - I/O hooks
|
||||
|
||||
|
||||
/*static*/ int
|
||||
|
@ -28,7 +28,8 @@ public:
|
||||
virtual status_t Close();
|
||||
|
||||
virtual status_t AllocateCookie(void** cookie,
|
||||
const media_format* format);
|
||||
const media_format* format,
|
||||
const media_codec_info* codecInfo);
|
||||
virtual status_t FreeCookie(void* cookie);
|
||||
|
||||
virtual status_t SetCopyright(void* cookie,
|
||||
|
@ -20,22 +20,46 @@ const EncoderDescription gEncoderTable[] = {
|
||||
CODEC_ID_MPEG4,
|
||||
{ 0 }
|
||||
},
|
||||
B_ANY_FORMAT_FAMILY,
|
||||
B_ANY_FORMAT_FAMILY, // TODO: Hm, actually not really /any/ family...
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
},
|
||||
{
|
||||
{
|
||||
"MP3 Audio",
|
||||
"mp3",
|
||||
"MPEG1 Video",
|
||||
"mpeg1video",
|
||||
0,
|
||||
CODEC_ID_MP3,
|
||||
CODEC_ID_MPEG1VIDEO,
|
||||
{ 0 }
|
||||
},
|
||||
B_ANY_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_AUDIO,
|
||||
B_MEDIA_ENCODED_AUDIO
|
||||
}
|
||||
B_MPEG_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
},
|
||||
{
|
||||
{
|
||||
"MPEG2 Video",
|
||||
"mpeg2video",
|
||||
0,
|
||||
CODEC_ID_MPEG2VIDEO,
|
||||
{ 0 }
|
||||
},
|
||||
B_MPEG_FORMAT_FAMILY,
|
||||
B_MEDIA_RAW_VIDEO,
|
||||
B_MEDIA_ENCODED_VIDEO
|
||||
},
|
||||
// {
|
||||
// {
|
||||
// "MP3 Audio",
|
||||
// "mp3",
|
||||
// 0,
|
||||
// CODEC_ID_MP3,
|
||||
// { 0 }
|
||||
// },
|
||||
// B_ANY_FORMAT_FAMILY,
|
||||
// B_MEDIA_RAW_AUDIO,
|
||||
// B_MEDIA_ENCODED_AUDIO
|
||||
// }
|
||||
};
|
||||
|
||||
const size_t gEncoderCount = sizeof(gEncoderTable) / sizeof(EncoderDescription);
|
||||
|
@ -24,6 +24,20 @@ const media_file_format gMuxerTable[] = {
|
||||
"avi",
|
||||
{ 0 }
|
||||
},
|
||||
{
|
||||
media_file_format::B_WRITABLE
|
||||
| media_file_format::B_KNOWS_ENCODED_VIDEO
|
||||
| media_file_format::B_KNOWS_ENCODED_AUDIO,
|
||||
{ 0 },
|
||||
B_MPEG_FORMAT_FAMILY,
|
||||
100,
|
||||
{ 0 },
|
||||
"video/mpeg",
|
||||
"MPEG (Motion Picture Experts Group)",
|
||||
"mpg",
|
||||
"mpg",
|
||||
{ 0 }
|
||||
},
|
||||
};
|
||||
|
||||
const size_t gMuxerCount = sizeof(gMuxerTable) / sizeof(media_file_format);
|
||||
|
@ -673,14 +673,14 @@
|
||||
#define CONFIG_MP2_MUXER 0
|
||||
#define CONFIG_MP3_MUXER 0
|
||||
#define CONFIG_MP4_MUXER 0
|
||||
#define CONFIG_MPEG1SYSTEM_MUXER 0
|
||||
#define CONFIG_MPEG1SYSTEM_MUXER 1
|
||||
#define CONFIG_MPEG1VCD_MUXER 0
|
||||
#define CONFIG_MPEG1VIDEO_MUXER 0
|
||||
#define CONFIG_MPEG1VIDEO_MUXER 1
|
||||
#define CONFIG_MPEG2DVD_MUXER 0
|
||||
#define CONFIG_MPEG2SVCD_MUXER 0
|
||||
#define CONFIG_MPEG2VIDEO_MUXER 0
|
||||
#define CONFIG_MPEG2VIDEO_MUXER 1
|
||||
#define CONFIG_MPEG2VOB_MUXER 0
|
||||
#define CONFIG_MPEGTS_MUXER 0
|
||||
#define CONFIG_MPEGTS_MUXER 1
|
||||
#define CONFIG_MPJPEG_MUXER 0
|
||||
#define CONFIG_MXF_MUXER 0
|
||||
#define CONFIG_MXF_D10_MUXER 0
|
||||
|
@ -2723,7 +2723,10 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
|
||||
AVPacket opkt;
|
||||
int ret= av_interleave_packet(s, &opkt, pkt, 0);
|
||||
if(ret<=0) //FIXME cleanup needed for ret<0 ?
|
||||
{
|
||||
av_log(NULL, AV_LOG_ERROR, "av_interleaved_write_frame() - av_interleave_packet() failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret= s->oformat->write_packet(s, &opkt);
|
||||
|
||||
@ -2731,9 +2734,15 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
|
||||
pkt= NULL;
|
||||
|
||||
if(ret<0)
|
||||
{
|
||||
av_log(NULL, AV_LOG_ERROR, "av_interleaved_write_frame() - write_packet() failed.\n");
|
||||
return ret;
|
||||
}
|
||||
if(url_ferror(s->pb))
|
||||
{
|
||||
av_log(NULL, AV_LOG_ERROR, "av_interleaved_write_frame() - url_ferror() failed.\n");
|
||||
return url_ferror(s->pb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
*/
|
||||
|
||||
#include "libavutil/avutil.h"
|
||||
#include "libavutil/internal.h"
|
||||
|
||||
#define LIBSWSCALE_VERSION_MAJOR 0
|
||||
#define LIBSWSCALE_VERSION_MINOR 7
|
||||
|
@ -60,7 +60,8 @@ BMediaFile::BMediaFile(const entry_ref* ref, const media_file_format* mfi,
|
||||
CALLED();
|
||||
_Init();
|
||||
fDeleteSource = true;
|
||||
_InitWriter(new(std::nothrow) BFile(ref, O_WRONLY), mfi, flags);
|
||||
_InitWriter(new(std::nothrow) BFile(ref, B_CREATE_FILE | B_ERASE_FILE
|
||||
| B_WRITE_ONLY), mfi, flags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +110,7 @@ MediaWriter::CreateEncoder(Encoder** _encoder,
|
||||
}
|
||||
|
||||
StreamInfo info;
|
||||
ret = fWriter->AllocateCookie(&info.cookie, format);
|
||||
ret = fWriter->AllocateCookie(&info.cookie, format, codecInfo);
|
||||
if (ret != B_OK) {
|
||||
_plugin_manager.DestroyEncoder(encoder);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user