diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp index 79db210898..910b30b7fc 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp @@ -462,12 +462,12 @@ AVCodecEncoder::_Setup() if (fContext->codec_id == CODEC_ID_MPEG2VIDEO) { // Just for testing, we also add B frames */ fContext->max_b_frames = 2; - } else if (fContext->codec_id == CODEC_ID_MPEG1VIDEO){ + } else if (fContext->codec_id == CODEC_ID_MPEG1VIDEO) { // Needed to avoid using macroblocks in which some coeffs overflow. // This does not happen with normal video, it just happens here as // the motion of the chroma plane does not match the luma plane. fContext->mb_decision = 2; - } + } // Unfortunately, we may fail later, when we try to open the codec // for real... but we need to delay this because we still allow @@ -491,6 +491,8 @@ AVCodecEncoder::_OpenCodecIfNeeded() if (fCodecInitStatus == CODEC_INIT_FAILED) return false; + fContext->strict_std_compliance = -2; + // Open the codec int result = avcodec_open(fContext, fCodec); if (result >= 0) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp index 11e1a96c04..1095a7d7d6 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp @@ -171,6 +171,9 @@ AVFormatWriter::StreamCookie::Init(media_format* format, // channels fStream->codec->channels = format->u.raw_audio.channel_count; + + // set fStream to the audio format we want to use. This is only a hint + // (each encoder has a different set of accepted formats) switch (format->u.raw_audio.format) { case media_raw_audio_format::B_AUDIO_FLOAT: fStream->codec->sample_fmt = AV_SAMPLE_FMT_FLT; @@ -193,6 +196,49 @@ AVFormatWriter::StreamCookie::Init(media_format* format, return B_MEDIA_BAD_FORMAT; break; } + + // Now negociate the actual format with the encoder + // First check if the requested format is acceptable + AVCodec* codec = avcodec_find_encoder(fStream->codec->codec_id); + const enum AVSampleFormat *p = codec->sample_fmts; + for (; *p != -1; p++) { + if (*p == fStream->codec->sample_fmt) + break; + } + // If not, force one of the acceptable ones + if (*p == -1) { + fStream->codec->sample_fmt = codec->sample_fmts[0]; + + // And finally set the format struct to the accepted format. It is + // then up to the caller to make sure we get data matching that + // format. + switch (fStream->codec->sample_fmt) { + case AV_SAMPLE_FMT_FLT: + format->u.raw_audio.format + = media_raw_audio_format::B_AUDIO_FLOAT; + break; + case AV_SAMPLE_FMT_DBL: + format->u.raw_audio.format + = media_raw_audio_format::B_AUDIO_DOUBLE; + break; + case AV_SAMPLE_FMT_S32: + format->u.raw_audio.format + = media_raw_audio_format::B_AUDIO_INT; + break; + case AV_SAMPLE_FMT_S16: + format->u.raw_audio.format + = media_raw_audio_format::B_AUDIO_SHORT; + break; + case AV_SAMPLE_FMT_U8: + format->u.raw_audio.format + = media_raw_audio_format::B_AUDIO_UCHAR; + break; + default: + return B_MEDIA_BAD_FORMAT; + break; + } + } + if (format->u.raw_audio.channel_mask == 0) { // guess the channel mask... switch (format->u.raw_audio.channel_count) { @@ -418,6 +464,7 @@ AVFormatWriter::CommitHeader() // we have no idea (in the future) what CodecID some encoder uses, // it may be an encoder from a different plugin. AVCodecContext* codecContext = stream->codec; + codecContext->strict_std_compliance = -2; AVCodec* codec = avcodec_find_encoder(codecContext->codec_id); if (codec == NULL || avcodec_open(codecContext, codec) < 0) { TRACE(" stream[%u] - failed to open AVCodecContext\n", i); diff --git a/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp b/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp index 69525eb85b..1b3445a7ef 100644 --- a/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/EncoderTable.cpp @@ -102,6 +102,19 @@ const EncoderDescription gEncoderTable[] = { B_MEDIA_ENCODED_AUDIO, 10 }, + { + { + "Advanced Audio Coding (AAC)", + "aac", + 0, + CODEC_ID_AAC, + { 0 } + }, + B_MPEG_FORMAT_FAMILY, + B_MEDIA_RAW_AUDIO, + B_MEDIA_ENCODED_AUDIO, + 10 + }, { { "Raw audio", @@ -115,24 +128,9 @@ const EncoderDescription gEncoderTable[] = { B_MEDIA_ENCODED_AUDIO, 1 }, - // All of those crash ffmpeg in one way or another... -#if 0 { { - "Advanced Audio Coding (AAC)", - "aac", - 0, - CODEC_ID_AAC, - { 0 } - }, - B_ANY_FORMAT_FAMILY, - B_MEDIA_RAW_AUDIO, - B_MEDIA_ENCODED_AUDIO, - 10 - }, - { - { - "Dolby AC-3", + "Dolby Digital (AC-3)", "ac3", 0, CODEC_ID_AC3, @@ -143,6 +141,7 @@ const EncoderDescription gEncoderTable[] = { B_MEDIA_ENCODED_AUDIO, 10 }, +#if 0 { { "Apple Lossless Audio Codec", @@ -221,19 +220,6 @@ const EncoderDescription gEncoderTable[] = { B_MEDIA_ENCODED_AUDIO, 10 }, - { - { - "Dolby Digital (AC-3)", - "ac3", - 0, - CODEC_ID_AC3, - { 0 } - }, - B_ANY_FORMAT_FAMILY, - B_MEDIA_RAW_AUDIO, - B_MEDIA_ENCODED_AUDIO, - 10 - }, { { "Vorbis audio", diff --git a/src/add-ons/media/plugins/ffmpeg/MuxerTable.cpp b/src/add-ons/media/plugins/ffmpeg/MuxerTable.cpp index b759229adb..2856694b98 100644 --- a/src/add-ons/media/plugins/ffmpeg/MuxerTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/MuxerTable.cpp @@ -121,7 +121,7 @@ const media_file_format gMuxerTable[] = { | media_file_format::B_KNOWS_ENCODED_VIDEO | media_file_format::B_KNOWS_ENCODED_AUDIO, { 0 }, - B_QUICKTIME_FORMAT_FAMILY, + B_ANY_FORMAT_FAMILY, 100, { 0 }, "video/x-matroska",