Android c++屏幕实时录制

本文介绍了一个将Android系统自带的screenrecord命令代码整理成C++库的方法,以便于在native程序中调用,获取屏幕实时的H264码流。后续计划实现码流从Android推送到PC并进行解码显示的功能。
摘要由CSDN通过智能技术生成

功能:沿用Android cmds下的screenrecord代码,整理成可以供native程序调用的一个可以获取实时screen h264码流的一个库,分享一下!!

头文件screenrecord.h

#include <stdint.h>

class IScreenRecordCallback
{
public:
	virtual ~IScreenRecordCallback(){}
	virtual void onData(void* pData, size_t size) = 0;
	//virtual void onCodecConfig(void* pData, size_t size) = 0;
};

class ScreenRecordImp;
class ScreenRecord
{
public:
	ScreenRecord();
	~ScreenRecord();
	int start(IScreenRecordCallback* callback);
	void stop();
private:
	ScreenRecordImp* m_pImp;
};


实现文件:screenrecord.cpp


#include "screenrecord.h"
#include <iostream>
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <utils/Errors.h>
#include <utils/Thread.h>
#include <utils/Timers.h>
#include <media/openmax/OMX_IVCommon.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/ISurfaceComposer.h>
#include <ui/DisplayInfo.h>

#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaErrors.h>
#include <media/ICrypto.h>
#include <utils/Errors.h>

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include <sys/wait.h>

using namespace android;

using namespace std;
#define LOG_TAG "LibScreenRecord"
//#define LOG_NDEBUG 0
static const uint32_t kFallbackWidth = 1280;        // 720p
static const uint32_t kFallbackHeight = 720;

class ScreenRecordImp
{
public:
	ScreenRecordImp();
	int start(IScreenRecordCallback* callback);
	void stop();
private:
	bool isDeviceRotated(int orientation);
	status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec,
        sp<IGraphicBufferProducer>* pBufferProducer);
	status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo,
        const sp<IGraphicBufferProducer>& bufferProducer,
        sp<IBinder>* pDisplayHandle);
	status_t setDisplayProjection(const sp<IBinder>& dpy,
        const DisplayInfo& mainDpyInfo);
	status_t runEncoder(const sp<MediaCodec>& encoder, IScreenRecordCallback* callback, sp<IBinder>& mainDpy, sp<IBinder>& dpy, uint8_t orientation);
private:
	bool mRotate;                // rotate 90 degrees
	//bool mSizeSpecified;         // was size explicitly requested?
	uint32_t mVideoWidth;            // default width+height
	uint32_t mVideoHeight;
	uint32_t mBitRate;
	//uint32_t mTimeLimitSec;
	bool mStopRequested;
};

ScreenRecord::ScreenRecord()
{
	m_pImp = new ScreenRecordImp;
}

ScreenRecord::~ScreenRecord()
{
	stop();
	delete m_pImp;
	m_pImp = NULL;
}


int ScreenRecord::start(IScreenRecordCallback* callback)
{
	return m_pImp->start(callback);
}
void ScreenRecord::stop()
{
	m_pImp->stop();
}
	

ScreenRecordImp::ScreenRecordImp():mRotate(false),
							mVideoWidth(0),
							mVideoHeight(0),
							mBitRate(4000000),         // 4Mbp
							mStopRequested(true)
{
}


bool ScreenRecordImp::isDeviceRotated(int orientation) {
    return orientation != DISPLAY_ORIENTATION_0 &&
            orientation != DISPLAY_ORIENTATION_180;
}

status_t ScreenRecordImp::setDisplayProjection(const sp<IBinder>& dpy,
        const DisplayInfo& mainDpyInfo) {
    status_t err;

    // Set the region of the layer stack we're interested in, which in our
    // case is "all of it".  If the app is rotated (so that the width of the
    // app is based on the height of the display), reverse width/height.
    bool deviceRotated = isDeviceRotated(mainDpyInfo.orientation);
    uint32_t sourceWidth, sourceHeight;
    if (!deviceRotated) {
        sourceWidth = mainDpyInfo.w;
        sourceHeight = mainDpyInfo.h;
    } else {
        ALOGV("using rotated width/height");
        sourceHeight = mainDpyInfo.w;
        sourceWidth = mainDpyInfo.h;
    }
    Rect layerStackRect(sourceWidth, sourceHeight);

    // We need to preserve the aspect ratio of the display.
    float displayAspect = (float) sourceHeight / (float) sourceWidth;


    // Set the way we map the output onto the display surface (which will
    // be e.g. 1280x720 for a 720p video).  The rect is interpreted
    // post-rotation, so if the displa
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>