SkipCutBuffer.cpp revision cb5b766bb0a3ed992998a5bd66de0ee1d2223b81
1a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen/* 2a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Copyright (C) 2012 The Android Open Source Project 3a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 4a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 5a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * you may not use this file except in compliance with the License. 6a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * You may obtain a copy of the License at 7a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 8a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 9a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 10a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Unless required by applicable law or agreed to in writing, software 11a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 12a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * See the License for the specific language governing permissions and 14a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * limitations under the License. 15a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen */ 16a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 17a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen//#define LOG_NDEBUG 0 18a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#define LOG_TAG "SkipCutBuffer" 19a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <utils/Log.h> 20a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 21a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <media/stagefright/foundation/ADebug.h> 22a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <media/stagefright/MediaBuffer.h> 23a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <media/stagefright/SkipCutBuffer.h> 24a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 25a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissennamespace android { 26a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 27cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco NelissenSkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut) { 28a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mFrontPadding = skip; 29a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mBackPadding = cut; 30a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mWriteHead = 0; 31a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mReadHead = 0; 32cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen mCapacity = cut + 4096; 33a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mCutBuffer = new char[mCapacity]; 34a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ALOGV("skipcutbuffer %d %d %d", skip, cut, mCapacity); 35a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 36a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 37a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco NelissenSkipCutBuffer::~SkipCutBuffer() { 38a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen delete[] mCutBuffer; 39a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 40a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 41a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenvoid SkipCutBuffer::submit(MediaBuffer *buffer) { 42a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t offset = buffer->range_offset(); 43a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t buflen = buffer->range_length(); 44a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 45a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // drop the initial data from the buffer if needed 46a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (mFrontPadding > 0) { 47a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // still data left to drop 48a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding; 49a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen offset += to_drop; 50a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen buflen -= to_drop; 51a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen buffer->set_range(offset, buflen); 52a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mFrontPadding -= to_drop; 53a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 54a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 55a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 56a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // append data to cutbuffer 57a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen char *src = ((char*) buffer->data()) + offset; 58a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen write(src, buflen); 59a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 60a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 61a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // the mediabuffer is now empty. Fill it from cutbuffer, always leaving 62a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // at least mBackPadding bytes in the cutbuffer 63a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen char *dst = (char*) buffer->data(); 64a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen size_t copied = read(dst, buffer->size()); 65a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen buffer->set_range(0, copied); 66a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 67a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 68cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissenvoid SkipCutBuffer::submit(const sp<ABuffer>& buffer) { 69cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen int32_t offset = buffer->offset(); 70cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen int32_t buflen = buffer->size(); 71cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 72cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // drop the initial data from the buffer if needed 73cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen if (mFrontPadding > 0) { 74cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // still data left to drop 75cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding; 76cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen offset += to_drop; 77cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen buflen -= to_drop; 78cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen buffer->setRange(offset, buflen); 79cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen mFrontPadding -= to_drop; 80cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen } 81cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 82cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 83cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // append data to cutbuffer 84cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen char *src = (char*) buffer->data(); 85cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen write(src, buflen); 86cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 87cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 88cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // the mediabuffer is now empty. Fill it from cutbuffer, always leaving 89cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // at least mBackPadding bytes in the cutbuffer 90cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen char *dst = (char*) buffer->base(); 91cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen size_t copied = read(dst, buffer->capacity()); 92cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen buffer->setRange(0, copied); 93cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen} 94cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 95a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenvoid SkipCutBuffer::clear() { 96a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mWriteHead = mReadHead = 0; 97a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 98a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 99a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenvoid SkipCutBuffer::write(const char *src, size_t num) { 100a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t sizeused = (mWriteHead - mReadHead); 101a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (sizeused < 0) sizeused += mCapacity; 102a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 103cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // Everything must fit. Make sure the buffer is a little larger than needed, 104cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // so there is no ambiguity as to whether mWriteHead == mReadHead means buffer 105cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen // full or empty 106cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen size_t available = mCapacity - sizeused - 32; 107cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen if (available < num) { 108cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen int32_t newcapacity = mCapacity + (num - available); 109cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen char * newbuffer = new char[newcapacity]; 110cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen memcpy(newbuffer, mCutBuffer, mCapacity); 111cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen delete [] mCutBuffer; 112cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen mCapacity = newcapacity; 113cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen mCutBuffer = newbuffer; 114cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen ALOGV("reallocated buffer at size %d", newcapacity); 115cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen } 116a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 117a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen size_t copyfirst = (mCapacity - mWriteHead); 118a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (copyfirst > num) copyfirst = num; 119a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (copyfirst) { 120a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen memcpy(mCutBuffer + mWriteHead, src, copyfirst); 121a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen num -= copyfirst; 122a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen src += copyfirst; 123a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mWriteHead += copyfirst; 124a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen CHECK_LE(mWriteHead, mCapacity); 125a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (mWriteHead == mCapacity) mWriteHead = 0; 126a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (num) { 127a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen memcpy(mCutBuffer, src, num); 128a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mWriteHead += num; 129a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 130a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 131a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 132a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 133a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissensize_t SkipCutBuffer::read(char *dst, size_t num) { 134a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t available = (mWriteHead - mReadHead); 135a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (available < 0) available += mCapacity; 136a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 137a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen available -= mBackPadding; 138a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (available <=0) { 139a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen return 0; 140a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 141cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen if (available < int32_t(num)) { 142a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen num = available; 143a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 144a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 145a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen size_t copyfirst = (mCapacity - mReadHead); 146a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (copyfirst > num) copyfirst = num; 147a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (copyfirst) { 148a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen memcpy(dst, mCutBuffer + mReadHead, copyfirst); 149a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen num -= copyfirst; 150a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen dst += copyfirst; 151a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mReadHead += copyfirst; 152a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen CHECK_LE(mReadHead, mCapacity); 153a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (mReadHead == mCapacity) mReadHead = 0; 154a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (num) { 155a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen memcpy(dst, mCutBuffer, num); 156a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mReadHead += num; 157a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 158a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 159a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen return available; 160a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 161a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 162a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissensize_t SkipCutBuffer::size() { 163a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int32_t available = (mWriteHead - mReadHead); 164a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen if (available < 0) available += mCapacity; 165a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen return available; 166a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} 167a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 168a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen} // namespace android 169