108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen/*
208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * Copyright (C) 2014 The Android Open Source Project
308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen *
408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * you may not use this file except in compliance with the License.
608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * You may obtain a copy of the License at
708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen *
808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen *
1008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * Unless required by applicable law or agreed to in writing, software
1108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
1208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * See the License for the specific language governing permissions and
1408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen * limitations under the License.
1508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen */
1608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
17c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260Marco Nelissen//#define LOG_NDEBUG 0
1808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#define LOG_TAG "NdkMediaMuxer"
1908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
2008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
2108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include "NdkMediaMuxer.h"
2208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include "NdkMediaCodec.h"
2308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include "NdkMediaFormatPriv.h"
2408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
2508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
2608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <utils/Log.h>
2708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <utils/StrongPointer.h>
2808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <media/stagefright/foundation/ABuffer.h>
2908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <media/stagefright/foundation/AMessage.h>
3008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <media/stagefright/MetaData.h>
3108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <media/stagefright/MediaMuxer.h>
3208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <media/IMediaHTTPService.h>
3308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <android_runtime/AndroidRuntime.h>
3408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <android_util_Binder.h>
3508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
3608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen#include <jni.h>
3708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
3808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissenusing namespace android;
3908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
40e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translate_error(status_t err) {
4108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    if (err == OK) {
42e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_OK;
4308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    }
4408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    ALOGE("sf error code: %d", err);
45e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_ERROR_UNKNOWN;
4608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
4708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
4808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissenstruct AMediaMuxer {
4908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    sp<MediaMuxer> mImpl;
5008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
5108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen};
5208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
5308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissenextern "C" {
5408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
553425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
5608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco NelissenAMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format) {
5708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    ALOGV("ctor");
5808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    AMediaMuxer *mData = new AMediaMuxer();
5908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    mData->mImpl = new MediaMuxer(fd, (android::MediaMuxer::OutputFormat)format);
6008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return mData;
6108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
6208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
633425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
64e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_delete(AMediaMuxer *muxer) {
6508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    ALOGV("dtor");
6608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    delete muxer;
67e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
6808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
6908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
703425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
71e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_setLocation(AMediaMuxer *muxer, float latitude, float longtitude) {
7208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(muxer->mImpl->setLocation(latitude * 10000, longtitude * 10000));
7308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
7408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
753425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
76e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_setOrientationHint(AMediaMuxer *muxer, int degrees) {
7708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(muxer->mImpl->setOrientationHint(degrees));
7808aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
7908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
803425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
8108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissenssize_t AMediaMuxer_addTrack(AMediaMuxer *muxer, const AMediaFormat *format) {
8208aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    sp<AMessage> msg;
8308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    AMediaFormat_getFormat(format, &msg);
8408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(muxer->mImpl->addTrack(msg));
8508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
8608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
873425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
88e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_start(AMediaMuxer *muxer) {
8908aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(muxer->mImpl->start());
9008aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
9108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
923425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
93e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_stop(AMediaMuxer *muxer) {
9408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(muxer->mImpl->stop());
9508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
9608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
973425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
98e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer,
990e03cf07deeda10c573657479591dcfbf1efca56Marco Nelissen        size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo *info) {
1000e03cf07deeda10c573657479591dcfbf1efca56Marco Nelissen    sp<ABuffer> buf = new ABuffer((void*)(data + info->offset), info->size);
10108aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen    return translate_error(
1020e03cf07deeda10c573657479591dcfbf1efca56Marco Nelissen            muxer->mImpl->writeSampleData(buf, trackIdx, info->presentationTimeUs, info->flags));
10308aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen}
10408aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
10508aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
10608aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen} // extern "C"
10708aaabe87960c04ecac180db1fe88b5a7bc2ed3bMarco Nelissen
108