summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Writer.cpp
diff options
context:
space:
mode:
authorLubin Yin <lubiny@codeaurora.org>2015-07-29 12:31:09 +0800
committerSatish Kamuju <skamuj@codeaurora.org>2015-10-06 17:33:49 +0530
commitae614d22fd87feb1857e8041978ab2c38cfaa16e (patch)
treeb6fe7142b7c1dbfcba5250f3fa36991da61a0f33 /media/libstagefright/MPEG4Writer.cpp
parent9079a349be70e7c7a5fa8e5bf98be22eeb054db7 (diff)
downloadframeworks_av-ae614d22fd87feb1857e8041978ab2c38cfaa16e.zip
frameworks_av-ae614d22fd87feb1857e8041978ab2c38cfaa16e.tar.gz
frameworks_av-ae614d22fd87feb1857e8041978ab2c38cfaa16e.tar.bz2
libstagefright: MPEG4Writer: Add support for HEVC muxing
Changes done to enable HEVC muxing - writing HVCC atom - configure HEVC encoder Fix HEVC flag initialization Check for HEVC for single track usecase Change-Id: I1757d0c442e7cc3ef251431f220395131a1eb4ec
Diffstat (limited to 'media/libstagefright/MPEG4Writer.cpp')
-rw-r--r--media/libstagefright/MPEG4Writer.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 8af2615..86ca2a1 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -38,6 +38,7 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/Utils.h>
#include <media/mediarecorder.h>
+#include <stagefright/AVExtensions.h>
#include <cutils/properties.h>
#include "include/ESDS.h"
@@ -91,6 +92,7 @@ public:
bool isAvc() const { return mIsAvc; }
bool isAudio() const { return mIsAudio; }
bool isMPEG4() const { return mIsMPEG4; }
+ bool isHEVC() const { return mIsHEVC; }
void addChunkOffset(off64_t offset);
int32_t getTrackId() const { return mTrackId; }
status_t dump(int fd, const Vector<String16>& args) const;
@@ -236,6 +238,7 @@ private:
bool mIsAvc;
bool mIsAudio;
bool mIsMPEG4;
+ bool mIsHEVC;
int32_t mTrackId;
int64_t mTrackDurationUs;
int64_t mMaxChunkDurationUs;
@@ -386,6 +389,7 @@ MPEG4Writer::MPEG4Writer(int fd)
mAreGeoTagsAvailable(false),
mStartTimeOffsetMs(-1),
mMetaKeys(new AMessage()),
+ mIsVideoHEVC(false),
mIsAudioAMR(false) {
addDeviceMeta();
@@ -464,6 +468,8 @@ const char *MPEG4Writer::Track::getFourCCForMime(const char *mime) {
return "s263";
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
return "avc1";
+ } else {
+ return AVUtils::get()->HEVCMuxerUtils().getFourCCForMime(mime);
}
} else {
ALOGE("Track (%s) other than video or audio is not supported", mime);
@@ -489,6 +495,7 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
const char *mime;
source->getFormat()->findCString(kKeyMIMEType, &mime);
bool isAudio = !strncasecmp(mime, "audio/", 6);
+ bool isVideo = !strncasecmp(mime, "video/", 6);
if (Track::getFourCCForMime(mime) == NULL) {
ALOGE("Unsupported mime '%s'", mime);
return ERROR_UNSUPPORTED;
@@ -497,6 +504,10 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime));
+ if (isVideo) {
+ mIsVideoHEVC = AVUtils::get()->HEVCMuxerUtils().isVideoHEVC(mime);
+ }
+
// At this point, we know the track to be added is either
// video or audio. Thus, we only need to check whether it
// is an audio track or not (if it is not, then it must be
@@ -1051,7 +1062,9 @@ void MPEG4Writer::writeFtypBox(MetaData *param) {
beginBox("ftyp");
int32_t fileType;
- if (mIsAudioAMR || (param && param->findInt32(kKeyFileType, &fileType) &&
+ if (mIsVideoHEVC) {
+ AVUtils::get()->HEVCMuxerUtils().writeHEVCFtypBox(this);
+ } else if (mIsAudioAMR || (param && param->findInt32(kKeyFileType, &fileType) &&
fileType != OUTPUT_FORMAT_MPEG_4)) {
writeFourcc("3gp4");
writeInt32(0);
@@ -1468,6 +1481,12 @@ MPEG4Writer::Track::Track(
mIsAudio = !strncasecmp(mime, "audio/", 6);
mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
+ mIsHEVC = AVUtils::get()->HEVCMuxerUtils().isVideoHEVC(mime);
+
+ if (mIsHEVC) {
+ AVUtils::get()->HEVCMuxerUtils().getHEVCCodecSpecificDataFromInputFormatIfPossible(
+ mMeta, &mCodecSpecificData, &mCodecSpecificDataSize, &mGotAllCodecSpecificData);
+ }
setTimeScale();
}
@@ -1663,7 +1682,7 @@ void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
while (!chunk->mSamples.empty()) {
List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
- off64_t offset = chunk->mTrack->isAvc()
+ off64_t offset = (chunk->mTrack->isAvc() || chunk->mTrack->isHEVC())
? addLengthPrefixedSample_l(*it)
: addSample_l(*it);
@@ -2244,6 +2263,13 @@ status_t MPEG4Writer::Track::threadEntry() {
(const uint8_t *)buffer->data()
+ buffer->range_offset(),
buffer->range_length());
+ } else if (mIsHEVC) {
+ status_t err = AVUtils::get()->HEVCMuxerUtils().makeHEVCCodecSpecificData(
+ (const uint8_t *)buffer->data() + buffer->range_offset(),
+ buffer->range_length(), &mCodecSpecificData, &mCodecSpecificDataSize);
+ if ((status_t)OK != err) {
+ return err;
+ }
}
buffer->release();
@@ -2263,10 +2289,10 @@ status_t MPEG4Writer::Track::threadEntry() {
buffer->release();
buffer = NULL;
- if (mIsAvc) StripStartcode(copy);
+ if (mIsAvc || mIsHEVC) StripStartcode(copy);
size_t sampleSize = copy->range_length();
- if (mIsAvc) {
+ if (mIsAvc || mIsHEVC) {
if (mOwner->useNalLengthFour()) {
sampleSize += 4;
} else {
@@ -2466,7 +2492,7 @@ status_t MPEG4Writer::Track::threadEntry() {
trackProgressStatus(timestampUs);
}
if (!hasMultipleTracks) {
- off64_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
+ off64_t offset = (mIsAvc || mIsHEVC)? mOwner->addLengthPrefixedSample_l(copy)
: mOwner->addSample_l(copy);
uint32_t count = (mOwner->use32BitFileOffset()
@@ -2723,7 +2749,8 @@ status_t MPEG4Writer::Track::checkCodecSpecificData() const {
CHECK(mMeta->findCString(kKeyMIMEType, &mime));
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
- !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
+ !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
+ mIsHEVC) {
if (!mCodecSpecificData ||
mCodecSpecificDataSize <= 0) {
ALOGE("Missing codec specific data");
@@ -2832,9 +2859,16 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
writeD263Box();
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
writeAvccBox();
+ } else if (mIsHEVC) {
+ AVUtils::get()->HEVCMuxerUtils().writeHvccBox(mOwner, mCodecSpecificData,
+ mCodecSpecificDataSize,
+ mOwner->useNalLengthFour());
+ }
+
+ if (!mIsHEVC) {
+ writePaspBox();
}
- writePaspBox();
mOwner->endBox(); // mp4v, s263 or avc1
}