输出格式video_output_open
2024-10-16
17
0
video_output_open中创建并初始化video_t结构体:
struct video_output {
struct video_output_info info;
pthread_t thread;
pthread_mutex_t data_mutex;
bool stop;
os_sem_t *update_semaphore;
uint64_t frame_time;
volatile long skipped_frames;
volatile long total_frames;
bool initialized;
pthread_mutex_t input_mutex;
DARRAY(struct video_input) inputs;
size_t available_frames;
size_t first_added;
size_t last_added;
struct cached_frame_info cache[MAX_CACHE_SIZE];//16个
volatile bool raw_active;
volatile long gpu_refs;
};
struct video_output;
typedef struct video_output video_t;
初始化后信息如下
缓冲帧cache的初始化如下:
static inline void init_cache(struct video_output *video)
{
if (video->info.cache_size > MAX_CACHE_SIZE)
video->info.cache_size = MAX_CACHE_SIZE;
for (size_t i = 0; i < video->info.cache_size; i++)
{
struct video_frame* frame =(struct video_frame *)&video->cache[i];
video_frame_init(frame, video->info.format, video->info.width, video->info.height);
}
video->available_frames = video->info.cache_size;
}
video_frame_init中根据格式和宽度进行初始化每个FRAME,这里至少一个(如RGB)或者三个(I420:YUV)或者二个(NV12:Y UV)
struct video_frame {
uint8_t *data[MAX_AV_PLANES];
uint32_t linesize[MAX_AV_PLANES];
};
如I420的代码格式如下:
case VIDEO_FORMAT_I420: {
size = width * height;
ALIGN_SIZE(size, alignment);//32字节的整数倍速对齐
offsets[0] = size;
const uint32_t half_width = (width + 1) / 2;
const uint32_t half_height = (height + 1) / 2;
const uint32_t quarter_area = half_width * half_height;
size += quarter_area;
ALIGN_SIZE(size, alignment); //u起始地址32对齐
offsets[1] = size;
size += quarter_area;
ALIGN_SIZE(size, alignment);/v起始地址32对齐
frame->data[0] = bmalloc(size);
frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
frame->linesize[0] = width;
frame->linesize[1] = half_width;
frame->linesize[2] = half_width;
break;
}
32地址的对齐我记得是GPU的要求,所以这为了CPU和GPU之间进行地址映射方便。