From eb01f516a3b44adfda231e814b65ddb79fe11d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 30 Aug 2010 21:04:29 +0000 Subject: [PATCH] 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 --- .../media/plugins/ffmpeg/AVCodecEncoder.cpp | 23 +++++++-- .../media/plugins/ffmpeg/AVCodecEncoder.h | 1 + .../media/plugins/ffmpeg/AVFormatWriter.cpp | 5 ++ .../media/plugins/ffmpeg/EncoderTable.cpp | 50 ++++++++++++++++--- .../media/plugins/ffmpeg/EncoderTable.h | 8 ++- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp index 5f2a8f3279..85388f15e5 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009, Stephan Amßus + * Copyright 2009-2010, Stephan Amßus * 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; diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.h b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.h index 9beddd0ec2..ba55cc87d8 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.h +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.h @@ -66,6 +66,7 @@ private: // FFmpeg related members // TODO: Refactor common base class from AVCodec[De|En]Coder! + CodecID fCodecID; AVCodec* fCodec; AVCodecContext* fContext; diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp index 48487e85e9..7282229791 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp @@ -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; } diff --git a/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp b/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp index e6770dbe2b..a96ac69e5f 100644 --- a/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp @@ -1,15 +1,11 @@ /* - * Copyright 2009 Stephan Aßmus + * Copyright 2009-2010 Stephan Aßmus * 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; + } + } +} + + + diff --git a/src/add-ons/media/plugins/ffmpeg/EncoderTable.h b/src/add-ons/media/plugins/ffmpeg/EncoderTable.h index 2f3a9e7a9b..2e966de91b 100644 --- a/src/add-ons/media/plugins/ffmpeg/EncoderTable.h +++ b/src/add-ons/media/plugins/ffmpeg/EncoderTable.h @@ -1,5 +1,5 @@ /* - * Copyright 2009 Stephan Aßmus + * Copyright 2009-2010 Stephan Aßmus * All rights reserved. Distributed under the terms of the MIT license. */ #ifndef ENCODER_TABLE_H @@ -8,6 +8,10 @@ #include +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