Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5ae9aa7 authored by Robert Shih's avatar Robert Shih Committed by Android (Google) Code Review
Browse files

Merge "Stagefright: added WebM muxer."

parents 3a90f284 343947ab
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ struct MediaAdapter;
struct MediaBuffer;
struct MediaSource;
struct MetaData;
struct MPEG4Writer;
struct MediaWriter;

// MediaMuxer is used to mux multiple tracks into a video. Currently, we only
// support a mp4 file as the output.
@@ -44,6 +44,7 @@ public:
    // OutputFormat is updated.
    enum OutputFormat {
        OUTPUT_FORMAT_MPEG_4 = 0,
        OUTPUT_FORMAT_WEBM   = 1,
        OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
    };

@@ -115,7 +116,8 @@ public:
                             int64_t timeUs, uint32_t flags) ;

private:
    sp<MPEG4Writer> mWriter;
    const OutputFormat mFormat;
    sp<MediaWriter> mWriter;
    Vector< sp<MediaAdapter> > mTrackList;  // Each track has its MediaAdapter.
    sp<MetaData> mFileMeta;  // Metadata for the whole file.

+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ LOCAL_STATIC_LIBRARIES := \
        libstagefright_color_conversion \
        libstagefright_aacenc \
        libstagefright_matroska \
        libstagefright_webm \
        libstagefright_timedtext \
        libvpx \
        libwebm \
+23 −4
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaMuxer"

#include "webm/WebmWriter.h"

#include <utils/Log.h>

#include <media/stagefright/MediaMuxer.h>
@@ -36,19 +39,30 @@
namespace android {

MediaMuxer::MediaMuxer(const char *path, OutputFormat format)
    : mState(UNINITIALIZED) {
    : mFormat(format),
      mState(UNINITIALIZED) {
    if (format == OUTPUT_FORMAT_MPEG_4) {
        mWriter = new MPEG4Writer(path);
    } else if (format == OUTPUT_FORMAT_WEBM) {
        mWriter = new WebmWriter(path);
    }

    if (mWriter != NULL) {
        mFileMeta = new MetaData;
        mState = INITIALIZED;
    }

}

MediaMuxer::MediaMuxer(int fd, OutputFormat format)
    : mState(UNINITIALIZED) {
    : mFormat(format),
      mState(UNINITIALIZED) {
    if (format == OUTPUT_FORMAT_MPEG_4) {
        mWriter = new MPEG4Writer(fd);
    } else if (format == OUTPUT_FORMAT_WEBM) {
        mWriter = new WebmWriter(fd);
    }

    if (mWriter != NULL) {
        mFileMeta = new MetaData;
        mState = INITIALIZED;
    }
@@ -109,8 +123,13 @@ status_t MediaMuxer::setLocation(int latitude, int longitude) {
        ALOGE("setLocation() must be called before start().");
        return INVALID_OPERATION;
    }
    if (mFormat != OUTPUT_FORMAT_MPEG_4) {
        ALOGE("setLocation() is only supported for .mp4 output.");
        return INVALID_OPERATION;
    }

    ALOGV("Setting location: latitude = %d, longitude = %d", latitude, longitude);
    return mWriter->setGeoData(latitude, longitude);
    return static_cast<MPEG4Writer*>(mWriter.get())->setGeoData(latitude, longitude);
}

status_t MediaMuxer::start() {
+23 −0
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CPPFLAGS += -D__STDINT_LIMITS \
                  -Werror

LOCAL_SRC_FILES:= EbmlUtil.cpp        \
                  WebmElement.cpp     \
                  WebmFrame.cpp       \
                  WebmFrameThread.cpp \
                  WebmWriter.cpp


LOCAL_C_INCLUDES += $(TOP)/frameworks/av/include

LOCAL_SHARED_LIBRARIES += libstagefright_foundation \
                          libstagefright \
                          libutils \
                          liblog

LOCAL_MODULE:= libstagefright_webm

include $(BUILD_STATIC_LIBRARY)
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdint.h>

namespace {

// Table for Seal's algorithm for Number of Trailing Zeros. Hacker's Delight
// online, Figure 5-18 (http://www.hackersdelight.org/revisions.pdf)
// The entries whose value is -1 are never referenced.
int NTZ_TABLE[] = {
    32,  0,  1, 12,  2,  6, -1, 13,   3, -1,  7, -1, -1, -1, -1, 14,
    10,  4, -1, -1,  8, -1, -1, 25,  -1, -1, -1, -1, -1, 21, 27, 15,
    31, 11,  5, -1, -1, -1, -1, -1,   9, -1, -1, 24, -1, -1, 20, 26,
    30, -1, -1, -1, -1, 23, -1, 19,  29, -1, 22, 18, 28, 17, 16, -1
};

int numberOfTrailingZeros32(int32_t i) {
    uint32_t u = (i & -i) * 0x0450FBAF;
    return NTZ_TABLE[(u) >> 26];
}

uint64_t highestOneBit(uint64_t n) {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    n |= (n >> 32);
    return n - (n >> 1);
}

uint64_t _powerOf2(uint64_t u) {
    uint64_t powerOf2 = highestOneBit(u);
    return powerOf2 ? powerOf2 : 1;
}

// Based on Long.numberOfTrailingZeros in Long.java
int numberOfTrailingZeros(uint64_t u) {
    int32_t low = u;
    return low !=0 ? numberOfTrailingZeros32(low)
                   : 32 + numberOfTrailingZeros32((int32_t) (u >> 32));
}
}

namespace webm {

// Encode the id and/or size of an EBML element bytes by setting a leading length descriptor bit:
//
//   1xxxxxxx                                                                - 1-byte values
//   01xxxxxx xxxxxxxx                                                       -
//   001xxxxx xxxxxxxx xxxxxxxx                                              -
//   0001xxxx xxxxxxxx xxxxxxxx xxxxxxxx                                     - ...
//   00001xxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx                            -
//   000001xx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx                   -
//   0000001x xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx          -
//   00000001 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx - 8-byte values
//
// This function uses the least the number of bytes possible.
uint64_t encodeUnsigned(uint64_t u) {
    uint64_t powerOf2 = _powerOf2(u);
    if (u + 1 == powerOf2 << 1)
        powerOf2 <<= 1;
    int shiftWidth = (7 + numberOfTrailingZeros(powerOf2)) / 7 * 7;
    long lengthDescriptor = 1 << shiftWidth;
    return lengthDescriptor | u;
}

// Like above but pads the input value with leading zeros up to the specified width. The length
// descriptor is calculated based on width.
uint64_t encodeUnsigned(uint64_t u, int width) {
    int shiftWidth = 7 * width;
    uint64_t lengthDescriptor = 1;
    lengthDescriptor <<= shiftWidth;
    return lengthDescriptor | u;
}

// Calculate the length of an EBML coded id or size from its length descriptor.
int sizeOf(uint64_t u) {
    uint64_t powerOf2 = _powerOf2(u);
    int unsignedLength = numberOfTrailingZeros(powerOf2) / 8 + 1;
    return unsignedLength;
}

// Serialize an EBML coded id or size in big-endian order.
int serializeCodedUnsigned(uint64_t u, uint8_t* bary) {
    int unsignedLength = sizeOf(u);
    for (int i = unsignedLength - 1; i >= 0; i--) {
        bary[i] = u & 0xff;
        u >>= 8;
    }
    return unsignedLength;
}

}
Loading