MediaCodec通过C++ 解码MP4视频完整代码例子
时间: 2023-12-12 07:06:06 浏览: 415
以下是一个简单的示例代码,展示了如何使用MediaCodec解码MP4视频文件。
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaFormat.h>
#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define VIDEO_FRAMERATE 30
#define VIDEO_BITRATE 2000000
#define MP4_FILE "/sdcard/test.mp4"
int main(int argc, char** argv) {
AMediaExtractor* extractor = AMediaExtractor_new();
AMediaExtractor_setDataSource(extractor, MP4_FILE);
int track_count = AMediaExtractor_getTrackCount(extractor);
AMediaFormat* format = NULL;
int video_track_index = -1;
for (int i = 0; i < track_count; i++) {
format = AMediaExtractor_getTrackFormat(extractor, i);
const char* mime_type = NULL;
AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime_type);
if (!strncmp(mime_type, "video/", 6)) {
video_track_index = i;
break;
}
}
if (video_track_index == -1) {
printf("No video track found in %s\n", MP4_FILE);
return -1;
}
AMediaExtractor_selectTrack(extractor, video_track_index);
AMediaCodec* codec = AMediaCodec_createDecoderByType(mime_type);
AMediaCodec_configure(codec, format, NULL, NULL, 0);
AMediaCodec_start(codec);
AMediaCodecBufferInfo buffer_info;
ssize_t sample_size = 0;
uint8_t* input_buffer = NULL;
uint8_t* output_buffer = NULL;
size_t input_buffer_size = 0;
size_t output_buffer_size = 0;
while (true) {
sample_size = AMediaExtractor_readSampleData(extractor, input_buffer, input_buffer_size);
if (sample_size < 0) {
break;
}
int flags = AMediaExtractor_getSampleFlags(extractor);
int64_t presentation_time_us = AMediaExtractor_getSampleTime(extractor);
int input_buffer_index = AMediaCodec_dequeueInputBuffer(codec, -1);
if (input_buffer_index >= 0) {
input_buffer = AMediaCodec_getInputBuffer(codec, input_buffer_index, &input_buffer_size);
memcpy(input_buffer, input_buffer, sample_size);
AMediaCodec_queueInputBuffer(codec, input_buffer_index, 0, sample_size, presentation_time_us, flags);
AMediaExtractor_advance(extractor);
}
int output_buffer_index = AMediaCodec_dequeueOutputBuffer(codec, &buffer_info, -1);
if (output_buffer_index >= 0) {
output_buffer = AMediaCodec_getOutputBuffer(codec, output_buffer_index, &output_buffer_size);
AMediaCodec_releaseOutputBuffer(codec, output_buffer_index, true);
}
}
AMediaCodec_stop(codec);
AMediaCodec_delete(codec);
AMediaExtractor_delete(extractor);
return 0;
}
```
这个示例代码使用了Android NDK中的MediaCodec API,可以在Android平台上运行。它首先通过MediaExtractor获取到视频轨道信息,然后创建一个解码器,将视频轨道的MIME类型传递给解码器,配置解码器参数,启动解码器,循环从输入流中读取数据,将数据传递给解码器进行解码,获取解码后的数据并处理。
阅读全文