Home | History | Annotate | Download | only in lvpp
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "VideoEditorSRC"
     19 
     20 #include <stdlib.h>
     21 #include <utils/Log.h>
     22 #include <audio_utils/primitives.h>
     23 #include <media/stagefright/foundation/ADebug.h>
     24 #include <media/stagefright/MetaData.h>
     25 #include <media/stagefright/MediaBuffer.h>
     26 #include <media/stagefright/MediaDefs.h>
     27 #include "VideoEditorSRC.h"
     28 
     29 
     30 namespace android {
     31 
     32 VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
     33     ALOGV("VideoEditorSRC %p(%p)", this, source.get());
     34     static const int32_t kDefaultSamplingFreqencyHz = kFreq32000Hz;
     35     mSource = source;
     36     mResampler = NULL;
     37     mChannelCnt = 0;
     38     mSampleRate = 0;
     39     mOutputSampleRate = kDefaultSamplingFreqencyHz;
     40     mStarted = false;
     41     mInitialTimeStampUs = -1;
     42     mAccuOutBufferSize  = 0;
     43     mSeekTimeUs = -1;
     44     mBuffer = NULL;
     45     mLeftover = 0;
     46     mFormatChanged = false;
     47     mStopPending = false;
     48     mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
     49 
     50     // Input Source validation
     51     sp<MetaData> format = mSource->getFormat();
     52     const char *mime;
     53     CHECK(format->findCString(kKeyMIMEType, &mime));
     54     CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
     55 
     56     // Set the metadata of the output after resampling.
     57     mOutputFormat = new MetaData;
     58     mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     59     mOutputFormat->setInt32(kKeySampleRate, kDefaultSamplingFreqencyHz);
     60     mOutputFormat->setInt32(kKeyChannelCount, 2);  // always stereo
     61 }
     62 
     63 VideoEditorSRC::~VideoEditorSRC() {
     64     ALOGV("~VideoEditorSRC %p(%p)", this, mSource.get());
     65     stop();
     66 }
     67 
     68 status_t VideoEditorSRC::start(MetaData *params) {
     69     ALOGV("start %p(%p)", this, mSource.get());
     70     CHECK(!mStarted);
     71 
     72     // Set resampler if required
     73     checkAndSetResampler();
     74 
     75     mSeekTimeUs = -1;
     76     mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
     77     mStarted = true;
     78     mSource->start();
     79 
     80     return OK;
     81 }
     82 
     83 status_t VideoEditorSRC::stop() {
     84     ALOGV("stop %p(%p)", this, mSource.get());
     85     if (!mStarted) {
     86         return OK;
     87     }
     88 
     89     if (mBuffer) {
     90         mBuffer->release();
     91         mBuffer = NULL;
     92     }
     93     mSource->stop();
     94     if (mResampler != NULL) {
     95         delete mResampler;
     96         mResampler = NULL;
     97     }
     98 
     99     mStarted = false;
    100     mInitialTimeStampUs = -1;
    101     mAccuOutBufferSize = 0;
    102     mLeftover = 0;
    103 
    104     return OK;
    105 }
    106 
    107 sp<MetaData> VideoEditorSRC::getFormat() {
    108     ALOGV("getFormat");
    109     return mOutputFormat;
    110 }
    111 
    112 status_t VideoEditorSRC::read(
    113         MediaBuffer **buffer_out, const ReadOptions *options) {
    114     ALOGV("read %p(%p)", this, mSource.get());
    115     *buffer_out = NULL;
    116 
    117     if (!mStarted) {
    118         return ERROR_END_OF_STREAM;
    119     }
    120 
    121     if (mResampler) {
    122         // Store the seek parameters
    123         int64_t seekTimeUs;
    124         ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
    125         if (options && options->getSeekTo(&seekTimeUs, &mode)) {
    126             ALOGV("read Seek %lld", seekTimeUs);
    127             mSeekTimeUs = seekTimeUs;
    128             mSeekMode = mode;
    129         }
    130 
    131         // We ask for 1024 frames in output
    132         // resampler output is always 2 channels and 32 bits
    133         const size_t kOutputFrameCount = 1024;
    134         const size_t kBytes = kOutputFrameCount * 2 * sizeof(int32_t);
    135         int32_t *pTmpBuffer = (int32_t *)calloc(1, kBytes);
    136         if (!pTmpBuffer) {
    137             ALOGE("calloc failed to allocate memory: %d bytes", kBytes);
    138             return NO_MEMORY;
    139         }
    140 
    141         // Resample to target quality
    142         mResampler->resample(pTmpBuffer, kOutputFrameCount, this);
    143 
    144         if (mStopPending) {
    145             stop();
    146             mStopPending = false;
    147         }
    148 
    149         // Change resampler and retry if format change happened
    150         if (mFormatChanged) {
    151             mFormatChanged = false;
    152             checkAndSetResampler();
    153             free(pTmpBuffer);
    154             return read(buffer_out, NULL);
    155         }
    156 
    157         // Create a new MediaBuffer
    158         int32_t outBufferSize = kOutputFrameCount * 2 * sizeof(int16_t);
    159         MediaBuffer* outBuffer = new MediaBuffer(outBufferSize);
    160 
    161         // Convert back to 2 channels and 16 bits
    162         ditherAndClamp(
    163                 (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()),
    164                 pTmpBuffer, kOutputFrameCount);
    165         free(pTmpBuffer);
    166 
    167         // Compute and set the new timestamp
    168         sp<MetaData> to = outBuffer->meta_data();
    169         int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2);
    170         int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
    171         to->setInt64(kKeyTime, timeUs);
    172 
    173         // update the accumulate size
    174         mAccuOutBufferSize += outBufferSize;
    175         *buffer_out = outBuffer;
    176     } else {
    177         // Resampling not required. Read and pass-through.
    178         MediaBuffer *aBuffer;
    179         status_t err = mSource->read(&aBuffer, options);
    180         if (err != OK) {
    181             ALOGV("read returns err = %d", err);
    182         }
    183 
    184         if (err == INFO_FORMAT_CHANGED) {
    185             checkAndSetResampler();
    186             return read(buffer_out, NULL);
    187         }
    188 
    189         // EOS or some other error
    190         if(err != OK) {
    191             stop();
    192             *buffer_out = NULL;
    193             return err;
    194         }
    195         *buffer_out = aBuffer;
    196     }
    197 
    198     return OK;
    199 }
    200 
    201 status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, int64_t pts) {
    202     ALOGV("getNextBuffer %d, chan = %d", pBuffer->frameCount, mChannelCnt);
    203     uint32_t done = 0;
    204     uint32_t want = pBuffer->frameCount * mChannelCnt * 2;
    205     pBuffer->raw = malloc(want);
    206 
    207     while (mStarted && want > 0) {
    208         // If we don't have any data left, read a new buffer.
    209         if (!mBuffer) {
    210             // if we seek, reset the initial time stamp and accumulated time
    211             ReadOptions options;
    212             if (mSeekTimeUs >= 0) {
    213                 ALOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
    214                 ReadOptions::SeekMode mode = mSeekMode;
    215                 options.setSeekTo(mSeekTimeUs, mode);
    216                 mSeekTimeUs = -1;
    217                 mInitialTimeStampUs = -1;
    218                 mAccuOutBufferSize = 0;
    219             }
    220 
    221             status_t err = mSource->read(&mBuffer, &options);
    222 
    223             if (err != OK) {
    224                 free(pBuffer->raw);
    225                 pBuffer->raw = NULL;
    226                 pBuffer->frameCount = 0;
    227             }
    228 
    229             if (err == INFO_FORMAT_CHANGED) {
    230                 ALOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED");
    231                 // At this point we cannot switch to a new AudioResampler because
    232                 // we are in a callback called by the AudioResampler itself. So
    233                 // just remember the fact that the format has changed, and let
    234                 // read() handles this.
    235                 mFormatChanged = true;
    236                 return err;
    237             }
    238 
    239             // EOS or some other error
    240             if (err != OK) {
    241                 ALOGV("EOS or some err: %d", err);
    242                 // We cannot call stop() here because stop() will release the
    243                 // AudioResampler, and we are in a callback of the AudioResampler.
    244                 // So just remember the fact and let read() call stop().
    245                 mStopPending = true;
    246                 return err;
    247             }
    248 
    249             CHECK(mBuffer);
    250             mLeftover = mBuffer->range_length();
    251             if (mInitialTimeStampUs == -1) {
    252                 int64_t curTS;
    253                 sp<MetaData> from = mBuffer->meta_data();
    254                 from->findInt64(kKeyTime, &curTS);
    255                 ALOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
    256                 mInitialTimeStampUs = curTS;
    257             }
    258         }
    259 
    260         // Now copy data to the destination
    261         uint32_t todo = mLeftover;
    262         if (todo > want) {
    263             todo = want;
    264         }
    265 
    266         uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset()
    267                 + mBuffer->range_length();
    268         memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo);
    269         done += todo;
    270         want -= todo;
    271         mLeftover -= todo;
    272 
    273         // Release MediaBuffer as soon as possible.
    274         if (mLeftover == 0) {
    275             mBuffer->release();
    276             mBuffer = NULL;
    277         }
    278     }
    279 
    280     pBuffer->frameCount = done / (mChannelCnt * 2);
    281     ALOGV("getNextBuffer done %d", pBuffer->frameCount);
    282     return OK;
    283 }
    284 
    285 
    286 void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
    287     ALOGV("releaseBuffer: %p", pBuffers);
    288     free(pBuffer->raw);
    289     pBuffer->raw = NULL;
    290     pBuffer->frameCount = 0;
    291 }
    292 
    293 void VideoEditorSRC::checkAndSetResampler() {
    294     ALOGV("checkAndSetResampler");
    295 
    296     static const uint16_t kUnityGain = 0x1000;
    297     sp<MetaData> format = mSource->getFormat();
    298     const char *mime;
    299     CHECK(format->findCString(kKeyMIMEType, &mime));
    300     CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
    301 
    302     CHECK(format->findInt32(kKeySampleRate, &mSampleRate));
    303     CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt));
    304 
    305     // If a resampler exists, delete it first
    306     if (mResampler != NULL) {
    307         delete mResampler;
    308         mResampler = NULL;
    309     }
    310 
    311     // Clear previous buffer
    312     if (mBuffer) {
    313         mBuffer->release();
    314         mBuffer = NULL;
    315     }
    316 
    317     if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) {
    318         ALOGV("Resampling required (%d => %d Hz, # channels = %d)",
    319             mSampleRate, mOutputSampleRate, mChannelCnt);
    320 
    321         mResampler = AudioResampler::create(
    322                         16 /* bit depth */,
    323                         mChannelCnt,
    324                         mOutputSampleRate);
    325         CHECK(mResampler);
    326         mResampler->setSampleRate(mSampleRate);
    327         mResampler->setVolume(kUnityGain, kUnityGain);
    328     } else {
    329         ALOGV("Resampling not required (%d => %d Hz, # channels = %d)",
    330             mSampleRate, mOutputSampleRate, mChannelCnt);
    331     }
    332 }
    333 
    334 } //namespce android
    335