SkipCutBuffer.cpp revision a98478bfbcc0f7fb4b164d3dce40ca96df75667d
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
27a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco NelissenSkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut, int32_t output_size) {
28a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mFrontPadding = skip;
29a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mBackPadding = cut;
30a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mWriteHead = 0;
31a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mReadHead = 0;
32a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mCapacity = cut + output_size;
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
68a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenvoid SkipCutBuffer::clear() {
69a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    mWriteHead = mReadHead = 0;
70a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen}
71a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
72a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenvoid SkipCutBuffer::write(const char *src, size_t num) {
73a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    int32_t sizeused = (mWriteHead - mReadHead);
74a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (sizeused < 0) sizeused += mCapacity;
75a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
76a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    // everything must fit
77a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    CHECK_GE((mCapacity - size_t(sizeused)), num);
78a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
79a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    size_t copyfirst = (mCapacity - mWriteHead);
80a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (copyfirst > num) copyfirst = num;
81a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (copyfirst) {
82a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        memcpy(mCutBuffer + mWriteHead, src, copyfirst);
83a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        num -= copyfirst;
84a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        src += copyfirst;
85a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        mWriteHead += copyfirst;
86a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        CHECK_LE(mWriteHead, mCapacity);
87a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        if (mWriteHead == mCapacity) mWriteHead = 0;
88a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        if (num) {
89a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen            memcpy(mCutBuffer, src, num);
90a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen            mWriteHead += num;
91a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        }
92a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    }
93a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen}
94a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
95a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissensize_t SkipCutBuffer::read(char *dst, size_t num) {
96a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    int32_t available = (mWriteHead - mReadHead);
97a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (available < 0) available += mCapacity;
98a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
99a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    available -= mBackPadding;
100a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (available <=0) {
101a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        return 0;
102a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    }
103a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (available < num) {
104a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        num = available;
105a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    }
106a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
107a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    size_t copyfirst = (mCapacity - mReadHead);
108a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (copyfirst > num) copyfirst = num;
109a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (copyfirst) {
110a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        memcpy(dst, mCutBuffer + mReadHead, copyfirst);
111a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        num -= copyfirst;
112a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        dst += copyfirst;
113a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        mReadHead += copyfirst;
114a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        CHECK_LE(mReadHead, mCapacity);
115a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        if (mReadHead == mCapacity) mReadHead = 0;
116a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        if (num) {
117a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen            memcpy(dst, mCutBuffer, num);
118a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen            mReadHead += num;
119a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen        }
120a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    }
121a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    return available;
122a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen}
123a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
124a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissensize_t SkipCutBuffer::size() {
125a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    int32_t available = (mWriteHead - mReadHead);
126a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    if (available < 0) available += mCapacity;
127a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen    return available;
128a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen}
129a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen
130a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen}  // namespace android
131