给出android av中使用kKeyIsSyncFrame 的完整代码
时间: 2024-03-27 16:41:37 浏览: 62
以下是使用android av中的kKeyIsSyncFrame的完整代码示例:
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/Utils.h>
...
sp<MediaExtractor> extractor = MediaExtractor::Create(
env, env->NewStringUTF(sourceUrl.c_str()));
// Find and select the first video track.
sp<MetaData> videoFormat;
ssize_t videoTrackIndex = -1;
for (size_t i = 0; i < extractor->countTracks(); ++i) {
videoFormat = extractor->getTrackFormat(i);
const char *mime;
if (!videoFormat->findCString(kKeyMIMEType, &mime)) {
continue;
}
if (!strncasecmp(mime, "video/", 6)) {
videoTrackIndex = i;
break;
}
}
if (videoTrackIndex < 0) {
// No video track found.
return;
}
extractor->selectTrack(videoTrackIndex);
// Create a MediaCodec for decoding.
sp<MediaCodec> decoder = MediaCodec::CreateByType(
env, videoFormat.get(), false /* encoder */, NULL /* crypto */);
decoder->configure(videoFormat.get(),
surface /* output surface */,
NULL /* crypto */,
0 /* flags */);
decoder->start();
// Start decoding.
bool sawInputEOS = false;
bool sawOutputEOS = false;
while (!sawOutputEOS) {
if (!sawInputEOS) {
ssize_t inputBufIndex = decoder->dequeueInputBuffer(kTimeoutUs);
if (inputBufIndex >= 0) {
sp<MediaCodecBuffer> inputBuf = decoder->getInputBuffer(inputBufIndex);
size_t sampleSize = extractor->readSampleData(inputBuf->data(), inputBuf->size());
if (sampleSize < 0) {
sawInputEOS = true;
sampleSize = 0;
}
int64_t presentationTimeUs = extractor->getSampleTime();
int32_t flags = extractor->getSampleFlags();
if (flags & MediaExtractor::SAMPLE_FLAG_SYNC) {
inputBuf->meta_data()->setInt32(kKeyIsSyncFrame, 1);
} else {
inputBuf->meta_data()->setInt32(kKeyIsSyncFrame, 0);
}
decoder->queueInputBuffer(
inputBufIndex,
0 /* offset */,
sampleSize,
presentationTimeUs,
flags);
extractor->advance();
}
}
MediaCodecBuffer *outBuf = NULL;
MediaCodec::BufferInfo outInfo;
ssize_t outBufIndex = decoder->dequeueOutputBuffer(&outBuf, &outInfo, kTimeoutUs);
if (outBufIndex >= 0) {
if (outInfo.flags & MediaCodec::BUFFER_FLAG_END_OF_STREAM) {
sawOutputEOS = true;
}
decoder->releaseOutputBuffer(outBufIndex, outInfo.size != 0);
} else if (outBufIndex == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
// The output buffers have changed, we need to get a new set.
} else if (outBufIndex == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
// The output format has changed, we need to use the new format and
// possibly resize the video output surface.
sp<MetaData> newFormat = decoder->getOutputFormat();
decoder->configure(newFormat.get(), surface, NULL, 0);
}
}
// Stop and release the decoder.
decoder->stop();
decoder->release();
在上述代码中,当从MediaExtractor
读取视频帧时,如果该帧是同步帧(也就是关键帧),则会将kKeyIsSyncFrame
元数据设置为1,否则设置为0,以便在解码后进行使用。
相关推荐


















