本文demo下载地址
https://gitee.com/lincocc/MediaCodecPro
本程序的硬件编码是基于下文的示例代码修改,再加上live555和libyuv
Android硬编解码接口MediaCodec使用完全解析
这篇文件写得很好,值得一看
live555和libyuv的编译可以看我前面几篇文章的介绍,编译的部分就不介绍了,主要是讲下怎么把camera图像传递给live555服务器
camera预览数据被MediaCodec编码成H264码流后,放到一个阻塞队列里面,然后jni里rtsp获取数据时,回调getFrame方法,从队列里面取数据
首先,需要定义一个DeviceSource.cpp,源码里有示例,这里直接复制一个放到jni根目录,同时把DeviceSource.hh也复制到jni/include目录,这里为不混淆,改名为DeviceSource1
//DeviceSource1.cpp
#include "DeviceSource1.hh"
#include <GroupsockHelper.hh> // for "gettimeofday()"
static int8_t buf[8192*4];
static int count = 0;
DeviceSource1*
DeviceSource1::createNew(UsageEnvironment& env) {
return new DeviceSource1(env);
}
EventTriggerId DeviceSource1::eventTriggerId = 0;
unsigned DeviceSource1::referenceCount = 0;
DeviceSource1::DeviceSource1(UsageEnvironment& env)
: FramedSource(env) {
if (referenceCount == 0) {
// Any global initialization of the device would be done here:
//%%% TO BE WRITTEN %%%
}
++referenceCount;
if (eventTriggerId == 0) {
eventTriggerId = envir().taskScheduler().createEventTrigger(deliverFrame0);
}
}
DeviceSource1::~DeviceSource1() {
--referenceCount;
if (referenceCount == 0) {
envir().taskScheduler().deleteEventTrigger(eventTriggerId);
eventTriggerId = 0;
}
}
void DeviceSource1::doGetNextFrame() {
count = getNextFrame(buf);
deliverFrame();
}
void DeviceSource1::deliverFrame0(void* clientData) {
((DeviceSource1*)clientData)->deliverFrame();
}
void DeviceSource1::deliverFrame() {
if (!isCurrentlyAwaitingData()) return; // we're not ready for the data yet
u_int8_t* newFrameDataStart = (u_int8_t*)buf; //%%% TO BE WRITTEN %%%
unsigned newFrameSize = static_cast<unsigned int>(count); //%%% TO BE WRITTEN %%%
// Deliver the data here:
if (newFrameSize > fMaxSize) {
fFrameS