87 lines
2.5 KiB
Objective-C
87 lines
2.5 KiB
Objective-C
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#import <VideoToolbox/VideoToolbox.h>
|
|
#import <CoreMedia/CoreMedia.h>
|
|
|
|
class H264Encoder {
|
|
public:
|
|
H264Encoder();
|
|
~H264Encoder();
|
|
|
|
// Initialize encoder
|
|
// @param width: frame width
|
|
// @param height: frame height
|
|
// @param fps: target frame rate
|
|
// @param bitrate: target bitrate in kbps (0 = auto)
|
|
bool open(int width, int height, int fps, int bitrate = 0);
|
|
|
|
// Close encoder and release resources
|
|
void close();
|
|
|
|
// Check if encoder is open
|
|
bool isOpen() const { return m_session != nullptr; }
|
|
|
|
// Encode a frame
|
|
// @param bgra: BGRA pixel data (bottom-up or top-down)
|
|
// @param bpp: bits per pixel (32 for BGRA)
|
|
// @param stride: bytes per row
|
|
// @param width: frame width
|
|
// @param height: frame height
|
|
// @param outData: pointer to receive encoded data pointer
|
|
// @param outSize: pointer to receive encoded data size
|
|
// @param flipVertical: true if image is bottom-up (BMP format)
|
|
// @return: encoded size, or 0 on failure
|
|
int encode(const uint8_t* bgra, uint8_t bpp, uint32_t stride,
|
|
uint32_t width, uint32_t height,
|
|
uint8_t** outData, uint32_t* outSize,
|
|
bool flipVertical = true);
|
|
|
|
// Force next frame to be keyframe
|
|
void forceKeyframe() { m_forceKeyframe = true; }
|
|
|
|
// Get last error message
|
|
const char* getLastError() const { return m_lastError; }
|
|
|
|
private:
|
|
// VideoToolbox compression callback
|
|
static void compressionCallback(void* outputCallbackRefCon,
|
|
void* sourceFrameRefCon,
|
|
OSStatus status,
|
|
VTEncodeInfoFlags infoFlags,
|
|
CMSampleBufferRef sampleBuffer);
|
|
|
|
// Process encoded sample buffer
|
|
void processSampleBuffer(CMSampleBufferRef sampleBuffer);
|
|
|
|
// Convert BGRA to I420 (YUV)
|
|
void convertBGRAtoI420(const uint8_t* bgra, uint32_t stride,
|
|
uint32_t width, uint32_t height,
|
|
bool flipVertical);
|
|
|
|
private:
|
|
VTCompressionSessionRef m_session;
|
|
|
|
int m_width;
|
|
int m_height;
|
|
int m_fps;
|
|
int m_bitrate;
|
|
|
|
// YUV buffers
|
|
std::vector<uint8_t> m_yPlane;
|
|
std::vector<uint8_t> m_uPlane;
|
|
std::vector<uint8_t> m_vPlane;
|
|
|
|
// Output buffer
|
|
std::vector<uint8_t> m_outputBuffer;
|
|
std::mutex m_outputMutex;
|
|
|
|
// State
|
|
std::atomic<bool> m_forceKeyframe;
|
|
int64_t m_frameCount;
|
|
char m_lastError[256];
|
|
};
|