72#define MOD_NAME "[video frame] "
114 for (
unsigned int i = 0u; i < buf->
tile_count; ++i) {
183 for(
unsigned int i = 0u; i < buf->
tile_count; ++i) {
190 assert ((
unsigned int) pos < buf->tile_count);
192 return &buf->
tiles[pos];
215 assert(
frame != NULL);
231 return "progressive";
233 return "interlaced (upper field first)";
235 return "interlaced (lower field first)";
237 return "interlaced merged";
239 return "progressive segmented";
281 struct il_lower_to_merged_state {
285 struct il_lower_to_merged_state *last_field = (
struct il_lower_to_merged_state *) *stored_state;
287 char *tmp = malloc(linesize * height);
292 int upper_field_len = linesize * ((height + 1) / 2);
294 if (last_field == NULL) {
295 last_field = (
struct il_lower_to_merged_state *)
296 malloc(
sizeof(
struct il_lower_to_merged_state) + upper_field_len);
297 last_field->field_len = upper_field_len;
298 *stored_state = last_field;
300 line2 = src + linesize * (height / 2);
303 line2 = last_field->field;
305 for (
int y = 0; y < (height + 1) / 2; y++) {
306 memcpy(line1, line2, linesize);
307 line1 += linesize * 2;
311 assert ((
int) last_field->field_len == upper_field_len);
312 memcpy(last_field->field, src + linesize * (height / 2), upper_field_len);
315 line1 = tmp + linesize;
317 for (
int y = 0; y < height / 2; y++) {
318 memcpy(line1, line2, linesize);
319 line1 += linesize * 2;
322 memcpy(dst, tmp, linesize * height);
331 char *tmp = malloc(linesize * height);
336 for(y = 0; y < (height + 1) / 2; y ++) {
337 memcpy(line1, line2, linesize);
338 line1 += linesize * 2;
342 line1 = tmp + linesize;
343 line2 = src + linesize * ((height + 1) / 2);
344 for(y = 0; y < height / 2; y ++) {
345 memcpy(line1, line2, linesize);
346 line1 += linesize * 2;
349 memcpy(dst, tmp, linesize * height);
357 char *tmp = malloc(linesize * height);
362 for(y = 0; y < (height + 1) / 2; y ++) {
363 memcpy(line1, line2, linesize);
365 line2 += linesize * 2;
368 line1 = tmp + linesize * ((height + 1) / 2);
369 line2 = src + linesize;
370 for(y = 0; y < height / 2; y ++) {
371 memcpy(line1, line2, linesize);
373 line2 += linesize * 2;
375 memcpy(dst, tmp, linesize * height);
413 for(
int i = 0; i < (int) frame_copy->
tile_count; ++i) {
444 uint16_t *dstline = (uint16_t *) (
void *) (tmp + (size_t) i * dst_linesize);
445 dec((
unsigned char *) dstline, (
unsigned char *)
frame->
tiles[0].
data + (
size_t) i * src_linesize,
448 uint16_t tmp = *dstline;
450 *dstline++ = htons(tmp);
458 unsigned char *data = NULL, *tmp_data = NULL;
471 data = tmp_data = (
unsigned char *) malloc(
len);
494 unsigned char *uyvy = (
unsigned char *)
tile->
data;
495 unsigned char *tmp_data_uyvy = NULL;
499 uyvy = tmp_data_uyvy = malloc(
len);
500 dec (uyvy, (
const unsigned char *)
tile->
data,
len, 0, 0, 0);
511 unsigned char *y416 = (
unsigned char *)
tile->
data;
512 unsigned char *tmp_data_y416 = NULL;
516 y416 = tmp_data_y416 = malloc(
len);
517 dec (y416, (
const unsigned char *)
tile->
data,
len, 0, 0, 0);
539 _Thread_local
static char filename[FILENAME_MAX];
544 snprintf(filename,
sizeof filename,
"%s.pnm",
name);
546 return ret ? filename : NULL;
550 snprintf(filename,
sizeof filename,
"%s.y4m",
name);
552 return ret ? filename : NULL;
557 FILE *out = fopen(filename,
"wb");
559 perror(
"save_video_frame fopen");
564 perror(
"save_video_frame fwrite");
575 FILE *in = fopen(
name,
"rb");
587 MSG(ERROR,
"Cannot read %u B from %s, got only %zu B!\n",
618 unsigned int ret = 0;
619 for (
unsigned int i = 0u; i < f->
tile_count; ++i) {
631 for (
int i = 0; i < 4; ++i) {
632 if (sub[i * 2] == 0) {
636 tmp += ((width + sub[i * 2] - 1) / sub[i * 2])
637 * ((height + sub[i * 2 + 1] - 1) / sub[i * 2 + 1]);
645 for (
int i = 0; i < 4; ++i) {
646 if (sub[2 * i] == 0) {
649 linesize[i] = (width + sub[2 * i] - 1) / sub[2 * i];
672 if (strlen(endptr) != 0) {
678 "Unsupported interlacing format: %s!\n",
struct video_frame * frame
int vc_get_linesize(unsigned int width, codec_t codec)
const char * get_codec_name(codec_t codec)
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
static void * aligned_malloc(size_t size, size_t alignment)
bool pam_write(const char *filename, unsigned int width, unsigned int height, int depth, int maxval, const unsigned char *data, bool pnm)
decoder_t get_decoder_from_to(codec_t in, codec_t out)
decoder_func_t * decoder_t
Struct tile is an area of video_frame.
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
enum interlacing_t interlacing
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
void(* data_deleter)(struct video_frame *)
void(* recycle)(struct video_frame *)
void(* copy)(struct video_frame *)
Struct video_frame represents a video frame and contains video description.
enum interlacing_t interlacing
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
struct video_frame_callbacks callbacks
@ LOWER_FIELD_FIRST
First stored field is bottom, followed by top.
@ UPPER_FIELD_FIRST
First stored field is top, followed by bottom.
@ PROGRESSIVE
progressive frame
@ SEGMENTED_FRAME
Segmented frame. Contains the same data as progressive frame.
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
#define VF_METADATA_START
@ RGB
RGB 8-bit (packed into 24-bit word)
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
@ RG48
16-bit RGB little-endian (RlRhGl...)
@ Y416
interleaved little-endian YCbCr 4444 16-bit - UYVA
void codec_get_planes_subsampling(codec_t pix_fmt, int *sub)
void y416_to_i444(int width, int height, const unsigned char *in, unsigned char *out, int depth)
bool is_codec_opaque(codec_t codec)
void uyvy_to_i422(int width, int height, const unsigned char *in, unsigned char *out)
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).
bool codec_is_const_size(codec_t codec)
Returns TRUE if specified pixelformat has constant size regardles of resolution. If so the block_size...
int get_pf_block_bytes(codec_t codec)
returns codec_info_t::block_size_bytes
const char * get_codec_file_extension(codec_t codec)
bool clear_video_buffer(unsigned char *data, size_t linesize, size_t pitch, size_t height, codec_t color_spec)
size_t vc_get_datalen(unsigned int width, unsigned int height, codec_t codec)
int get_bits_per_component(codec_t codec)
struct video_frame * vf_alloc(int count)
Allocates blank video frame.
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
enum interlacing_t get_interlacing_from_suffix(const char *suffix)
void vf_clear(struct video_frame *f)
void il_merged_to_upper(char *dst, char *src, int linesize, int height, void **state)
Converts interlaced merged to upper-field-first.
void buf_get_linesizes(int width, codec_t color_spec, int *linesize)
void vf_data_deleter(struct video_frame *buf)
const char * save_video_frame(struct video_frame *frame, const char *name, bool raw)
bool video_desc_eq_excl_param(struct video_desc a, struct video_desc b, unsigned int excluded_params)
Compares two video descriptions.
const char * get_interlacing_suffix(enum interlacing_t interlacing)
Returns suffix describing interlacing Eg. p, i or psf.
static unsigned char * get_16_bit_pnm_data(struct video_frame *frame)
double compute_fps(int fps, int fpsd, int fd, int fi)
Computes FPS as a double from packet fields.
static const char * interlacing_suffixes[]
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
bool parse_fps(const char *fps, struct video_desc *desc)
unsigned int vf_get_data_len(struct video_frame *f)
void il_lower_to_merged(char *dst, char *src, int linesize, int height, void **stored_state)
void vf_recycle(struct video_frame *buf)
This function should be called before returning a frame back to a frame pool. Currently this is used ...
void vf_store_metadata(const struct video_frame *f, void *s)
bool save_video_frame_as_pnm(struct video_frame *frame, const char *name)
struct video_frame * vf_get_copy(struct video_frame *original_frame)
Makes deep copy of the video frame.
struct tile * vf_get_tile(struct video_frame *buf, int pos)
Returns pointer to n-th tile from video frame Equivalent to &video_frame::tiles[pos].
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
allocates struct video_frame including data pointers in RAM
bool video_desc_eq(struct video_desc a, struct video_desc b)
Compares two video descriptions.
void vf_restore_metadata(struct video_frame *f, void *s)
const char * get_interlacing_description(enum interlacing_t interlacing)
Returns description of interlacing Eg. "progressive".
void il_upper_to_merged(char *dst, char *src, int linesize, int height, void **state)
Converts upper-field-first to interlaced merged.
void buf_get_planes(int width, int height, codec_t color_spec, char *data, char **planes)
void vf_copy_metadata(struct video_frame *dest, const struct video_frame *src)
static void vf_aligned_data_deleter(struct video_frame *buf)
static bool save_video_frame_as_y4m(struct video_frame *frame, const char *name)
struct video_frame * load_video_frame(const char *name, codec_t codec, int width, int height)
#define PARAM_INTERLACING
bool y4m_write(const char *filename, const struct y4m_metadata *info, const unsigned char *data)