Here is my CaptureFrame class. Not cricket::CapturedFrame. I want to transfer my data from CaptureFrame to webrtc::VideoFrame.
I don't know how to transfer data to webrtc::VideoFrame. Can you give me some examples? Thank you. yh.
/*
* tavarua_data_structure.h
*
* Created on: Dec 22, 2017
* Author: yh
*/
#ifndef TAVARUA_DATA_STRUCTURE_H_
#define TAVARUA_DATA_STRUCTURE_H_
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include "utils/buffer.h"
#include "utils/tqueue.h"
#include "utils/timestamp.h"
enum TAVARUA_FMT {
TAVARUA_PIX_FMT_NONE = 0xFF00,
TAVARUA_PIX_FMT_MJPEG,
TAVARUA_PIX_FMT_PNG,
TAVARUA_PIX_FMT_H264,
TAVARUA_PIX_FMT_VP8,
TAVARUA_PIX_FMT_VP9,
TAVARUA_PIX_FMT_MPEG4,
TAVARUA_PIX_FMT_YUV420P,
TAVARUA_PIX_FMT_YUV422P,
TAVARUA_PIX_FMT_YUYV422,
TAVARUA_PIX_FMT_UYVY422,
TAVARUA_PIX_FMT_BGRA,
TAVARUA_AUDIO_PCM,
TAVARUA_AUDIO_AAC,
TAVARUA_AUDIO_G711,
TAVARUA_AUDIO_OPUS
};
class CaptureFrame {
public:
static void *operator new(size_t size) {
return malloc(size);
}
static void operator delete(void *block) {
free(block);
}
union{
size_t width;
size_t sample_rate;
};
union{
size_t height;
size_t channel;
};
size_t pix_fmt;
buffer frame; // a big enough buffer for store frame
size_t frame_size; // the real size of frame, the "frame.size()" is not equal to frame_size
// always save the below three "time" variables in microsecondsto be portable
int64_t timestamp;
int64_t rtc_timestamp;
CaptureFrame(size_t w=0, size_t h=0, size_t fmt=TAVARUA_PIX_FMT_NONE):
width(w), height(h), pix_fmt(fmt), frame(), frame_size(0), timestamp(us_timestamp::now()), rtc_timestamp(0){
}
CaptureFrame(size_t w, size_t h, size_t fmt, buffer b):
width(w), height(h), pix_fmt(fmt), frame(b), frame_size(b.size()), timestamp(us_timestamp::now()), rtc_timestamp(0){
}
CaptureFrame(size_t w, size_t h, size_t fmt, buffer b, int64_t ts, int64_t rtc_ts=0):
width(w), height(h), pix_fmt(fmt), frame(b), frame_size(b.size()), timestamp(ts), rtc_timestamp(rtc_ts){
}
~CaptureFrame() {}
bool operator ==(const CaptureFrame& cf) const {
return (width == cf.width) &&
(height == cf.height) &&
(pix_fmt == cf.pix_fmt) &&
(timestamp == cf.timestamp ) &&
(frame == cf.frame);
}
bool operator !=(const CaptureFrame& cf) const {
return (width != cf.width) ||
(height != cf.height) ||
(pix_fmt != cf.pix_fmt) ||
(timestamp != cf.timestamp) ||
(frame != cf.frame);
}
operator bool () const {
return (pix_fmt != TAVARUA_PIX_FMT_NONE) && (frame.is_valid());
}
size_t size() {
return frame.is_valid() ? frame.size() : 0;
}
};
class CircularCaptureQueue {
protected:
tqueue< shared_ptr<CaptureFrame> > freeCaptureFrameq;
public:
CircularCaptureQueue() : freeCaptureFrameq(10) {}
virtual ~CircularCaptureQueue() { freeCaptureFrameq.clear(); }
virtual void freeFrameBuffer(shared_ptr<CaptureFrame> freeFrame) {
if(freeFrame) freeCaptureFrameq.push_back(freeFrame);
}
virtual shared_ptr<CaptureFrame> getFrameBuffer(size_t size, size_t w=0, size_t h=0, size_t fmt=TAVARUA_PIX_FMT_NONE, int64_t timestamp=0) {
if(!freeCaptureFrameq.empty()) {
shared_ptr<CaptureFrame> ret = freeCaptureFrameq.pop_front();
if(ret && ret->frame.max_size() >= size) {
ret->frame.clear();
ret->frame.set_length(size);
ret->width = w;
ret->height = h;
ret->pix_fmt = fmt;
ret->timestamp = timestamp;
return ret;
}
}
// INFO << "No free element or size = "<< size <<". Create new one, qsize = " << freeCaptureFrameq.size();
if(timestamp == 0) timestamp = us_timestamp::now();
return shared_ptr<CaptureFrame>(new CaptureFrame(w, h, fmt, buffer(size), timestamp));
}
};
/* Add by Yang, 2012-03-20
* FrameNumber is for VIDEO ENCODER and VIDEO DECODER
* It implements circular number in 2^23 - 1.
*
* Assume A and B is in FrameNumber.
* Define:
* 1. A+B = (A + B) % MAX_FRAME_NUMBER
* 2. A-B = (A + MAX_FRAME_NUMBER - B) % MAX_FRAME_NUMBER
* 3. diff(A,B) = min(A-B, B-A)
*
* Support:
* 1. int = FrameNumber + int
* 2. FrameNumber = int
* 3. FrameNumber A >= FrameNumber B
* If true, B + diff(A,B) = A , else false.
* 4. FrameNumber A <= FrameNumber B
* If true, A + diff(A,B) = B , else false.
* */
class FrameNumber {
private:
const static int MAX_FRAME_NUMBER = 8388607 ; // 2^23-1
int number;
inline int diff(int a, int b) {
int diff1 = minus(a, b);
int diff2 = minus(b, a);
return (diff1 > diff2)? diff2 : diff1;
}
inline int minus(int a, int b) {
return (a + MAX_FRAME_NUMBER - b) % MAX_FRAME_NUMBER;
}
inline int pulse(int a, int b) {
return (a + b) % MAX_FRAME_NUMBER;
}
void setValue(int value) {
number = value;
}
public:
FrameNumber(int init_value = 0) : number(init_value) { }
~FrameNumber(){ }
bool operator < (const FrameNumber &B) {
int difference = diff(number, B);
return bool (pulse(number, difference) == B);
}
bool operator > (const FrameNumber &B) {
int difference = diff(number, B);
return bool (number == pulse(B, difference));
}
int operator ++ ( int /*dummy*/ ) {
int original = number;
setValue(pulse(number, 1));
return original;
}
int operator - (FrameNumber B) {
return diff(number, B.number);
}
int operator - (int B) {
return diff(number, B);
}
int operator + (const int value) {
return pulse( this->number, value);
}
void operator = (const int value) {
setValue(value);
}
void operator = (const FrameNumber value) {
setValue(value);
}
operator int () const {
return number;
}
};
class VideoEncodedChunk {
public:
struct Header {
int64_t timestamp;
Header(int64_t t=0):timestamp(t){}
~Header() {}
}header;
const static int headerLength = sizeof(Header); // 64 ippc + 8 timestamp
bool key_frame; // is key frame;
int frame; // frame number
int num_encoders;
buffer encodedFrameData;
VideoEncodedChunk(struct Header h=Header(), bool key=false, int fn=0, int ne=1, buffer buf=buffer()) :
header(h),key_frame(key), frame(fn), num_encoders(ne), encodedFrameData(buf) { }
~VideoEncodedChunk() { }
operator bool () const { return (encodedFrameData.is_valid()); }
int get_encoded_frame_size() { return encodedFrameData.length(); }
int get_sended_data_len() { return encodedFrameData.length(); }
char* get_sended_data() { return encodedFrameData.is_valid() ? encodedFrameData.get_data() : NULL; }
bool is_valid() { return encodedFrameData.is_valid(); }
};
struct AudioEncodedChunk {
int frame_number;
buffer data;
int64_t timestamp;
AudioEncodedChunk(int _num = 0, buffer _data = buffer(), int64_t ts=0) : frame_number(_num), data(_data), timestamp(ts) {}
~AudioEncodedChunk() {}
operator bool () const { return data.is_valid() && (frame_number!=0); }
bool operator !=(const AudioEncodedChunk& aec) const {
return (aec.frame_number != frame_number) || (aec.data != data);
}
};
struct ArchivedChunk {
bool is_raw;
size_t width;
size_t height;
int64_t timestamp;
buffer image;
ArchivedChunk(bool raw=false, size_t w=0, size_t h=0, buffer img=buffer(), int64_t ts=0)
: is_raw(raw), width(w), height(h), timestamp(0), image(img) {
timestamp = (ts!=0) ? ts : us_timestamp::now();
}
~ArchivedChunk() { }
operator bool () const {
return (image.is_valid() && width>0 && height>0);
}
};
#endif /* TAVARUA_DATA_STRUCTURE_H_ */