1*a58d3d2aSXin Li /******************************************************************************
2*a58d3d2aSXin Li *
3*a58d3d2aSXin Li * Copyright (C) 2020 The Android Open Source Project
4*a58d3d2aSXin Li *
5*a58d3d2aSXin Li * Licensed under the Apache License, Version 2.0 (the "License");
6*a58d3d2aSXin Li * you may not use this file except in compliance with the License.
7*a58d3d2aSXin Li * You may obtain a copy of the License at:
8*a58d3d2aSXin Li *
9*a58d3d2aSXin Li * http://www.apache.org/licenses/LICENSE-2.0
10*a58d3d2aSXin Li *
11*a58d3d2aSXin Li * Unless required by applicable law or agreed to in writing, software
12*a58d3d2aSXin Li * distributed under the License is distributed on an "AS IS" BASIS,
13*a58d3d2aSXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*a58d3d2aSXin Li * See the License for the specific language governing permissions and
15*a58d3d2aSXin Li * limitations under the License.
16*a58d3d2aSXin Li *
17*a58d3d2aSXin Li *****************************************************************************
18*a58d3d2aSXin Li * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*a58d3d2aSXin Li */
20*a58d3d2aSXin Li
21*a58d3d2aSXin Li #include <algorithm>
22*a58d3d2aSXin Li
23*a58d3d2aSXin Li #include "opus.h"
24*a58d3d2aSXin Li
25*a58d3d2aSXin Li using namespace std;
26*a58d3d2aSXin Li
27*a58d3d2aSXin Li constexpr int kFrameDuration = 50;
28*a58d3d2aSXin Li constexpr int kMaxPacket = 1500;
29*a58d3d2aSXin Li constexpr int kMinBitRate = 500;
30*a58d3d2aSXin Li constexpr int kMaxBitRate = 512000;
31*a58d3d2aSXin Li
32*a58d3d2aSXin Li constexpr opus_int32 kSampleRates[] = {8000, 12000, 16000, 24000, 48000};
33*a58d3d2aSXin Li constexpr size_t kSampleRatesSize = size(kSampleRates);
34*a58d3d2aSXin Li
35*a58d3d2aSXin Li #ifndef MULTISTREAM
36*a58d3d2aSXin Li constexpr int kChannels[] = {1, 2};
37*a58d3d2aSXin Li constexpr size_t kChannelsSize = size(kChannels);
38*a58d3d2aSXin Li #endif
39*a58d3d2aSXin Li
40*a58d3d2aSXin Li constexpr int kApplications[] = {OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO,
41*a58d3d2aSXin Li OPUS_APPLICATION_RESTRICTED_LOWDELAY};
42*a58d3d2aSXin Li constexpr size_t kApplicationsSize = size(kApplications);
43*a58d3d2aSXin Li
44*a58d3d2aSXin Li constexpr int kSignals[] = {OPUS_AUTO, OPUS_SIGNAL_VOICE, OPUS_SIGNAL_MUSIC};
45*a58d3d2aSXin Li constexpr size_t kSignalsSize = size(kSignals);
46*a58d3d2aSXin Li
47*a58d3d2aSXin Li constexpr int kSetDTX[] = {0, 1};
48*a58d3d2aSXin Li constexpr size_t kSetDTXSize = size(kSetDTX);
49*a58d3d2aSXin Li
50*a58d3d2aSXin Li constexpr int kSetVBR[] = {0, 1};
51*a58d3d2aSXin Li constexpr size_t kSetVBRSize = size(kSetVBR);
52*a58d3d2aSXin Li
53*a58d3d2aSXin Li constexpr int kSetInbandFec[] = {0, 1};
54*a58d3d2aSXin Li constexpr size_t kSetInbandFecSize = size(kSetInbandFec);
55*a58d3d2aSXin Li
56*a58d3d2aSXin Li constexpr int kSetVBRConstraint[] = {0, 1};
57*a58d3d2aSXin Li constexpr size_t kSetVBRConstraintSize = size(kSetVBRConstraint);
58*a58d3d2aSXin Li
59*a58d3d2aSXin Li constexpr int kSetPredDisable[] = {0, 1};
60*a58d3d2aSXin Li constexpr size_t kSetPredDisableSize = size(kSetPredDisable);
61*a58d3d2aSXin Li
62*a58d3d2aSXin Li constexpr int kComplexities[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
63*a58d3d2aSXin Li constexpr size_t kComplexitiesSize = size(kComplexities);
64*a58d3d2aSXin Li
65*a58d3d2aSXin Li constexpr int kForceChannels[] = {OPUS_AUTO, 1, 2};
66*a58d3d2aSXin Li constexpr size_t kForceChannelsSize = size(kForceChannels);
67*a58d3d2aSXin Li
68*a58d3d2aSXin Li constexpr int kMaxBandwidths[] = {OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_MEDIUMBAND,
69*a58d3d2aSXin Li OPUS_BANDWIDTH_WIDEBAND, OPUS_BANDWIDTH_SUPERWIDEBAND,
70*a58d3d2aSXin Li OPUS_BANDWIDTH_FULLBAND};
71*a58d3d2aSXin Li constexpr size_t kMaxBandwidthsSize = size(kMaxBandwidths);
72*a58d3d2aSXin Li
73*a58d3d2aSXin Li constexpr int kPacketLossPerc[] = {0, 1, 2, 5};
74*a58d3d2aSXin Li constexpr size_t kPacketLossPercSize = size(kPacketLossPerc);
75*a58d3d2aSXin Li
76*a58d3d2aSXin Li constexpr int kLsbDepths[] = {8, 24};
77*a58d3d2aSXin Li constexpr size_t kLsbDepthsSize = size(kLsbDepths);
78*a58d3d2aSXin Li
79*a58d3d2aSXin Li constexpr int kFrameDurations[] = {
80*a58d3d2aSXin Li OPUS_FRAMESIZE_2_5_MS, OPUS_FRAMESIZE_5_MS, OPUS_FRAMESIZE_10_MS,
81*a58d3d2aSXin Li OPUS_FRAMESIZE_20_MS, OPUS_FRAMESIZE_40_MS, OPUS_FRAMESIZE_60_MS,
82*a58d3d2aSXin Li OPUS_FRAMESIZE_80_MS, OPUS_FRAMESIZE_100_MS, OPUS_FRAMESIZE_120_MS};
83*a58d3d2aSXin Li constexpr size_t kFrameDurationsSize = size(kFrameDurations);
84*a58d3d2aSXin Li
85*a58d3d2aSXin Li #ifdef MULTISTREAM
86*a58d3d2aSXin Li #include "opus_multistream.h"
87*a58d3d2aSXin Li #define OPUS_ENC_DATA_TYPE OpusMSEncoder
88*a58d3d2aSXin Li #define OPUS_ENC_ENCODE_API opus_multistream_encode
89*a58d3d2aSXin Li #define OPUS_ENC_CTL_API opus_multistream_encoder_ctl
90*a58d3d2aSXin Li #define OPUS_ENC_CREATE_API ms_opus_encoder_create
91*a58d3d2aSXin Li #define OPUS_ENC_DESTROY_API opus_multistream_encoder_destroy
ms_opus_encoder_create(opus_int32 sampleRate,int channels,int application,int * error)92*a58d3d2aSXin Li static OpusMSEncoder* ms_opus_encoder_create(opus_int32 sampleRate, int channels, int application,
93*a58d3d2aSXin Li int* error) {
94*a58d3d2aSXin Li unsigned char* mapping = (unsigned char*)malloc(sizeof(unsigned char) * channels);
95*a58d3d2aSXin Li if (!mapping) {
96*a58d3d2aSXin Li *error = 1;
97*a58d3d2aSXin Li return nullptr;
98*a58d3d2aSXin Li }
99*a58d3d2aSXin Li for (unsigned char x = 0; x < channels; ++x) {
100*a58d3d2aSXin Li mapping[x] = x;
101*a58d3d2aSXin Li }
102*a58d3d2aSXin Li OpusMSEncoder* enc = opus_multistream_encoder_create(sampleRate, channels, 1, channels - 1,
103*a58d3d2aSXin Li mapping, application, error);
104*a58d3d2aSXin Li free(mapping);
105*a58d3d2aSXin Li return enc;
106*a58d3d2aSXin Li }
107*a58d3d2aSXin Li #else
108*a58d3d2aSXin Li #define OPUS_ENC_DATA_TYPE OpusEncoder
109*a58d3d2aSXin Li #define OPUS_ENC_ENCODE_API opus_encode
110*a58d3d2aSXin Li #define OPUS_ENC_CTL_API opus_encoder_ctl
111*a58d3d2aSXin Li #define OPUS_ENC_CREATE_API opus_encoder_create
112*a58d3d2aSXin Li #define OPUS_ENC_DESTROY_API opus_encoder_destroy
113*a58d3d2aSXin Li #endif
114*a58d3d2aSXin Li
115*a58d3d2aSXin Li enum {
116*a58d3d2aSXin Li IDX_SAMPLE_RATE_INDEX = 0,
117*a58d3d2aSXin Li IDX_CHANNEL,
118*a58d3d2aSXin Li IDX_BIT_RATE_1,
119*a58d3d2aSXin Li IDX_BIT_RATE_2,
120*a58d3d2aSXin Li IDX_BIT_RATE_3,
121*a58d3d2aSXin Li IDX_COMPLEXITY,
122*a58d3d2aSXin Li IDX_APPLICATION,
123*a58d3d2aSXin Li IDX_SET_DTX,
124*a58d3d2aSXin Li IDX_SET_SIGNAL,
125*a58d3d2aSXin Li IDX_SET_VBR,
126*a58d3d2aSXin Li IDX_SET_VBR_CONSTRAINT,
127*a58d3d2aSXin Li IDX_FORCE_CHANNEL_INDEX,
128*a58d3d2aSXin Li IDX_SET_MAX_BANDWIDTH,
129*a58d3d2aSXin Li IDX_SET_INBAND_FEC,
130*a58d3d2aSXin Li IDX_SET_PACKET_LOSS_PERC,
131*a58d3d2aSXin Li IDX_SET_LSB_DEPTH,
132*a58d3d2aSXin Li IDX_SET_PREDICTION_DISABLED,
133*a58d3d2aSXin Li IDX_FRAME_ENUM,
134*a58d3d2aSXin Li IDX_LAST
135*a58d3d2aSXin Li };
136*a58d3d2aSXin Li
137*a58d3d2aSXin Li template <typename type1, typename type2, typename type3>
generateNumberInRangeFromData(type1 data,type2 min,type3 max)138*a58d3d2aSXin Li auto generateNumberInRangeFromData(type1 data, type2 min, type3 max) -> decltype(max) {
139*a58d3d2aSXin Li return (data % (1 + max - min)) + min;
140*a58d3d2aSXin Li }
141*a58d3d2aSXin Li
142*a58d3d2aSXin Li class Codec {
143*a58d3d2aSXin Li public:
~Codec()144*a58d3d2aSXin Li ~Codec() { deInitEncoder(); }
145*a58d3d2aSXin Li bool initEncoder(uint8_t** dataPtr, size_t* sizePtr);
146*a58d3d2aSXin Li void encodeFrames(const uint8_t* data, size_t size);
147*a58d3d2aSXin Li void deInitEncoder();
148*a58d3d2aSXin Li
149*a58d3d2aSXin Li private:
150*a58d3d2aSXin Li OPUS_ENC_DATA_TYPE* mEncoder = nullptr;
151*a58d3d2aSXin Li int mChannels = 0;
152*a58d3d2aSXin Li int mNumSamplesPerFrame = 0;
153*a58d3d2aSXin Li size_t mFrameSize = 0;
154*a58d3d2aSXin Li size_t mNumPcmBytesPerInputFrame = 0;
155*a58d3d2aSXin Li };
156*a58d3d2aSXin Li
get_frame_size(int frameSizeEnum,int samplingRate)157*a58d3d2aSXin Li int get_frame_size(int frameSizeEnum, int samplingRate) {
158*a58d3d2aSXin Li int frameSize = 0;
159*a58d3d2aSXin Li switch (frameSizeEnum) {
160*a58d3d2aSXin Li case OPUS_FRAMESIZE_2_5_MS:
161*a58d3d2aSXin Li frameSize = samplingRate / 400;
162*a58d3d2aSXin Li break;
163*a58d3d2aSXin Li case OPUS_FRAMESIZE_5_MS:
164*a58d3d2aSXin Li frameSize = samplingRate / 200;
165*a58d3d2aSXin Li break;
166*a58d3d2aSXin Li case OPUS_FRAMESIZE_10_MS:
167*a58d3d2aSXin Li frameSize = samplingRate / 100;
168*a58d3d2aSXin Li break;
169*a58d3d2aSXin Li case OPUS_FRAMESIZE_20_MS:
170*a58d3d2aSXin Li frameSize = samplingRate / 50;
171*a58d3d2aSXin Li break;
172*a58d3d2aSXin Li case OPUS_FRAMESIZE_40_MS:
173*a58d3d2aSXin Li frameSize = samplingRate / 25;
174*a58d3d2aSXin Li break;
175*a58d3d2aSXin Li case OPUS_FRAMESIZE_60_MS:
176*a58d3d2aSXin Li frameSize = 3 * samplingRate / 50;
177*a58d3d2aSXin Li break;
178*a58d3d2aSXin Li case OPUS_FRAMESIZE_80_MS:
179*a58d3d2aSXin Li frameSize = 4 * samplingRate / 50;
180*a58d3d2aSXin Li break;
181*a58d3d2aSXin Li case OPUS_FRAMESIZE_100_MS:
182*a58d3d2aSXin Li frameSize = 5 * samplingRate / 50;
183*a58d3d2aSXin Li break;
184*a58d3d2aSXin Li case OPUS_FRAMESIZE_120_MS:
185*a58d3d2aSXin Li frameSize = 6 * samplingRate / 50;
186*a58d3d2aSXin Li break;
187*a58d3d2aSXin Li default:
188*a58d3d2aSXin Li break;
189*a58d3d2aSXin Li }
190*a58d3d2aSXin Li return frameSize;
191*a58d3d2aSXin Li }
192*a58d3d2aSXin Li
initEncoder(uint8_t ** dataPtr,size_t * sizePtr)193*a58d3d2aSXin Li bool Codec::initEncoder(uint8_t** dataPtr, size_t* sizePtr) {
194*a58d3d2aSXin Li uint8_t* data = *dataPtr;
195*a58d3d2aSXin Li
196*a58d3d2aSXin Li int sampleRateIndex = data[IDX_SAMPLE_RATE_INDEX] % kSampleRatesSize;
197*a58d3d2aSXin Li opus_int32 sampleRate = kSampleRates[sampleRateIndex];
198*a58d3d2aSXin Li
199*a58d3d2aSXin Li #ifdef MULTISTREAM
200*a58d3d2aSXin Li mChannels = generateNumberInRangeFromData(data[IDX_CHANNEL], 1, 255);
201*a58d3d2aSXin Li #else
202*a58d3d2aSXin Li int channelIndex = data[IDX_CHANNEL] % kChannelsSize;
203*a58d3d2aSXin Li mChannels = kChannels[channelIndex];
204*a58d3d2aSXin Li #endif
205*a58d3d2aSXin Li
206*a58d3d2aSXin Li mNumSamplesPerFrame = sampleRate / kFrameDuration;
207*a58d3d2aSXin Li mNumPcmBytesPerInputFrame = mChannels * mNumSamplesPerFrame * sizeof(int16_t);
208*a58d3d2aSXin Li
209*a58d3d2aSXin Li int application = kApplications[data[IDX_APPLICATION] % kApplicationsSize];
210*a58d3d2aSXin Li int err = 0;
211*a58d3d2aSXin Li mEncoder = OPUS_ENC_CREATE_API(sampleRate, mChannels, application, &err);
212*a58d3d2aSXin Li if (err) {
213*a58d3d2aSXin Li return false;
214*a58d3d2aSXin Li }
215*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_APPLICATION(application));
216*a58d3d2aSXin Li
217*a58d3d2aSXin Li int complexityIndex = data[IDX_COMPLEXITY] % kComplexitiesSize;
218*a58d3d2aSXin Li int complexity = kComplexities[complexityIndex];
219*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_COMPLEXITY(complexity));
220*a58d3d2aSXin Li
221*a58d3d2aSXin Li int setDTXIndex = data[IDX_SET_DTX] % kSetDTXSize;
222*a58d3d2aSXin Li int setDTX = kSetDTX[setDTXIndex];
223*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_DTX(setDTX));
224*a58d3d2aSXin Li
225*a58d3d2aSXin Li int signalIndex = data[IDX_SET_SIGNAL] % kSignalsSize;
226*a58d3d2aSXin Li int signal = kSignals[signalIndex];
227*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_SIGNAL(signal));
228*a58d3d2aSXin Li
229*a58d3d2aSXin Li int setVBRIndex = data[IDX_SET_VBR] % kSetVBRSize;
230*a58d3d2aSXin Li int setVBR = kSetVBR[setVBRIndex];
231*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_VBR(setVBR));
232*a58d3d2aSXin Li
233*a58d3d2aSXin Li int setVBRConstraintIndex = data[IDX_SET_VBR_CONSTRAINT] % kSetVBRConstraintSize;
234*a58d3d2aSXin Li int setVBRConstraint = kSetVBRConstraint[setVBRConstraintIndex];
235*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_VBR_CONSTRAINT(setVBRConstraint));
236*a58d3d2aSXin Li
237*a58d3d2aSXin Li // Clubbing 3 bytes of data to ensure bit rate in the range [kMinBitRate, kMaxBitRate]
238*a58d3d2aSXin Li uint32_t tempValue =
239*a58d3d2aSXin Li (data[IDX_BIT_RATE_1] << 16) | (data[IDX_BIT_RATE_2] << 8) | data[IDX_BIT_RATE_3];
240*a58d3d2aSXin Li uint32_t bitRate = generateNumberInRangeFromData(tempValue, kMinBitRate, kMaxBitRate);
241*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_BITRATE(bitRate));
242*a58d3d2aSXin Li
243*a58d3d2aSXin Li int forceChanneIndex = data[IDX_FORCE_CHANNEL_INDEX] % kForceChannelsSize;
244*a58d3d2aSXin Li int forceChannel = kForceChannels[forceChanneIndex];
245*a58d3d2aSXin Li forceChannel = min(forceChannel, mChannels);
246*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_FORCE_CHANNELS(forceChannel));
247*a58d3d2aSXin Li
248*a58d3d2aSXin Li int maxBandwidthIndex = data[IDX_SET_MAX_BANDWIDTH] % kMaxBandwidthsSize;
249*a58d3d2aSXin Li opus_int32 maxBandwidth = kMaxBandwidths[maxBandwidthIndex];
250*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_MAX_BANDWIDTH(maxBandwidth));
251*a58d3d2aSXin Li
252*a58d3d2aSXin Li int setInbandFecIndex = data[IDX_SET_INBAND_FEC] % kSetInbandFecSize;
253*a58d3d2aSXin Li int setInbandFec = kSetInbandFec[setInbandFecIndex];
254*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_INBAND_FEC(setInbandFec));
255*a58d3d2aSXin Li
256*a58d3d2aSXin Li int pktLossIndex = data[IDX_SET_PACKET_LOSS_PERC] % kPacketLossPercSize;
257*a58d3d2aSXin Li int pktLoss = kPacketLossPerc[pktLossIndex];
258*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_PACKET_LOSS_PERC(pktLoss));
259*a58d3d2aSXin Li
260*a58d3d2aSXin Li int lsbDepthIndex = data[IDX_SET_LSB_DEPTH] % kLsbDepthsSize;
261*a58d3d2aSXin Li int lsbDepth = kLsbDepths[lsbDepthIndex];
262*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_LSB_DEPTH(lsbDepth));
263*a58d3d2aSXin Li
264*a58d3d2aSXin Li int setPredDisableIndex = data[IDX_SET_PREDICTION_DISABLED] % kSetPredDisableSize;
265*a58d3d2aSXin Li int setPredDisable = kSetPredDisable[setPredDisableIndex];
266*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_PREDICTION_DISABLED(setPredDisable));
267*a58d3d2aSXin Li
268*a58d3d2aSXin Li int frameSizesEnumIndex = data[IDX_FRAME_ENUM] % kFrameDurationsSize;
269*a58d3d2aSXin Li int frameSizeEnum = kFrameDurations[frameSizesEnumIndex];
270*a58d3d2aSXin Li OPUS_ENC_CTL_API(mEncoder, OPUS_SET_EXPERT_FRAME_DURATION(frameSizeEnum));
271*a58d3d2aSXin Li
272*a58d3d2aSXin Li mFrameSize = get_frame_size(frameSizeEnum, sampleRate);
273*a58d3d2aSXin Li if (mFrameSize == 0) {
274*a58d3d2aSXin Li return false;
275*a58d3d2aSXin Li }
276*a58d3d2aSXin Li
277*a58d3d2aSXin Li // Not re-using the data which was used for configuration for encoding
278*a58d3d2aSXin Li *dataPtr += IDX_LAST;
279*a58d3d2aSXin Li *sizePtr -= IDX_LAST;
280*a58d3d2aSXin Li return true;
281*a58d3d2aSXin Li }
282*a58d3d2aSXin Li
encodeFrames(const uint8_t * data,size_t size)283*a58d3d2aSXin Li void Codec::encodeFrames(const uint8_t* data, size_t size) {
284*a58d3d2aSXin Li opus_int16* inputBuffer = (opus_int16*)data;
285*a58d3d2aSXin Li size = size / sizeof(opus_int16);
286*a58d3d2aSXin Li size_t offset = 0;
287*a58d3d2aSXin Li do {
288*a58d3d2aSXin Li size_t frameSize = mFrameSize / mChannels;
289*a58d3d2aSXin Li if (frameSize > (size - offset)) {
290*a58d3d2aSXin Li frameSize = size - offset;
291*a58d3d2aSXin Li }
292*a58d3d2aSXin Li unsigned char packet[kMaxPacket];
293*a58d3d2aSXin Li (void)OPUS_ENC_ENCODE_API(mEncoder, &inputBuffer[offset], frameSize, packet, kMaxPacket);
294*a58d3d2aSXin Li offset += mFrameSize * mChannels;
295*a58d3d2aSXin Li } while (offset < size);
296*a58d3d2aSXin Li }
297*a58d3d2aSXin Li
deInitEncoder()298*a58d3d2aSXin Li void Codec::deInitEncoder() {
299*a58d3d2aSXin Li if (mEncoder) {
300*a58d3d2aSXin Li OPUS_ENC_DESTROY_API(mEncoder);
301*a58d3d2aSXin Li mEncoder = nullptr;
302*a58d3d2aSXin Li }
303*a58d3d2aSXin Li }
304*a58d3d2aSXin Li
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)305*a58d3d2aSXin Li extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
306*a58d3d2aSXin Li if (size < IDX_LAST) {
307*a58d3d2aSXin Li return 0;
308*a58d3d2aSXin Li }
309*a58d3d2aSXin Li Codec encoder;
310*a58d3d2aSXin Li if (encoder.initEncoder(const_cast<uint8_t**>(&data), &size)) {
311*a58d3d2aSXin Li encoder.encodeFrames(data, size);
312*a58d3d2aSXin Li }
313*a58d3d2aSXin Li return 0;
314*a58d3d2aSXin Li }
315