1 /* 2 * Copyright (C) 2020 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 #ifndef ANDROID_MEDIA_SAMPLE_H 18 #define ANDROID_MEDIA_SAMPLE_H 19 20 #include <cstdint> 21 #include <functional> 22 #include <memory> 23 24 namespace android { 25 26 /** 27 * Media sample flags. 28 * These flags purposely match the media NDK's buffer and extractor flags with one exception. The 29 * NDK extractor's flag for encrypted samples (AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED) is equal to 2, 30 * i.e. the same as SAMPLE_FLAG_CODEC_CONFIG below and NDK's AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG. 31 * Sample producers based on the NDK's extractor is responsible for catching those values. 32 * Note that currently the media transcoder does not support encrypted samples. 33 */ 34 enum : uint32_t { 35 SAMPLE_FLAG_SYNC_SAMPLE = 1, 36 SAMPLE_FLAG_CODEC_CONFIG = 2, 37 SAMPLE_FLAG_END_OF_STREAM = 4, 38 SAMPLE_FLAG_PARTIAL_FRAME = 8, 39 }; 40 41 /** 42 * MediaSampleInfo is an object that carries information about a compressed media sample without 43 * holding any sample data. 44 */ 45 struct MediaSampleInfo { 46 /** The sample's presentation timestamp in microseconds. */ 47 int64_t presentationTimeUs = 0; 48 49 /** The size of the compressed sample data in bytes. */ 50 size_t size = 0; 51 52 /** Sample flags. */ 53 uint32_t flags = 0; 54 }; 55 56 /** 57 * MediaSample holds a compressed media sample in memory. 58 */ 59 struct MediaSample { 60 /** 61 * Callback to notify that a media sample is about to be released, giving the creator a chance 62 * to reclaim the data buffer backing the sample. Once this callback returns, the media sample 63 * instance *will* be released so it cannot be used outside of the callback. To enable the 64 * callback, create the media sample with {@link #createWithReleaseCallback}. 65 * @param sample The sample to be released. 66 */ 67 using OnSampleReleasedCallback = std::function<void(MediaSample* sample)>; 68 69 /** 70 * Creates a new media sample instance with a registered release callback. The release callback 71 * will get called right before the media sample is released giving the creator a chance to 72 * reclaim the buffer. 73 * @param buffer Byte buffer containing the sample's compressed data. 74 * @param dataOffset Offset, in bytes, to the sample's compressed data inside the buffer. 75 * @param bufferId Buffer identifier that can be used to identify the buffer on release. 76 * @param releaseCallback The sample release callback. 77 * @return A new media sample instance. 78 */ createWithReleaseCallbackMediaSample79 static std::shared_ptr<MediaSample> createWithReleaseCallback( 80 uint8_t* buffer, size_t dataOffset, uint32_t bufferId, 81 OnSampleReleasedCallback releaseCallback) { 82 MediaSample* sample = new MediaSample(buffer, dataOffset, bufferId, releaseCallback); 83 return std::shared_ptr<MediaSample>( 84 sample, std::bind(&MediaSample::releaseSample, std::placeholders::_1)); 85 } 86 87 /** 88 * Byte buffer containing the sample's compressed data. The media sample instance does not take 89 * ownership of the buffer and will not automatically release the memory, but the caller can 90 * register a release callback by creating the media sample with 91 * {@link #createWithReleaseCallback}. 92 */ 93 const uint8_t* buffer = nullptr; 94 95 /** Offset, in bytes, to the sample's compressed data inside the buffer. */ 96 size_t dataOffset = 0; 97 98 /** 99 * Buffer identifier. This identifier is likely only meaningful to the sample data producer and 100 * can be used for reclaiming the buffer once a consumer is done processing it. 101 */ 102 uint32_t bufferId = 0xBAADF00D; 103 104 /** Media sample information. */ 105 MediaSampleInfo info; 106 107 MediaSample() = default; 108 109 private: MediaSampleMediaSample110 MediaSample(uint8_t* buffer, size_t dataOffset, uint32_t bufferId, 111 OnSampleReleasedCallback releaseCallback) 112 : buffer(buffer), 113 dataOffset(dataOffset), 114 bufferId(bufferId), 115 mReleaseCallback(releaseCallback){}; 116 releaseSampleMediaSample117 static void releaseSample(MediaSample* sample) { 118 if (sample->mReleaseCallback != nullptr) { 119 sample->mReleaseCallback(sample); 120 } 121 delete sample; 122 } 123 124 // Do not allow copying to prevent dangling pointers in the copied object after the original is 125 // released. 126 MediaSample(const MediaSample&) = delete; 127 MediaSample& operator=(const MediaSample&) = delete; 128 129 const OnSampleReleasedCallback mReleaseCallback = nullptr; 130 }; 131 132 } // namespace android 133 #endif // ANDROID_MEDIA_SAMPLE_H 134