void EncoderTest::testRegression36Internal (const Codec::ID codecId, const int32_t numSamples, const int32_t sampleRate, const int32_t channels, const AudioChannel::Layout channelLayout, const AudioFormat::Type audioFormat, const int64_t bitRate, const char* testOutputName) { VS_LOG_DEBUG("Output filename: %s", testOutputName); RefPointer<Codec> codec = Codec::findEncodingCodec (codecId); RefPointer<Encoder> encoder = Encoder::make (codec.value ()); RefPointer<FilterGraph> graph = FilterGraph::make (); RefPointer<MediaAudio> audio = MediaAudio::make (numSamples, sampleRate, channels, channelLayout, audioFormat); // set the encoder properties we need encoder->setSampleRate (audio->getSampleRate ()); encoder->setSampleFormat (audio->getFormat ()); encoder->setChannelLayout (audio->getChannelLayout ()); encoder->setChannels (audio->getChannels ()); encoder->setProperty ("b", (int64_t) (bitRate)); RefPointer<Rational> tb = Rational::make (1, sampleRate); encoder->setTimeBase (tb.value ()); // create an output muxer RefPointer<Muxer> muxer = Muxer::make (testOutputName, 0, 0); RefPointer<MuxerFormat> format = muxer->getFormat (); if (format->getFlag (MuxerFormat::GLOBAL_HEADER)) encoder->setFlag (Encoder::FLAG_GLOBAL_HEADER, true); // open the encoder encoder->open (0, 0); RefPointer<FilterAudioSink> fsink = graph->addAudioSink ( "out", audio->getSampleRate (), audio->getChannelLayout (), audio->getFormat ()); // Generate a 220 Hz sine wave with a 880 Hz beep each second, for 10 seconds. graph->open ("sine=frequency=220:beep_factor=4:duration=11[out]"); fsink->setFrameSize (numSamples); // add a stream for the encoded packets { RefPointer<MuxerStream> stream = muxer->addNewStream (encoder.value ()); } // and open the muxer muxer->open (0, 0); // now we're (in theory) ready to start writing data. int32_t numCompletePackets = 0; RefPointer<MediaPacket> packet; // Get one audio packet that is larger than the frame-size. fsink->getAudio (audio.value ()); TS_ASSERT(audio->isComplete ()); TS_ASSERT_EQUALS(audio->getNumSamples (), sampleRate); audio->setTimeStamp (0); // let's encode packet = MediaPacket::make (); encoder->encodeAudio (packet.value (), audio.value ()); if (packet->isComplete ()) { muxer->write (packet.value (), false); } // now flush the encoder do { packet = MediaPacket::make (); encoder->encodeAudio (packet.value (), 0); if (packet->isComplete ()) { muxer->write (packet.value (), false); ++numCompletePackets; } } while (packet->isComplete ()); muxer->close (); if (!(codec->getCapabilities() & Codec::CAP_VARIABLE_FRAME_SIZE)) { const int32_t numExpectedPackets = audio->getNumSamples() / encoder->getFrameSize(); VS_LOG_DEBUG("%ld vs %ld; framesize: %ld", numCompletePackets, numExpectedPackets, encoder->getFrameSize()); TS_ASSERT(numCompletePackets > 10); } }
void EncoderTest::testEncodeAudio() { Logger::setGlobalIsLogging(Logger::LEVEL_TRACE, false); LoggerStack stack; stack.setGlobalLevel(Logger::LEVEL_INFO, false); const bool isMemCheck = getenv("VS_TEST_MEMCHECK") ? true : false; const int32_t sampleRate = 44100; const int32_t maxSamples = isMemCheck ? sampleRate*0.5 : sampleRate*10; const int32_t numSamples = 1024; const AudioChannel::Layout channelLayout = AudioChannel::CH_LAYOUT_STEREO; const int32_t channels = AudioChannel::getNumChannelsInLayout(channelLayout); const AudioFormat::Type audioFormat = AudioFormat::SAMPLE_FMT_S16; RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_AAC); RefPointer<Encoder> encoder = Encoder::make(codec.value()); RefPointer<FilterGraph> graph = FilterGraph::make(); RefPointer<MediaAudio> audio = MediaAudio::make(numSamples, sampleRate, channels, channelLayout, audioFormat); // set the encoder properties we need encoder->setSampleRate(audio->getSampleRate()); encoder->setSampleFormat(audio->getFormat()); encoder->setChannelLayout(audio->getChannelLayout()); encoder->setChannels(audio->getChannels()); encoder->setProperty("b", (int64_t)64000); // bitrate RefPointer<Rational> tb = Rational::make(1,25); encoder->setTimeBase(tb.value()); // create an output muxer RefPointer<Muxer> muxer = Muxer::make("EncoderTest_encodeAudio.mp4", 0, 0); RefPointer<MuxerFormat> format = muxer->getFormat(); if (format->getFlag(MuxerFormat::GLOBAL_HEADER)) encoder->setFlag(Encoder::FLAG_GLOBAL_HEADER, true); // open the encoder encoder->open(0, 0); RefPointer<FilterAudioSink> fsink = graph->addAudioSink("out", audio->getSampleRate(), audio->getChannelLayout(), audio->getFormat()); // Generate a 220 Hz sine wave with a 880 Hz beep each second, for 10 seconds. graph->open("sine=frequency=660:beep_factor=4:duration=11[out]"); // Generate an amplitude modulated signal //graph->open("aevalsrc=sin(10*2*PI*t)*sin(880*2*PI*t)[out]"); // add a stream for the encoded packets { RefPointer<MuxerStream> stream = muxer->addNewStream(encoder.value()); } // and open the muxer muxer->open(0, 0); // now we're (in theory) ready to start writing data. int32_t numFrames = 0; RefPointer<MediaPacket> packet; while(fsink->getAudio(audio.value()) >= 0 && audio->isComplete() && numFrames*audio->getNumSamples() < maxSamples) { audio->setTimeStamp(numFrames*audio->getNumSamples()); // let's encode packet = MediaPacket::make(); encoder->encodeAudio(packet.value(), audio.value()); if (packet->isComplete()) { muxer->write(packet.value(), false); } ++numFrames; } // now flush the encoder do { packet = MediaPacket::make(); encoder->encodeAudio(packet.value(), 0); if (packet->isComplete()) { muxer->write(packet.value(), false); } } while (packet->isComplete()); muxer->close(); }