The CodecID for raw-audio actually depends on the sample format

and can't be hard-coded in the EncoderTable.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38464 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-08-30 21:04:29 +00:00
parent 6387dbc3f2
commit eb01f516a3
5 changed files with 76 additions and 11 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2009, Stephan Amßus <superstippi@gmx.de>
* Copyright 2009-2010, Stephan Amßus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
@ -15,6 +15,7 @@ extern "C" {
#include "rational.h"
}
#include "EncoderTable.h"
#include "gfx_util.h"
@ -36,6 +37,7 @@ AVCodecEncoder::AVCodecEncoder(uint32 codecID, int bitRateScale)
:
Encoder(),
fBitRateScale(bitRateScale),
fCodecID((enum CodecID)codecID),
fCodec(NULL),
fContext(avcodec_alloc_context()),
fCodecInitStatus(CODEC_INIT_NEEDED),
@ -49,8 +51,10 @@ AVCodecEncoder::AVCodecEncoder(uint32 codecID, int bitRateScale)
{
TRACE("AVCodecEncoder::AVCodecEncoder()\n");
fCodec = avcodec_find_encoder((enum CodecID)codecID);
TRACE(" found AVCodec for %lu: %p\n", codecID, fCodec);
if (fCodecID > 0) {
fCodec = avcodec_find_encoder(fCodecID);
TRACE(" found AVCodec for %u: %p\n", fCodecID, fCodec);
}
memset(&fInputFormat, 0, sizeof(media_format));
@ -131,12 +135,23 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
{
TRACE("AVCodecEncoder::SetUp()\n");
if (fContext == NULL || fCodec == NULL)
if (fContext == NULL)
return B_NO_INIT;
if (inputFormat == NULL)
return B_BAD_VALUE;
// Codec IDs for raw-formats may need to be figured out here.
if (fCodec == NULL && fCodecID == CODEC_ID_NONE) {
fCodecID = raw_audio_codec_id_for(*inputFormat);
if (fCodecID != CODEC_ID_NONE)
fCodec = avcodec_find_encoder(fCodecID);
}
if (fCodec == NULL) {
TRACE(" encoder not found!\n");
return B_NO_INIT;
}
_CloseCodecIfNeeded();
fInputFormat = *inputFormat;

View File

@ -66,6 +66,7 @@ private:
// FFmpeg related members
// TODO: Refactor common base class from AVCodec[De|En]Coder!
CodecID fCodecID;
AVCodec* fCodec;
AVCodecContext* fContext;

View File

@ -23,6 +23,7 @@ extern "C" {
}
#include "DemuxerTable.h"
#include "EncoderTable.h"
#include "gfx_util.h"
@ -119,6 +120,8 @@ AVFormatWriter::StreamCookie::Init(const media_format* format,
// TODO: This is a hack for now! Use avcodec_find_encoder_by_name()
// or something similar...
fStream->codec->codec_id = (CodecID)codecInfo->sub_id;
if (fStream->codec->codec_id == CODEC_ID_NONE)
fStream->codec->codec_id = raw_audio_codec_id_for(*format);
// Setup the stream according to the media format...
if (format->type == B_MEDIA_RAW_VIDEO) {
@ -430,6 +433,7 @@ AVFormatWriter::CommitHeader()
else
fHeaderWritten = true;
#if TRACE_AVFORMAT_WRITER
TRACE(" wrote header\n");
for (unsigned i = 0; i < fContext->nb_streams; i++) {
AVStream* stream = fContext->streams[i];
@ -437,6 +441,7 @@ AVFormatWriter::CommitHeader()
i, stream->time_base.num, stream->time_base.den,
stream->codec->time_base.num, stream->codec->time_base.den);
}
#endif // TRACE_AVFORMAT_WRITER
return result == 0 ? B_OK : B_ERROR;
}

View File

@ -1,15 +1,11 @@
/*
* Copyright 2009 Stephan Aßmus <superstippi@gmx.de>
* Copyright 2009-2010 Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "EncoderTable.h"
extern "C" {
#include "avcodec.h"
}
const EncoderDescription gEncoderTable[] = {
{
@ -56,7 +52,7 @@ const EncoderDescription gEncoderTable[] = {
"Raw Audio",
"pcm",
0,
CODEC_ID_PCM_S16LE,
0,
{ 0 }
},
B_ANY_FORMAT_FAMILY,
@ -81,3 +77,45 @@ const EncoderDescription gEncoderTable[] = {
const size_t gEncoderCount = sizeof(gEncoderTable) / sizeof(EncoderDescription);
/*static*/ CodecID
raw_audio_codec_id_for(const media_format& format)
{
if (format.type != B_MEDIA_RAW_AUDIO)
return CODEC_ID_NONE;
if (format.u.raw_audio.byte_order == B_MEDIA_LITTLE_ENDIAN) {
switch (format.u.raw_audio.format) {
case media_raw_audio_format::B_AUDIO_FLOAT:
return CODEC_ID_PCM_F32LE;
case media_raw_audio_format::B_AUDIO_DOUBLE:
return CODEC_ID_PCM_F64LE;
case media_raw_audio_format::B_AUDIO_INT:
return CODEC_ID_PCM_S32LE;
case media_raw_audio_format::B_AUDIO_SHORT:
return CODEC_ID_PCM_S16LE;
case media_raw_audio_format::B_AUDIO_UCHAR:
return CODEC_ID_PCM_U8;
default:
return CODEC_ID_NONE;
}
} else {
switch (format.u.raw_audio.format) {
case media_raw_audio_format::B_AUDIO_FLOAT:
return CODEC_ID_PCM_F32BE;
case media_raw_audio_format::B_AUDIO_DOUBLE:
return CODEC_ID_PCM_F64BE;
case media_raw_audio_format::B_AUDIO_INT:
return CODEC_ID_PCM_S32BE;
case media_raw_audio_format::B_AUDIO_SHORT:
return CODEC_ID_PCM_S16BE;
case media_raw_audio_format::B_AUDIO_UCHAR:
return CODEC_ID_PCM_U8;
default:
return CODEC_ID_NONE;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2009 Stephan Aßmus <superstippi@gmx.de>
* Copyright 2009-2010 Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef ENCODER_TABLE_H
@ -8,6 +8,10 @@
#include <MediaFormats.h>
extern "C" {
#include "avcodec.h"
}
struct EncoderDescription {
media_codec_info codec_info;
@ -21,5 +25,7 @@ struct EncoderDescription {
extern const EncoderDescription gEncoderTable[];
extern const size_t gEncoderCount;
CodecID raw_audio_codec_id_for(const media_format& format);
#endif // ENCODER_TABLE_H