SkipCutBuffer.cpp revision a98478bfbcc0f7fb4b164d3dce40ca96df75667d
1/* 2 * Copyright (C) 2012 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 "SkipCutBuffer" 19#include <utils/Log.h> 20 21#include <media/stagefright/foundation/ADebug.h> 22#include <media/stagefright/MediaBuffer.h> 23#include <media/stagefright/SkipCutBuffer.h> 24 25namespace android { 26 27SkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut, int32_t output_size) { 28 mFrontPadding = skip; 29 mBackPadding = cut; 30 mWriteHead = 0; 31 mReadHead = 0; 32 mCapacity = cut + output_size; 33 mCutBuffer = new char[mCapacity]; 34 ALOGV("skipcutbuffer %d %d %d", skip, cut, mCapacity); 35} 36 37SkipCutBuffer::~SkipCutBuffer() { 38 delete[] mCutBuffer; 39} 40 41void SkipCutBuffer::submit(MediaBuffer *buffer) { 42 int32_t offset = buffer->range_offset(); 43 int32_t buflen = buffer->range_length(); 44 45 // drop the initial data from the buffer if needed 46 if (mFrontPadding > 0) { 47 // still data left to drop 48 int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding; 49 offset += to_drop; 50 buflen -= to_drop; 51 buffer->set_range(offset, buflen); 52 mFrontPadding -= to_drop; 53 } 54 55 56 // append data to cutbuffer 57 char *src = ((char*) buffer->data()) + offset; 58 write(src, buflen); 59 60 61 // the mediabuffer is now empty. Fill it from cutbuffer, always leaving 62 // at least mBackPadding bytes in the cutbuffer 63 char *dst = (char*) buffer->data(); 64 size_t copied = read(dst, buffer->size()); 65 buffer->set_range(0, copied); 66} 67 68void SkipCutBuffer::clear() { 69 mWriteHead = mReadHead = 0; 70} 71 72void SkipCutBuffer::write(const char *src, size_t num) { 73 int32_t sizeused = (mWriteHead - mReadHead); 74 if (sizeused < 0) sizeused += mCapacity; 75 76 // everything must fit 77 CHECK_GE((mCapacity - size_t(sizeused)), num); 78 79 size_t copyfirst = (mCapacity - mWriteHead); 80 if (copyfirst > num) copyfirst = num; 81 if (copyfirst) { 82 memcpy(mCutBuffer + mWriteHead, src, copyfirst); 83 num -= copyfirst; 84 src += copyfirst; 85 mWriteHead += copyfirst; 86 CHECK_LE(mWriteHead, mCapacity); 87 if (mWriteHead == mCapacity) mWriteHead = 0; 88 if (num) { 89 memcpy(mCutBuffer, src, num); 90 mWriteHead += num; 91 } 92 } 93} 94 95size_t SkipCutBuffer::read(char *dst, size_t num) { 96 int32_t available = (mWriteHead - mReadHead); 97 if (available < 0) available += mCapacity; 98 99 available -= mBackPadding; 100 if (available <=0) { 101 return 0; 102 } 103 if (available < num) { 104 num = available; 105 } 106 107 size_t copyfirst = (mCapacity - mReadHead); 108 if (copyfirst > num) copyfirst = num; 109 if (copyfirst) { 110 memcpy(dst, mCutBuffer + mReadHead, copyfirst); 111 num -= copyfirst; 112 dst += copyfirst; 113 mReadHead += copyfirst; 114 CHECK_LE(mReadHead, mCapacity); 115 if (mReadHead == mCapacity) mReadHead = 0; 116 if (num) { 117 memcpy(dst, mCutBuffer, num); 118 mReadHead += num; 119 } 120 } 121 return available; 122} 123 124size_t SkipCutBuffer::size() { 125 int32_t available = (mWriteHead - mReadHead); 126 if (available < 0) available += mCapacity; 127 return available; 128} 129 130} // namespace android 131