summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-08-04 14:16:20 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-08-04 14:16:20 -0700
commit979c6c9720d8861375570b81222e55c43bb2838d (patch)
tree439273d62401b78354d6723dcaed780b5de354f1 /media/libstagefright
parent39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8 (diff)
parent2b3b9b2237468db96d9bb49dccd2b2a1eb8ae2db (diff)
downloadframeworks_av-979c6c9720d8861375570b81222e55c43bb2838d.zip
frameworks_av-979c6c9720d8861375570b81222e55c43bb2838d.tar.gz
frameworks_av-979c6c9720d8861375570b81222e55c43bb2838d.tar.bz2
Merge "Don't return a decoder error if the encoded stream does not start with SPS/PPS." into gingerbread
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/codecs/avc/dec/AVCDecoder.cpp276
-rw-r--r--media/libstagefright/include/AVCDecoder.h3
2 files changed, 149 insertions, 130 deletions
diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
index 050e3da..7154ba5 100644
--- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
+++ b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
@@ -53,7 +53,9 @@ AVCDecoder::AVCDecoder(const sp<MediaSource> &source)
mNumSamplesOutput(0),
mPendingSeekTimeUs(-1),
mPendingSeekMode(MediaSource::ReadOptions::SEEK_CLOSEST_SYNC),
- mTargetTimeUs(-1) {
+ mTargetTimeUs(-1),
+ mSPSSeen(false),
+ mPPSSeen(false) {
memset(mHandle, 0, sizeof(tagAVCHandle));
mHandle->AVCObject = NULL;
mHandle->userData = this;
@@ -165,6 +167,8 @@ status_t AVCDecoder::start(MetaData *) {
mPendingSeekTimeUs = -1;
mPendingSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
mTargetTimeUs = -1;
+ mSPSSeen = false;
+ mPPSSeen = false;
mStarted = true;
return OK;
@@ -314,184 +318,196 @@ status_t AVCDecoder::read(
if (res != AVCDEC_SUCCESS) {
LOGE("cannot determine nal type");
- } else switch (nalType) {
- case AVC_NALTYPE_SPS:
- {
- res = PVAVCDecSeqParamSet(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
-
- if (res != AVCDEC_SUCCESS) {
- break;
- }
+ } else if (nalType == AVC_NALTYPE_SPS || nalType == AVC_NALTYPE_PPS
+ || (mSPSSeen && mPPSSeen)) {
+ switch (nalType) {
+ case AVC_NALTYPE_SPS:
+ {
+ mSPSSeen = true;
+
+ res = PVAVCDecSeqParamSet(
+ mHandle, const_cast<uint8_t *>(fragPtr),
+ fragSize);
- AVCDecObject *pDecVid = (AVCDecObject *)mHandle->AVCObject;
+ if (res != AVCDEC_SUCCESS) {
+ break;
+ }
- int32_t width =
- (pDecVid->seqParams[0]->pic_width_in_mbs_minus1 + 1) * 16;
+ AVCDecObject *pDecVid = (AVCDecObject *)mHandle->AVCObject;
- int32_t height =
- (pDecVid->seqParams[0]->pic_height_in_map_units_minus1 + 1) * 16;
+ int32_t width =
+ (pDecVid->seqParams[0]->pic_width_in_mbs_minus1 + 1) * 16;
- int32_t crop_left, crop_right, crop_top, crop_bottom;
- if (pDecVid->seqParams[0]->frame_cropping_flag)
- {
- crop_left = 2 * pDecVid->seqParams[0]->frame_crop_left_offset;
- crop_right =
- width - (2 * pDecVid->seqParams[0]->frame_crop_right_offset + 1);
+ int32_t height =
+ (pDecVid->seqParams[0]->pic_height_in_map_units_minus1 + 1) * 16;
- if (pDecVid->seqParams[0]->frame_mbs_only_flag)
+ int32_t crop_left, crop_right, crop_top, crop_bottom;
+ if (pDecVid->seqParams[0]->frame_cropping_flag)
{
- crop_top = 2 * pDecVid->seqParams[0]->frame_crop_top_offset;
- crop_bottom =
- height -
- (2 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
+ crop_left = 2 * pDecVid->seqParams[0]->frame_crop_left_offset;
+ crop_right =
+ width - (2 * pDecVid->seqParams[0]->frame_crop_right_offset + 1);
+
+ if (pDecVid->seqParams[0]->frame_mbs_only_flag)
+ {
+ crop_top = 2 * pDecVid->seqParams[0]->frame_crop_top_offset;
+ crop_bottom =
+ height -
+ (2 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
+ }
+ else
+ {
+ crop_top = 4 * pDecVid->seqParams[0]->frame_crop_top_offset;
+ crop_bottom =
+ height -
+ (4 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
+ }
+ } else {
+ crop_bottom = height - 1;
+ crop_right = width - 1;
+ crop_top = crop_left = 0;
}
- else
- {
- crop_top = 4 * pDecVid->seqParams[0]->frame_crop_top_offset;
- crop_bottom =
- height -
- (4 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
+
+ int32_t aligned_width = (crop_right - crop_left + 1 + 15) & ~15;
+ int32_t aligned_height = (crop_bottom - crop_top + 1 + 15) & ~15;
+
+ int32_t oldWidth, oldHeight;
+ CHECK(mFormat->findInt32(kKeyWidth, &oldWidth));
+ CHECK(mFormat->findInt32(kKeyHeight, &oldHeight));
+
+ if (oldWidth != aligned_width || oldHeight != aligned_height) {
+ mFormat->setInt32(kKeyWidth, aligned_width);
+ mFormat->setInt32(kKeyHeight, aligned_height);
+
+ err = INFO_FORMAT_CHANGED;
+ } else {
+ *out = new MediaBuffer(0);
+ err = OK;
}
- } else {
- crop_bottom = height - 1;
- crop_right = width - 1;
- crop_top = crop_left = 0;
+ break;
}
- int32_t aligned_width = (crop_right - crop_left + 1 + 15) & ~15;
- int32_t aligned_height = (crop_bottom - crop_top + 1 + 15) & ~15;
+ case AVC_NALTYPE_PPS:
+ {
+ mPPSSeen = true;
- int32_t oldWidth, oldHeight;
- CHECK(mFormat->findInt32(kKeyWidth, &oldWidth));
- CHECK(mFormat->findInt32(kKeyHeight, &oldHeight));
+ res = PVAVCDecPicParamSet(
+ mHandle, const_cast<uint8_t *>(fragPtr),
+ fragSize);
- if (oldWidth != aligned_width || oldHeight != aligned_height) {
- mFormat->setInt32(kKeyWidth, aligned_width);
- mFormat->setInt32(kKeyHeight, aligned_height);
+ if (res != AVCDEC_SUCCESS) {
+ break;
+ }
- err = INFO_FORMAT_CHANGED;
- } else {
*out = new MediaBuffer(0);
- err = OK;
- }
- break;
- }
-
- case AVC_NALTYPE_PPS:
- {
- res = PVAVCDecPicParamSet(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
- if (res != AVCDEC_SUCCESS) {
+ err = OK;
break;
}
- *out = new MediaBuffer(0);
+ case AVC_NALTYPE_SLICE:
+ case AVC_NALTYPE_IDR:
+ {
+ res = PVAVCDecodeSlice(
+ mHandle, const_cast<uint8_t *>(fragPtr),
+ fragSize);
- err = OK;
- break;
- }
+ if (res == AVCDEC_PICTURE_OUTPUT_READY) {
+ int32_t index;
+ int32_t Release;
+ AVCFrameIO Output;
+ Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
- case AVC_NALTYPE_SLICE:
- case AVC_NALTYPE_IDR:
- {
- res = PVAVCDecodeSlice(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
+ CHECK_EQ(PVAVCDecGetOutput(mHandle, &index, &Release, &Output),
+ AVCDEC_SUCCESS);
- if (res == AVCDEC_PICTURE_OUTPUT_READY) {
- int32_t index;
- int32_t Release;
- AVCFrameIO Output;
- Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
+ CHECK(index >= 0);
+ CHECK(index < (int32_t)mFrames.size());
- CHECK_EQ(PVAVCDecGetOutput(mHandle, &index, &Release, &Output),
- AVCDEC_SUCCESS);
+ MediaBuffer *mbuf = mFrames.editItemAt(index);
- CHECK(index >= 0);
- CHECK(index < (int32_t)mFrames.size());
+ bool skipFrame = false;
- MediaBuffer *mbuf = mFrames.editItemAt(index);
+ if (mTargetTimeUs >= 0) {
+ int64_t timeUs;
+ CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
+ CHECK(timeUs <= mTargetTimeUs);
- bool skipFrame = false;
+ if (timeUs < mTargetTimeUs) {
+ // We're still waiting for the frame with the matching
+ // timestamp and we won't return the current one.
+ skipFrame = true;
- if (mTargetTimeUs >= 0) {
- int64_t timeUs;
- CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
- CHECK(timeUs <= mTargetTimeUs);
+ LOGV("skipping frame at %lld us", timeUs);
+ } else {
+ LOGV("found target frame at %lld us", timeUs);
- if (timeUs < mTargetTimeUs) {
- // We're still waiting for the frame with the matching
- // timestamp and we won't return the current one.
- skipFrame = true;
+ mTargetTimeUs = -1;
+ }
+ }
- LOGV("skipping frame at %lld us", timeUs);
+ if (!skipFrame) {
+ *out = mbuf;
+ (*out)->set_range(0, (*out)->size());
+ (*out)->add_ref();
} else {
- LOGV("found target frame at %lld us", timeUs);
-
- mTargetTimeUs = -1;
+ *out = new MediaBuffer(0);
}
+
+ // Do _not_ release input buffer yet.
+
+ releaseFragment = false;
+ err = OK;
+ break;
}
- if (!skipFrame) {
- *out = mbuf;
- (*out)->set_range(0, (*out)->size());
- (*out)->add_ref();
- } else {
+ if (res == AVCDEC_PICTURE_READY || res == AVCDEC_SUCCESS) {
*out = new MediaBuffer(0);
+
+ err = OK;
+ } else {
+ LOGV("failed to decode frame (res = %d)", res);
}
+ break;
+ }
- // Do _not_ release input buffer yet.
+ case AVC_NALTYPE_SEI:
+ {
+ res = PVAVCDecSEI(
+ mHandle, const_cast<uint8_t *>(fragPtr),
+ fragSize);
+
+ if (res != AVCDEC_SUCCESS) {
+ break;
+ }
+
+ *out = new MediaBuffer(0);
- releaseFragment = false;
err = OK;
break;
}
- if (res == AVCDEC_PICTURE_READY || res == AVCDEC_SUCCESS) {
+ case AVC_NALTYPE_AUD:
+ case AVC_NALTYPE_FILL:
+ {
*out = new MediaBuffer(0);
err = OK;
- } else {
- LOGV("failed to decode frame (res = %d)", res);
+ break;
}
- break;
- }
-
- case AVC_NALTYPE_SEI:
- {
- res = PVAVCDecSEI(
- mHandle, const_cast<uint8_t *>(fragPtr),
- fragSize);
- if (res != AVCDEC_SUCCESS) {
+ default:
+ {
+ LOGE("Should not be here, unknown nalType %d", nalType);
+ CHECK(!"Should not be here");
break;
}
-
- *out = new MediaBuffer(0);
-
- err = OK;
- break;
- }
-
- case AVC_NALTYPE_AUD:
- case AVC_NALTYPE_FILL:
- {
- *out = new MediaBuffer(0);
-
- err = OK;
- break;
}
+ } else {
+ // We haven't seen SPS or PPS yet.
- default:
- {
- LOGE("Should not be here, unknown nalType %d", nalType);
- CHECK(!"Should not be here");
- break;
- }
+ *out = new MediaBuffer(0);
+ err = OK;
}
if (releaseFragment) {
diff --git a/media/libstagefright/include/AVCDecoder.h b/media/libstagefright/include/AVCDecoder.h
index 7810171..898c90a 100644
--- a/media/libstagefright/include/AVCDecoder.h
+++ b/media/libstagefright/include/AVCDecoder.h
@@ -62,6 +62,9 @@ private:
int64_t mTargetTimeUs;
+ bool mSPSSeen;
+ bool mPPSSeen;
+
void addCodecSpecificData(const uint8_t *data, size_t size);
static int32_t ActivateSPSWrapper(