BOOL setStreamInfo()

in src/JNI/com/amazonaws/kinesis/video/producer/jni/Parameters.cpp [326:718]


BOOL setStreamInfo(JNIEnv* env, jobject streamInfo, PStreamInfo pStreamInfo)
{
    STATUS retStatus = STATUS_SUCCESS;
    jmethodID methodId = NULL;
    jbyteArray byteArray = NULL;
    jbyte* bufferPtr = NULL;
    jsize arrayLen = 0;
    UINT32 trackInfoCount = 0;
    const char *retChars;

    CHECK(env != NULL && streamInfo != NULL && pStreamInfo != NULL);

    // Load StreamInfo
    jclass cls = env->GetObjectClass(streamInfo);
    if (cls == NULL) {
        DLOGE("Failed to create StreamInfo class.");
        CHK(FALSE, STATUS_INVALID_OPERATION);
    }

    // Retrieve the methods and call it
    methodId = env->GetMethodID(cls, "getVersion", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getVersion");
    } else {
        pStreamInfo->version = env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getName");
    } else {
        jstring retString = (jstring) env->CallObjectMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);

        if (retString != NULL) {
            retChars = env->GetStringUTFChars(retString, NULL);
            STRNCPY(pStreamInfo->name, retChars, MAX_STREAM_NAME_LEN + 1);

            // Just in case - null terminate the copied string
            pStreamInfo->name[MAX_STREAM_NAME_LEN] = '\0';

            env->ReleaseStringUTFChars(retString, retChars);
        } else {
            pStreamInfo->name[0] = '\0';
        }
    }

    methodId = env->GetMethodID(cls, "getStreamingType", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getStreamingType");
    } else {
        pStreamInfo->streamCaps.streamingType = (STREAMING_TYPE) env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getContentType", "()Ljava/lang/String;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getContentType");
    } else {
        jstring retString = (jstring) env->CallObjectMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);

        if (retString != NULL) {
            retChars = env->GetStringUTFChars(retString, NULL);
            STRNCPY(pStreamInfo->streamCaps.contentType, retChars, MAX_CONTENT_TYPE_LEN + 1);
            pStreamInfo->streamCaps.contentType[MAX_CONTENT_TYPE_LEN] = '\0';
            env->ReleaseStringUTFChars(retString, retChars);
        } else {
            pStreamInfo->streamCaps.contentType[0] = '\0';
        }
    }

    methodId = env->GetMethodID(cls, "getKmsKeyId", "()Ljava/lang/String;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getKmsKeyId");
    } else {
        jstring retString = (jstring) env->CallObjectMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);

        if (retString != NULL) {
            retChars = env->GetStringUTFChars(retString, NULL);
            STRNCPY(pStreamInfo->kmsKeyId, retChars, MAX_ARN_LEN + 1);
            pStreamInfo->kmsKeyId[MAX_ARN_LEN] = '\0';
            env->ReleaseStringUTFChars(retString, retChars);
        } else {
            pStreamInfo->kmsKeyId[0] = '\0';
        }
    }

    methodId = env->GetMethodID(cls, "getRetentionPeriod", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getRetentionPeriod");
    } else {
        pStreamInfo->retention = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isAdaptive", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isAdaptive");
    } else {
        pStreamInfo->streamCaps.adaptive = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getMaxLatency", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getMaxLatency");
    } else {
        pStreamInfo->streamCaps.maxLatency = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getFragmentDuration", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getFragmentDuration");
    } else {
        pStreamInfo->streamCaps.fragmentDuration = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isKeyFrameFragmentation", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isKeyFrameFragmentation");
    } else {
        pStreamInfo->streamCaps.keyFrameFragmentation = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isFrameTimecodes", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isFrameTimecodes");
    } else {
        pStreamInfo->streamCaps.frameTimecodes = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isAbsoluteFragmentTimes", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isAbsoluteFragmentTimes");
    } else {
        pStreamInfo->streamCaps.absoluteFragmentTimes = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isFragmentAcks", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isFragmentAcks");
    } else {
        pStreamInfo->streamCaps.fragmentAcks = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isRecoverOnError", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isRecoverOnError");
    } else {
        pStreamInfo->streamCaps.recoverOnError = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "isRecalculateMetrics", "()Z");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id isRecalculateMetrics");
    } else {
        pStreamInfo->streamCaps.recalculateMetrics = env->CallBooleanMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getNalAdaptationFlags", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getNalAdaptationFlags");
    } else {
        pStreamInfo->streamCaps.nalAdaptationFlags = env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    // Initialize to NULL first in case of failures
    pStreamInfo->streamCaps.segmentUuid = NULL;
    methodId = env->GetMethodID(cls, "getSegmentUuidBytes", "()[B");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getSegmentUuidBytes");
    } else {
        byteArray = (jbyteArray) env->CallObjectMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);

        if (byteArray != NULL) {
            // Extract the bits from the byte buffer
            bufferPtr = env->GetByteArrayElements(byteArray, NULL);
            arrayLen = env->GetArrayLength(byteArray);

            // Ensure we have at least UUID size
            CHK(arrayLen == MKV_SEGMENT_UUID_LEN, STATUS_INVALID_ARG_LEN);

            // Allocate a temp storage
            pStreamInfo->streamCaps.segmentUuid = (PBYTE) MEMALLOC(MKV_SEGMENT_UUID_LEN);
            CHK(pStreamInfo->streamCaps.segmentUuid != NULL, STATUS_NOT_ENOUGH_MEMORY);

            // Copy the bits
            MEMCPY(pStreamInfo->streamCaps.segmentUuid, bufferPtr, MKV_SEGMENT_UUID_LEN);

            // Release the buffer
            env->ReleaseByteArrayElements(byteArray, bufferPtr, JNI_ABORT);
        }
    }

    methodId = env->GetMethodID(cls, "getTrackInfoCount", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTrackInfoCount");
    } else {
        trackInfoCount = (UINT32) env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    CHECK_EXT(trackInfoCount > 0, "TrackInfo count should be greater than 0");
    pStreamInfo->streamCaps.trackInfoCount = trackInfoCount;
    pStreamInfo->streamCaps.trackInfoList = (PTrackInfo) MEMALLOC(trackInfoCount * SIZEOF(TrackInfo));
    MEMSET(pStreamInfo->streamCaps.trackInfoList, 0, SIZEOF(TrackInfo) * trackInfoCount);
    CHK(pStreamInfo->streamCaps.trackInfoList != NULL, STATUS_NOT_ENOUGH_MEMORY);

    methodId = env->GetMethodID(cls, "getTrackInfoVersion", "(I)I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTrackInfoVersion");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            pStreamInfo->streamCaps.trackInfoList[i].version = (UINT64) env->CallIntMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);
        }
    }

    methodId = env->GetMethodID(cls, "getTrackName", "(I)Ljava/lang/String;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTrackName");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            jstring retString = (jstring) env->CallObjectMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);

            if (retString != NULL) {
                retChars = env->GetStringUTFChars(retString, NULL);
                STRNCPY(pStreamInfo->streamCaps.trackInfoList[i].trackName, retChars, MKV_MAX_TRACK_NAME_LEN + 1);
                pStreamInfo->streamCaps.trackInfoList[i].trackName[MKV_MAX_TRACK_NAME_LEN] = '\0';
                env->ReleaseStringUTFChars(retString, retChars);
            } else {
                pStreamInfo->streamCaps.trackInfoList[i].trackName[0] = '\0';
            }
        }
    }

    methodId = env->GetMethodID(cls, "getCodecId", "(I)Ljava/lang/String;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getCodecId");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            jstring retString = (jstring) env->CallObjectMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);

            if (retString != NULL) {
                retChars = env->GetStringUTFChars(retString, NULL);
                STRNCPY(pStreamInfo->streamCaps.trackInfoList[i].codecId, retChars, MKV_MAX_CODEC_ID_LEN + 1);
                pStreamInfo->streamCaps.trackInfoList[i].codecId[MKV_MAX_CODEC_ID_LEN] = '\0';
                env->ReleaseStringUTFChars(retString, retChars);
            } else {
                pStreamInfo->streamCaps.trackInfoList[i].codecId[0] = '\0';
            }
        }
    }

    methodId = env->GetMethodID(cls, "getCodecPrivateData", "(I)[B");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getCodecPrivateData");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            byteArray = (jbyteArray) env->CallObjectMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);

            if (byteArray != NULL) {
                // Extract the bits from the byte buffer
                bufferPtr = env->GetByteArrayElements(byteArray, NULL);
                arrayLen = env->GetArrayLength(byteArray);

                // Allocate a temp storage
                pStreamInfo->streamCaps.trackInfoList[i].codecPrivateDataSize = (UINT32) arrayLen;
                pStreamInfo->streamCaps.trackInfoList[i].codecPrivateData = (PBYTE) MEMALLOC(arrayLen);
                CHK(pStreamInfo->streamCaps.trackInfoList[i].codecPrivateData != NULL, STATUS_NOT_ENOUGH_MEMORY);

                // Copy the bits
                MEMCPY(pStreamInfo->streamCaps.trackInfoList[i].codecPrivateData, bufferPtr, arrayLen);

                // Release the buffer
                env->ReleaseByteArrayElements(byteArray, bufferPtr, JNI_ABORT);
            } else {
                pStreamInfo->streamCaps.trackInfoList[i].codecPrivateDataSize = 0;
                pStreamInfo->streamCaps.trackInfoList[i].codecPrivateData = NULL;
            }
        }
    }

    methodId = env->GetMethodID(cls, "getTrackInfoType", "(I)I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTrackInfoType");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            pStreamInfo->streamCaps.trackInfoList[i].trackType = (MKV_TRACK_INFO_TYPE) env->CallIntMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);
        }
    }

    methodId = env->GetMethodID(cls, "getTrackId", "(I)J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTrackId");
    } else {
        for(UINT32 i = 0; i < trackInfoCount; ++i) {
            pStreamInfo->streamCaps.trackInfoList[i].trackId = (UINT64) env->CallLongMethod(streamInfo, methodId, i);
            CHK_JVM_EXCEPTION(env);
        }
    }

    methodId = env->GetMethodID(cls, "getAvgBandwidthBps", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getAvgBandwidthBps");
    } else {
        pStreamInfo->streamCaps.avgBandwidthBps = env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getFrameRate", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getFrameRate");
    } else {
        pStreamInfo->streamCaps.frameRate = env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getBufferDuration", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getBufferDuration");
    } else {
        pStreamInfo->streamCaps.bufferDuration = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getReplayDuration", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getReplayDuration");
    } else {
        pStreamInfo->streamCaps.replayDuration = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getConnectionStalenessDuration", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getConnectionStalenessDuration");
    } else {
        pStreamInfo->streamCaps.connectionStalenessDuration = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    methodId = env->GetMethodID(cls, "getTimecodeScale", "()J");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTimecodeScale");
    } else {
        pStreamInfo->streamCaps.timecodeScale = env->CallLongMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

    // Set the tags to empty first
    pStreamInfo->tagCount = 0;
    pStreamInfo->tags = NULL;
    methodId = env->GetMethodID(cls, "getTags", "()[Lcom/amazonaws/kinesisvideo/producer/Tag;");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getTags");
    } else {
        jobjectArray array = (jobjectArray) env->CallObjectMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);

        if (!setTags(env, array, &pStreamInfo->tags, &pStreamInfo->tagCount)) {
            DLOGW("Failed getting/setting tags.");
        }
    }

    methodId = env->GetMethodID(cls, "getFrameOrderMode", "()I");
    if (methodId == NULL) {
        DLOGW("Couldn't find method id getFrameOrderMode");
    } else {
        pStreamInfo->streamCaps.frameOrderingMode = (FRAME_ORDER_MODE) env->CallIntMethod(streamInfo, methodId);
        CHK_JVM_EXCEPTION(env);
    }

CleanUp:
    return STATUS_FAILED(retStatus) ? FALSE : TRUE;
}