Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
updating project source codes
Browse files Browse the repository at this point in the history
  • Loading branch information
grancia committed May 22, 2018
1 parent 84a394e commit adfcd48
Show file tree
Hide file tree
Showing 50 changed files with 9,968 additions and 0 deletions.
Binary file not shown.
409 changes: 409 additions & 0 deletions Source Codes/FBCaptureSDK/Encoder/AMDEncoder.cpp

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions Source Codes/FBCaptureSDK/Encoder/AMDEncoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/****************************************************************************************************************
Filename : AMDEncoder.h
Content : AMD Encoder implementation for creating h264 format video
Created : Jan 26, 2017
Authors : Homin Lee
Copyright :
****************************************************************************************************************/

#pragma once
#include <stdio.h>
#include <tchar.h>
#include <codecvt>
#include <wincodec.h>
#include "AMD/common/AMFFactory.h"
#include "AMD/include/components/VideoEncoderVCE.h"
#include "AMD/include/components/VideoEncoderHEVC.h"
#include "AMD/common/Thread.h"
#include "AMD/common/AMFSTL.h"
#include "ScreenGrab.h"
#include "Log.h"
#include "Common.h"
#include "ScopedCOMPtr.h"

#define START_TIME_PROPERTY L"StartTimeProperty" // custom property ID to store submission time in a frame - all custom properties are copied from input to output
#define MILLISEC_TIME 10000
#define ENABLE_4K 1

//--------------------------------------------------------------------------------------------------------------
// *** SAFE_RELEASE macro
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(a) if (a) { a->Release(); a= NULL; }
#endif

using namespace FBCapture::Common;
using namespace Directx;
using namespace std;

namespace FBCapture {
namespace Video {

class PollingThread : public amf::AMFThread {
protected:
amf::AMFContextPtr context_ = nullptr;
amf::AMFComponentPtr encoder_ = nullptr;
FILE *file_ = nullptr;
public:
PollingThread(amf::AMFContext *context, amf::AMFComponent *encoder, const wchar_t *pFileName);
~PollingThread();
virtual void Run();
};

class AMDEncoder {
public:
FBCAPTURE_STATUS initAMDEncodingSession();
FBCAPTURE_STATUS encodeMain(const void* texturePtr, const wstring& fullSavePath, int bitrate, int fps, bool needFlipping);
FBCAPTURE_STATUS flushInputTextures();
FBCAPTURE_STATUS saveScreenShot(const void* texturePtr, const wstring& fullSavePath, bool is360);
AMDEncoder(ID3D11Device* device); // Constructor
virtual ~AMDEncoder();
protected:
PollingThread* thread_ = nullptr;

wchar_t *codec_ = nullptr;

// initialize AMF
amf::AMFContextPtr context_ = nullptr;
amf::AMFComponentPtr encoder_ = nullptr;
amf::AMFSurfacePtr surfaceIn_ = nullptr;

amf::AMF_MEMORY_TYPE memoryTypeIn_;
amf::AMF_SURFACE_FORMAT formatIn_;

amf_int32 widthIn_ = 0;
amf_int32 heightIn_ = 0;
amf_int32 frameRateIn_ = 0;
amf_int64 bitRateIn_ = 0; // in bits, 5MBit
bool maximumSpeed_ = false;
bool encodingConfigInitiated_ = false;

// DX 11 interfaces
ID3D11Texture2D* fromTexturePtr_ = nullptr;
ScopedCOMPtr<ID3D11Device> device_ = nullptr;
D3D11_BOX dirtyRegion_ = {};
D3D11_TEXTURE2D_DESC globalTexDesc_ = {};

protected:
FBCAPTURE_STATUS initializeEncodingComponents(const wstring& fullSavePath, int bitrate, int fps);
FBCAPTURE_STATUS fillSurface(amf::AMFSurface *surface);
FBCAPTURE_STATUS createD3D11Resources(ID3D11Texture2D* texture);
};
}
}
138 changes: 138 additions & 0 deletions Source Codes/FBCaptureSDK/Encoder/AudioBuffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "AudioBuffer.h"

#include "log.h"
#include "Common.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits>
#include <assert.h>

#define CHECK_HRESULT(hr, message) \
if (FAILED(hr)) \
{ \
LOG(message ": %x.\n", hr); \
return; \
} \
else \
void(0)

using namespace FBCapture::Common;

namespace FBCapture {
namespace Audio {
AudioBuffer::AudioBuffer() : buffers_(nullptr), numBuffers_(0), mixBuffer_(nullptr) {}

AudioBuffer::~AudioBuffer() {
releaseBuffers();
}

void AudioBuffer::releaseBuffers() {

if (buffers_ == nullptr)
return;

for (int i = 0; i < numBuffers_; ++i) {
Buffer& buff = buffers_[i];
if (buff.data_ != nullptr) {
free(buff.data_);
}
}

delete[] buffers_;
buffers_ = nullptr;

if (mixBuffer_ != nullptr) {
free(mixBuffer_);
mixBuffer_ = nullptr;
}
}

void AudioBuffer::initizalize(int numBuffers) {
numBuffers_ = numBuffers;
buffers_ = new Buffer[numBuffers];
memset(buffers_, 0, numBuffers * sizeof(Buffer));
mixBuffer_ = static_cast<int16_t*>(malloc(kMIX_BUFFER_LENGTH * kSTEREO * sizeof(int16_t)));
}

void AudioBuffer::initializeBuffer(int index, int channelCount) {
if (index >= numBuffers_) {
return; // out of bounds!
}

Buffer& buff = buffers_[index];

buff.channelCount_ = channelCount;
}

void AudioBuffer::write(int index, const int16_t* data, size_t lengthFrames) {
if (index >= numBuffers_) {
return; // out of bounds!
}

Buffer& buff = buffers_[index];
assert(buff.positionFrames_ >= 0);

const int requiredLengthFrames = buff.positionFrames_ + lengthFrames;

if (requiredLengthFrames > (1024 * 500)) {
return; // sanity check!
}

if (buff.length_ < requiredLengthFrames) {
buff.data_ = static_cast<int16_t*>(realloc(buff.data_, requiredLengthFrames * buff.channelCount_ * sizeof(int16_t)));
buff.length_ = requiredLengthFrames;
}

memcpy(buff.data_ + (buff.positionFrames_ * buff.channelCount_), data, lengthFrames * buff.channelCount_ * sizeof(int16_t));
buff.positionFrames_ += lengthFrames;

assert(buff.positionFrames_ >= 0);
}

void AudioBuffer::getBuffer(const int16_t** buffer, size_t* length, bool enabledAudioCapture, bool enabledMicCapture) {
int len = kMIX_BUFFER_LENGTH;

for (int i = 0; i < numBuffers_; ++i) {
if (buffers_[i].positionFrames_ < len) {
assert(buffers_[i].positionFrames_ >= 0);
len = buffers_[i].positionFrames_;
}
}

if (len <= 0) {
return;
}

memset(mixBuffer_, 0, kMIX_BUFFER_LENGTH * sizeof(int16_t));

for (int i = 0; i < numBuffers_; ++i) {
Buffer& buff = buffers_[i];
for (int frame = 0; frame < len; ++frame) {
for (int chan = 0; chan < kSTEREO; ++chan) {
if (enabledAudioCapture && !enabledMicCapture) { // Mix buffer for input audio data only
if (i == BufferIndex_Headphones) {
mixBuffer_[(frame * kSTEREO) + chan] += buff.data_[(frame * buff.channelCount_) + chan % buff.channelCount_];
}
} else if (!enabledAudioCapture && enabledMicCapture) { // Mix buffer for output audio data only
if (i == BufferIndex_Microphone) {
mixBuffer_[(frame * kSTEREO) + chan] += buff.data_[(frame * buff.channelCount_) + chan % buff.channelCount_];
}
} else if (enabledAudioCapture && enabledMicCapture) { // Mix buffer for both of input and output audio data
mixBuffer_[(frame * kSTEREO) + chan] += buff.data_[(frame * buff.channelCount_) + chan % buff.channelCount_];
}
}
}

// Compact the buffer
memmove(buff.data_, buff.data_ + (len * buff.channelCount_), (buff.length_ - len) * sizeof(int16_t) * buff.channelCount_);
buff.positionFrames_ -= len;
assert(buff.positionFrames_ >= 0);
}

*length = len * kSTEREO;
*buffer = mixBuffer_;
}
}
}
60 changes: 60 additions & 0 deletions Source Codes/FBCaptureSDK/Encoder/AudioBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/****************************************************************************************************************
Filename : AdaptiveResampler.h
Content : A adaptive resampling ringbuffer to sync to input signals at different and varying sample rates
Created : June 16, 2017
Authors : Pete Stirling
Copyright :
****************************************************************************************************************/

#pragma once

#define NOMINMAX
#include <Audioclient.h>
#include <stdint.h>

namespace FBCapture {
namespace Audio {

enum BufferIndex {
BufferIndex_Headphones = 0,
BufferIndex_Microphone,
BufferIndex_Max
};

enum BufferNums {
No_Device = 0,
Output_Device_Only,
Input_Output_Device
};

class AudioBuffer {
public:
AudioBuffer();
~AudioBuffer();

void initizalize(int numBuffers);
void initializeBuffer(int index, int channelCount); // WAVEFORMATEX *bufferFormat, IAudioClock* clock);
void write(int index, const int16_t* data, size_t length);
void getBuffer(const int16_t** buffer, size_t* length, bool enabledAudioCapture, bool enabledMicCapture);
void releaseBuffers();

private:
struct Buffer {
int16_t* data_;
int channelCount_;
int length_;
int positionFrames_;
};

Buffer* buffers_;
int numBuffers_;
int16_t* mixBuffer_;
static const size_t kMIX_BUFFER_LENGTH = 4096; // PAS
static const int kSTEREO = 2;
};

}
}
Loading

0 comments on commit adfcd48

Please sign in to comment.