void
MediaPictureResamplerTest::testCreation()
{
  RefPointer<MediaPictureResampler> resampler;

  int32_t oWidth = 200;
  int32_t oHeight = 100;
  PixelFormat::Type oFormat = PixelFormat::PIX_FMT_YUV420P;

  int32_t iWidth = 100;
  int32_t iHeight = 100;
  PixelFormat::Type iFormat = PixelFormat::PIX_FMT_ABGR;

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaPictureResampler::make(0, oHeight, oFormat, iWidth, iHeight, iFormat, 0),HumbleInvalidArgument);
    TS_ASSERT_THROWS(MediaPictureResampler::make(oWidth, 0, oFormat, iWidth, iHeight, iFormat, 0),HumbleInvalidArgument);
    TS_ASSERT_THROWS(MediaPictureResampler::make(oWidth, oHeight, PixelFormat::PIX_FMT_NONE, iWidth, iHeight, iFormat, 0),HumbleInvalidArgument);
    TS_ASSERT_THROWS(MediaPictureResampler::make(oWidth, oHeight, oFormat, 0, iHeight, iFormat, 0),HumbleInvalidArgument);
    TS_ASSERT_THROWS(MediaPictureResampler::make(oWidth, oHeight, oFormat, iWidth, 0, iFormat, 0),HumbleInvalidArgument);
    TS_ASSERT_THROWS(MediaPictureResampler::make(oWidth, oHeight, oFormat, iWidth, iHeight, PixelFormat::PIX_FMT_NONE, 0),HumbleInvalidArgument);
  }

  resampler = MediaPictureResampler::make(oWidth, oHeight, oFormat, iWidth, iHeight, iFormat, 0);
  TS_ASSERT(resampler);
}
void
AudioResamplerTest :: testGetters()
{
  RefPointer<IAudioResampler> sampler = IAudioResampler::make(1, 2,
      22050, 44100,
      IAudioSamples::FMT_S16,
      IAudioSamples::FMT_FLT,
      16,
      1,
      true,
      0.8);
  VS_TUT_ENSURE("!sampler", sampler);
  VS_TUT_ENSURE_EQUALS("", sampler->getOutputChannels(), 1);
  VS_TUT_ENSURE_EQUALS("", sampler->getInputChannels(), 2);
  VS_TUT_ENSURE_EQUALS("", sampler->getOutputRate(), 22050);
  VS_TUT_ENSURE_EQUALS("", sampler->getInputRate(), 44100);
  VS_TUT_ENSURE_EQUALS("", sampler->getOutputFormat(), IAudioSamples::FMT_S16);
  VS_TUT_ENSURE_EQUALS("", sampler->getInputFormat(), IAudioSamples::FMT_FLT);
  VS_TUT_ENSURE_EQUALS("", sampler->getFilterLen(), 16);
  VS_TUT_ENSURE_EQUALS("", sampler->getLog2PhaseCount(), 1);
  VS_TUT_ENSURE("", sampler->isLinear());
  VS_TUT_ENSURE_DISTANCE("", sampler->getCutoffFrequency(), 0.8, 0.001);
  
  
  // Turn down logging for this test as it should be noisy
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

  sampler = IAudioResampler::make(3, 2,
      22050, 44100);
  VS_TUT_ENSURE("sampler", !sampler);
  sampler = IAudioResampler::make(-1, -1,
      -1, -1);
  VS_TUT_ENSURE("sampler", !sampler);
}
Esempio n. 3
0
void
PropertyTest :: testSetMetaData()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

  RefPointer<Configurable> c = Demuxer::make();
  RefPointer<KeyValueBag> dict = KeyValueBag::make();
  RefPointer<KeyValueBag> unset = KeyValueBag::make();
  const char* realKey = "packetsize";
  const char* fakeKey = "not-a-valid-key-no-way-all-hail-zod";
  const char* realValue = "1000";
  const char* fakeValue = "1025";
  dict->setValue(realKey, realValue);
  dict->setValue(fakeKey, fakeValue);

  TSM_ASSERT("", dict->getNumKeys() == 2);
  TSM_ASSERT("", unset->getNumKeys() == 0);

  c->setProperty(dict.value(), unset.value());

  TSM_ASSERT("", c->getPropertyAsLong(realKey) == 1000);

  // make sure the fake isn't there.
  TS_ASSERT_THROWS(c->getPropertyMetaData(fakeKey), PropertyNotFoundException);

  // now make sure the returned dictionary only had the fake in it.
  TSM_ASSERT("", unset->getNumKeys() == 1);

  TSM_ASSERT("", strcmp(unset->getValue(fakeKey, KeyValueBag::KVB_NONE), fakeValue) == 0);
}
Esempio n. 4
0
void
PropertyTest :: testIteration()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);

  RefPointer<Configurable> c = Demuxer::make();

  int32_t numProperties = c->getNumProperties();
  TSM_ASSERT("", numProperties > 0);

  for(int32_t i = 0; i < numProperties; i++)
  {
    RefPointer <Property> property =  c->getPropertyMetaData(i);
    const char* name = property->getName();
    VS_LOG_DEBUG("Name: %s", name);
    VS_LOG_DEBUG("Description: %s", property->getHelp());
    VS_LOG_DEBUG("Default: %lld", property->getDefault());
    if (strcmp(name, "cryptokey")==0)
      continue;
    VS_LOG_DEBUG("Current value (boolean) : %d", (int32_t)c->getPropertyAsBoolean(name));
    VS_LOG_DEBUG("Current value (double)  : %f", c->getPropertyAsDouble(name));
    VS_LOG_DEBUG("Current value (long)    : %lld", c->getPropertyAsLong(name));
    RefPointer<Rational> rational = c->getPropertyAsRational(name);
    VS_LOG_DEBUG("Current value (rational): %f", rational->getValue());
    char* value=c->getPropertyAsString(name);
    VS_LOG_DEBUG("Current value (string)  : %s", value);
    if (value) free(value);
  }
}
Esempio n. 5
0
void
StreamCoderTest :: testSetCodec()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);

  h->setupReading(h->SAMPLE_FILE);

  coder = h->coders[0];
  RefPointer<ICodec> codec = h->codecs[0];

  // The helper, the coder, and me
  VS_TUT_ENSURE_EQUALS("wrong codec ref count",
      codec->getCurrentRefCount(),
      3);

  coder->setCodec(0);
  // The helper, and me
  VS_TUT_ENSURE_EQUALS("wrong codec ref count",
      codec->getCurrentRefCount(),
      2);

  coder->setCodec(ICodec::CODEC_ID_NELLYMOSER);
  codec = coder->getCodec();
  VS_TUT_ENSURE("could not find NELLYMOSER codec", codec);

  // The coder, and me
  VS_TUT_ENSURE_EQUALS("codec refcount wrong",
      codec->getCurrentRefCount(),
      2);
  // Just the helper
  VS_TUT_ENSURE_EQUALS("codec refcount wrong",
      h->codecs[0]->getCurrentRefCount(),
      1);

  codec = ICodec::findDecodingCodecByName("aac");
  VS_TUT_ENSURE("could not find ac3 decoder", codec);
  VS_TUT_ENSURE_EQUALS("ac3 codec refcount wrong",
      codec->getCurrentRefCount(),
      1);
  coder->setCodec(codec.value());
  VS_TUT_ENSURE_EQUALS("ac3 codec refcount wrong after setting",
      codec->getCurrentRefCount(),
      2);

  // This should fail because it's an Encoder, not a Decoder
  RefPointer<ICodec> encodec = h->codecs[0];

  encodec = ICodec::findEncodingCodecByName("libmp3lame");

  VS_TUT_ENSURE("could not find libmp3lame encoder", codec);
  coder->setSampleRate(22050);
  coder->setCodec(encodec.value());
  codec = coder->getCodec();
  VS_TUT_ENSURE_EQUALS("should allow wrong direction", codec.value(), encodec.value());
  int retval = coder->open();
  VS_TUT_ENSURE("should succeed even though wrong direction", retval >= 0);
  (void) retval; // in release compiles VS_TUT_ENSURE is removed and so -Werror produces errors about unused retvals
  coder->close();
}
Esempio n. 6
0
void
PropertyTest :: testCreation()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);
  RefPointer<Configurable> c = Demuxer::make();
  RefPointer<Property> property =  c->getPropertyMetaData("packetsize");
  VS_LOG_DEBUG("Name: %s", property->getName());
  VS_LOG_DEBUG("Description: %s", property->getHelp());
  TSM_ASSERT("should exist", property);
}
void
AudioResamplerTest :: testInvalidArguments()
{
  int retval = -1;

  // Turn down logging for this test as it should be noisy
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

  RefPointer<IAudioResampler> sampler;
  sampler = IAudioResampler::make(3, 2,
      22050, 44100);
  VS_TUT_ENSURE("sampler", !sampler);
  sampler = IAudioResampler::make(-1, -1,
      -1, -1);
  VS_TUT_ENSURE("sampler", !sampler);
  
  sampler = IAudioResampler::make(1, 2, 22050, 44100,
      IAudioSamples::FMT_S16, IAudioSamples::FMT_S16,
      -1, 0, true, 0.8);
  VS_TUT_ENSURE("sampler", !sampler);
  
  sampler = IAudioResampler::make(1, 2, 22050, 44100,
      IAudioSamples::FMT_S16, IAudioSamples::FMT_S16,
      16, -1, true, 0.8);
  VS_TUT_ENSURE("sampler", !sampler);

  sampler = IAudioResampler::make(1, 2, 22050, 44100,
      IAudioSamples::FMT_S16, IAudioSamples::FMT_S16,
      16, 0, true, -1.0);
  VS_TUT_ENSURE("sampler", !sampler);

  sampler = IAudioResampler::make(1, 2, 22050, 44100);
  VS_TUT_ENSURE("! sampler", sampler);

  retval = sampler->resample(0, 0, 0);
  VS_TUT_ENSURE("no crash", retval < 0);

  RefPointer<IAudioSamples> inSamples = IAudioSamples::make(1024, 1);
  RefPointer<IAudioSamples> outSamples = IAudioSamples::make(1024, 1);
  // Set to the wrong sample rate.
  inSamples->setComplete(true, 2, 22050, 2, IAudioSamples::FMT_S16, 0);
  retval = sampler->resample(outSamples.value(),
      inSamples.value(),
      4);
  VS_TUT_ENSURE("should fail because of sample rate", retval < 0);
  inSamples->setComplete(true, 4, 44100, 1, IAudioSamples::FMT_S16, 0);
  retval = sampler->resample(outSamples.value(),
      inSamples.value(),
      4);
  VS_TUT_ENSURE("should fail because of channels", retval < 0);
}
Esempio n. 8
0
void
MediaAudioTest::testCreationFromBufferPlanar() {
  const int32_t numSamples = 155; // I choose an odd number because HV will align up to 32
  const int32_t sampleRate = 22050;
  const int32_t channels = 15; // choose a large # of channels to make sure we expand the Frame
  const AudioChannel::Layout layout = AudioChannel::CH_LAYOUT_UNKNOWN;
  const AudioFormat::Type format = AudioFormat::SAMPLE_FMT_DBLP;

  int32_t bufSize = AudioFormat::getBufferSizeNeeded(numSamples, channels,
      format);
  // test that there is rounding up
  int32_t minSize = AudioFormat::getBytesPerSample(format) * numSamples
      * channels;
  TS_ASSERT_LESS_THAN(minSize, bufSize);

  RefPointer<Buffer> src = Buffer::make(0, bufSize);
  double* srcData = (double*) src->getBytes(0, bufSize);

  // now, let's go nuts!
  for (size_t i = 0; i < bufSize / sizeof(double); i++) {
    srcData[i] = i;
  }

  RefPointer<MediaAudio> audio;

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(0, numSamples, sampleRate, channels, layout,
        format), HumbleInvalidArgument);
  }
  audio = MediaAudio::make(src.value(), numSamples, sampleRate, channels,
      layout, format);
  TS_ASSERT(audio);

  TS_ASSERT_EQUALS(channels, audio->getNumDataPlanes());

  // sigh; time to test each plane.
  for (int i = 0; i < channels; i++) {
    RefPointer<Buffer> dst = audio->getData(i);
    TS_ASSERT(dst);
    double* dstData = (double*) dst->getBytes(0, dst->getBufferSize());

    // the values should be monotonically increasing given how we set them.
    double last = dstData[0];
    for (size_t j = 1; j < dst->getBufferSize() / sizeof(double); j++) {
      TS_ASSERT_DELTA(last + 1, dstData[j], 0.001);
      last = dstData[j];
    }
  }
}
Esempio n. 9
0
void
EncoderTest::testRegression36() {
  Logger::setGlobalIsLogging(Logger::LEVEL_TRACE, false);
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_INFO, false);

  {
    const int32_t sampleRate = 44100;
    const int32_t numSamples = sampleRate; // this is important for the test -- we want to extract 1 second of audio
    const AudioChannel::Layout channelLayout = AudioChannel::CH_LAYOUT_STEREO;
    const int32_t channels = AudioChannel::getNumChannelsInLayout(channelLayout);
    const AudioFormat::Type audioFormat = AudioFormat::SAMPLE_FMT_FLTP;
    const char* testOutputName = "EncoderTest_testRegression36.mp3";
    const Codec::ID codecId = Codec::CODEC_ID_MP3;
    const int64_t bitRate = 64000;

    testRegression36Internal (codecId, numSamples, sampleRate, channels,
                              channelLayout, audioFormat, bitRate,
                              testOutputName);
  }
  {
    const int32_t sampleRate = 22050;
    const int32_t numSamples = sampleRate; // this is important for the test -- we want to extract 1 second of audio
    const AudioChannel::Layout channelLayout = AudioChannel::CH_LAYOUT_MONO;
    const int32_t channels = AudioChannel::getNumChannelsInLayout(channelLayout);
    const AudioFormat::Type audioFormat = AudioFormat::SAMPLE_FMT_FLTP;
    const char* testOutputName = "EncoderTest_testRegression36.ogg";
    const Codec::ID codecId = Codec::CODEC_ID_VORBIS;
    const int64_t bitRate = 64000;

    testRegression36Internal (codecId, numSamples, sampleRate, channels,
                              channelLayout, audioFormat, bitRate,
                              testOutputName);
  }
  {
    const int32_t sampleRate = 22050;
    const int32_t numSamples = sampleRate; // this is important for the test -- we want to extract 1 second of audio
    const AudioChannel::Layout channelLayout = AudioChannel::CH_LAYOUT_MONO;
    const int32_t channels = AudioChannel::getNumChannelsInLayout(channelLayout);
    const AudioFormat::Type audioFormat = AudioFormat::SAMPLE_FMT_FLT;
    const char* testOutputName = "EncoderTest_testRegression36.flv";
    const Codec::ID codecId = Codec::CODEC_ID_NELLYMOSER;
    const int64_t bitRate = 64000;

    testRegression36Internal (codecId, numSamples, sampleRate, channels,
                              channelLayout, audioFormat, bitRate,
                              testOutputName);
  }
}
Esempio n. 10
0
void
PropertyTest::testValgrindStrlenIssue()
{
  // This is a bug in FFmpeg which I fixed in our
  // captive build. The error crops up for BINARY
  // option types that have no data in them.
  // This test tries to ensure we have a patched FFmpeg.
  RefPointer<Configurable> c = Demuxer::make();

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    char* value = c->getPropertyAsString("cryptokey");
    if (value) free(value);
  }
}
void
BitStreamFilterTypeTest::testGetBitStreamFilterType() {
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_INFO, false);

  // This test makes sure that the getBitStreamFilterType method calls Global::init
  RefPointer<BitStreamFilterType> t = BitStreamFilterType::getBitStreamFilterType(0);
  TS_ASSERT(t.value());

  int32_t n = BitStreamFilterType::getNumBitStreamFilterTypes();
  for(int32_t i = 0; i < n; i++) {
    RefPointer<BitStreamFilterType> t1 = BitStreamFilterType::getBitStreamFilterType(i);
    TS_ASSERT(t1->getName() != 0);
    RefPointer<BitStreamFilterType> t2 = BitStreamFilterType::getBitStreamFilterType(t1->getName());
    TS_ASSERT(strcmp(t1->getName(), t2->getName()) == 0);
    VS_LOG_DEBUG("(%03d) Filter: %s", i, t1->getName());
  }
}
Esempio n. 12
0
void
CodecTest::testGetSupportedProfiles()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_INFO, false);

  codec = Codec::findDecodingCodec(Codec::CODEC_ID_MPEG4);
  TS_ASSERT(codec);
  int32_t num = codec->getNumSupportedProfiles();
  TS_ASSERT(num > 0);
  for (int i = 0; i < num; i++) {
    RefPointer<CodecProfile> p = codec->getSupportedProfile(i);
    TS_ASSERT(p);
    VS_LOG_DEBUG("Profile: %s", p->getName());
  }
  TS_ASSERT(!codec->getSupportedProfile(-1));
  TS_ASSERT(!codec->getSupportedProfile(0x7FFFFFFF));
}
Esempio n. 13
0
void
StreamCoderTest :: testOpenButNoClose()
{
  int retval = 0;

  // Temporarily turn down logging
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);
  {
    Helper lh;
    lh.setupReading(lh.SAMPLE_FILE);
    for(int i = 0; i < lh.num_streams; i++)
    {
      retval = lh.coders[i]->open();
      VS_TUT_ENSURE("could not open coder", retval >= 0);
    }
  }
}
Esempio n. 14
0
void
MediaAudioTest::testCreationFromBufferPacked() {
  const int32_t numSamples = 155; // I choose an odd number because HV will align up to 32
  const int32_t sampleRate = 22050;
  const int32_t channels = 8;
  const AudioChannel::Layout layout = AudioChannel::CH_LAYOUT_7POINT1;
  const AudioFormat::Type format = AudioFormat::SAMPLE_FMT_DBL;

  int32_t bufSize = AudioFormat::getBufferSizeNeeded(numSamples, channels,
      format);
  RefPointer<Buffer> src = Buffer::make(0, bufSize);
  double* srcData = (double*) src->getBytes(0, bufSize);

  // now, let's go nuts!
  for (size_t i = 0; i < bufSize / sizeof(double); i++) {
    srcData[i] = i;
  }

  RefPointer<MediaAudio> audio;

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(0, numSamples, sampleRate, channels, layout,
        format), HumbleInvalidArgument);
  }
  audio = MediaAudio::make(src.value(), numSamples, sampleRate, channels,
      layout, format);
  TS_ASSERT(audio);

  TS_ASSERT_EQUALS(1, audio->getNumDataPlanes());
  RefPointer<Buffer> dst = audio->getData(0);
  TS_ASSERT(dst);
  double* dstData = (double*) dst->getBytes(0, dst->getBufferSize());

  // the test in packed data is simple -- the buffers should be equal!
  TS_ASSERT_EQUALS(src->getBufferSize(), dst->getBufferSize());
  TS_ASSERT_EQUALS(srcData, dstData);

}
Esempio n. 15
0
void
CodecTest :: testGetInstalledCodecs()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_INFO, false);

  int num = Codec::getNumInstalledCodecs();
  TSM_ASSERT("should be > 1", num > 1);
  for(int i = 0; i < num; i++)
  {
    codec = Codec::getInstalledCodec(i);
    TSM_ASSERT("should be valid", codec);
    if (codec) {
      VS_LOG_DEBUG("%s: %s",
          codec->getName(), codec->getLongName());
    }
  }
  TSM_ASSERT("could fail quietly",
      0 == Codec::getInstalledCodec(-1));
  TSM_ASSERT("could fail quietly",
      0 == Codec::getInstalledCodec(0x7FFFFFFF));
}
Esempio n. 16
0
void
StreamCoderFaacTest :: testDecodingAndEncodingFaacAudio()
{
  RefPointer<IAudioSamples> samples = 0;
  RefPointer<IVideoPicture> frame = 0;
  RefPointer<IRational> num(0);
  RefPointer<IStreamCoder> ic(0);
  RefPointer<IStreamCoder> oc(0);

  RefPointer<ICodec> newcodec;
  newcodec = ICodec::findEncodingCodecByName("libfaac");
  if (!newcodec)
  {
    VS_LOG_ERROR("libfaac not supported by this build; ignoring test");
    return;
  }

  int numSamples = 0;
  int numPackets = 0;
  int numFrames = 0;
  int numKeyFrames = 0;

  int retval = -1;

  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);

  // use the 20 second file to make memcheck faster
  h->setupReading("testfile_videoonly_20sec.flv");

  RefPointer<IPacket> packet = IPacket::make();

  hw->setupWriting("StreamCoderFaacTest_testDecodingAndEncodingFaacAudio.mov", "mpeg4", "libfaac", "mov");

  RefPointer<IPacket> opacket = IPacket::make();
  VS_TUT_ENSURE("! opacket", opacket);

  {
    // Let's set up audio first.
    ic = h->coders[h->first_input_audio_stream];
    oc = hw->coders[hw->first_output_audio_stream];

    // Set the output coder correctly.
    oc->setSampleRate(ic->getSampleRate());
    oc->setChannels(ic->getChannels());
    oc->setBitRate(ic->getBitRate());

    samples = IAudioSamples::make(1024, ic->getChannels());
    VS_TUT_ENSURE("got no samples", samples);


    retval = ic->open();
    VS_TUT_ENSURE("Could not open input coder", retval >= 0);
    retval = oc->open();
    VS_TUT_ENSURE("Could not open output coder", retval >= 0);
  }
  {
    // now, let's set up video.
    ic = h->coders[h->first_input_video_stream];
    oc = hw->coders[hw->first_output_video_stream];

    // We're going to set up high quality video
    oc->setBitRate(720000);
    oc->setGlobalQuality(0);
    oc->setFlags(oc->getFlags() | IStreamCoder::FLAG_QSCALE);

    oc->setPixelType(ic->getPixelType());
    oc->setHeight(ic->getHeight());
    oc->setWidth(ic->getWidth());
    num = IRational::make(1,15);
    oc->setFrameRate(num.value());
    num = ic->getTimeBase();
    oc->setTimeBase(num.value());
    oc->setNumPicturesInGroupOfPictures(
                      ic->getNumPicturesInGroupOfPictures()
                      );

    // Ask the StreamCoder to guess width and height for us
    frame = IVideoPicture::make(
                  ic->getPixelType(),
                  -1, -1);
    VS_TUT_ENSURE("got no frame", frame);
    VS_TUT_ENSURE("should not have width", frame->getWidth() <= 0);
    VS_TUT_ENSURE("should not have height", frame->getHeight() <= 0);

    retval = ic->open();
    VS_TUT_ENSURE("Could not open input coder", retval >= 0);
    retval = oc->open();
    VS_TUT_ENSURE("Could not open output coder", retval >= 0);
  }

  // write header
  retval = hw->container->writeHeader();
  VS_TUT_ENSURE("could not write header", retval >= 0);

  while (h->container->readNextPacket(packet.value()) == 0)
  {
    ic = h->coders[packet->getStreamIndex()];
    oc = hw->coders[packet->getStreamIndex()];

    if (packet->getStreamIndex() == h->first_input_audio_stream)
    {
      int offset = 0;

      numPackets++;

      while (offset < packet->getSize())
      {
        retval = ic->decodeAudio(
                     samples.value(),
                     packet.value(),
                     offset);
        VS_TUT_ENSURE("could not decode any audio",
                retval > 0);
        offset += retval;
        VS_TUT_ENSURE("could not write any samples",
                samples->getNumSamples() > 0);
        numSamples += samples->getNumSamples();

        // now, write out the packets.
        unsigned int numSamplesConsumed = 0;
        do {
          retval = oc->encodeAudio(opacket.value(), samples.value(),
                       numSamplesConsumed);
          VS_TUT_ENSURE("Could not encode any audio", retval > 0);
          numSamplesConsumed += retval;

          if (opacket->isComplete())
          {
            VS_TUT_ENSURE("could not encode audio", opacket->getSize() > 0);
            RefPointer<IBuffer> encodedBuffer = opacket->getData();
            VS_TUT_ENSURE("no encoded data", encodedBuffer);
            VS_TUT_ENSURE("less data than there should be",
                    encodedBuffer->getBufferSize() >=
                    opacket->getSize());

            retval = hw->container->writePacket(opacket.value());
            VS_TUT_ENSURE("could not write packet", retval >= 0);
          }
        } while (numSamplesConsumed < samples->getNumSamples());
      }
    } else if (packet->getStreamIndex() == h->first_input_video_stream)
    {
      int offset = 0;

      numPackets++;

      VS_LOG_TRACE("packet: pts: %ld; dts: %ld", packet->getPts(),
             packet->getDts());
      while (offset < packet->getSize())
      {

        retval = ic->decodeVideo(
                     frame.value(),
                     packet.value(),
                     offset);
        VS_TUT_ENSURE("could not decode any video", retval>0);
        num = ic->getTimeBase();
        VS_TUT_ENSURE_DISTANCE("time base changed", num->getDouble(), h->expected_time_base, 0.00001);
        offset += retval;
        if (frame->isComplete())
        {
          VS_TUT_ENSURE("should now have a frame width", frame->getWidth() > 0);
          VS_TUT_ENSURE("should now have a frame height", frame->getHeight() > 0);

          numFrames++;
          if (frame->isKeyFrame())
            numKeyFrames++;

          frame->setQuality(0);
          retval = oc->encodeVideo(
                       opacket.value(),
                       frame.value(),
                       -1);

          VS_TUT_ENSURE("could not encode video", retval >= 0);
          VS_TUT_ENSURE("could not encode video", opacket->isComplete());

          VS_TUT_ENSURE("could not encode video", opacket->getSize() > 0);

          RefPointer<IBuffer> encodedBuffer = opacket->getData();
          VS_TUT_ENSURE("no encoded data", encodedBuffer);
          VS_TUT_ENSURE("less data than there should be",
                  encodedBuffer->getBufferSize() >=
                  opacket->getSize());

          // now, write the packet to disk.
          retval = hw->container->writePacket(opacket.value());
          VS_TUT_ENSURE("could not write packet", retval >= 0);


        }
      }
    }
  }
  // sigh; it turns out that to flush the encoding buffers you need to
  // ask the encoder to encode a NULL set of samples.  So, let's do that.
  retval = hw->coders[hw->first_output_audio_stream]->encodeAudio(opacket.value(), 0, 0);
  VS_TUT_ENSURE("Could not encode any audio", retval >= 0);
  if (opacket->isComplete())
  {
    retval = hw->container->writePacket(opacket.value());
    VS_TUT_ENSURE("could not write packet", retval >= 0);
  }
  retval = hw->coders[hw->first_output_video_stream]->encodeVideo(opacket.value(), 0, 0);
  VS_TUT_ENSURE("Could not encode any video", retval >= 0);
  if (opacket->isComplete())
  {
    retval = hw->container->writePacket(opacket.value());
    VS_TUT_ENSURE("could not write packet", retval >= 0);
  }

  retval = hw->container->writeTrailer();
  VS_TUT_ENSURE("! writeTrailer", retval >= 0);

  retval = h->coders[h->first_input_audio_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = h->coders[h->first_input_video_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = hw->coders[hw->first_output_audio_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = hw->coders[hw->first_output_video_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  VS_TUT_ENSURE("could not get any audio packets", numPackets > 0);
  VS_TUT_ENSURE("could not decode any audio", numSamples > 0);
  VS_TUT_ENSURE("could not decode any video", numFrames >0);
  VS_TUT_ENSURE("could not find any key frames", numKeyFrames >0);

  if (h->expected_packets)
    VS_TUT_ENSURE_EQUALS("unexpected number of packets",
               numPackets, 1062);
  if (h->expected_audio_samples)
    VS_TUT_ENSURE_EQUALS("unexpected number of audio samples",
               numSamples, 438912);
  if (h->expected_video_frames)
    VS_TUT_ENSURE_EQUALS("unexpected number of video frames",
               numFrames, 300);
  if (h->expected_video_key_frames)
    VS_TUT_ENSURE_EQUALS("unexpected number of video key frames",
               numKeyFrames, 25);
}
Esempio n. 17
0
/**
 * Test that memory is not leaked/corrupted during error paths.
 */
void
EncoderTest::testEncodeInvalidParameters()
{
  // Sub-test 1
  {
    int32_t width=176;
    int32_t height=360; // invalid dimensions for H263 codec
    RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_H263);
    RefPointer<Encoder> encoder = Encoder::make(codec.value());

    RefPointer<MediaPicture> picture = MediaPicture::make(width*2,height*2,
        PixelFormat::PIX_FMT_YUV420P);

    // set the encoder properties we need
    encoder->setWidth(picture->getWidth());
    encoder->setHeight(picture->getHeight());
    encoder->setPixelFormat(picture->getFormat());
    encoder->setProperty("b", (int64_t)400000); // bitrate
    encoder->setProperty("g", (int64_t) 10); // gop

    RefPointer<Rational> tb = Rational::make(1,25);
    encoder->setTimeBase(tb.value());

    // open the encoder
    try {
      // Temporarily turn down logging
      LoggerStack stack;
      stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

      encoder->open(0, 0);
      TS_FAIL("should never get here");
    } catch (std::exception & e) {
      // ignore exception
    }
  }

  // Sub-test 2
  {
    int32_t width=176;
    int32_t height=144;

    RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_H264);
    RefPointer<Encoder> encoder = Encoder::make(codec.value());
    RefPointer<MediaPicture> picture = MediaPicture::make(width*2,height*2,
        PixelFormat::PIX_FMT_YUV420P);

    // set the encoder properties we need
    encoder->setWidth(picture->getWidth());
    encoder->setHeight(picture->getHeight());
    encoder->setPixelFormat(picture->getFormat());
    encoder->setProperty("b", (int64_t)400000); // bitrate
    encoder->setProperty("g", (int64_t) 10); // gop
    encoder->setProperty("bf", (int64_t)1); // max b frames

    RefPointer<Rational> tb = Rational::make(1,25);
    encoder->setTimeBase(tb.value());

    // Do not open the encoder

    // create an output muxer
    RefPointer<Muxer> muxer = Muxer::make("EncoderTest_encodeVideo.mov", 0, 0);

    // add a stream for the encoded packets
    try {
      // Temporarily turn down logging
      LoggerStack stack;
      stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

      RefPointer<MuxerStream> stream = muxer->addNewStream(encoder.value());
      TS_FAIL("should never get here");
    } catch (std::exception & e) {
      // success
    }
  }
}
Esempio n. 18
0
/**
 * This test will read ironman (FLV, H263 video and mp3 audio) and transcode
 * to MP4 (H264 Video and aac audio).
 */
void
EncoderTest::testTranscode()
{
  // enable trace logging
  Logger::setGlobalIsLogging(Logger::LEVEL_TRACE, false);
  const bool isMemCheck = getenv("VS_TEST_MEMCHECK") ? true : false;
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_INFO, false);

  TestData::Fixture* fixture;
  fixture=mFixtures.getFixture("testfile.flv");
//  fixture=mFixtures.getFixture("testfile_h264_mp4a_tmcd.mov");
//  fixture=mFixtures.getFixture("bigbuckbunny_h264_aac_5.1.mp4");
  TS_ASSERT(fixture);
  char filepath[2048];
  mFixtures.fillPath(fixture, filepath, sizeof(filepath));

  RefPointer<Demuxer> source = Demuxer::make();
  source->open(filepath, 0, false, true, 0, 0);
  int32_t numStreams = source->getNumStreams();
  TS_ASSERT_EQUALS(fixture->num_streams, numStreams);

  // Let's create a helper object to help us with decoding
  typedef struct {
    MediaDescriptor::Type type;
    RefPointer<DemuxerStream> stream;
    RefPointer<Decoder> decoder;
    RefPointer<MediaSampled> media;
  } DemuxerStreamHelper;

  // I know there are only 2 in the input file.
  DemuxerStreamHelper inputHelpers[10];
  for(int32_t i = 0; i < numStreams; i++) {
    DemuxerStreamHelper* input = &inputHelpers[i];
    input->stream = source->getStream(i);
    input->decoder = input->stream->getDecoder();
    if (!input->decoder)
      // skip
      break;
    input->decoder->open(0, 0);
    input->type = input->decoder->getCodecType();
    if (input->type == MediaDescriptor::MEDIA_AUDIO)
      input->media = MediaAudio::make(
          input->decoder->getFrameSize(),
          input->decoder->getSampleRate(),
          input->decoder->getChannels(),
          input->decoder->getChannelLayout(),
          input->decoder->getSampleFormat());
    else if (input->type  == MediaDescriptor::MEDIA_VIDEO)
      input->media = MediaPicture::make(
          input->decoder->getWidth(),
          input->decoder->getHeight(),
          input->decoder->getPixelFormat()
      );
  }

  // now, let's set up our output file.
  RefPointer<Muxer> muxer = Muxer::make("EncoderTest_testTranscode.mp4", 0, 0);
  RefPointer<MuxerFormat> format = muxer->getFormat();

  // Let's create a helper object to help us with decoding
  typedef struct {
    MediaDescriptor::Type type;
    RefPointer<MuxerStream> stream;
    RefPointer<MediaResampler> resampler;
    RefPointer<MediaSampled> media;
    RefPointer<Encoder> encoder;
  } MuxerStreamHelper;

  MuxerStreamHelper outputHelpers[10];
  for(int32_t i = 0; i < numStreams; i++) {
    DemuxerStreamHelper *input = &inputHelpers[i];
    MuxerStreamHelper *output = &outputHelpers[i];
    if (!input->decoder)
      // skip
      break;
    output->type = input->type;
    RefPointer<Encoder> encoder;
    if (output->type == MediaDescriptor::MEDIA_VIDEO) {
      RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_H264);
      encoder = Encoder::make(codec.value());

      // set the encoder properties we need
      encoder->setWidth(input->decoder->getWidth());
      encoder->setHeight(input->decoder->getHeight());
      encoder->setPixelFormat(input->decoder->getPixelFormat());
      encoder->setProperty("b", (int64_t)400000); // bitrate
      encoder->setProperty("g", (int64_t) 10); // gop
      encoder->setProperty("bf", (int64_t)0); // max b frames
      RefPointer<Rational> tb = Rational::make(1,2997);
      encoder->setTimeBase(tb.value());


    } else if (output->type == MediaDescriptor::MEDIA_AUDIO) {
      RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_AAC);
      encoder = Encoder::make(codec.value());

      // set the encoder properties we need
      encoder->setSampleRate(input->decoder->getSampleRate());
      encoder->setSampleFormat(input->decoder->getSampleFormat());
      encoder->setSampleFormat(AudioFormat::SAMPLE_FMT_S16);
      encoder->setChannelLayout(input->decoder->getChannelLayout());
      encoder->setChannels(input->decoder->getChannels());
      encoder->setProperty("b", (int64_t)64000); // bitrate
      RefPointer<Rational> tb = Rational::make(1,encoder->getSampleRate());
      encoder->setTimeBase(tb.value());
      //      //input->decoder->getTimeBase();
      //      output->encoder->setTimeBase(tb.value());

    }
    output->encoder.reset(encoder.value(), true);
    if (output->encoder) {
      if (format->getFlag(MuxerFormat::GLOBAL_HEADER))
        output->encoder->setFlag(Encoder::FLAG_GLOBAL_HEADER, true);

      output->encoder->open(0,0);

      // sometimes encoders need to change parameters to fit; let's see
      // if that happened.
      output->stream = muxer->addNewStream(output->encoder.value());
    }
    output->media = input->media;
    output->resampler = 0;
    if (output->type == MediaDescriptor::MEDIA_AUDIO) {
      // sometimes encoders only accept certain media types and discard
      // our suggestions. Let's check.
      if (
          output->encoder->getSampleRate() != input->decoder->getSampleRate() ||
          output->encoder->getSampleFormat() != input->decoder->getSampleFormat() ||
          output->encoder->getChannelLayout() != input->decoder->getChannelLayout() ||
          output->encoder->getChannels() != input->decoder->getChannels()
          )
      {
        // we need a resampler.
        VS_LOG_DEBUG("Resampling: [%"PRId32", %"PRId32", %"PRId32"] [%"PRId32", %"PRId32", %"PRId32"]",
                     (int32_t)output->encoder->getChannelLayout(),
                     (int32_t)output->encoder->getSampleRate(),
                     (int32_t)output->encoder->getSampleFormat(),
                     (int32_t)input->decoder->getChannelLayout(),
                     (int32_t)input->decoder->getSampleRate(),
                     (int32_t)input->decoder->getSampleFormat()
        );
        RefPointer<MediaAudioResampler> resampler = MediaAudioResampler::make(
            output->encoder->getChannelLayout(),
            output->encoder->getSampleRate(),
            output->encoder->getSampleFormat(),
            input->decoder->getChannelLayout(),
            input->decoder->getSampleRate(),
            input->decoder->getSampleFormat()
            );
        resampler->open();
        output->resampler.reset(resampler.value(), true);
        output->media = MediaAudio::make(
                  output->encoder->getFrameSize(),
                  output->encoder->getSampleRate(),
                  output->encoder->getChannels(),
                  output->encoder->getChannelLayout(),
                  output->encoder->getSampleFormat());
      }
    }
  }
  // now we should be ready to open the muxer
  muxer->open(0, 0);

  // now, let's start a decoding loop.
  RefPointer<MediaPacket> packet = MediaPacket::make();

  int numPackets = 0;
  while(source->read(packet.value()) >= 0) {
    // got a packet; now we try to decode it.
    if (packet->isComplete()) {
      int32_t streamNo = packet->getStreamIndex();
      DemuxerStreamHelper *input = &inputHelpers[streamNo];
      MuxerStreamHelper* output = &outputHelpers[streamNo];
      if (input->decoder) decodeAndEncode(
          packet.value(),
          input->decoder.value(),
          input->media.value(),
          output->resampler.value(),
          output->media.value(),
          muxer.value(),
          output->encoder.value());
      ++numPackets;
      if (isMemCheck && numPackets > 100) {
        VS_LOG_WARN("Exiting early under valgrind");
        break;
      }
    }
  }

  // now, flush any cached packets
  for(int i = 0; i < numStreams; i++) {
    DemuxerStreamHelper *input = &inputHelpers[i];
    MuxerStreamHelper* output = &outputHelpers[i];
    if (input->decoder) decodeAndEncode(
        0,
        input->decoder.value(),
        input->media.value(),
        output->resampler.value(),
        output->media.value(),
        muxer.value(),
        output->encoder.value());

  }
  source->close();
  muxer->close();
}
Esempio n. 19
0
void
EncoderTest::testEncodeVideo() {
  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 maxPics = isMemCheck ? 10 : 500;
  int32_t width=176;
  int32_t height=144;

  RefPointer<Codec> codec = Codec::findEncodingCodec(Codec::CODEC_ID_H264);
  RefPointer<Encoder> encoder = Encoder::make(codec.value());
  RefPointer<MediaPicture> picture = MediaPicture::make(width*2,height*2,
      PixelFormat::PIX_FMT_YUV420P);

  // set the encoder properties we need
  encoder->setWidth(picture->getWidth());
  encoder->setHeight(picture->getHeight());
  encoder->setPixelFormat(picture->getFormat());
  encoder->setProperty("b", (int64_t)400000); // bitrate
  encoder->setProperty("g", (int64_t) 10); // gop
  encoder->setProperty("bf", (int64_t)1); // max b frames

  RefPointer<Rational> tb = Rational::make(1,25);
  encoder->setTimeBase(tb.value());

  // mandlebrot, that is then negated, horizontally flipped, and edge detected, before
  // final outputting to a new picture with each version in one of 4 quadrants.
  char graphCommand[1024];
  snprintf(graphCommand,sizeof(graphCommand),"mandelbrot=s=%dx%d[mb];"
      "[mb]split=4[0][1][2][3];"
      "[0]pad=iw*2:ih*2[a];"
      "[1]negate[b];"
      "[2]hflip[c];"
      "[3]edgedetect[d];"
      "[a][b]overlay=w[x];"
      "[x][c]overlay=0:h[y];"
      "[y][d]overlay=w:h[out]", width, height);

  RefPointer<FilterGraph> graph = FilterGraph::make();
  RefPointer<FilterPictureSink> fsink = graph->addPictureSink("out", picture->getFormat());
  graph->open(graphCommand);

  // let's set a frame time base of 1/30
  RefPointer<Rational> pictureTb = Rational::make(1,30);

  // create an output muxer
  RefPointer<Muxer> muxer = Muxer::make("EncoderTest_encodeVideo.mov", 0, 0);
  RefPointer<MuxerFormat> format = muxer->getFormat();

  // if the container will require a global header, then the encoder needs to set this.
  if (format->getFlag(MuxerFormat::GLOBAL_HEADER))
    encoder->setFlag(Encoder::FLAG_GLOBAL_HEADER, true);

  // open the encoder
  encoder->open(0, 0);

  // 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 numPics = 0;
  RefPointer<MediaPacket> packet;

  while(fsink->getPicture(picture.value()) >= 0 && numPics < maxPics) {
    picture->setTimeBase(pictureTb.value());
    picture->setTimeStamp(numPics);

    // let's encode
    packet = MediaPacket::make();
    encoder->encodeVideo(packet.value(), picture.value());
    if (packet->isComplete()) {
      muxer->write(packet.value(), false);
    }
    ++numPics;
  }
  // now flush the encoder
  do {
    packet = MediaPacket::make();
    encoder->encodeVideo(packet.value(), 0);
    if (packet->isComplete()) {
      muxer->write(packet.value(), false);
    }
  } while (packet->isComplete());

  muxer->close();

}
Esempio n. 20
0
void
StreamCoderX264Test :: testDecodingAndEncodingH264Video()
{
  // This test doesn't pass memcheck but we're disabling for now
  const char *memcheck = getenv("VS_TEST_MEMCHECK");
  if (memcheck)
    return;
  return;
  RefPointer<IAudioSamples> samples = 0;
  RefPointer<IVideoPicture> frame = 0;
  RefPointer<IRational> num(0);
  RefPointer<IStreamCoder> ic(0);
  RefPointer<IStreamCoder> oc(0);

  RefPointer<ICodec> newcodec;
  newcodec = ICodec::findEncodingCodecByName("libx264");
  if (!newcodec)
    // we're probably in a LGPL build, and so we shouldn't run this test
    return;

  int numSamples = 0;
  int numPackets = 0;
  int numFrames = 0;
  int numKeyFrames = 0;

  int retval = -1;

  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);

  // use the 20 second file to make memcheck faster
  h->setupReading("testfile_videoonly_20sec.flv");

  RefPointer<IPacket> packet = IPacket::make();

  hw->setupWriting("StreamCoderX264Test_testDecodingAndEncodingH264Video.mp4", "libx264", "libmp3lame", "mp4");

  RefPointer<IPacket> opacket = IPacket::make();
  VS_TUT_ENSURE("! opacket", opacket);

  {
    // Let's set up audio first.
    ic = h->coders[h->first_input_audio_stream];
    oc = hw->coders[hw->first_output_audio_stream];

    // Set the output coder correctly.
    oc->setSampleRate(ic->getSampleRate());
    oc->setChannels(ic->getChannels());
    oc->setBitRate(ic->getBitRate());

    samples = IAudioSamples::make(1024, ic->getChannels());
    VS_TUT_ENSURE("got no samples", samples);


    retval = ic->open();
    VS_TUT_ENSURE("Could not open input coder", retval >= 0);
    retval = oc->open();
    VS_TUT_ENSURE("Could not open output coder", retval >= 0);
  }
  {
    // now, let's set up video.
    ic = h->coders[h->first_input_video_stream];
    oc = hw->coders[hw->first_output_video_stream];

    // We're going to set up high quality video
    oc->setBitRate(720000);
    oc->setGlobalQuality(0);
    oc->setFlags(oc->getFlags() | IStreamCoder::FLAG_QSCALE);

    oc->setPixelType(ic->getPixelType());
    oc->setHeight(ic->getHeight());
    oc->setWidth(ic->getWidth());
    num = IRational::make(1,15);
    oc->setFrameRate(num.value());
    num = ic->getTimeBase();
    oc->setTimeBase(num.value());
    oc->setNumPicturesInGroupOfPictures(
                      ic->getNumPicturesInGroupOfPictures()
                      );

    // Ask the StreamCoder to guess width and height for us
    frame = IVideoPicture::make(
                  ic->getPixelType(),
                  -1, -1);
    VS_TUT_ENSURE("got no frame", frame);
    VS_TUT_ENSURE("should not have width", frame->getWidth() <= 0);
    VS_TUT_ENSURE("should not have height", frame->getHeight() <= 0);

    oc->setProperty("coder", "0");
    oc->setProperty("flags", "+loop");
    oc->setProperty("cmp", "+chroma");
    oc->setProperty("partitions", "-parti8x8+parti4x4+partp8x8-partp4x4-partb8x8");
    oc->setProperty("me_method", "hex");
    oc->setProperty("subq", "3");
    oc->setProperty("me_range", "16");
    oc->setProperty("g", "250");
    oc->setProperty("keyint_min", "25");
    oc->setProperty("sc_threshold", "40");
    oc->setProperty("i_qfactor", "0.71");
    oc->setProperty("b_strategy", "1");
    oc->setProperty("qcomp", "0.6");
    oc->setProperty("qmin", "10");
    oc->setProperty("qmax", "51");
    oc->setProperty("qdiff", "4");
    oc->setProperty("directpred", "1");
    oc->setProperty("flags2", "+fastpskip");
    oc->setProperty("cqp", "0");
    retval = ic->open();
    VS_TUT_ENSURE("Could not open input coder", retval >= 0);
    retval = oc->open();
    if (retval < 0)
      // this fails on Mac builds
      return;
    VS_TUT_ENSURE("Could not open output coder", retval >= 0);
  }

  // write header
  retval = hw->container->writeHeader();
  VS_TUT_ENSURE("could not write header", retval >= 0);

  while (h->container->readNextPacket(packet.value()) == 0)
  {
    ic = h->coders[packet->getStreamIndex()];
    oc = hw->coders[packet->getStreamIndex()];

    if (packet->getStreamIndex() == h->first_input_audio_stream)
    {
      int offset = 0;

      numPackets++;

      while (offset < packet->getSize())
      {
        retval = ic->decodeAudio(
                     samples.value(),
                     packet.value(),
                     offset);
        VS_TUT_ENSURE("could not decode any audio",
                retval > 0);
        offset += retval;
        VS_TUT_ENSURE("could not write any samples",
                samples->getNumSamples() > 0);
        numSamples += samples->getNumSamples();

        // now, write out the packets.
        unsigned int numSamplesConsumed = 0;
        do {
          retval = oc->encodeAudio(opacket.value(), samples.value(),
                       numSamplesConsumed);
          VS_TUT_ENSURE("Could not encode any audio", retval > 0);
          numSamplesConsumed += retval;

          if (opacket->isComplete())
          {
            VS_TUT_ENSURE("could not encode audio", opacket->getSize() > 0);
            RefPointer<IBuffer> encodedBuffer = opacket->getData();
            VS_TUT_ENSURE("no encoded data", encodedBuffer);
            VS_TUT_ENSURE("less data than there should be",
                    encodedBuffer->getBufferSize() >=
                    opacket->getSize());

            retval = hw->container->writePacket(opacket.value());
            VS_TUT_ENSURE("could not write packet", retval >= 0);
          }
        } while (numSamplesConsumed < samples->getNumSamples());
      }
    } else if (packet->getStreamIndex() == h->first_input_video_stream)
    {
      int offset = 0;

      numPackets++;

      VS_LOG_TRACE("packet: pts: %ld; dts: %ld", packet->getPts(),
             packet->getDts());
      while (offset < packet->getSize())
      {

        retval = ic->decodeVideo(
                     frame.value(),
                     packet.value(),
                     offset);
        VS_TUT_ENSURE("could not decode any video", retval>0);
        num = ic->getTimeBase();
        VS_TUT_ENSURE_DISTANCE("time base changed", num->getDouble(), h->expected_time_base, 0.00001);
        offset += retval;
        if (frame->isComplete())
        {
          VS_TUT_ENSURE("should now have a frame width", frame->getWidth() > 0);
          VS_TUT_ENSURE("should now have a frame height", frame->getHeight() > 0);

          numFrames++;
          if (frame->isKeyFrame())
            numKeyFrames++;

          frame->setQuality(0);
          retval = oc->encodeVideo(
                       opacket.value(),
                       frame.value(),
                       -1);
          VS_TUT_ENSURE("could not encode video", retval >= 0);
          if (opacket->isComplete())
          {
            VS_TUT_ENSURE("could not encode video", opacket->isComplete());

            VS_TUT_ENSURE("could not encode video", opacket->getSize() > 0);

            RefPointer<IBuffer> encodedBuffer = opacket->getData();
            VS_TUT_ENSURE("no encoded data", encodedBuffer);
            VS_TUT_ENSURE("less data than there should be",
                encodedBuffer->getBufferSize() >=
                opacket->getSize());

            // now, write the packet to disk.
            retval = hw->container->writePacket(opacket.value());
            VS_TUT_ENSURE("could not write packet", retval >= 0);
          }

        }
      }
    }
  }
  // sigh; it turns out that to flush the encoding buffers you need to
  // ask the encoder to encode a NULL set of samples.  So, let's do that.
  retval = hw->coders[hw->first_output_audio_stream]->encodeAudio(opacket.value(), 0, 0);
  VS_TUT_ENSURE("Could not encode any audio", retval >= 0);
  if (opacket->isComplete())
  {
    retval = hw->container->writePacket(opacket.value());
    VS_TUT_ENSURE("could not write packet", retval >= 0);
  }
  retval = hw->coders[hw->first_output_video_stream]->encodeVideo(opacket.value(), 0, 0);
  VS_TUT_ENSURE("Could not encode any video", retval >= 0);
  if (opacket->isComplete())
  {
    retval = hw->container->writePacket(opacket.value());
    VS_TUT_ENSURE("could not write packet", retval >= 0);
  }

  retval = hw->container->writeTrailer();
  VS_TUT_ENSURE("! writeTrailer", retval >= 0);

  retval = h->coders[h->first_input_audio_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = h->coders[h->first_input_video_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = hw->coders[hw->first_output_audio_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  retval = hw->coders[hw->first_output_video_stream]->close();
  VS_TUT_ENSURE("! close", retval >= 0);

  VS_TUT_ENSURE("could not get any audio packets", numPackets > 0);
  VS_TUT_ENSURE("could not decode any audio", numSamples > 0);
  VS_TUT_ENSURE("could not decode any video", numFrames >0);
  VS_TUT_ENSURE("could not find any key frames", numKeyFrames >0);

  if (h->expected_packets)
    VS_TUT_ENSURE_EQUALS("unexpected number of packets",
               numPackets, 1062);
  if (h->expected_audio_samples)
    VS_TUT_ENSURE_EQUALS("unexpected number of audio samples",
               numSamples, 438912);
  if (h->expected_video_frames)
    VS_TUT_ENSURE_EQUALS("unexpected number of video frames",
               numFrames, 300);
  if (h->expected_video_key_frames)
    VS_TUT_ENSURE_EQUALS("unexpected number of video key frames",
               numKeyFrames, 25);
}
Esempio n. 21
0
void
MediaAudioTest::testCreation() {
  const int32_t numSamples = 1024;
  const int32_t sampleRate = 22050;
  const int32_t channels = 8;
  const AudioChannel::Layout layout = AudioChannel::CH_LAYOUT_7POINT1;
  const AudioFormat::Type format = AudioFormat::SAMPLE_FMT_S16P;

  // now let's test invalid methods.
  RefPointer<MediaAudio> audio;

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(-1, sampleRate, channels, layout, format),
        HumbleInvalidArgument);
  }

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(numSamples, -1, channels, layout, format),
        HumbleInvalidArgument);
  }

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(numSamples, sampleRate, -1, layout, format),
        HumbleInvalidArgument);
  }

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(numSamples, sampleRate, channels + 1, layout,
        format), HumbleInvalidArgument);
  }

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(MediaAudio::make(numSamples, sampleRate, channels, layout,
        AudioFormat::SAMPLE_FMT_NONE), HumbleInvalidArgument);
  }

  // And this should be valid
  audio = MediaAudio::make(numSamples, sampleRate, channels + 1,
      AudioChannel::CH_LAYOUT_UNKNOWN, format);
  TS_ASSERT(audio);

  audio = MediaAudio::make(numSamples, sampleRate, channels, layout, format);
  TS_ASSERT(audio);

  // now let's try getting the data
  RefPointer<Buffer> buf;

  TS_ASSERT_EQUALS(numSamples, audio->getMaxNumSamples());
  TS_ASSERT_EQUALS(numSamples, audio->getNumSamples());
  TS_ASSERT(!audio->isComplete());
  TS_ASSERT_EQUALS(channels, audio->getChannels());
  TS_ASSERT_EQUALS(channels, audio->getNumDataPlanes());
  TS_ASSERT_EQUALS(layout, audio->getChannelLayout());
  TS_ASSERT_EQUALS(sampleRate, audio->getSampleRate());
  TS_ASSERT_EQUALS(format, audio->getFormat());

  {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);

    TS_ASSERT_THROWS(
        audio->setNumSamples(audio->getMaxNumSamples()+1),
        HumbleInvalidArgument);
    TS_ASSERT_THROWS(audio->setNumSamples(-1), HumbleInvalidArgument);
    TS_ASSERT_THROWS(audio->setNumSamples(0), HumbleInvalidArgument);
  }

  audio->setNumSamples(1);
  TS_ASSERT_EQUALS(1, audio->getNumSamples());
  audio->setComplete(true);
  TS_ASSERT(audio->isComplete());

  for (int i = 0; i < channels; i++) {
    buf = audio->getData(i);
    TS_ASSERT(buf);
    TS_ASSERT_EQUALS(audio->getDataPlaneSize(i),
        audio->getNumSamples()*AudioFormat::getBytesPerSample(audio->getFormat())*(audio->isPlanar()?1:audio->getChannels()));
  }
  // now let's try packed audio
  audio = MediaAudio::make(numSamples, sampleRate, channels, layout,
      AudioFormat::getPackedSampleFormat(format));
  TS_ASSERT(audio);
  TS_ASSERT_EQUALS(AudioFormat::getPackedSampleFormat(format),
      audio->getFormat());
  TS_ASSERT_EQUALS(channels, audio->getChannels());
  TS_ASSERT_EQUALS(1, audio->getNumDataPlanes());

  buf = audio->getData(0);
  TS_ASSERT(buf);
  for (int i = 1; i < channels; i++) {
    LoggerStack stack;
    stack.setGlobalLevel(Logger::LEVEL_ERROR, false);
    TS_ASSERT_THROWS(audio->getData(i), HumbleInvalidArgument);
  }

}
Esempio n. 22
0
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();
}
Esempio n. 23
0
void
StreamCoderTest :: testGetters()
{
  int refcount=0;
  h->setupReading(h->SAMPLE_FILE);

  for(int i = 0; i< h->num_streams; i++)
  {
    RefPointer<IStream> stream;
    RefPointer<ICodec> codec;
    RefPointer<IRational> rational;
    stream = h->streams[i];
    coder = h->coders[i];

    VS_TUT_ENSURE_EQUALS("invalid direction", coder->getDirection(),
        IStreamCoder::DECODING);

    codec = coder->getCodec();
    refcount = codec->getCurrentRefCount();
    {
      LoggerStack stack;
      stack.setGlobalLevel(Logger::LEVEL_ERROR, false);
      coder->setCodec(codec.value());
    }
    // ensure that one release and one acquire happens
    VS_TUT_ENSURE_EQUALS("invalid releasing or acquiring of codec",
        codec->getCurrentRefCount(),
        refcount);

    VS_TUT_ENSURE_EQUALS("wrong codec type",
        codec->getType(),
        h->expected_codec_types[i]);
    VS_TUT_ENSURE_EQUALS("wrong codec id",
        codec->getID(),
        h->expected_codec_ids[i]);

    if (codec->getType() == ICodec::CODEC_TYPE_AUDIO)
    {
      if (h->expected_sample_rate)
        VS_TUT_ENSURE_EQUALS("unexpected sample rate",
            coder->getSampleRate(),
            h->expected_sample_rate
        );
      if (h->expected_channels)
        VS_TUT_ENSURE_EQUALS("unexpected sample rate",
            coder->getChannels(),
            h->expected_channels
        );

    } else if (codec->getType() == ICodec::CODEC_TYPE_VIDEO)
    {
      if (h->expected_width)
        VS_TUT_ENSURE_EQUALS("unexpected width",
            coder->getWidth(),
            h->expected_width
        );
      if (h->expected_height)
              VS_TUT_ENSURE_EQUALS("unexpected height",
                  coder->getHeight(),
                  h->expected_height
              );
      if (h->expected_gops)
        VS_TUT_ENSURE_EQUALS("unexpected group of pictures",
            coder->getNumPicturesInGroupOfPictures(),
            h->expected_gops
        );
      if (h->expected_pixel_format != IPixelFormat::NONE)
        VS_TUT_ENSURE_EQUALS("unexpected group of pictures",
            coder->getPixelType(),
            h->expected_pixel_format
        );
      if (h->expected_time_base)
      {
        rational = coder->getTimeBase();
        VS_TUT_ENSURE_DISTANCE("unexpected time base",
            rational->getDouble(),
            h->expected_time_base,
            0.0001
        );
        rational = stream->getTimeBase();
        VS_TUT_ENSURE_DISTANCE("unexpected time base",
            rational->getDouble(),
            h->expected_time_base,
            0.0001
        );

      }
    }
    else
    {
      VS_LOG_ERROR("Unexpected type of codec");
      TS_ASSERT(false);
    }
  }
}
Esempio n. 24
0
void
StreamCoderTest :: testTimestamps()
{
  LoggerStack stack;
  stack.setGlobalLevel(Logger::LEVEL_WARN, false);
  Helper hr;
  hr.setupReading("testfile_h264_mp4a_tmcd.mov");
  RefPointer<IStreamCoder> ac;
  RefPointer<IStreamCoder> vc;
  if (hr.first_input_audio_stream >= 0)
    ac = hr.coders[hr.first_input_audio_stream];

  if (hr.first_input_video_stream >= 0)
    vc = hr.coders[hr.first_input_video_stream];

  hw->setupWriting("StreamCoderTest_7_output.flv",
      vc ? "flv" : 0,
      ac ? "libmp3lame" : 0,
      "flv",
      vc ? vc->getPixelType() : IPixelFormat::YUV420P,
      vc ? vc->getWidth() : 0,
      vc ? vc->getHeight() : 0,
      false,
      ac ? ac->getSampleRate() : 0,
      ac ? ac->getChannels() : 0,
      true);

  RefPointer<IVideoPicture> frame;

  if (vc) {
    frame = IVideoPicture::make(
      vc->getPixelType(),
      vc->getWidth(),
      vc->getHeight());
  }
  RefPointer<IAudioSamples> samples;
  if (ac) {
    samples = IAudioSamples::make(10000,
        ac->getChannels());
  }
  int retval = -1;
  int numReads = 0;
  int maxReads = 10000;

  while ((retval = hr.readNextDecodedObject(samples.value(), frame.value())) > 0
      && numReads < maxReads)
  {
    int result = retval;
    numReads++;
    VS_TUT_ENSURE("should only return 1 or 2", retval == 1 || retval == 2);

    if (retval == 1)
    {
      VS_TUT_ENSURE("something should be complete...", samples->isComplete());
      retval = hw->writeSamples(samples.value());
      VS_TUT_ENSURE("could not write audio", retval >= 0);
    }

    if (retval == 2)
    {
      VS_TUT_ENSURE("something should be complete...", frame->isComplete());
      retval = hw->writeFrame(frame.value());
      VS_TUT_ENSURE("could not write video", retval >= 0);
    }

    {
      RefPointer<IRational> timebase = hr.coders[hr.packet->getStreamIndex()]->getTimeBase();
      ICodec::Type type = hr.coders[hr.packet->getStreamIndex()]->getCodecType();
      (void) type;
      (void) result;
      VS_LOG_TRACE("Packet stream: %d.%d; pts: %lld; dts: %lld; spts: %lld; fpts: %lld; tb: %d/%d; ret: %d,"
          "samps: %d",
          hr.packet->getStreamIndex(),
          type,
          hr.packet->getPts(),
          hr.packet->getDts(),
          samples ? samples->getPts() : -1,
          frame ? frame->getPts() : -1,
          timebase->getNumerator(), timebase->getDenominator(),
          result,
          samples ? samples->getNumSamples() : 0);
    }


  }
  VS_TUT_ENSURE("should return some data",
      numReads > 0);
}