mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 13:40:21 +00:00
Added transition from LFF to interlaced merged
This commit is contained in:
@@ -109,7 +109,7 @@ struct state_video_decoder;
|
||||
* Interlacing changing function protoype. The function should be able to change buffer
|
||||
* in place, that is when dst and src are the same.
|
||||
*/
|
||||
typedef void (*change_il_t)(char *dst, char *src, int linesize, int height);
|
||||
typedef void (*change_il_t)(char *dst, char *src, int linesize, int height, void **state);
|
||||
|
||||
// prototypes
|
||||
static bool reconfigure_decoder(struct state_video_decoder *decoder,
|
||||
@@ -216,6 +216,7 @@ struct state_video_decoder
|
||||
|
||||
unsigned int max_substreams; ///< maximal number of expected substreams
|
||||
change_il_t change_il; ///< function to change interlacing, if needed. Otherwise NULL.
|
||||
vector<void *> change_il_state;
|
||||
|
||||
mutex lock;
|
||||
|
||||
@@ -526,7 +527,7 @@ static void *decompress_thread(void *args) {
|
||||
for(i = 0; i < decoder->frame->tile_count; ++i) {
|
||||
struct tile *tile = vf_get_tile(decoder->frame, i);
|
||||
decoder->change_il(tile->data, tile->data, vc_get_linesize(tile->width,
|
||||
decoder->out_codec), tile->height);
|
||||
decoder->out_codec), tile->height, &decoder->change_il_state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,6 +783,11 @@ static void cleanup(struct state_video_decoder *decoder)
|
||||
free(decoder->line_decoder);
|
||||
decoder->line_decoder = NULL;
|
||||
}
|
||||
|
||||
for (auto && item : decoder->change_il_state) {
|
||||
free(item);
|
||||
}
|
||||
decoder->change_il_state.resize(0);
|
||||
}
|
||||
|
||||
#define PRINT_STATISTICS fprintf(stderr, "Video decoder statistics: %lu total: %lu displayed / %lu "\
|
||||
@@ -1039,6 +1045,7 @@ static change_il_t select_il_func(enum interlacing_t in_il, enum interlacing_t *
|
||||
struct transcode_t { enum interlacing_t in; enum interlacing_t out; change_il_t func; };
|
||||
|
||||
struct transcode_t transcode[] = {
|
||||
{LOWER_FIELD_FIRST, INTERLACED_MERGED, il_lower_to_merged},
|
||||
{UPPER_FIELD_FIRST, INTERLACED_MERGED, il_upper_to_merged},
|
||||
{INTERLACED_MERGED, UPPER_FIELD_FIRST, il_merged_to_upper}
|
||||
};
|
||||
@@ -1062,6 +1069,8 @@ static change_il_t select_il_func(enum interlacing_t in_il, enum interlacing_t *
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "[Warning] Cannot find transition between incoming and display "
|
||||
"interlacing modes!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1155,7 @@ static bool reconfigure_decoder(struct state_video_decoder *decoder,
|
||||
|
||||
decoder->change_il = select_il_func(desc.interlacing, decoder->disp_supported_il,
|
||||
decoder->disp_supported_il_cnt, &display_il);
|
||||
decoder->change_il_state.resize(decoder->max_substreams);
|
||||
|
||||
if (!decoder->postprocess || !pp_does_change_tiling_mode) { /* otherwise we need postprocessor mode, which we obtained before */
|
||||
render_mode = display_mode;
|
||||
|
||||
@@ -211,9 +211,62 @@ const char *get_interlacing_suffix(enum interlacing_t interlacing)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: rewrite following 2 functions in more efficient way */
|
||||
void il_upper_to_merged(char *dst, char *src, int linesize, int height)
|
||||
/**
|
||||
* @todo
|
||||
* Needs to be more efficient
|
||||
*/
|
||||
void il_lower_to_merged(char *dst, char *src, int linesize, int height, void **stored_state)
|
||||
{
|
||||
struct il_lower_to_merged_state {
|
||||
size_t field_len;
|
||||
char field[];
|
||||
};
|
||||
struct il_lower_to_merged_state *last_field = (struct il_lower_to_merged_state *) *stored_state;
|
||||
|
||||
int y;
|
||||
char *tmp = malloc(linesize * height);
|
||||
char *line1, *line2;
|
||||
|
||||
// upper field
|
||||
line1 = tmp;
|
||||
int field_len = linesize * (height / 2);
|
||||
// first check if we have field from last frame
|
||||
if (last_field == NULL) {
|
||||
last_field = (struct il_lower_to_merged_state *)
|
||||
malloc(sizeof(struct il_lower_to_merged_state) + field_len);
|
||||
last_field->field_len = field_len;
|
||||
*stored_state = last_field;
|
||||
// if no, use current one
|
||||
line2 = src + linesize * ((height + 1) / 2);
|
||||
} else {
|
||||
// otherwise use field from last "frame"
|
||||
line2 = last_field->field;
|
||||
}
|
||||
for(y = 0; y < height / 2; y ++) {
|
||||
memcpy(line1, line2, linesize);
|
||||
line1 += linesize * 2;
|
||||
line2 += linesize;
|
||||
}
|
||||
// store
|
||||
assert ((int) last_field->field_len == field_len);
|
||||
memcpy(last_field->field, src + linesize * ((height + 1) / 2), field_len);
|
||||
|
||||
// lower field
|
||||
line1 = tmp + linesize;
|
||||
line2 = src;
|
||||
for(y = 0; y < (height + 1) / 2; y ++) {
|
||||
memcpy(line1, line2, linesize);
|
||||
line1 += linesize * 2;
|
||||
line2 += linesize;
|
||||
}
|
||||
memcpy(dst, tmp, linesize * height);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* TODO: rewrite following 2 functions in more efficient way */
|
||||
void il_upper_to_merged(char *dst, char *src, int linesize, int height, void **state)
|
||||
{
|
||||
UNUSED(state);
|
||||
int y;
|
||||
char *tmp = malloc(linesize * height);
|
||||
char *line1, *line2;
|
||||
@@ -237,8 +290,9 @@ void il_upper_to_merged(char *dst, char *src, int linesize, int height)
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void il_merged_to_upper(char *dst, char *src, int linesize, int height)
|
||||
void il_merged_to_upper(char *dst, char *src, int linesize, int height, void **state)
|
||||
{
|
||||
UNUSED(state);
|
||||
int y;
|
||||
char *tmp = malloc(linesize * height);
|
||||
char *line1, *line2;
|
||||
|
||||
@@ -151,15 +151,16 @@ const char *get_interlacing_description(enum interlacing_t interlacing);
|
||||
*/
|
||||
const char *get_interlacing_suffix(enum interlacing_t interlacing);
|
||||
|
||||
void il_lower_to_merged(char *dst, char *src, int linesize, int height, void **stored_state);
|
||||
/* these functions transcode one interlacing format to another */
|
||||
/**
|
||||
* @brief Converts upper-field-first to interlaced merged.
|
||||
*/
|
||||
void il_upper_to_merged(char *dst, char *src, int linesize, int height);
|
||||
void il_upper_to_merged(char *dst, char *src, int linesize, int height, void **stored_state);
|
||||
/**
|
||||
* @brief Converts interlaced merged to upper-field-first.
|
||||
*/
|
||||
void il_merged_to_upper(char *dst, char *src, int linesize, int height);
|
||||
void il_merged_to_upper(char *dst, char *src, int linesize, int height, void **stored_state);
|
||||
|
||||
/**
|
||||
* @brief Computes FPS as a double from packet fields.
|
||||
|
||||
Reference in New Issue
Block a user