1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker *
4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker *
8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker *
10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker */
16*b7c941bbSAndroid Build Coastguard Worker
17*b7c941bbSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*b7c941bbSAndroid Build Coastguard Worker #define LOG_TAG "NativeMuxerUnitTest"
19*b7c941bbSAndroid Build Coastguard Worker #include <log/log.h>
20*b7c941bbSAndroid Build Coastguard Worker
21*b7c941bbSAndroid Build Coastguard Worker #include <fcntl.h>
22*b7c941bbSAndroid Build Coastguard Worker #include <jni.h>
23*b7c941bbSAndroid Build Coastguard Worker #include <media/NdkMediaExtractor.h>
24*b7c941bbSAndroid Build Coastguard Worker #include <media/NdkMediaFormat.h>
25*b7c941bbSAndroid Build Coastguard Worker #include <media/NdkMediaMuxer.h>
26*b7c941bbSAndroid Build Coastguard Worker #include <sys/stat.h>
27*b7c941bbSAndroid Build Coastguard Worker #include <unistd.h>
28*b7c941bbSAndroid Build Coastguard Worker
29*b7c941bbSAndroid Build Coastguard Worker #include <cmath>
30*b7c941bbSAndroid Build Coastguard Worker #include <cstring>
31*b7c941bbSAndroid Build Coastguard Worker #include <fstream>
32*b7c941bbSAndroid Build Coastguard Worker #include <map>
33*b7c941bbSAndroid Build Coastguard Worker #include <vector>
34*b7c941bbSAndroid Build Coastguard Worker
35*b7c941bbSAndroid Build Coastguard Worker #include "NativeMediaCommon.h"
36*b7c941bbSAndroid Build Coastguard Worker
insertPerFrameSubtitles(AMediaMuxer * muxer,long pts,size_t trackID)37*b7c941bbSAndroid Build Coastguard Worker static media_status_t insertPerFrameSubtitles(AMediaMuxer* muxer, long pts, size_t trackID) {
38*b7c941bbSAndroid Build Coastguard Worker const char* greeting = "hello world";
39*b7c941bbSAndroid Build Coastguard Worker auto* info = new AMediaCodecBufferInfo;
40*b7c941bbSAndroid Build Coastguard Worker info->offset = 0;
41*b7c941bbSAndroid Build Coastguard Worker info->size = strlen(greeting);
42*b7c941bbSAndroid Build Coastguard Worker info->presentationTimeUs = pts;
43*b7c941bbSAndroid Build Coastguard Worker info->flags = 0;
44*b7c941bbSAndroid Build Coastguard Worker media_status_t status = AMediaMuxer_writeSampleData(muxer, trackID, (uint8_t*)greeting, info);
45*b7c941bbSAndroid Build Coastguard Worker delete info;
46*b7c941bbSAndroid Build Coastguard Worker return status;
47*b7c941bbSAndroid Build Coastguard Worker }
48*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfInvalidFdIsRejected(JNIEnv *,jobject)49*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfInvalidFdIsRejected(JNIEnv*, jobject) {
50*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(-1, AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP);
51*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
52*b7c941bbSAndroid Build Coastguard Worker if (muxer != nullptr) {
53*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
54*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer constructor accepts invalid file descriptor");
55*b7c941bbSAndroid Build Coastguard Worker isPass = false;
56*b7c941bbSAndroid Build Coastguard Worker }
57*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
58*b7c941bbSAndroid Build Coastguard Worker }
59*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfReadOnlyFdIsRejected(JNIEnv * env,jobject,jstring jdstPath)60*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfReadOnlyFdIsRejected(JNIEnv* env, jobject, jstring jdstPath) {
61*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
62*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "rbe");
63*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
64*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
65*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
66*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
67*b7c941bbSAndroid Build Coastguard Worker }
68*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP);
69*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
70*b7c941bbSAndroid Build Coastguard Worker if (muxer != nullptr) {
71*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
72*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer constructor accepts read-only file descriptor");
73*b7c941bbSAndroid Build Coastguard Worker isPass = false;
74*b7c941bbSAndroid Build Coastguard Worker }
75*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
76*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
77*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
78*b7c941bbSAndroid Build Coastguard Worker }
79*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfNonSeekableFdIsRejected(JNIEnv *,jobject)80*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfNonSeekableFdIsRejected(JNIEnv*, jobject) {
81*b7c941bbSAndroid Build Coastguard Worker int pipefd[2];
82*b7c941bbSAndroid Build Coastguard Worker if (pipe(pipefd) == -1) {
83*b7c941bbSAndroid Build Coastguard Worker ALOGE("unable to create pipe fd");
84*b7c941bbSAndroid Build Coastguard Worker return false;
85*b7c941bbSAndroid Build Coastguard Worker }
86*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(pipefd[1], AMEDIAMUXER_OUTPUT_FORMAT_THREE_GPP);
87*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
88*b7c941bbSAndroid Build Coastguard Worker if (muxer != nullptr) {
89*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
90*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer constructor accepts non-seekable file descriptor");
91*b7c941bbSAndroid Build Coastguard Worker isPass = false;
92*b7c941bbSAndroid Build Coastguard Worker }
93*b7c941bbSAndroid Build Coastguard Worker close(pipefd[0]);
94*b7c941bbSAndroid Build Coastguard Worker close(pipefd[1]);
95*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
96*b7c941bbSAndroid Build Coastguard Worker }
97*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfInvalidOutputFormatIsRejected(JNIEnv * env,jobject,jstring jdstPath)98*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfInvalidOutputFormatIsRejected(JNIEnv* env, jobject, jstring jdstPath) {
99*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
100*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
101*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
102*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
103*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
104*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
105*b7c941bbSAndroid Build Coastguard Worker }
106*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = nullptr;
107*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
108*b7c941bbSAndroid Build Coastguard Worker
109*b7c941bbSAndroid Build Coastguard Worker muxer = AMediaMuxer_new(fileno(ofp), (OutputFormat)(-1));
110*b7c941bbSAndroid Build Coastguard Worker if (muxer != nullptr) {
111*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
112*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer constructor accepts invalid (negative) output format");
113*b7c941bbSAndroid Build Coastguard Worker isPass = false;
114*b7c941bbSAndroid Build Coastguard Worker muxer = nullptr;
115*b7c941bbSAndroid Build Coastguard Worker }
116*b7c941bbSAndroid Build Coastguard Worker muxer = AMediaMuxer_new(fileno(ofp), (OutputFormat)(LOCAL_AMEDIAMUXER_OUTPUT_FORMAT_LAST + 1));
117*b7c941bbSAndroid Build Coastguard Worker if (muxer != nullptr) {
118*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
119*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer constructor accepts invalid (too large) output format");
120*b7c941bbSAndroid Build Coastguard Worker isPass = false;
121*b7c941bbSAndroid Build Coastguard Worker muxer = nullptr;
122*b7c941bbSAndroid Build Coastguard Worker }
123*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
124*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
125*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
126*b7c941bbSAndroid Build Coastguard Worker }
127*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfInvalidMediaFormatIsRejected(JNIEnv * env,jobject,jstring jdstPath)128*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfInvalidMediaFormatIsRejected(JNIEnv* env, jobject, jstring jdstPath) {
129*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
130*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
131*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
132*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
133*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
134*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
135*b7c941bbSAndroid Build Coastguard Worker }
136*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
137*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
138*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
139*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
140*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds with format that has no mediaType key");
141*b7c941bbSAndroid Build Coastguard Worker isPass = false;
142*b7c941bbSAndroid Build Coastguard Worker }
143*b7c941bbSAndroid Build Coastguard Worker
144*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "text/cea-608");
145*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
146*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds with format whose mediaType is non-compliant");
147*b7c941bbSAndroid Build Coastguard Worker isPass = false;
148*b7c941bbSAndroid Build Coastguard Worker }
149*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
150*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
151*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
152*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
153*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
154*b7c941bbSAndroid Build Coastguard Worker }
155*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfCorruptMediaFormatIsRejected(JNIEnv * env,jobject,jstring jdstPath)156*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfCorruptMediaFormatIsRejected(JNIEnv* env, jobject, jstring jdstPath) {
157*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
158*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
159*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
160*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
161*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
162*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
163*b7c941bbSAndroid Build Coastguard Worker }
164*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
165*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
166*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
167*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_AUDIO_AAC);
168*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, -1);
169*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
170*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds with erroneous key-value pairs in media format");
171*b7c941bbSAndroid Build Coastguard Worker isPass = false;
172*b7c941bbSAndroid Build Coastguard Worker }
173*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
174*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
175*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
176*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
177*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
178*b7c941bbSAndroid Build Coastguard Worker }
179*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfAddTrackSucceedsAfterStart(JNIEnv * env,jobject,jstring jdstPath)180*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfAddTrackSucceedsAfterStart(JNIEnv* env, jobject, jstring jdstPath) {
181*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
182*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
183*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
184*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
185*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
186*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
187*b7c941bbSAndroid Build Coastguard Worker }
188*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
189*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
190*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
191*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
192*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_addTrack(muxer, format) >= 0;
193*b7c941bbSAndroid Build Coastguard Worker isPass &= (AMediaMuxer_start(muxer) == AMEDIA_OK);
194*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
195*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds after muxer.start");
196*b7c941bbSAndroid Build Coastguard Worker isPass = false;
197*b7c941bbSAndroid Build Coastguard Worker }
198*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
199*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
200*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
201*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
202*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
203*b7c941bbSAndroid Build Coastguard Worker }
204*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfAddTrackSucceedsAfterWriteSampleData(JNIEnv * env,jobject,jstring jdstPath)205*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfAddTrackSucceedsAfterWriteSampleData(JNIEnv* env, jobject,
206*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
207*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
208*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
209*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
210*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
211*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
212*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
213*b7c941bbSAndroid Build Coastguard Worker }
214*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
215*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
216*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
217*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
218*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
219*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
220*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
221*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
222*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
223*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds after muxer.writeSampleData");
224*b7c941bbSAndroid Build Coastguard Worker isPass = false;
225*b7c941bbSAndroid Build Coastguard Worker }
226*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
227*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
228*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
229*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
230*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
231*b7c941bbSAndroid Build Coastguard Worker }
232*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfAddTrackSucceedsAfterStop(JNIEnv * env,jobject,jstring jdstPath)233*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfAddTrackSucceedsAfterStop(JNIEnv* env, jobject, jstring jdstPath) {
234*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
235*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
236*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
237*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
238*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
239*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
240*b7c941bbSAndroid Build Coastguard Worker }
241*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
242*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
243*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
244*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
245*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
246*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
247*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
248*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
249*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_stop(muxer) == AMEDIA_OK;
250*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_addTrack(muxer, format) >= 0) {
251*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.addTrack succeeds after muxer.stop");
252*b7c941bbSAndroid Build Coastguard Worker isPass = false;
253*b7c941bbSAndroid Build Coastguard Worker }
254*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
255*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
256*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
257*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
258*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
259*b7c941bbSAndroid Build Coastguard Worker }
260*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfMuxerStartsBeforeAddTrack(JNIEnv * env,jobject,jstring jdstPath)261*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfMuxerStartsBeforeAddTrack(JNIEnv* env, jobject, jstring jdstPath) {
262*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
263*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
264*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
265*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
266*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
267*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
268*b7c941bbSAndroid Build Coastguard Worker }
269*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
270*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
271*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_start(muxer) == AMEDIA_OK) {
272*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.start succeeds before muxer.addTrack");
273*b7c941bbSAndroid Build Coastguard Worker isPass = false;
274*b7c941bbSAndroid Build Coastguard Worker }
275*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
276*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
277*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
278*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
279*b7c941bbSAndroid Build Coastguard Worker }
280*b7c941bbSAndroid Build Coastguard Worker
nativeTestIdempotentStart(JNIEnv * env,jobject,jstring jdstPath)281*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIdempotentStart(JNIEnv* env, jobject, jstring jdstPath) {
282*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
283*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
284*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
285*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
286*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
287*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
288*b7c941bbSAndroid Build Coastguard Worker }
289*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
290*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
291*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
292*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
293*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_addTrack(muxer, format) >= 0;
294*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
295*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_start(muxer) == AMEDIA_OK) {
296*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: double muxer.start succeeds");
297*b7c941bbSAndroid Build Coastguard Worker isPass = false;
298*b7c941bbSAndroid Build Coastguard Worker }
299*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
300*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
301*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
302*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
303*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
304*b7c941bbSAndroid Build Coastguard Worker }
305*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfMuxerStartsAfterWriteSampleData(JNIEnv * env,jobject,jstring jdstPath)306*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfMuxerStartsAfterWriteSampleData(JNIEnv* env, jobject,
307*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
308*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
309*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
310*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
311*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
312*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
313*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
314*b7c941bbSAndroid Build Coastguard Worker }
315*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
316*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
317*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
318*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
319*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
320*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
321*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
322*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
323*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_start(muxer) == AMEDIA_OK) {
324*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.start succeeds after muxer.writeSampleData");
325*b7c941bbSAndroid Build Coastguard Worker isPass = false;
326*b7c941bbSAndroid Build Coastguard Worker }
327*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
328*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
329*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
330*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
331*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
332*b7c941bbSAndroid Build Coastguard Worker }
333*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfMuxerStartsAfterStop(JNIEnv * env,jobject,jstring jdstPath)334*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfMuxerStartsAfterStop(JNIEnv* env, jobject, jstring jdstPath) {
335*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
336*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
337*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
338*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
339*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
340*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
341*b7c941bbSAndroid Build Coastguard Worker }
342*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
343*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
344*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
345*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
346*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
347*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
348*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
349*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
350*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_stop(muxer) == AMEDIA_OK;
351*b7c941bbSAndroid Build Coastguard Worker if (AMediaMuxer_start(muxer) == AMEDIA_OK) {
352*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.start succeeds after muxer.stop");
353*b7c941bbSAndroid Build Coastguard Worker isPass = false;
354*b7c941bbSAndroid Build Coastguard Worker }
355*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
356*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
357*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
358*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
359*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
360*b7c941bbSAndroid Build Coastguard Worker }
361*b7c941bbSAndroid Build Coastguard Worker
nativeTestStopOnANonStartedMuxer(JNIEnv * env,jobject,jstring jdstPath)362*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestStopOnANonStartedMuxer(JNIEnv* env, jobject, jstring jdstPath) {
363*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
364*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
365*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
366*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
367*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
368*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
369*b7c941bbSAndroid Build Coastguard Worker }
370*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
371*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
372*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
373*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
374*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_addTrack(muxer, format) >= 0;
375*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == AMediaMuxer_stop(muxer)) {
376*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.stop succeeds before muxer.start");
377*b7c941bbSAndroid Build Coastguard Worker isPass = false;
378*b7c941bbSAndroid Build Coastguard Worker }
379*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
380*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
381*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
382*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
383*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
384*b7c941bbSAndroid Build Coastguard Worker }
385*b7c941bbSAndroid Build Coastguard Worker
nativeTestIdempotentStop(JNIEnv * env,jobject,jstring jdstPath)386*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIdempotentStop(JNIEnv* env, jobject, jstring jdstPath) {
387*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
388*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
389*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
390*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
391*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
392*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
393*b7c941bbSAndroid Build Coastguard Worker }
394*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
395*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
396*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
397*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
398*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
399*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
400*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
401*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
402*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_stop(muxer) == AMEDIA_OK;
403*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == AMediaMuxer_stop(muxer)) {
404*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: double muxer.stop succeeds");
405*b7c941bbSAndroid Build Coastguard Worker isPass = false;
406*b7c941bbSAndroid Build Coastguard Worker }
407*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
408*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
409*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
410*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
411*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
412*b7c941bbSAndroid Build Coastguard Worker }
413*b7c941bbSAndroid Build Coastguard Worker
nativeTestSimpleStartStop(JNIEnv * env,jobject,jstring jdstPath)414*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestSimpleStartStop(JNIEnv* env, jobject, jstring jdstPath) {
415*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
416*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
417*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
418*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
419*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
420*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
421*b7c941bbSAndroid Build Coastguard Worker }
422*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
423*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
424*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
425*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
426*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
427*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
428*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
429*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_stop(muxer) == AMEDIA_OK;
430*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
431*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
432*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
433*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
434*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
435*b7c941bbSAndroid Build Coastguard Worker }
436*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfWriteSampleDataRejectsInvalidTrackIndex(JNIEnv * env,jobject,jstring jdstPath)437*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfWriteSampleDataRejectsInvalidTrackIndex(JNIEnv* env, jobject,
438*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
439*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
440*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
441*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
442*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
443*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
444*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
445*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
446*b7c941bbSAndroid Build Coastguard Worker }
447*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
448*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
449*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
450*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
451*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
452*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
453*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
454*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == insertPerFrameSubtitles(muxer, 22000, trackID + 1)) {
455*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.writeSampleData succeeds for invalid track ID");
456*b7c941bbSAndroid Build Coastguard Worker isPass = false;
457*b7c941bbSAndroid Build Coastguard Worker }
458*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
459*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
460*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
461*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
462*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
463*b7c941bbSAndroid Build Coastguard Worker }
464*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfWriteSampleDataRejectsInvalidPts(JNIEnv * env,jobject,jstring jdstPath)465*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfWriteSampleDataRejectsInvalidPts(JNIEnv* env, jobject,
466*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
467*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
468*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
469*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
470*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
471*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
472*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
473*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
474*b7c941bbSAndroid Build Coastguard Worker }
475*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
476*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
477*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
478*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
479*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
480*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
481*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
482*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == insertPerFrameSubtitles(muxer, -33000, trackID)) {
483*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.writeSampleData succeeds for invalid pts");
484*b7c941bbSAndroid Build Coastguard Worker isPass = false;
485*b7c941bbSAndroid Build Coastguard Worker }
486*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
487*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
488*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
489*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
490*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
491*b7c941bbSAndroid Build Coastguard Worker }
492*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfWriteSampleDataSucceedsBeforeStart(JNIEnv * env,jobject,jstring jdstPath)493*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfWriteSampleDataSucceedsBeforeStart(JNIEnv* env, jobject,
494*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
495*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
496*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
497*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
498*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
499*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
500*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
501*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
502*b7c941bbSAndroid Build Coastguard Worker }
503*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
504*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
505*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
506*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
507*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
508*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == insertPerFrameSubtitles(muxer, 0, trackID)) {
509*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.writeSampleData succeeds before muxer.start");
510*b7c941bbSAndroid Build Coastguard Worker isPass = false;
511*b7c941bbSAndroid Build Coastguard Worker }
512*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
513*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
514*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
515*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
516*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
517*b7c941bbSAndroid Build Coastguard Worker }
518*b7c941bbSAndroid Build Coastguard Worker
nativeTestIfWriteSampleDataSucceedsAfterStop(JNIEnv * env,jobject,jstring jdstPath)519*b7c941bbSAndroid Build Coastguard Worker static jboolean nativeTestIfWriteSampleDataSucceedsAfterStop(JNIEnv* env, jobject,
520*b7c941bbSAndroid Build Coastguard Worker jstring jdstPath) {
521*b7c941bbSAndroid Build Coastguard Worker bool isPass = true;
522*b7c941bbSAndroid Build Coastguard Worker const char* cdstPath = env->GetStringUTFChars(jdstPath, nullptr);
523*b7c941bbSAndroid Build Coastguard Worker FILE* ofp = fopen(cdstPath, "wbe+");
524*b7c941bbSAndroid Build Coastguard Worker if (ofp == nullptr) {
525*b7c941bbSAndroid Build Coastguard Worker ALOGE("Unable to open file %s", cdstPath);
526*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
527*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(false);
528*b7c941bbSAndroid Build Coastguard Worker }
529*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer* muxer = AMediaMuxer_new(fileno(ofp), AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
530*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* format = AMediaFormat_new();
531*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "application/x-subrip");
532*b7c941bbSAndroid Build Coastguard Worker ssize_t trackID = AMediaMuxer_addTrack(muxer, format);
533*b7c941bbSAndroid Build Coastguard Worker isPass &= trackID >= 0;
534*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_start(muxer) == AMEDIA_OK;
535*b7c941bbSAndroid Build Coastguard Worker isPass &= insertPerFrameSubtitles(muxer, 0, trackID) == AMEDIA_OK;
536*b7c941bbSAndroid Build Coastguard Worker isPass &= AMediaMuxer_stop(muxer) == AMEDIA_OK;
537*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK == insertPerFrameSubtitles(muxer, 33000, trackID)) {
538*b7c941bbSAndroid Build Coastguard Worker ALOGE("error: muxer.writeSampleData succeeds after muxer.stop");
539*b7c941bbSAndroid Build Coastguard Worker isPass = false;
540*b7c941bbSAndroid Build Coastguard Worker }
541*b7c941bbSAndroid Build Coastguard Worker AMediaFormat_delete(format);
542*b7c941bbSAndroid Build Coastguard Worker AMediaMuxer_delete(muxer);
543*b7c941bbSAndroid Build Coastguard Worker fclose(ofp);
544*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(jdstPath, cdstPath);
545*b7c941bbSAndroid Build Coastguard Worker return static_cast<jboolean>(isPass);
546*b7c941bbSAndroid Build Coastguard Worker }
547*b7c941bbSAndroid Build Coastguard Worker
registerAndroidMediaV2CtsMuxerUnitTestApi(JNIEnv * env)548*b7c941bbSAndroid Build Coastguard Worker int registerAndroidMediaV2CtsMuxerUnitTestApi(JNIEnv* env) {
549*b7c941bbSAndroid Build Coastguard Worker const JNINativeMethod methodTable[] = {
550*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfInvalidFdIsRejected", "()Z", (void*)nativeTestIfInvalidFdIsRejected},
551*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfReadOnlyFdIsRejected", "(Ljava/lang/String;)Z",
552*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfReadOnlyFdIsRejected},
553*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfNonSeekableFdIsRejected", "()Z",
554*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfNonSeekableFdIsRejected},
555*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfInvalidOutputFormatIsRejected", "(Ljava/lang/String;)Z",
556*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfInvalidOutputFormatIsRejected},
557*b7c941bbSAndroid Build Coastguard Worker
558*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfInvalidMediaFormatIsRejected", "(Ljava/lang/String;)Z",
559*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfInvalidMediaFormatIsRejected},
560*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfCorruptMediaFormatIsRejected", "(Ljava/lang/String;)Z",
561*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfCorruptMediaFormatIsRejected},
562*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfAddTrackSucceedsAfterStart", "(Ljava/lang/String;)Z",
563*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfAddTrackSucceedsAfterStart},
564*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfAddTrackSucceedsAfterWriteSampleData", "(Ljava/lang/String;)Z",
565*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfAddTrackSucceedsAfterWriteSampleData},
566*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfAddTrackSucceedsAfterStop", "(Ljava/lang/String;)Z",
567*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfAddTrackSucceedsAfterStop},
568*b7c941bbSAndroid Build Coastguard Worker
569*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfMuxerStartsBeforeAddTrack", "(Ljava/lang/String;)Z",
570*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfMuxerStartsBeforeAddTrack},
571*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIdempotentStart", "(Ljava/lang/String;)Z",
572*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIdempotentStart},
573*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfMuxerStartsAfterWriteSampleData", "(Ljava/lang/String;)Z",
574*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfMuxerStartsAfterWriteSampleData},
575*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfMuxerStartsAfterStop", "(Ljava/lang/String;)Z",
576*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfMuxerStartsAfterStop},
577*b7c941bbSAndroid Build Coastguard Worker
578*b7c941bbSAndroid Build Coastguard Worker {"nativeTestStopOnANonStartedMuxer", "(Ljava/lang/String;)Z",
579*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestStopOnANonStartedMuxer},
580*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIdempotentStop", "(Ljava/lang/String;)Z", (void*)nativeTestIdempotentStop},
581*b7c941bbSAndroid Build Coastguard Worker {"nativeTestSimpleStartStop", "(Ljava/lang/String;)Z",
582*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestSimpleStartStop},
583*b7c941bbSAndroid Build Coastguard Worker
584*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfWriteSampleDataRejectsInvalidTrackIndex", "(Ljava/lang/String;)Z",
585*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfWriteSampleDataRejectsInvalidTrackIndex},
586*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfWriteSampleDataRejectsInvalidPts", "(Ljava/lang/String;)Z",
587*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfWriteSampleDataRejectsInvalidPts},
588*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfWriteSampleDataSucceedsBeforeStart", "(Ljava/lang/String;)Z",
589*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfWriteSampleDataSucceedsBeforeStart},
590*b7c941bbSAndroid Build Coastguard Worker {"nativeTestIfWriteSampleDataSucceedsAfterStop", "(Ljava/lang/String;)Z",
591*b7c941bbSAndroid Build Coastguard Worker (void*)nativeTestIfWriteSampleDataSucceedsAfterStop},
592*b7c941bbSAndroid Build Coastguard Worker };
593*b7c941bbSAndroid Build Coastguard Worker jclass c = env->FindClass("android/mediav2/cts/MuxerUnitTest$TestApiNative");
594*b7c941bbSAndroid Build Coastguard Worker return env->RegisterNatives(c, methodTable, sizeof(methodTable) / sizeof(JNINativeMethod));
595*b7c941bbSAndroid Build Coastguard Worker }
596