New packet format for video

+ tons of changes
+ TODO: fps is now temporarily located in packet. change its location
  when assesed final position
This commit is contained in:
Martin Pulec
2011-12-14 11:52:09 +01:00
parent 143aa30a5f
commit e10c07a4e8
44 changed files with 830 additions and 593 deletions

View File

@@ -314,7 +314,7 @@ ihdtv_send(ihdtv_connection * connection, struct video_frame *tx_frame,
packet_1.offset = packet_relative_offset;
vector1[0].iov_base = &packet_1;
vector1[0].iov_len = 16; // we only use the header
vector1[1].iov_base = tile_get(tx_frame, 0, 0)->data + offset_absolut_1;
vector1[1].iov_base = vf_get_tile(tx_frame, 0)->data + offset_absolut_1;
vector1[1].iov_len = connection->video_data_per_packet;
if (sendmsg(connection->tx_socket_1, &msg1, 0) == -1) {
perror("Sending data to address 1");
@@ -324,7 +324,7 @@ ihdtv_send(ihdtv_connection * connection, struct video_frame *tx_frame,
packet_2.offset = packet_relative_offset;
vector2[0].iov_base = &packet_2;
vector2[0].iov_len = 16; // we only use the header
vector2[1].iov_base = tile_get(tx_frame, 0, 0)->data + offset_absolut_2;
vector2[1].iov_base = vf_get_tile(tx_frame, 0)->data + offset_absolut_2;
vector2[1].iov_len = connection->video_data_per_packet;
if (sendmsg(connection->tx_socket_2, &msg2, 0) == -1) {
perror("Sending data to address 2");
@@ -339,7 +339,7 @@ ihdtv_send(ihdtv_connection * connection, struct video_frame *tx_frame,
packet_1.offset = packet_relative_offset;
vector1[0].iov_base = &packet_1;
vector1[0].iov_len = 16; // we only use the header
vector1[1].iov_base = tile_get(tx_frame, 0, 0)->data + offset_absolut_1;
vector1[1].iov_base = vf_get_tile(tx_frame, 0)->data + offset_absolut_1;
vector1[1].iov_len = connection->video_data_per_last_packet;
if (sendmsg(connection->tx_socket_1, &msg1, 0) == -1) {
perror("Sending data to address 1");
@@ -349,7 +349,7 @@ ihdtv_send(ihdtv_connection * connection, struct video_frame *tx_frame,
packet_2.offset = packet_relative_offset;
vector2[0].iov_base = &packet_2;
vector2[0].iov_len = 16; // we only use the header
vector2[1].iov_base = tile_get(tx_frame, 0, 0)->data + offset_absolut_2;
vector2[1].iov_base = vf_get_tile(tx_frame, 0)->data + offset_absolut_2;
vector2[1].iov_len = connection->video_data_per_last_packet;
if (sendmsg(connection->tx_socket_2, &msg2, 0) == -1) {
perror("Sending data to address 2");

View File

@@ -49,9 +49,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Revision: 1.30 $
* $Date: 2010/02/05 14:06:17 $
*
*/
#include <string.h>
@@ -100,7 +97,8 @@ struct state_uv {
struct timeval start_time, curr_time;
struct pdb *participants;
char *decoder_options;
char *decoder_mode;
char *postprocess;
uint32_t ts;
struct tx *tx;
@@ -118,7 +116,8 @@ struct state_uv {
long packet_rate = 13600;
volatile int should_exit = FALSE;
static sem_t should_exit_sem;
volatile int wait_to_finish = FALSE;
volatile int threads_joined = FALSE;
uint32_t RTT = 0; /* this is computed by handle_rr in rtp_callback */
struct video_frame *frame_buffer = NULL;
@@ -143,16 +142,20 @@ static void signal_handler(int signal)
#endif /* WIN32 */
void exit_uv(int status) {
wait_to_finish = TRUE;
should_exit = TRUE;
display_finish(uv_state->display_device);
platform_sem_post(&should_exit_sem);
if(!threads_joined) {
display_finish(uv_state->display_device);
audio_finish(uv_state->audio);
}
wait_to_finish = FALSE;
}
static void usage(void)
{
/* TODO -c -p -b are deprecated options */
printf("\nUsage: uv [-d <display_device>] [-t <capture_device>] [-r <audio_playout>] [-s <audio_caputre>] \n");
printf(" [-m <mtu>] [-c] [-i] address(es)\n\n");
printf(" [-m <mtu>] [-c] [-i] [-M <video_mode>] [-p <postprocess>] address(es)\n\n");
printf
("\t-d <display_device> \tselect display device, use '-d help' to get\n");
printf("\t \tlist of supported devices\n");
@@ -171,6 +174,10 @@ static void usage(void)
printf("\n");
printf("\t-j <settings> \tJACK Audio Connection Kit settings (see '-j help')\n");
printf("\n");
printf("\t-M <video_mode> \treceived video mode (eg tiled-4K, stereo, dual)\n");
printf("\n");
printf("\t-p <postprocess> \tpostprocess module\n");
printf("\n");
printf("\taddress(es) \tdestination address\n");
printf("\n");
printf("\t \tIf comma-separated list of addresses\n");
@@ -401,10 +408,10 @@ static void *receiver_thread(void *arg)
struct timeval last_tile_received;
struct state_decoder *dec_state;
dec_state = decoder_init(uv->decoder_options);
dec_state = decoder_init(uv->decoder_mode, uv->postprocess);
if(!dec_state) {
fprintf(stderr, "Error initializing decoder ('-M' option).\n");
should_exit = TRUE;
exit_uv(1);
} else {
decoder_register_video_display(dec_state, uv->display_device);
}
@@ -511,7 +518,7 @@ static void *sender_thread(void *arg)
/* we have more than one connection */
if(tile_y_count > 1) {
/* it is simply stripping frame */
splitted_frames = vf_alloc(1, tile_y_count);
splitted_frames = vf_alloc(tile_y_count);
}
while (!should_exit) {
@@ -537,7 +544,7 @@ static void *sender_thread(void *arg)
vf_split_horizontal(splitted_frames, tx_frame,
tile_y_count);
for (i = 0; i < tile_y_count; ++i) {
tx_send_tile(uv->tx, splitted_frames, 0, i,
tx_send_tile(uv->tx, splitted_frames, i,
uv->network_devices[i]);
}
}
@@ -600,13 +607,15 @@ int main(int argc, char *argv[])
uv = (struct state_uv *)malloc(sizeof(struct state_uv));
uv_state = uv;
uv->audio = NULL;
uv->ts = 0;
uv->display_device = NULL;
uv->requested_display = "none";
uv->requested_capture = "none";
uv->requested_compression = FALSE;
uv->compress_options = NULL;
uv->decoder_options = NULL;
uv->decoder_mode = NULL;
uv->postprocess = NULL;
uv->requested_mtu = 0;
uv->use_ihdtv_protocol = 0;
uv->participants = NULL;
@@ -615,10 +624,8 @@ int main(int argc, char *argv[])
perf_init();
perf_record(UVP_INIT, 0);
platform_sem_init(&should_exit_sem, 0, 0);
while ((ch =
getopt_long(argc, argv, "d:t:m:r:s:vc:ihj:M:", getopt_options,
getopt_long(argc, argv, "d:t:m:r:s:vc:ihj:M:p:", getopt_options,
&option_index)) != -1) {
switch (ch) {
case 'd':
@@ -643,7 +650,10 @@ int main(int argc, char *argv[])
uv->requested_mtu = atoi(optarg);
break;
case 'M':
uv->decoder_options = optarg;
uv->decoder_mode = optarg;
break;
case 'p':
uv->postprocess = optarg;
break;
case 'v':
printf("%s\n", ULTRAGRID_VERSION);
@@ -851,7 +861,8 @@ int main(int argc, char *argv[])
return EXIT_FAIL_TRANSMIT;
}
if (strcmp("none", uv->requested_display) != 0) {
if (strcmp("none", uv->requested_display) != 0 ||
uv->postprocess || uv->decoder_mode) {
if (pthread_create
(&receiver_thread_id, NULL, receiver_thread,
(void *)uv) != 0) {
@@ -878,12 +889,6 @@ int main(int argc, char *argv[])
if (strcmp("none", uv->requested_display) != 0)
display_run(uv->display_device);
platform_sem_wait(&should_exit_sem);
/* here we let modules know that they should exit in order to avoid waitin on
* semaphores or so. Finishing for video display is signalized in exit_uv because
* it occupies this thread */
audio_finish(uv->audio);
if (strcmp("none", uv->requested_display) != 0)
pthread_join(receiver_thread_id, NULL);
@@ -893,6 +898,10 @@ int main(int argc, char *argv[])
/* also wait for audio threads */
audio_join(uv->audio);
while(wait_to_finish)
;
threads_joined = TRUE;
audio_done(uv->audio);
tx_done(uv->tx);
destroy_devices(uv->network_devices);

View File

@@ -56,7 +56,6 @@
struct state_decoder;
struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, struct video_desc desc,
struct tile_info tileinfo,
struct video_frame *frame);
enum decoder_type_t {
@@ -85,10 +84,11 @@ struct state_decoder {
/* requested values */
int requested_pitch;
int rshift, gshift, bshift;
int max_substreams;
struct display *display;
codec_t *native_codecs;
int native_count;
size_t native_count;
/* actual values */
enum decoder_type_t decoder_type;
@@ -108,25 +108,50 @@ struct state_decoder {
struct vo_postprocess *postprocess;
struct video_frame *pp_frame;
};
unsigned int video_mode;
unsigned merged_fb:1;
};
struct state_decoder *decoder_init(char *requested_mode)
struct state_decoder *decoder_init(char *requested_mode, char *postprocess)
{
struct state_decoder *s;
s = (struct state_decoder *) calloc(1, sizeof(struct state_decoder));
s->native_codecs = NULL;
s->postprocess = NULL;
s->video_mode = VIDEO_NORMAL;
if(requested_mode) {
s->postprocess = vo_postprocess_init(requested_mode);
if(!s->postprocess) {
fprintf(stderr, "Initializing postprocessor \"%s\" failed.\n", requested_mode);
/* these are data comming from newtork ! */
if(strcasecmp(requested_mode, "help") == 0) {
printf("Video mode options\n\n");
printf("-M {tiled-4K | 3D | dual-link }\n");
free(s);
return NULL;
} else if(strcasecmp(requested_mode, "tiled-4K") == 0) {
s->video_mode = VIDEO_4K;
} else if(strcasecmp(requested_mode, "3D") == 0) {
s->video_mode = VIDEO_STEREO;
} else if(strcasecmp(requested_mode, "dual-link") == 0) {
s->video_mode = VIDEO_DUAL;
} else {
fprintf(stderr, "[decoder] Unknown video mode (see -M help)\n");
free(s);
return NULL;
}
}
s->max_substreams = get_video_mode_tiles_x(s->video_mode)
* get_video_mode_tiles_y(s->video_mode);
if(postprocess) {
s->postprocess = vo_postprocess_init(postprocess);
if(!s->postprocess) {
fprintf(stderr, "Initializing postprocessor \"%s\" failed.\n", postprocess);
free(s);
return NULL;
}
} else {
s->postprocess = NULL;
}
return s;
@@ -157,6 +182,9 @@ void decoder_register_video_display(struct state_decoder *decoder, struct displa
void decoder_destroy(struct state_decoder *decoder)
{
if(!decoder)
return;
if(decoder->ext_decoder_funcs) {
decoder->ext_decoder_funcs->done(decoder->ext_decoder_state);
decoder->ext_decoder_funcs = NULL;
@@ -180,7 +208,7 @@ void decoder_destroy(struct state_decoder *decoder)
}
static codec_t choose_codec_and_decoder(struct state_decoder * const decoder, struct video_desc desc,
struct tile_info tile_info, codec_t *in_codec, decoder_t *decode_line)
codec_t *in_codec, decoder_t *decode_line)
{
codec_t out_codec;
*decode_line = NULL;
@@ -191,9 +219,9 @@ static codec_t choose_codec_and_decoder(struct state_decoder * const decoder, st
*in_codec = UYVY;
}
int native;
size_t native;
/* first check if the codec is natively supported */
for(native = 0; native < decoder->native_count; ++native)
for(native = 0u; native < decoder->native_count; ++native)
{
out_codec = decoder->native_codecs[native];
if(out_codec == DVS8 || out_codec == Vuy2)
@@ -201,8 +229,7 @@ static codec_t choose_codec_and_decoder(struct state_decoder * const decoder, st
if(*in_codec == out_codec) {
if((out_codec == DXT1 || out_codec == DXT1_YUV ||
out_codec == DXT5)
&& (tile_info.x_count > 1 ||
tile_info.y_count > 1))
&& desc.video_mode != VIDEO_NORMAL)
continue; /* it is a exception, see NOTES #1 */
if(*in_codec == RGBA || /* another exception - we may change shifts */
*in_codec == RGB)
@@ -268,12 +295,12 @@ after_decoder_lookup:
}
struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, struct video_desc desc,
struct tile_info tile_info,
struct video_frame *frame_display)
{
codec_t out_codec, in_codec;
decoder_t decode_line;
struct video_frame *frame;
int display_mode;
assert(decoder != NULL);
assert(decoder->native_codecs != NULL);
@@ -295,23 +322,22 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
free(decoder->ext_recv_buffer);
decoder->ext_recv_buffer = NULL;
}
if(decoder->pp_frame) {
vo_postprocess_done(decoder->postprocess);
decoder->pp_frame = NULL;
}
desc.width *= get_video_mode_tiles_x(decoder->video_mode);
desc.height *= get_video_mode_tiles_y(decoder->video_mode);
out_codec = choose_codec_and_decoder(decoder, desc, tile_info, &in_codec, &decode_line);
out_codec = choose_codec_and_decoder(decoder, desc, &in_codec, &decode_line);
struct video_desc display_desc = desc;
if(decoder->postprocess) {
decoder->pp_frame = vo_postprocess_reconfigure(decoder->postprocess, desc, tile_info);
struct video_desc_ti desc_ti;
vo_postprocess_get_out_desc(decoder->postprocess, &desc_ti);
desc = desc_ti.desc;
tile_info = desc_ti.ti;
struct video_desc pp_desc = desc;
pp_desc.color_spec = out_codec;
decoder->pp_frame = vo_postprocess_reconfigure(decoder->postprocess, pp_desc);
vo_postprocess_get_out_desc(decoder->postprocess, &display_desc, &display_mode);
}
struct video_desc cur_desc = desc;
cur_desc.color_spec = out_codec;
if(!video_desc_eq(decoder->display_desc, cur_desc))
display_desc.color_spec = out_codec;
if(!video_desc_eq(decoder->display_desc, display_desc))
{
/*
* TODO: put frame should be definitely here. On the other hand, we cannot be sure
@@ -319,9 +345,9 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
*/
//display_put_frame(decoder->display, frame);
/* reconfigure VO and give it opportunity to pass us pitch */
display_reconfigure(decoder->display, cur_desc);
display_reconfigure(decoder->display, display_desc);
frame_display = display_get_frame(decoder->display);
decoder->display_desc = cur_desc;
decoder->display_desc = display_desc;
}
if(decoder->postprocess) {
frame = decoder->pp_frame;
@@ -329,7 +355,7 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
frame = frame_display;
}
int len = sizeof(int);
size_t len = sizeof(int);
int ret;
ret = display_get_property(decoder->display, DISPLAY_PROPERTY_RSHIFT,
&decoder->rshift, &len);
@@ -354,20 +380,42 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
decoder->requested_pitch = PITCH_DEFAULT;
}
if (!decoder->postprocess) { /* otherwise we need postprocessor mode, which we obtained before */
ret = display_get_property(decoder->display, DISPLAY_PROPERTY_VIDEO_MODE,
&display_mode, &len);
if(!ret) {
debug_msg("Failed to get video display mode.");
display_mode = DISPLAY_PROPERTY_VIDEO_MERGED;
}
}
int linewidth;
if(display_mode == DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES) {
linewidth = desc.width / get_video_mode_tiles_x(decoder->video_mode);
} else {
linewidth = desc.width;
}
if(!decoder->postprocess) {
if(decoder->requested_pitch == PITCH_DEFAULT)
decoder->pitch = vc_get_linesize(desc.width / frame->grid_width, out_codec);
decoder->pitch = vc_get_linesize(linewidth, out_codec);
else
decoder->pitch = decoder->requested_pitch;
} else {
decoder->pitch = vc_get_linesize(desc.width, out_codec);
decoder->pitch = vc_get_linesize(linewidth, out_codec);
}
int src_x_tiles = get_video_mode_tiles_x(desc.video_mode);
int src_y_tiles = get_video_mode_tiles_y(desc.video_mode);
if(decoder->decoder_type == LINE_DECODER) {
decoder->line_decoder = malloc(tile_info.x_count * tile_info.y_count *
decoder->line_decoder = malloc(src_x_tiles * src_y_tiles *
sizeof(struct line_decoder));
if(frame->grid_width == 1 && frame->grid_height == 1 && tile_info.x_count == 1 && tile_info.y_count == 1) {
if(display_mode == DISPLAY_PROPERTY_VIDEO_MERGED && desc.video_mode == VIDEO_NORMAL) {
struct line_decoder *out = &decoder->line_decoder[0];
out->base_offset = 0;
out->src_bpp = get_bpp(in_codec);
@@ -381,16 +429,16 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
out->src_linesize = vc_get_linesize(desc.width, in_codec);
out->dst_linesize = vc_get_linesize(desc.width, out_codec);
decoder->merged_fb = TRUE;
} else if(frame->grid_width == 1 && frame->grid_height == 1
&& (tile_info.x_count != 1 || tile_info.y_count != 1)) {
} else if(display_mode == DISPLAY_PROPERTY_VIDEO_MERGED
&& desc.video_mode != VIDEO_NORMAL) {
int x, y;
for(x = 0; x < tile_info.x_count; ++x) {
for(y = 0; y < tile_info.y_count; ++y) {
for(x = 0; x < src_x_tiles; ++x) {
for(y = 0; y < src_y_tiles; ++y) {
struct line_decoder *out = &decoder->line_decoder[x +
tile_info.x_count * y];
out->base_offset = y * (desc.height / tile_info.y_count)
src_x_tiles * y];
out->base_offset = y * (desc.height / src_y_tiles)
* decoder->pitch +
vc_get_linesize(x * desc.width / tile_info.x_count, out_codec);
vc_get_linesize(x * desc.width / src_x_tiles, out_codec);
out->src_bpp = get_bpp(in_codec);
out->dst_bpp = get_bpp(out_codec);
@@ -403,18 +451,18 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
out->dst_pitch = decoder->pitch;
out->src_linesize =
vc_get_linesize(desc.width / tile_info.x_count, in_codec);
vc_get_linesize(desc.width / src_x_tiles, in_codec);
out->dst_linesize =
vc_get_linesize(desc.width / tile_info.x_count, out_codec);
vc_get_linesize(desc.width / src_x_tiles, out_codec);
}
}
decoder->merged_fb = TRUE;
} else if(frame->grid_width == tile_info.x_count && frame->grid_height == tile_info.y_count) {
} else if (display_mode == DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES) {
int x, y;
for(x = 0; x < tile_info.x_count; ++x) {
for(y = 0; y < tile_info.y_count; ++y) {
for(x = 0; x < src_x_tiles; ++x) {
for(y = 0; y < src_y_tiles; ++y) {
struct line_decoder *out = &decoder->line_decoder[x +
tile_info.x_count * y];
src_x_tiles * y];
out->base_offset = 0;
out->src_bpp = get_bpp(in_codec);
out->dst_bpp = get_bpp(out_codec);
@@ -424,10 +472,10 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
out->decode_line = decode_line;
out->src_linesize =
vc_get_linesize(desc.width / tile_info.x_count, in_codec);
vc_get_linesize(desc.width / src_x_tiles, in_codec);
out->dst_pitch =
out->dst_linesize =
vc_get_linesize(desc.width / tile_info.x_count, out_codec);
vc_get_linesize(desc.width / src_x_tiles, out_codec);
}
}
decoder->merged_fb = FALSE;
@@ -436,18 +484,17 @@ struct video_frame * reconfigure_decoder(struct state_decoder * const decoder, s
int buf_size;
int i;
desc.width /= tile_info.x_count;
desc.height /= tile_info.y_count;
desc.width /= src_x_tiles;
desc.height /= src_y_tiles;
decoder->ext_decoder_state = decoder->ext_decoder_funcs->init();
buf_size = decoder->ext_decoder_funcs->reconfigure(decoder->ext_decoder_state, desc,
decoder->rshift, decoder->gshift, decoder->bshift, decoder->pitch, out_codec);
decoder->ext_recv_buffer = malloc((tile_info.x_count * tile_info.y_count + 1) * sizeof(char *));
decoder->total_bytes = calloc(1, (tile_info.x_count * tile_info.y_count) * sizeof(int));
for (i = 0; i < tile_info.x_count * tile_info.y_count; ++i)
decoder->rshift, decoder->gshift, decoder->bshift, decoder->pitch , out_codec);
decoder->ext_recv_buffer = malloc((src_x_tiles * src_y_tiles + 1) * sizeof(char *));
decoder->total_bytes = calloc(1, (src_x_tiles * src_y_tiles) * sizeof(int));
for (i = 0; i < src_x_tiles * src_y_tiles; ++i)
decoder->ext_recv_buffer[i] = malloc(buf_size);
decoder->ext_recv_buffer[i] = NULL;
if(frame->grid_width == tile_info.x_count && frame->grid_height == tile_info.y_count) {
if(display_mode == DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES) {
decoder->merged_fb = FALSE;
} else {
decoder->merged_fb = TRUE;
@@ -462,17 +509,18 @@ void decode_frame(struct coded_data *cdata, struct video_frame *frame, struct st
uint32_t width;
uint32_t height;
uint32_t offset;
uint32_t aux;
struct tile_info tile_info;
enum interlacing_t interlacing;
int len;
codec_t color_spec;
rtp_packet *pckt;
unsigned char *source;
payload_hdr_t *hdr;
video_payload_hdr_t *hdr;
uint32_t data_pos;
int prints=0;
double fps;
struct tile *tile = NULL;
uint32_t tmp;
uint32_t substream;
perf_record(UVP_DECODEFRAME, frame);
@@ -485,25 +533,23 @@ void decode_frame(struct coded_data *cdata, struct video_frame *frame, struct st
while (cdata != NULL) {
pckt = cdata->data;
hdr = (payload_hdr_t *) pckt->data;
width = ntohs(hdr->width);
height = ntohs(hdr->height);
color_spec = hdr->colorspc;
len = ntohs(hdr->length);
hdr = (video_payload_hdr_t *) pckt->data;
width = ntohs(hdr->hres);
height = ntohs(hdr->vres);
color_spec = get_codec_from_fcc(ntohl(hdr->fourcc));
len = pckt->data_len - sizeof(video_payload_hdr_t);
data_pos = ntohl(hdr->offset);
tmp = ntohl(hdr->substream_bufnum_il);
interlacing = (enum interlacing_t) (tmp & 0x3);
substream = tmp >> 22;
fps = ntohl(hdr->fps)/65536.0;
aux = ntohl(hdr->aux);
tile_info = ntoh_uint2tileinfo(hdr->tileinfo);
if(aux & AUX_TILED) {
width = width * tile_info.x_count;
height = height * tile_info.y_count;
} else {
tile_info.x_count = 1;
tile_info.y_count = 1;
tile_info.pos_x = 0;
tile_info.pos_y = 0;
if(substream >= decoder->max_substreams) {
fprintf(stderr, "[decoder] received substream ID %d. Expecting %d substreams. Did you set -M option?\n", substream, decoder->max_substreams);
exit_uv(1);
return;
}
/* Critical section
* each thread *MUST* wait here if this condition is true
@@ -511,37 +557,38 @@ void decode_frame(struct coded_data *cdata, struct video_frame *frame, struct st
if (!(decoder->received_vid_desc.width == width &&
decoder->received_vid_desc.height == height &&
decoder->received_vid_desc.color_spec == color_spec &&
decoder->received_vid_desc.aux == aux &&
decoder->received_vid_desc.interlacing == interlacing &&
//decoder->received_vid_desc.video_type == video_type &&
decoder->received_vid_desc.fps == fps
)) {
decoder->received_vid_desc.width = width;
decoder->received_vid_desc.height = height;
decoder->received_vid_desc.color_spec = color_spec;
decoder->received_vid_desc.aux = aux;
decoder->received_vid_desc.interlacing = interlacing;
decoder->received_vid_desc.video_mode = decoder->video_mode;
decoder->received_vid_desc.fps = fps;
frame = reconfigure_decoder(decoder, decoder->received_vid_desc,
tile_info, frame);
frame);
}
if(!decoder->postprocess) {
if (aux & AUX_TILED && !decoder->merged_fb) {
tile = tile_get(frame, tile_info.pos_x, tile_info.pos_y);
if (!decoder->merged_fb) {
tile = vf_get_tile(frame, substream);
} else {
tile = tile_get(frame, 0, 0);
tile = vf_get_tile(frame, 0);
}
} else {
if (aux & AUX_TILED && !decoder->merged_fb) {
tile = tile_get(decoder->pp_frame, tile_info.pos_x, tile_info.pos_y);
if (!decoder->merged_fb) {
tile = vf_get_tile(decoder->pp_frame, substream);
} else {
tile = tile_get(decoder->pp_frame, 0, 0);
tile = vf_get_tile(decoder->pp_frame, 0);
}
}
if(decoder->decoder_type == LINE_DECODER) {
struct line_decoder *line_decoder =
&decoder->line_decoder[tile_info.pos_x +
tile_info.pos_y * tile_info.x_count];
&decoder->line_decoder[substream];
/* End of critical section */
@@ -564,7 +611,7 @@ void decode_frame(struct coded_data *cdata, struct video_frame *frame, struct st
line_decoder->dst_bpp;
/* pointer to data payload in packet */
source = (unsigned char*)(pckt->data + sizeof(payload_hdr_t));
source = (unsigned char*)(pckt->data + sizeof(video_payload_hdr_t));
/* copy whole packet that can span several lines.
* we need to clip data (v210 case) or center data (RGBA, R10k cases)
@@ -617,34 +664,41 @@ void decode_frame(struct coded_data *cdata, struct video_frame *frame, struct st
y += line_decoder->dst_pitch; /* next line */
}
} else if(decoder->decoder_type == EXTERNAL_DECODER) {
int pos = tile_info.pos_x + tile_info.x_count * tile_info.pos_y;
memcpy(decoder->ext_recv_buffer[pos] + data_pos, (unsigned char*)(pckt->data + sizeof(payload_hdr_t)),
//int pos = (substream >> 3) & 0x7 + (substream & 0x7) * frame->grid_width;
memcpy(decoder->ext_recv_buffer[substream] + data_pos, (unsigned char*)(pckt->data + sizeof(video_payload_hdr_t)),
len);
decoder->total_bytes[pos] = max(decoder->total_bytes[pos], data_pos + len);
decoder->total_bytes[substream] = max(decoder->total_bytes[substream], data_pos + len);
}
cdata = cdata->nxt;
}
if(decoder->decoder_type == EXTERNAL_DECODER) {
int tile_width = decoder->received_vid_desc.width / tile_info.x_count;
int tile_height = decoder->received_vid_desc.height / tile_info.y_count;
int tile_width = decoder->received_vid_desc.width; // get_video_mode_tiles_x(decoder->video_mode);
int tile_height = decoder->received_vid_desc.height; // get_video_mode_tiles_y(decoder->video_mode);
int x, y;
for (x = 0; x < tile_info.x_count; ++x) {
for (y = 0; y < tile_info.y_count; ++y) {
struct video_frame *output;
if(decoder->postprocess) {
output = decoder->pp_frame;
} else {
output = frame;
}
for (x = 0; x < get_video_mode_tiles_x(decoder->video_mode); ++x) {
for (y = 0; y < get_video_mode_tiles_y(decoder->video_mode); ++y) {
int pos = x + get_video_mode_tiles_x(decoder->video_mode) * y;
char *out;
if(decoder->merged_fb) {
tile = tile_get(frame, 0, 0);
tile = vf_get_tile(output, 0);
out = tile->data + y * decoder->pitch * tile_height +
vc_get_linesize(tile_width, decoder->out_codec) * x;
} else {
tile = tile_get(frame, x, y);
tile = vf_get_tile(output, x);
out = tile->data;
}
decoder->ext_decoder_funcs->decompress(decoder->ext_decoder_state,
(unsigned char *) out,
(unsigned char *) decoder->ext_recv_buffer[x + tile_info.x_count * y],
decoder->total_bytes[x + tile_info.x_count * y]);
(unsigned char *) decoder->ext_recv_buffer[pos],
decoder->total_bytes[pos]);
}
}
}

View File

@@ -55,7 +55,7 @@ struct tile;
*/
void decode_frame(struct coded_data *compressed_frame, struct video_frame *framebuffer, struct state_decoder *s);
struct state_decoder *decoder_init(char *requested_mode);
struct state_decoder *decoder_init(char *requested_mode, char *postprocess);
void decoder_destroy(struct state_decoder *decoder);
void decoder_register_video_display(struct state_decoder *decoder, struct display *display);

View File

@@ -47,6 +47,7 @@
* http://www.cesnet.cz/doc/techzpravy/2010/4k-packet-format/
*/
#if 0
typedef struct {
uint16_t width; /* pixels */
uint16_t height; /* pixels */
@@ -58,6 +59,30 @@ typedef struct {
uint32_t aux; /* auxiliary data */
uint32_t tileinfo; /* info about tile position (if tiled) */
} payload_hdr_t;
#endif
typedef struct {
/* first word */
uint32_t substream_bufnum_il; /* bits 0 - 9 substream
bits 10 - 29 buffer
bits 30 - 31 interlace */
/* second word */
uint32_t offset;
/* third word */
uint32_t length;
/* fourth word */
uint16_t hres;
uint16_t vres;
/* fifth word */
uint32_t fourcc;
/* temporary */
uint32_t fps;
} __attribute__((__packed__)) video_payload_hdr_t;
typedef struct {
/* first word */

View File

@@ -67,29 +67,25 @@ void vf_split(struct video_frame *out, struct video_frame *src,
out->color_spec = src->color_spec;
out->fps = src->fps;
out->aux = src->aux | AUX_TILED;
//out->aux = src->aux | AUX_TILED;
assert(tile_get(src, 0, 0)->width % x_count == 0u && tile_get(src, 0, 0)->height % y_count == 0u);
assert(vf_get_tile(src, 0)->width % x_count == 0u && vf_get_tile(src, 0)->height % y_count == 0u);
for(tile_idx = 0u; tile_idx < x_count * y_count; ++tile_idx) {
out->tiles[tile_idx].width = tile_get(src, 0, 0)->width / x_count;
out->tiles[tile_idx].height = tile_get(src, 0, 0)->height / y_count;
out->tiles[tile_idx].width = vf_get_tile(src, 0)->width / x_count;
out->tiles[tile_idx].height = vf_get_tile(src, 0)->height / y_count;
out->tiles[tile_idx].tile_info.x_count = x_count;
out->tiles[tile_idx].tile_info.y_count = y_count;
out->tiles[tile_idx].tile_info.pos_x = tile_idx % x_count;
out->tiles[tile_idx].tile_info.pos_y = tile_idx / x_count;
out->tiles[tile_idx].linesize = vc_get_linesize(out->tiles[tile_idx].width,
src->color_spec);
out->tiles[tile_idx].data_len = out->tiles[tile_idx].linesize * out->tiles[tile_idx].height;
}
cur_tiles = &out->tiles[0];
for(line_idx = 0u; line_idx < tile_get(src, 0, 0)->height; ++line_idx, ++tile_line) {
for(line_idx = 0u; line_idx < vf_get_tile(src, 0)->height; ++line_idx, ++tile_line) {
unsigned int cur_tile_idx;
unsigned int byte = 0u;
if (line_idx % (tile_get(src, 0, 0)->height / y_count) == 0u) /* next tiles*/
if (line_idx % (vf_get_tile(src, 0)->height / y_count) == 0u) /* next tiles*/
{
tile_line = 0u;
if (line_idx != 0u)
@@ -123,7 +119,7 @@ void vf_split_horizontal(struct video_frame *out, struct video_frame *src,
unsigned int i;
for(i = 0u; i < y_count; ++i) {
out->aux = src->aux | AUX_TILED;
//out->aux = src->aux | AUX_TILED;
out->fps = src->fps;
out->color_spec = src->color_spec;
out->tiles[i].width = src->tiles[0].width;

View File

@@ -48,9 +48,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Revision: 1.5.2.6 $
* $Date: 2010/02/05 13:56:49 $
*
*/
#include "config.h"
@@ -82,8 +79,9 @@ extern long packet_rate;
#endif /* HAVE_MACOSX */
void
tx_send_base(struct tx *tx, struct tile *frame, struct rtp *rtp_session, uint32_t ts, int send_m,
codec_t color_spec, double fps, int aux);
tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session,
uint32_t ts, int send_m, codec_t color_spec, double fps,
enum interlacing_t interlacing, unsigned int substream);
struct tx {
uint32_t magic;
@@ -122,36 +120,37 @@ tx_send(struct tx *tx, struct video_frame *frame, struct rtp *rtp_session)
ts = get_local_mediatime();
for(i = 0; i < frame->grid_width; ++i)
for(i = 0; i < frame->tile_count; ++i)
{
for(j = 0; j < frame->grid_height; ++j) {
int last = FALSE;
if (i == frame->grid_width - 1 &&
j == frame->grid_height - 1)
last = TRUE;
tx_send_base(tx, tile_get(frame, i, j), rtp_session, ts, last,
frame->color_spec, frame->fps, frame->aux);
}
int last = FALSE;
if (i == frame->tile_count - 1)
last = TRUE;
tx_send_base(tx, vf_get_tile(frame, i), rtp_session, ts, last,
frame->color_spec, frame->fps, frame->interlacing,
i);
}
}
void
tx_send_tile(struct tx *tx, struct video_frame *frame, int x_pos, int y_pos, struct rtp *rtp_session)
tx_send_tile(struct tx *tx, struct video_frame *frame, int pos, struct rtp *rtp_session)
{
struct tile *tile;
tile = tile_get(frame, x_pos, y_pos);
tile = vf_get_tile(frame, pos);
uint32_t ts = 0;
ts = get_local_mediatime();
tx_send_base(tx, tile, rtp_session, ts, TRUE, frame->color_spec, frame->fps, frame->aux);
tx_send_base(tx, tile, rtp_session, ts, TRUE, frame->color_spec, frame->fps, frame->interlacing, pos);
}
void
tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session, uint32_t ts, int send_m, codec_t color_spec, double fps, int aux)
tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session,
uint32_t ts, int send_m, codec_t color_spec, double fps,
enum interlacing_t interlacing, unsigned int substream)
{
int m, data_len;
payload_hdr_t payload_hdr;
video_payload_hdr_t payload_hdr;
int pt = 96; /* A dynamic payload type for the tests... */
char *data;
unsigned int pos;
@@ -161,6 +160,7 @@ tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session, uint32_t
struct timespec start, stop;
#endif /* HAVE_MACOSX */
long delta;
uint32_t tmp;
assert(tx->magic == TRANSMIT_MAGIC);
@@ -169,19 +169,21 @@ tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session, uint32_t
m = 0;
pos = 0;
payload_hdr.width = htons(tile->width);
payload_hdr.height = htons(tile->height);
payload_hdr.colorspc = color_spec;
payload_hdr.fps = htonl((int)(fps * 65536));
payload_hdr.aux = htonl(aux);
payload_hdr.tileinfo = hton_tileinfo2uint(tile->tile_info);
payload_hdr.hres = htons(tile->width);
payload_hdr.vres = htons(tile->height);
payload_hdr.fourcc = htonl(get_fourcc(color_spec));
payload_hdr.length = htonl(tile->data_len);
payload_hdr.fps = htonl(fps * 65536.0);
tmp = substream << 22;
tmp |= tx->buffer << 2;
tmp |= interlacing;
payload_hdr.substream_bufnum_il = htonl(tmp);
do {
payload_hdr.offset = htonl(pos);
payload_hdr.flags = htons(1 << 15);
data = tile->data + pos;
data_len = tx->mtu - 40 - (sizeof(payload_hdr_t));
data_len = tx->mtu - 40 - (sizeof(video_payload_hdr_t));
data_len = (data_len / 48) * 48;
if (pos + data_len >= tile->data_len) {
if (send_m)
@@ -189,10 +191,9 @@ tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session, uint32_t
data_len = tile->data_len - pos;
}
pos += data_len;
payload_hdr.length = htons(data_len);
GET_STARTTIME;
rtp_send_data_hdr(rtp_session, ts, pt, m, 0, 0,
(char *)&payload_hdr, sizeof(payload_hdr_t),
(char *)&payload_hdr, sizeof(video_payload_hdr_t),
data, data_len, 0, 0, 0);
do {
GET_STOPTIME;
@@ -202,6 +203,8 @@ tx_send_base(struct tx *tx, struct tile *tile, struct rtp *rtp_session, uint32_t
} while (packet_rate - delta > 0);
} while (pos < tile->data_len);
tx->buffer ++;
}
void audio_tx_send(struct tx* tx, struct rtp *rtp_session, audio_frame * buffer)

View File

@@ -54,7 +54,7 @@ struct video_frame;
struct tx *tx_init(unsigned mtu);
void tx_done(struct tx *tx_session);
void tx_send_tile(struct tx *tx_session, struct video_frame *frame, int x_pos, int y_pos, struct rtp *rtp_session);
void tx_send_tile(struct tx *tx_session, struct video_frame *frame, int pos, struct rtp *rtp_session);
void tx_send(struct tx *tx_session, struct video_frame *frame, struct rtp *rtp_session);
void audio_tx_send(struct tx *tx_session, struct rtp *rtp_session, audio_frame *buffer);

View File

@@ -55,32 +55,16 @@
#include <string.h>
#include "video.h"
struct video_frame * vf_alloc(int grid_width, int grid_height)
struct video_frame * vf_alloc(int count)
{
struct video_frame *buf;
buf = (struct video_frame *) malloc(sizeof(struct video_frame));
buf->tiles = (struct tiles *)
calloc(1, sizeof(struct tile) * grid_width *
grid_height);
buf->grid_width = grid_width;
buf->grid_height = grid_height;
calloc(1, sizeof(struct tile) * count);
buf->tile_count = count;
int x, y;
for(x = 0; x < grid_width; ++x) {
for(y = 0; y < grid_height; ++y) {
buf->tiles[x + y * grid_width].tile_info.x_count =
grid_width;
buf->tiles[x + y * grid_width].tile_info.y_count =
grid_height;
buf->tiles[x + y * grid_width].tile_info.pos_x =
x;
buf->tiles[x + y * grid_width].tile_info.pos_y =
y;
}
}
return buf;
}
@@ -92,11 +76,11 @@ void vf_free(struct video_frame *buf)
free(buf);
}
struct tile * tile_get(struct video_frame *buf, int grid_x_pos, int grid_y_pos)
struct tile * vf_get_tile(struct video_frame *buf, int pos)
{
assert (grid_x_pos < buf->grid_width && grid_y_pos < buf->grid_height);
assert (pos < buf->tile_count);
return &buf->tiles[grid_x_pos + grid_y_pos * buf->grid_width];
return &buf->tiles[pos];
}
int video_desc_eq(struct video_desc a, struct video_desc b)
@@ -104,7 +88,56 @@ int video_desc_eq(struct video_desc a, struct video_desc b)
return a.width == b.width &&
a.height == b.height &&
a.color_spec == b.color_spec &&
fabs(a.fps - b.fps) < 0.01 &&
fabs(a.fps - b.fps) < 0.01;// &&
// TODO: remove these obsolete constants
(a.aux & (~AUX_RGB & ~AUX_YUV & ~AUX_10Bit)) == (b.aux & (~AUX_RGB & ~AUX_YUV & ~AUX_10Bit));
//(a.aux & (~AUX_RGB & ~AUX_YUV & ~AUX_10Bit)) == (b.aux & (~AUX_RGB & ~AUX_YUV & ~AUX_10Bit));
}
int get_video_mode_tiles_x(int video_type)
{
int ret;
switch(video_type) {
case VIDEO_NORMAL:
case VIDEO_DUAL:
ret = 1;
break;
case VIDEO_4K:
case VIDEO_STEREO:
ret = 2;
break;
}
return ret;
}
int get_video_mode_tiles_y(int video_type)
{
int ret;
switch(video_type) {
case VIDEO_NORMAL:
case VIDEO_STEREO:
ret = 1;
break;
case VIDEO_4K:
case VIDEO_DUAL:
ret = 2;
break;
}
return ret;
}
const char *get_interlacing_description(enum interlacing_t interlacing)
{
switch (interlacing) {
case PROGRESSIVE:
return "progressive";
case UPPER_FIELD_FIRST:
return "interlaced (upper field first)";
case LOWER_FIELD_FIRST:
return "interlaced (lower field first)";
case INTERLACED_MERGED:
return "interlaced merged";
case SEGMENTED_FRAME:
return "progressive segmented";
}
}

View File

@@ -65,13 +65,29 @@ typedef enum {
JPEG
} codec_t;
enum interlacing_t {
PROGRESSIVE = 0,
UPPER_FIELD_FIRST = 1,
LOWER_FIELD_FIRST = 2,
INTERLACED_MERGED = 3,
SEGMENTED_FRAME = 4
};
#define VIDEO_NORMAL 0u
#define VIDEO_DUAL 1u
#define VIDEO_STEREO 2u
#define VIDEO_4K 3u
/* please note that tiles have also its own widths and heights */
struct video_desc {
unsigned int width;
unsigned int height;
codec_t color_spec;
int aux;
double fps;
enum interlacing_t interlacing;
unsigned int video_mode;
};
/* contains full information both about video and about tiles.
@@ -84,12 +100,11 @@ struct video_desc_ti {
struct video_frame
{
codec_t color_spec;
int aux;
enum interlacing_t interlacing;
double fps;
struct tile *tiles;
unsigned int grid_width; /* tiles */
unsigned int grid_height;
unsigned int tile_count;
};
struct tile {
@@ -102,25 +117,23 @@ struct tile {
*/
unsigned int data_len; /* relative to data pos, not framebuffer size! */
unsigned int linesize;
struct tile_info tile_info;
};
struct video_frame * vf_alloc(int grid_width, int grid_height);
struct video_frame * vf_alloc(int count);
void vf_free(struct video_frame *buf);
struct tile * tile_get(struct video_frame *buf, int grid_x_pos, int grid_y_pos);
struct tile * vf_get_tile(struct video_frame *buf, int pos);
int video_desc_eq(struct video_desc, struct video_desc);
int get_video_mode_tiles_x(int video_mode);
int get_video_mode_tiles_y(int video_mode);
const char *get_interlacing_description(enum interlacing_t);
/*
* Currently used (pre 1.0) is only AUX_{INTERLACED, PROGRESSIVE, SF, TILED}
*/
#define AUX_INTERLACED (1<<0)
#define AUX_PROGRESSIVE (1<<1)
#define AUX_SF (1<<2)
#define AUX_RGB (1<<3) /* if device supports both, set both */
#define AUX_YUV (1<<4)
#define AUX_10Bit (1<<5)
#define AUX_TILED (1<<6)
#endif

View File

@@ -486,8 +486,7 @@ vidcap_decklink_init(char *fmt, unsigned int flags)
device_found[i] = false;
if(s->stereo) {
s->frame = vf_alloc(2, 1);
s->frame->aux = AUX_TILED;
s->frame = vf_alloc(2);
if (s->devices_cnt > 1) {
fprintf(stderr, "[DeckLink] Passed more than one device while setting 3D mode. "
"In this mode, only one device needs to be passed.");
@@ -495,25 +494,13 @@ vidcap_decklink_init(char *fmt, unsigned int flags)
return NULL;
}
} else {
if (s->devices_cnt > 1) {
double x_cnt = sqrt(s->devices_cnt);
int x_count = x_cnt - round(x_cnt) == 0.0 ? x_cnt : s->devices_cnt;
int y_count = s->devices_cnt / x_cnt;
s->frame = vf_alloc(x_count, y_count);
s->frame->aux = AUX_TILED;
} else {
s->frame = vf_alloc(1, 1);
s->frame->aux = 0;
}
s->frame = vf_alloc(s->devices_cnt);
}
/* TODO: make sure that all devices are have compatible properties */
for (int i = 0; i < s->devices_cnt; ++i)
{
int x_pos = i % s->frame->tiles[0].tile_info.x_count;
int y_pos = i / s->frame->tiles[0].tile_info.x_count;
struct tile * tile = tile_get(s->frame, x_pos, y_pos);
struct tile * tile = vf_get_tile(s->frame, i);
dnum = 0;
deckLink = NULL;
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
@@ -619,13 +606,13 @@ vidcap_decklink_init(char *fmt, unsigned int flags)
switch(displayMode->GetFieldDominance()) {
case bmdLowerFieldFirst:
case bmdUpperFieldFirst:
s->frame->aux |= AUX_INTERLACED;
s->frame->interlacing = INTERLACED_MERGED;
break;
case bmdProgressiveFrame:
s->frame->aux |= AUX_PROGRESSIVE;
s->frame->interlacing = PROGRESSIVE;
break;
case bmdProgressiveSegmentedFrame:
s->frame->aux |= AUX_SF;
s->frame->interlacing = SEGMENTED_FRAME;
break;
}

View File

@@ -201,8 +201,8 @@ void *vidcap_dvs_init_impl(char *fmt, unsigned int flags)
s = (struct vidcap_dvs_state *)
calloc(1, sizeof(struct vidcap_dvs_state));
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
if (s == NULL) {
debug_msg("Unable to allocate DVS state\n");
@@ -290,7 +290,18 @@ void *vidcap_dvs_init_impl(char *fmt, unsigned int flags)
s->tile->width = s->mode->width;
s->tile->height = s->mode->height;
s->frame->fps = s->mode->fps;
s->frame->aux = s->mode->aux;
switch(s->mode->aux) {
case AUX_PROGRESSIVE:
s->frame->interlacing = PROGRESSIVE;
break;
case AUX_INTERLACED:
s->frame->interlacing = INTERLACED_MERGED;
break;
case AUX_SF:
s->frame->interlacing = SEGMENTED_FRAME;
break;
}
s->tile->linesize = vc_get_linesize(s->tile->width, s->frame->color_spec);
s->tile->data_len = s->tile->linesize * s->tile->height;

View File

@@ -103,7 +103,7 @@ struct frame_mode {
unsigned int width;
unsigned int height;
double fps;
int interlacing; /* AUX_* */
int aux; /* AUX_* */
unsigned int magic;
};
@@ -191,7 +191,7 @@ static const struct frame_mode frame_modes[] = {
};
struct vidcap_quad_state {
int device_cnt;
int devices_cnt;
int fd[MAX_TILES];
struct pollfd pfd[MAX_TILES];
int audio_fd;
@@ -353,7 +353,7 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
int i;
char *save_ptr = NULL;
char *fmt_dup, *item;
int tile_x_cnt, tile_y_cnt;
int devices[4];
printf("vidcap_quad_init\n");
@@ -383,8 +383,23 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
}
fmt_dup = strdup(init_fmt);
item = strtok_r(fmt_dup, ":", &save_ptr);
item = strtok_r(NULL, ":", &save_ptr);
assert(item != NULL);
char *devices_str = strdup(item);
s->devices_cnt = 0;
char *ptr, *saveptr2 = NULL;
ptr = strtok_r(devices_str, ",", &saveptr2);
do {
devices[s->devices_cnt] = atoi(ptr);
++s->devices_cnt;
} while (ptr = strtok_r(NULL, ",", &saveptr2));
free(devices_str);
item = strtok_r(fmt_dup, ":", &save_ptr);
assert(item);
frame_mode_number = atoi(item);
if(frame_mode_number < 0 ||
(unsigned int) frame_mode_number >=
@@ -397,25 +412,10 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
"via sysfs.");
return NULL;
}
if((item = strtok_r(NULL, ":", &save_ptr)) != NULL)
{
tile_x_cnt = atoi(item);
item = strtok_r(NULL, ":", &save_ptr);
if (item == NULL) {
fprintf(stderr, "quad: One tile dimension entered, expected zero or 2 values (see -g help)!");
return NULL;
}
tile_y_cnt = atoi(item);
s->device_cnt = tile_x_cnt * tile_y_cnt;
} else {
tile_x_cnt = 1;
tile_y_cnt = 1;
s->device_cnt = 1;
}
free(fmt_dup);
s->frame = vf_alloc(tile_x_cnt, tile_y_cnt);
s->frame = vf_alloc(s->devices_cnt);
/* CHECK IF QUAD CAN WORK CORRECTLY */
@@ -428,7 +428,7 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
memset((void *) s->fd, 0, sizeof(s->fd));
//memset((void *) s->frame, 0, sizeof(s->frame));
for(i = 0; i < s->device_cnt; ++i) {
for(i = 0; i < s->devices_cnt; ++i) {
char dev_name[MAXLEN];
unsigned int cap;
unsigned int val;
@@ -443,10 +443,7 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
unsigned long int mode;
const struct codec_info_t *c_info;
int tile_x = i % tile_x_cnt;
int tile_y = i / tile_x_cnt;
snprintf(dev_name, sizeof(dev_name), devfile_fmt, i);
snprintf(dev_name, sizeof(dev_name), devfile_fmt, devices[i]);
memset (&buf, 0, sizeof (buf));
if(stat (dev_name, &buf) < 0) {
@@ -622,19 +619,26 @@ vidcap_quad_init(char *init_fmt, unsigned int flags)
/*Get video standard*/
/*frame_mode = get_video_standard (s->fd);*/
struct tile *tile = tile_get(s->frame, tile_x, tile_y);
struct tile *tile = vf_get_tile(s->frame, i);
s->frame->color_spec = c_info->codec;
s->frame->fps = frame_mode->fps;
s->frame->aux = frame_mode->interlacing;
switch(frame_mode->aux) {
case AUX_PROGRESSIVE:
s->frame->interlacing = PROGRESSIVE;
break;
case AUX_INTERLACED:
s->frame->interlacing = INTERLACED_MERGED;
break;
case AUX_SF:
s->frame->interlacing = SEGMENTED_FRAME;
break;
}
tile->width = frame_mode->width;
tile->height = frame_mode->height;
tile->linesize = vc_get_linesize(frame_mode->width, c_info->codec);
tile->data_len = tile->linesize * tile->height;
if(s->device_cnt > 1) {
s->frame->aux |= AUX_TILED;
}
if((tile->data = (char *)
malloc (tile->data_len)) == NULL) {
@@ -665,7 +669,7 @@ vidcap_quad_done(void *state)
if (s != NULL) {
int i;
for (i = 0; i < s->device_cnt; ++i) {
for (i = 0; i < s->devices_cnt; ++i) {
if(s->frame->tiles[i].data != NULL)
free(s->frame->tiles[i].data);
if(s->fd[i] != 0)
@@ -697,19 +701,17 @@ static void * vidcap_grab_thread(void *args)
if (should_exit)
break;
//for(cur_dev = 0; cur_dev < s->device_cnt; ++cur_dev)
while (return_vec != (1 << s->device_cnt) - 1)
//for(cur_dev = 0; cur_dev < s->devices_cnt; ++cur_dev)
while (return_vec != (1 << s->devices_cnt) - 1)
{
if(poll (s->pfd, s->device_cnt, 1000/23) < 0) {
if(poll (s->pfd, s->devices_cnt, 1000/23) < 0) {
//fprintf (stderr, "%s: ", device);
perror ("unable to poll device file");
return NULL;
}
for(cur_dev = 0; cur_dev < s->device_cnt; ++cur_dev) {
int x_til_cnt = s->frame->tiles[0].tile_info.x_count;
struct tile *tile = tile_get(s->frame, cur_dev % x_til_cnt,
cur_dev / x_til_cnt);
for(cur_dev = 0; cur_dev < s->devices_cnt; ++cur_dev) {
struct tile *tile = vf_get_tile(s->frame, cur_dev);
if (s->pfd[cur_dev].revents & POLLIN) {
@@ -754,11 +756,9 @@ static void * vidcap_grab_thread(void *args)
}
}
while (poll (s->pfd, s->device_cnt, 0) > 0) {
for(cur_dev = 0; cur_dev < s->device_cnt; ++cur_dev) {
int x_til_cnt = s->frame->tiles[0].tile_info.x_count;
struct tile *tile = tile_get(s->frame, cur_dev % x_til_cnt,
cur_dev / x_til_cnt);
while (poll (s->pfd, s->devices_cnt, 0) > 0) {
for(cur_dev = 0; cur_dev < s->devices_cnt; ++cur_dev) {
struct tile *tile = vf_get_tile(s->frame, cur_dev);
if (s->pfd[cur_dev].revents & POLLIN) {
unsigned int ret;
@@ -847,8 +847,58 @@ vidcap_quad_grab(void *state, struct audio_frame **audio)
static void print_output_modes()
{
unsigned int i;
printf("usage: -t quad:<mode>:[<x_tiles_count>:<y_tiles_count>]\n\twhere mode is one of following.\n");
printf("Available output modes:\n");
printf("usage: -t quad:<device(s)>:<mode>\n\twhere mode is one of following.\n");
printf("\nAvailable devices (inputs):\n");
for(i = 0; i < 16; ++i) {
char dev_name[MAXLEN];
struct stat buf;
snprintf(dev_name, sizeof(dev_name), devfile_fmt, i);
memset (&buf, 0, sizeof (buf));
if(stat (dev_name, &buf) < 0) {
break;
} else {
struct util_info *info;
char type;
int num;
unsigned long int id;
char name[MAXLEN];
/* Check if it is a character device or not */
if(!S_ISCHR (buf.st_mode)) {
fprintf (stderr, "not a character device\n");
continue;
}
if(!(buf.st_rdev & 0x0080)) {
fprintf (stderr, "not a receiver\n");
continue;
}
/* Check the minor number to determine if it is a receive or transmit device */
type = (buf.st_rdev & 0x0080) ? 'r' : 't';
/* Get the receiver or transmitter number */
num = buf.st_rdev & 0x007f;
/* Build the path to sysfs file */
snprintf (name, sizeof (name), sys_fmt, type, num, "dev");
if (util_strtoul (name, &id) < 0) {
fprintf (stderr, "unable to get the firmware version");
continue;
}
if ((info = getinfo (id)) == NULL) {
printf ("\tUnknown device\n");
} else {
printf ("\t%d) %s\n", i,
info->name);
}
}
}
printf("\nAvailable output modes:\n");
for(i = 0; i < sizeof(frame_modes)/sizeof(struct frame_mode); ++i) {
if(frame_modes[i].magic == FMODE_MAGIC)
printf("\t%2u: %s\n", i, frame_modes[i].name);
@@ -859,3 +909,4 @@ static void print_output_modes()
#endif /* HAVE_QUAD */
#endif /* HAVE_MACOSX */

View File

@@ -623,7 +623,17 @@ static int qt_open_grabber(struct qt_grabber_state *s, char *fmt)
s->qt_mode->height,
s->qt_mode->fps,
s->qt_mode->aux);
s->frame->aux = s->qt_mode->aux & (AUX_INTERLACED|AUX_PROGRESSIVE|AUX_SF);
switch(s->qt_mode->aux & (AUX_INTERLACED|AUX_PROGRESSIVE|AUX_SF)) {
case AUX_PROGRESSIVE:
s->frame->interlacing = PROGRESSIVE;
break;
case AUX_INTERLACED:
s->frame->interlacing = INTERLACED_MERGED;
break;
case AUX_SF:
s->frame->interlacing = SEGMENTED_FRAME;
break;
}
free(device);
free(input);
break;
@@ -807,8 +817,8 @@ void *vidcap_quicktime_init(char *fmt, unsigned int flags)
s = (struct qt_grabber_state *)calloc(1,sizeof(struct qt_grabber_state));
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
if (s != NULL) {
s->magic = MAGIC_QT_GRABBER;

View File

@@ -104,6 +104,7 @@ struct testcard_state {
struct audio_frame audio;
char **tiles_data;
int tiles_cnt_horizontal;
char *audio_data;
volatile int audio_start, audio_end;
@@ -398,10 +399,10 @@ static int configure_tiling(struct testcard_state *s, const char *fmt)
grid_h = atoi(token);
free(tmp);
s->tiled = vf_alloc(grid_w, grid_h);
s->tiled = vf_alloc(grid_w * grid_h);
s->tiles_cnt_horizontal = grid_h;
s->tiled->color_spec = s->frame->color_spec;
s->tiled->fps = s->frame->fps;
s->tiled->aux = s->frame->aux | AUX_TILED;
tile_cnt = grid_w *
grid_h;
@@ -423,10 +424,6 @@ static int configure_tiling(struct testcard_state *s, const char *fmt)
s->tiled->tiles[x].width = s->frame->tiles[0].width/ grid_w;
s->tiled->tiles[x].height = s->frame->tiles[0].height / grid_h;
s->tiled->tiles[x].data_len = s->frame->tiles[0].data_len / (grid_w * grid_h);
s->tiled->tiles[x].tile_info.x_count = grid_w;
s->tiled->tiles[x].tile_info.y_count = grid_h;
s->tiled->tiles[x].tile_info.pos_x = x;
s->tiled->tiles[x].tile_info.pos_y = 0;
s->tiled->tiles[x].data =
s->tiles_data[x] = (char *) realloc(s->tiled->tiles[x].data,
@@ -447,7 +444,6 @@ static int configure_tiling(struct testcard_state *s, const char *fmt)
s->tiled->tiles[y * grid_w + x].data =
s->tiles_data[x] +
y * s->tiled->tiles[x].height * s->tiled->tiles[x].linesize;
s->tiled->tiles[y * grid_w + x].tile_info.pos_y = y;
}
}
@@ -479,7 +475,7 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
if (!s)
return NULL;
s->frame = vf_alloc(1, 1);
s->frame = vf_alloc(1);
char *tmp;
@@ -489,19 +485,14 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
free(s);
return NULL;
}
tile_get(s->frame, 0, 0)->width = atoi(tmp);
if(tile_get(s->frame, 0, 0)->width % 2 != 0) {
fprintf(stderr, "[testcard] Width must be multiple of 2.\n");
free(s);
return NULL;
}
vf_get_tile(s->frame, 0)->width = atoi(tmp);
tmp = strtok(NULL, ":");
if (!tmp) {
fprintf(stderr, "Wrong format for testcard '%s'\n", fmt);
free(s);
return NULL;
}
tile_get(s->frame, 0, 0)->height = atoi(tmp);
vf_get_tile(s->frame, 0)->height = atoi(tmp);
tmp = strtok(NULL, ":");
if (!tmp) {
free(s);
@@ -537,16 +528,16 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
return NULL;
}
aligned_x = tile_get(s->frame, 0, 0)->width;
aligned_x = vf_get_tile(s->frame, 0)->width;
if (h_align) {
aligned_x = (aligned_x + h_align - 1) / h_align * h_align;
}
rect_size = (tile_get(s->frame, 0, 0)->width + rect_size - 1) / rect_size;
rect_size = (vf_get_tile(s->frame, 0)->width + rect_size - 1) / rect_size;
tile_get(s->frame, 0, 0)->linesize = aligned_x * bpp;
s->frame->aux = AUX_PROGRESSIVE;
s->size = aligned_x * tile_get(s->frame, 0, 0)->height * bpp;
vf_get_tile(s->frame, 0)->linesize = aligned_x * bpp;
s->frame->interlacing = PROGRESSIVE;
s->size = aligned_x * vf_get_tile(s->frame, 0)->height * bpp;
filename = strtok(NULL, ":");
if (filename && strcmp(filename, "p") != 0
@@ -581,7 +572,7 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
struct testcard_rect r;
int col_num = 0;
s->pixmap.w = aligned_x;
s->pixmap.h = tile_get(s->frame, 0, 0)->height * 2;
s->pixmap.h = vf_get_tile(s->frame, 0)->height * 2;
s->pixmap.data = malloc(s->pixmap.w * s->pixmap.h * sizeof(int));
if (filename) {
@@ -591,10 +582,10 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
strip_fmt = filename;
}
for (j = 0; j < tile_get(s->frame, 0, 0)->height; j += rect_size) {
for (j = 0; j < vf_get_tile(s->frame, 0)->height; j += rect_size) {
int grey = 0xff010101;
if (j == rect_size * 2) {
r.w = tile_get(s->frame, 0, 0)->width;
r.w = vf_get_tile(s->frame, 0)->width;
r.h = rect_size / 4;
r.x = 0;
r.y = j;
@@ -602,7 +593,7 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
r.y = j + rect_size * 3 / 4;
testcard_fillRect(&s->pixmap, &r, 0);
}
for (i = 0; i < tile_get(s->frame, 0, 0)->width; i += rect_size) {
for (i = 0; i < vf_get_tile(s->frame, 0)->width; i += rect_size) {
r.w = rect_size;
r.h = rect_size;
r.x = i;
@@ -623,42 +614,42 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
s->data = s->pixmap.data;
if (codec == UYVY || codec == v210 || codec == Vuy2) {
rgb2yuv422((unsigned char *) s->data, aligned_x,
tile_get(s->frame, 0, 0)->height);
vf_get_tile(s->frame, 0)->height);
}
if (codec == v210) {
s->data =
(char *)tov210((unsigned char *) s->data, aligned_x,
aligned_x, tile_get(s->frame, 0, 0)->height, bpp);
aligned_x, vf_get_tile(s->frame, 0)->height, bpp);
}
if (codec == R10k) {
toR10k((unsigned char *) s->data, tile_get(s->frame, 0, 0)->width,
tile_get(s->frame, 0, 0)->height);
toR10k((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width,
vf_get_tile(s->frame, 0)->height);
}
if(codec == RGB) {
s->data =
(char *)toRGB((unsigned char *) s->data, tile_get(s->frame, 0, 0)->width,
tile_get(s->frame, 0, 0)->height);
(char *)toRGB((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width,
vf_get_tile(s->frame, 0)->height);
}
if(codec == RGBA) {
toRGB((unsigned char *) s->data, tile_get(s->frame, 0, 0)->width,
tile_get(s->frame, 0, 0)->height);
toRGB((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width,
vf_get_tile(s->frame, 0)->height);
}
}
tile_get(s->frame, 0, 0)->data = malloc(2 * s->size);
vf_get_tile(s->frame, 0)->data = malloc(2 * s->size);
memcpy(tile_get(s->frame, 0, 0)->data, s->data, s->size);
memcpy(tile_get(s->frame, 0, 0)->data + s->size, tile_get(s->frame, 0, 0)->data, s->size);
memcpy(vf_get_tile(s->frame, 0)->data, s->data, s->size);
memcpy(vf_get_tile(s->frame, 0)->data + s->size, vf_get_tile(s->frame, 0)->data, s->size);
if(s->pixmap.data)
free(s->pixmap.data);
else
free(tile_get(s->frame, 0, 0)->data);
free(vf_get_tile(s->frame, 0)->data);
s->data = tile_get(s->frame, 0, 0)->data;
s->data = vf_get_tile(s->frame, 0)->data;
tmp = strtok(NULL, ":");
if (tmp) {
@@ -678,16 +669,14 @@ void *vidcap_testcard_init(char *fmt, unsigned int flags)
s->count = 0;
gettimeofday(&(s->last_frame_time), NULL);
printf("Testcard capture set to %dx%d, bpp %f\n", tile_get(s->frame, 0, 0)->width,
tile_get(s->frame, 0, 0)->height, bpp);
printf("Testcard capture set to %dx%d, bpp %f\n", vf_get_tile(s->frame, 0)->width,
vf_get_tile(s->frame, 0)->height, bpp);
tile_get(s->frame, 0, 0)->data_len = s->size;
vf_get_tile(s->frame, 0)->data_len = s->size;
if(strip_fmt != NULL) {
if(configure_tiling(s, strip_fmt) != 0)
return NULL;
} else {
s->frame->aux &= ~AUX_TILED;
}
if(flags & VIDCAP_FLAG_ENABLE_AUDIO) {
@@ -768,9 +757,9 @@ struct video_frame *vidcap_testcard_grab(void *arg, struct audio_frame **audio)
}
tile_get(state->frame, 0, 0)->data += tile_get(state->frame, 0, 0)->linesize;
if(tile_get(state->frame, 0, 0)->data > state->data + state->size)
tile_get(state->frame, 0, 0)->data = state->data;
vf_get_tile(state->frame, 0)->data += vf_get_tile(state->frame, 0)->linesize;
if(vf_get_tile(state->frame, 0)->data > state->data + state->size)
vf_get_tile(state->frame, 0)->data = state->data;
/*char line[state->frame.src_linesize * 2 + state->pan];
unsigned int i;
@@ -800,8 +789,7 @@ struct video_frame *vidcap_testcard_grab(void *arg, struct audio_frame **audio)
if (state->tiled) {
/* update tile data instead */
int i;
int count = state->tiled->grid_width *
state->tiled->grid_height;
int count = state->tiled->tile_count;
for (i = 0; i < count; ++i) {
/* shift - for semantics of vars refer to configure_tiling*/
@@ -810,7 +798,7 @@ struct video_frame *vidcap_testcard_grab(void *arg, struct audio_frame **audio)
* keep in mind that we have two "pictures" for
* every tile stored sequentially */
if(state->tiled->tiles[i].data >= state->tiles_data[i] +
state->tiled->tiles[i].data_len * state->tiled->grid_height) {
state->tiled->tiles[i].data_len * state->tiles_cnt_horizontal) {
state->tiled->tiles[i].data = state->tiles_data[i];
}
}

View File

@@ -162,8 +162,8 @@ void *vidcap_testcard2_init(char *fmt, unsigned int flags)
char *tmp;
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
tmp = strtok(fmt, ":");
if (!tmp) {
@@ -226,7 +226,7 @@ void *vidcap_testcard2_init(char *fmt, unsigned int flags)
rect_size = (s->tile->width + rect_size - 1) / rect_size;
s->frame->aux = AUX_PROGRESSIVE;
s->frame->interlacing = AUX_PROGRESSIVE;
s->size = s->aligned_x * s->tile->height * bpp;
{

View File

@@ -126,6 +126,30 @@ double get_bpp(codec_t codec)
return 0;
}
uint32_t get_fourcc(codec_t codec)
{
int i = 0;
while (codec_info[i].name != NULL) {
if (codec == codec_info[i].codec)
return codec_info[i].fcc;
i++;
}
return 0;
}
codec_t get_codec_from_fcc(uint32_t fourcc)
{
int i = 0;
while (codec_info[i].name != NULL) {
if (fourcc == codec_info[i].fcc)
return codec_info[i].codec;
i++;
}
return 0;
}
static int get_halign(codec_t codec)
{
int i = 0;

View File

@@ -71,6 +71,8 @@ extern const struct line_decode_from_to line_decoders[]; /* defined int .c */
void show_codec_help(char *mode);
double get_bpp(codec_t codec);
uint32_t get_fourcc(codec_t codec);
codec_t get_codec_from_fcc(uint32_t fourcc);
int get_haligned(int width_pixels, codec_t codec);
int vc_get_linesize(unsigned int width, codec_t codec);

View File

@@ -86,21 +86,19 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
int h_align = 0;
enum dxt_format format;
assert(tile_get(frame, 0, 0)->width % 4 == 0);
s->out = vf_alloc(frame->grid_width, frame->grid_height);
assert(vf_get_tile(frame, 0)->width % 4 == 0);
s->out = vf_alloc(frame->tile_count);
for (x = 0; x < frame->grid_width; ++x) {
for (y = 0; y < frame->grid_height; ++y) {
if (tile_get(frame, x, y)->width != tile_get(frame, 0, 0)->width ||
tile_get(frame, x, y)->width != tile_get(frame, 0, 0)->width)
for (x = 0; x < frame->tile_count; ++x) {
if (vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width ||
vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width)
error_with_code_msg(128,"[RTDXT] Requested to compress tiles of different size!");
tile_get(s->out, x, y)->width = tile_get(frame, 0, 0)->width;
tile_get(s->out, x, y)->height = tile_get(frame, 0, 0)->height;
}
vf_get_tile(s->out, x)->width = vf_get_tile(frame, 0)->width;
vf_get_tile(s->out, x)->height = vf_get_tile(frame, 0)->height;
}
s->out->aux = frame->aux;
s->out->interlacing = PROGRESSIVE;
s->out->fps = frame->fps;
s->out->color_spec = s->color_spec;
@@ -140,41 +138,36 @@ static void configure_with(struct video_compress *s, struct video_frame *frame)
}
/* We will deinterlace the output frame */
if(s->out->aux & AUX_INTERLACED)
if(frame->interlacing == INTERLACED_MERGED)
s->interlaced_input = TRUE;
else
s->interlaced_input = FALSE;
s->out->aux &= ~AUX_INTERLACED;
s->dxt_height = (s->out->tiles[0].height + 3) / 4 * 4;
if(s->out->color_spec == DXT1) {
s->encoder = dxt_encoder_create(DXT_TYPE_DXT1, s->out->tiles[0].width, s->dxt_height, format);
s->out->aux |= AUX_RGB;
s->out->tiles[0].data_len = s->out->tiles[0].width * s->dxt_height / 2;
} else if(s->out->color_spec == DXT5){
s->encoder = dxt_encoder_create(DXT_TYPE_DXT5_YCOCG, s->out->tiles[0].width, s->dxt_height, format);
s->out->aux |= AUX_YUV; /* YCoCg */
s->out->tiles[0].data_len = s->out->tiles[0].width * s->dxt_height;
}
for (x = 0; x < frame->grid_width; ++x) {
for (y = 0; y < frame->grid_height; ++y) {
tile_get(s->out, x, y)->linesize = s->out->tiles[0].width;
switch(format) {
case DXT_FORMAT_RGBA:
tile_get(s->out, x, y)->linesize *= 4;
break;
case DXT_FORMAT_RGB:
tile_get(s->out, x, y)->linesize *= 3;
break;
case DXT_FORMAT_YUV422:
tile_get(s->out, x, y)->linesize *= 2;
break;
}
tile_get(s->out, x, y)->data_len = s->out->tiles[0].data_len;
tile_get(s->out, x, y)->data = (char *) malloc(s->out->tiles[0].data_len);
for (x = 0; x < frame->tile_count; ++x) {
vf_get_tile(s->out, x)->linesize = s->out->tiles[0].width;
switch(format) {
case DXT_FORMAT_RGBA:
vf_get_tile(s->out, x)->linesize *= 4;
break;
case DXT_FORMAT_RGB:
vf_get_tile(s->out, x)->linesize *= 3;
break;
case DXT_FORMAT_YUV422:
vf_get_tile(s->out, x)->linesize *= 2;
break;
}
vf_get_tile(s->out, x)->data_len = s->out->tiles[0].data_len;
vf_get_tile(s->out, x)->data = (char *) malloc(s->out->tiles[0].data_len);
}
if(!s->encoder) {
@@ -238,41 +231,39 @@ struct video_frame * dxt_glsl_compress(void *arg, struct video_frame * tx)
if(!s->configured)
configure_with(s, tx);
for (x = 0; x < tx->grid_width; ++x) {
for (y = 0; y < tx->grid_height; ++y) {
struct tile *in_tile = tile_get(tx, x, y);
struct tile *out_tile = tile_get(s->out, x, y);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded;
for (i = 0; i < (int) in_tile->height; ++i) {
s->decoder(line2, line1, out_tile->linesize,
0, 8, 16);
line1 += vc_get_linesize(in_tile->width, tx->color_spec);
line2 += out_tile->linesize;
}
/* if height % 4 != 0, copy last line to align */
if(s->dxt_height != out_tile->height) {
int y;
line1 = s->decoded + out_tile->linesize * (out_tile->height - 1);
for (y = out_tile->height; y < s->dxt_height; ++y)
{
memcpy(line2, line1, out_tile->linesize);
line2 += out_tile->linesize;
}
line2 += out_tile->linesize;
}
if(s->interlaced_input)
vc_deinterlace((unsigned char *) s->decoded, out_tile->linesize,
s->dxt_height);
dxt_encoder_compress(s->encoder,
(unsigned char *) s->decoded,
(unsigned char *) out_tile->data);
for (x = 0; x < tx->tile_count; ++x) {
struct tile *in_tile = vf_get_tile(tx, x);
struct tile *out_tile = vf_get_tile(s->out, x);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded;
for (i = 0; i < (int) in_tile->height; ++i) {
s->decoder(line2, line1, out_tile->linesize,
0, 8, 16);
line1 += vc_get_linesize(in_tile->width, tx->color_spec);
line2 += out_tile->linesize;
}
/* if height % 4 != 0, copy last line to align */
if(s->dxt_height != out_tile->height) {
int y;
line1 = s->decoded + out_tile->linesize * (out_tile->height - 1);
for (y = out_tile->height; y < s->dxt_height; ++y)
{
memcpy(line2, line1, out_tile->linesize);
line2 += out_tile->linesize;
}
line2 += out_tile->linesize;
}
if(s->interlaced_input)
vc_deinterlace((unsigned char *) s->decoded, out_tile->linesize,
s->dxt_height);
dxt_encoder_compress(s->encoder,
(unsigned char *) s->decoded,
(unsigned char *) out_tile->data);
}
return s->out;

View File

@@ -94,12 +94,13 @@ struct video_compress {
pthread_mutex_t lock;
volatile int thread_count;
pthread_t thread_ids[MAX_THREADS];
int tx_aux;
codec_t tx_color_spec;
sem_t thread_compress[MAX_THREADS];
sem_t thread_done[MAX_THREADS];
int dxt_height;
enum interlacing_t interlacing_source;
int rgb:1;
decoder_t decoder;
@@ -108,55 +109,55 @@ struct video_compress {
};
static void compress_thread(void *args);
void reconfigure_compress(struct video_compress *compress, int width, int height, codec_t codec, int aux, double fps);
void reconfigure_compress(struct video_compress *compress, int width, int height, codec_t codec, enum interlacing_t, double fps);
void reconfigure_compress(struct video_compress *compress, int width, int height, codec_t codec, int aux, double fps)
void reconfigure_compress(struct video_compress *compress, int width, int height, codec_t codec, enum interlacing_t interlacing, double fps)
{
int x;
fprintf(stderr, "Compression reinitialized for %ux%u video.\n",
width, height);
/* Store original attributes to allow format change detection */
compress->tx_aux = aux;
compress->tx_color_spec = codec;
compress->interlacing_source = interlacing;
compress->tile->width = width;
compress->tile->height = height;
compress->dxt_height = (compress->tile->height + 3) / 4 * 4;
compress->frame->color_spec = codec;
compress->frame->aux = aux;
compress->frame->interlacing = PROGRESSIVE;
compress->frame->fps = fps;
switch (codec) {
case RGB:
compress->decoder = (decoder_t) vc_copylineRGBtoRGBA;
compress->frame->aux |= AUX_RGB;
compress->rgb = TRUE;
break;
case RGBA:
compress->decoder = (decoder_t) memcpy;
compress->frame->aux |= AUX_RGB;
compress->rgb = TRUE;
break;
case R10k:
compress->decoder = (decoder_t) vc_copyliner10k;
compress->frame->aux |= AUX_RGB;
compress->rgb = TRUE;
break;
case UYVY:
case Vuy2:
case DVS8:
compress->decoder = (decoder_t) memcpy;
compress->frame->aux |= AUX_YUV;
compress->rgb = FALSE;
break;
case v210:
compress->decoder = (decoder_t) vc_copylinev210;
compress->frame->aux |= AUX_YUV;
compress->rgb = FALSE;
break;
case DVS10:
compress->decoder = (decoder_t) vc_copylineDVS10;
compress->frame->aux |= AUX_YUV;
compress->rgb = FALSE;
break;
case DPX10:
compress->decoder = (decoder_t) vc_copylineDPX10toRGBA;
compress->frame->aux |= AUX_RGB;
compress->rgb = FALSE;
break;
default:
error_with_code_msg(128, "Unknown codec %d!", codec);
@@ -170,18 +171,15 @@ void reconfigure_compress(struct video_compress *compress, int width, int height
}
}
assert(h_align != 0);
compress->tile->linesize = tile_get(compress->frame, 0, 0)->width *
(compress->frame->aux & AUX_RGB ? 4 /*RGBA*/: 2/*YUV 422*/);
compress->tile->linesize = vf_get_tile(compress->frame, 0)->width *
(compress->rgb ? 4 /*RGBA*/: 2/*YUV 422*/);
if(compress->frame->aux & AUX_RGB) {
if(compress->rgb) {
compress->frame->color_spec = DXT1;
} else {
compress->frame->color_spec = DXT1_YUV;
}
/* We will deinterlace the output frame */
compress->frame->aux &= ~AUX_INTERLACED;
for (x = 0; x < compress->num_threads; x++) {
int my_height = (compress->dxt_height / compress->num_threads) / 4 * 4;
if(x == compress->num_threads - 1) {
@@ -232,8 +230,8 @@ void *fastdxt_init(const char *num_threads_str)
compress->num_threads = atoi(num_threads_str);
assert (compress->num_threads >= 1 && compress->num_threads <= MAX_THREADS);
compress->frame = vf_alloc(1, 1);
compress->tile = tile_get(compress->frame, 0, 0);
compress->frame = vf_alloc(1);
compress->tile = vf_get_tile(compress->frame, 0);
compress->tile->width = 0;
compress->tile->height = 0;
@@ -275,17 +273,17 @@ struct video_frame * fastdxt_compress(void *args, struct video_frame *tx)
unsigned int x;
unsigned char *line1, *line2;
assert(tx->grid_height == 1 && tx->grid_width == 1);
assert(tile_get(tx, 0, 0)->width % 4 == 0);
assert(tx->tile_count == 1);
assert(vf_get_tile(tx, 0)->width % 4 == 0);
pthread_mutex_lock(&(compress->lock));
if(tile_get(tx, 0, 0)->width != compress->tile->width ||
tile_get(tx, 0, 0)->height != compress->tile->height ||
tx->aux != compress->tx_aux ||
if(vf_get_tile(tx, 0)->width != compress->tile->width ||
vf_get_tile(tx, 0)->height != compress->tile->height ||
tx->interlacing != compress->interlacing_source ||
tx->color_spec != compress->tx_color_spec)
{
reconfigure_compress(compress, tile_get(tx, 0, 0)->width, tile_get(tx, 0, 0)->height, tx->color_spec, tx->aux, tx->fps);
reconfigure_compress(compress, vf_get_tile(tx, 0)->width, vf_get_tile(tx, 0)->height, tx->color_spec, tx->interlacing, tx->fps);
}
line1 = (unsigned char *)tx->tiles[0].data;
@@ -299,9 +297,15 @@ struct video_frame * fastdxt_compress(void *args, struct video_frame *tx)
line2 += compress->tile->linesize;
}
if(tx->aux & AUX_INTERLACED)
if(tx->interlacing != INTERLACED_MERGED && tx->interlacing != PROGRESSIVE) {
fprintf(stderr, "Unsupported interlacing format.\n");
exit_uv(1);
}
if(tx->interlacing == INTERLACED_MERGED) {
vc_deinterlace(compress->output_data, compress->tile->linesize,
compress->tile->height);
}
for (x = 0; x < compress->num_threads; x++) {
@@ -345,7 +349,7 @@ static void compress_thread(void *args)
}
my_range = my_height * compress->tile->width;
if(compress->frame->aux & AUX_YUV)
if(!compress->rgb)
{
unsigned char *input;
input = (compress->output_data) + myId

View File

@@ -78,21 +78,19 @@ static void configure_with(struct compress_jpeg_state *s, struct video_frame *fr
int x, y;
int h_align = 0;
assert(tile_get(frame, 0, 0)->width % 4 == 0);
s->out = vf_alloc(frame->grid_width, frame->grid_height);
assert(vf_get_tile(frame, 0)->width % 4 == 0);
s->out = vf_alloc(frame->tile_count);
for (x = 0; x < frame->grid_width; ++x) {
for (y = 0; y < frame->grid_height; ++y) {
if (tile_get(frame, x, y)->width != tile_get(frame, 0, 0)->width ||
tile_get(frame, x, y)->width != tile_get(frame, 0, 0)->width)
error_with_code_msg(128,"[JPEG] Requested to compress tiles of different size!");
tile_get(s->out, x, y)->width = tile_get(frame, 0, 0)->width;
tile_get(s->out, x, y)->height = tile_get(frame, 0, 0)->height;
}
for (x = 0; x < frame->tile_count; ++x) {
if (vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width ||
vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width)
error_with_code_msg(128,"[JPEG] Requested to compress tiles of different size!");
vf_get_tile(s->out, x)->width = vf_get_tile(frame, 0)->width;
vf_get_tile(s->out, x)->height = vf_get_tile(frame, 0)->height;
}
s->out->aux = frame->aux;
s->out->interlacing = PROGRESSIVE;
s->out->fps = frame->fps;
s->out->color_spec = s->color_spec;
@@ -133,11 +131,16 @@ static void configure_with(struct compress_jpeg_state *s, struct video_frame *fr
}
/* We will deinterlace the output frame */
if(s->out->aux & AUX_INTERLACED)
if(frame->interlacing == INTERLACED_MERGED)
s->interlaced_input = TRUE;
else
else if(frame->interlacing == PROGRESSIVE)
s->interlaced_input = FALSE;
s->out->aux &= ~AUX_INTERLACED;
else {
fprintf(stderr, "Unsupported interlacing option: %s.\n", get_interlacing_description(frame->interlacing));
free(s);
return NULL;
}
s->out->color_spec = JPEG;
struct jpeg_image_parameters param_image;
@@ -155,11 +158,8 @@ static void configure_with(struct compress_jpeg_state *s, struct video_frame *fr
s->encoder = jpeg_encoder_create(&param_image, &s->encoder_param);
for (x = 0; x < frame->grid_width; ++x) {
for (y = 0; y < frame->grid_height; ++y) {
tile_get(s->out, x, y)->data = (char *) malloc(s->out->tiles[0].width * s->jpeg_height * 3);
tile_get(s->out, x, y)->linesize = s->out->tiles[0].width * (param_image.color_space == JPEG_RGB ? 3 : 2);
}
for (x = 0; x < frame->tile_count; ++x) {
vf_get_tile(s->out, x)->data = (char *) malloc(s->out->tiles[0].width * s->jpeg_height * 3);
}
if(!s->encoder) {
@@ -242,42 +242,40 @@ struct video_frame * jpeg_compress(void *arg, struct video_frame * tx)
if(!s->encoder)
configure_with(s, tx);
for (x = 0; x < tx->grid_width; ++x) {
for (y = 0; y < tx->grid_height; ++y) {
struct tile *in_tile = tile_get(tx, x, y);
struct tile *out_tile = tile_get(s->out, x, y);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded;
for (i = 0; i < (int) in_tile->height; ++i) {
s->decoder(line2, line1, out_tile->linesize,
0, 8, 16);
line1 += vc_get_linesize(in_tile->width, tx->color_spec);
line2 += out_tile->linesize;
}
line1 = out_tile->data + (in_tile->height - 1) * out_tile->linesize;
for( ; i < s->jpeg_height; ++i) {
memcpy(line2, line1, out_tile->linesize);
line2 += out_tile->linesize;
}
if(s->interlaced_input)
vc_deinterlace((unsigned char *) s->decoded, out_tile->linesize,
s->jpeg_height);
uint8_t *compressed;
int size;
int ret;
ret = jpeg_encoder_encode(s->encoder, s->decoded, &compressed, &size);
if(ret != 0)
return NULL;
out_tile->data_len = size;
memcpy(out_tile->data, compressed, size);
for (x = 0; x < tx->tile_count; ++x) {
struct tile *in_tile = vf_get_tile(tx, x);
struct tile *out_tile = vf_get_tile(s->out, x);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded;
for (i = 0; i < (int) in_tile->height; ++i) {
s->decoder(line2, line1, out_tile->linesize,
0, 8, 16);
line1 += vc_get_linesize(in_tile->width, tx->color_spec);
line2 += out_tile->linesize;
}
line1 = out_tile->data + (in_tile->height - 1) * out_tile->linesize;
for( ; i < s->jpeg_height; ++i) {
memcpy(line2, line1, out_tile->linesize);
line2 += out_tile->linesize;
}
if(s->interlaced_input)
vc_deinterlace((unsigned char *) s->decoded, out_tile->linesize,
s->jpeg_height);
uint8_t *compressed;
int size;
int ret;
ret = jpeg_encoder_encode(s->encoder, s->decoded, &compressed, &size);
if(ret != 0)
return NULL;
out_tile->data_len = size;
memcpy(out_tile->data, compressed, size);
}
return s->out;

View File

@@ -79,7 +79,7 @@ typedef struct {
struct video_frame *(*func_getf) (void *state);
int (*func_putf) (void *state, char *frame);
void (*func_reconfigure)(void *state, struct video_desc desc);
int (*func_get_property)(void *state, int property, void *val, int *len);
int (*func_get_property)(void *state, int property, void *val, size_t *len);
struct audio_frame *(*func_get_audio_frame) (void *state);
void (*func_put_audio_frame) (void *state, const struct audio_frame *frame);
@@ -325,7 +325,7 @@ void display_reconfigure(struct display *d, struct video_desc desc)
display_device_table[d->index].func_reconfigure(d->state, desc);
}
int display_get_property(struct display *d, int property, void *val, int *len)
int display_get_property(struct display *d, int property, void *val, size_t *len)
{
assert(d->magic == DISPLAY_MAGIC);
return display_device_table[d->index].func_get_property(d->state, property, val, len);

View File

@@ -79,8 +79,11 @@ typedef struct {
#define DISPLAY_PROPERTY_GSHIFT 2 /* int */
#define DISPLAY_PROPERTY_BSHIFT 3 /* int */
#define DISPLAY_PROPERTY_BUF_PITCH 4 /* int */
#define DISPLAY_PROPERTY_VIDEO_MODE 5 /* int */
#define PITCH_DEFAULT -1 /* default to linesize */
#define DISPLAY_PROPERTY_VIDEO_MERGED 0
#define DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES 1
int display_init_devices(void);
void display_free_devices(void);
@@ -106,7 +109,7 @@ void display_reconfigure(struct display *d, struct video_desc desc);
struct audio_frame * display_get_audio_frame(struct display *d);
void display_put_audio_frame(struct display *d, const struct audio_frame *frame);
int display_get_property(struct display *d, int property, void *val, int *len);
int display_get_property(struct display *d, int property, void *val, size_t *len);
/*
* Additional interface allowing querying properties and monitoring changes

View File

@@ -354,7 +354,7 @@ static BMDDisplayMode get_mode(IDeckLinkOutput *deckLinkOutput, struct video_des
deckLinkDisplayMode->GetFrameRate(frameRateDuration,
frameRateScale);
displayFPS = (double) *frameRateScale / *frameRateDuration;
if(fabs(desc.fps - displayFPS) < 0.01// && (aux & AUX_INTERLACED && interlaced || !interlaced)
if(fabs(desc.fps - displayFPS) < 0.01 && (desc.interlacing == INTERLACED_MERGED && interlaced || !interlaced)
)
{
printf("Device %d - selected mode: %s\n", index, modeNameCString);
@@ -383,7 +383,7 @@ display_decklink_reconfigure(void *state, struct video_desc desc)
assert(s->magic == DECKLINK_MAGIC);
s->frame->color_spec = desc.color_spec;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
s->frame->fps = desc.fps;
switch (desc.color_spec) {
@@ -403,7 +403,7 @@ display_decklink_reconfigure(void *state, struct video_desc desc)
if(s->stereo) {
desc.width /= 2; // half of with for each channel
for (int i = 0; i < 2; ++i) {
struct tile *tile = tile_get(s->frame, i, 0);
struct tile *tile = vf_get_tile(s->frame, i);
tile->width = desc.width;
tile->height = desc.height;
tile->linesize = vc_get_linesize(tile->width, s->frame->color_spec);
@@ -420,7 +420,7 @@ display_decklink_reconfigure(void *state, struct video_desc desc)
exit(128);
}
s->state[0].deckLinkFrame = DeckLink3DFrame::Create(desc.width, desc.height, tile_get(s->frame, 0, 0)->linesize, pixelFormat);
s->state[0].deckLinkFrame = DeckLink3DFrame::Create(desc.width, desc.height, vf_get_tile(s->frame, 0)->linesize, pixelFormat);
s->state[0].deckLinkOutput->EnableVideoOutput(displayMode, bmdVideoOutputDualStream3D);
s->state[0].deckLinkFrame->GetBytes((void **) &s->frame->tiles[0].data);
@@ -433,10 +433,16 @@ display_decklink_reconfigure(void *state, struct video_desc desc)
for(int i = 0; i < s->devices_cnt; ++i) {
struct video_desc desc_dev;
/* compute position */
int x_count = s->frame->grid_width;
int y_count = s->frame->grid_height;
struct tile *tile = tile_get(s->frame, i % x_count,
i / x_count);
int x_count;
int y_count;
if(s->devices_cnt == 2) { /* stereo */
x_count = 2;
y_count = 1;
} else if (s->devices_cnt == 4) { /* tiled 4K */
x_count = y_count = 2;
}
struct tile *tile = vf_get_tile(s->frame, i);
desc_dev = desc;
@@ -575,17 +581,11 @@ void *display_decklink_init(char *fmt, unsigned int flags)
s->play_audio = FALSE;
}
double x_cnt = sqrt(s->devices_cnt);
int x_count = x_cnt - round(x_cnt) == 0.0 ? x_cnt : s->devices_cnt;
int y_count = s->devices_cnt / x_count;
if(s->stereo) {
s->frame = vf_alloc(2, 1);
s->frame = vf_alloc(2);
} else {
s->frame = vf_alloc(x_count, y_count);
s->frame = vf_alloc(s->devices_cnt);
}
if(s->devices_cnt > 1) {
s->frame->aux = AUX_TILED;
}
for(int i = 0; i < s->devices_cnt; ++i) {
// Obtain the audio/video output interface (IDeckLinkOutput)
@@ -634,8 +634,9 @@ display_type_t *display_decklink_probe(void)
return dtype;
}
int display_decklink_get_property(void *state, int property, void *val, int *len)
int display_decklink_get_property(void *state, int property, void *val, size_t *len)
{
struct state_decklink *s = (struct state_decklink *)state;
codec_t codecs[] = {v210, UYVY, RGBA};
switch (property) {
@@ -664,6 +665,12 @@ int display_decklink_get_property(void *state, int property, void *val, int *len
*(int *) val = PITCH_DEFAULT;
*len = sizeof(int);
break;
case DISPLAY_PROPERTY_VIDEO_MODE:
if(s->devices_cnt == 1)
*(int *) val = DISPLAY_PROPERTY_VIDEO_MERGED;
else
*(int *) val = DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES;
default:
return FALSE;
}

View File

@@ -57,7 +57,7 @@ struct video_frame *display_decklink_getf(void *state);
int display_decklink_putf(void *state, char *frame);
void display_decklink_reconfigure(void *state,
struct video_desc desc);
int display_decklink_get_property(void *state, int property, void *val, int *len);
int display_decklink_get_property(void *state, int property, void *val, size_t *len);
struct audio_frame * display_decklink_get_audio_frame(void *state);
void display_decklink_put_audio_frame(void *state, struct audio_frame *frame);

View File

@@ -79,7 +79,7 @@ typedef struct audio_frame * (*display_dvs_get_audio_frame_t)(void *state);
typedef void (*display_dvs_put_audio_frame_t)(void *state, struct audio_frame *frame);
typedef void (*display_dvs_reconfigure_t)(void *state,
struct video_desc desc);
typedef int (*display_dvs_get_property_t)(void *state, int property, void *val, int *len);
typedef int (*display_dvs_get_property_t)(void *state, int property, void *val, size_t *len);
static display_dvs_init_t display_dvs_init_func = NULL;
static display_dvs_run_t display_dvs_run_func = NULL;
@@ -261,7 +261,7 @@ void display_dvs_reconfigure(void *state,
display_dvs_reconfigure_func(state, desc);
}
int display_dvs_get_property(void *state, int property, void *val, int *len)
int display_dvs_get_property(void *state, int property, void *val, size_t *len)
{
pthread_once(&DVSLibraryLoad, loadLibrary);

View File

@@ -63,7 +63,7 @@ struct video_frame *display_dvs_getf(void *state);
int display_dvs_putf(void *state, char *frame);
void display_dvs_reconfigure(void *state,
struct video_desc desc);
int display_dvs_get_property(void *state, int property, void *val, int *len);
int display_dvs_get_property(void *state, int property, void *val, size_t *len);
struct audio_frame * display_dvs_get_audio_frame(void *state);
void display_dvs_put_audio_frame(void *state, struct audio_frame *frame);

View File

@@ -502,7 +502,7 @@ void display_dvs_reconfigure_impl(void *state,
s->frame->color_spec = desc.color_spec;
s->frame->fps = desc.fps;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
s->tile->width = desc.width;
s->tile->height = desc.height;
@@ -512,17 +512,21 @@ void display_dvs_reconfigure_impl(void *state,
for(i=0; hdsp_mode_table[i].width != 0; i++) {
if(hdsp_mode_table[i].width == desc.width &&
hdsp_mode_table[i].height == desc.height &&
(desc.aux == 0 || (desc.aux & hdsp_mode_table[i].aux)) &&
fabs(desc.fps - hdsp_mode_table[i].fps) < 0.01 ) {
s->mode = &hdsp_mode_table[i];
break;
if ((desc.interlacing == INTERLACED_MERGED && hdsp_mode_table[i].aux == AUX_INTERLACED ) ||
(desc.interlacing == PROGRESSIVE && hdsp_mode_table[i].aux == AUX_PROGRESSIVE) ||
(desc.interlacing == SEGMENTED_FRAME && hdsp_mode_table[i].aux == AUX_SF)) {
s->mode = &hdsp_mode_table[i];
break;
}
}
}
if(s->mode == NULL) {
fprintf(stderr, "Reconfigure failed. Expect troubles pretty soon..\n"
"\tRequested: %dx%d, color space %d, fps %f, aux: %d\n",
desc.width, desc.height, desc.color_spec, desc.fps, desc.aux);
"\tRequested: %dx%d, color space %d, fps %f,%s\n",
desc.width, desc.height, desc.color_spec, desc.fps,
get_interlacing_description(desc.interlacing));
return;
}
@@ -608,8 +612,8 @@ void *display_dvs_init_impl(char *fmt, unsigned int flags)
s->mode_set_manually = FALSE;
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
if (fmt != NULL) {
if (strcmp(fmt, "help") == 0) {
@@ -681,7 +685,23 @@ void *display_dvs_init_impl(char *fmt, unsigned int flags)
s->first_run = TRUE;
if(s->mode) {
struct video_desc desc = {s->mode->width, s->mode->height, s->frame->color_spec, s->mode->aux, s->mode->fps};
struct video_desc desc;
desc.width = s->mode->width;
desc.height = s->mode->height;
desc.color_spec = s->frame->color_spec;
switch(s->mode->aux) {
case AUX_INTERLACED:
desc.interlacing = INTERLACED_MERGED;
break;
case AUX_PROGRESSIVE:
desc.interlacing = PROGRESSIVE;
break;
case AUX_SF:
desc.interlacing = SEGMENTED_FRAME;
break;
}
desc.fps = s->mode->fps;
display_dvs_reconfigure_impl(s,
desc);
s->mode_set_manually = TRUE;
@@ -721,7 +741,7 @@ void display_dvs_done_impl(void *state)
free(s);
}
int display_dvs_get_property_impl(void *state, int property, void *val, int *len)
int display_dvs_get_property_impl(void *state, int property, void *val, size_t *len)
{
codec_t codecs[] = {DVS10, UYVY, RGBA, RGB};

View File

@@ -63,7 +63,7 @@ struct video_frame *display_dvs_getf_impl(void *state);
int display_dvs_putf_impl(void *state, char *frame);
void display_dvs_reconfigure_impl(void *state,
struct video_desc desc);
int display_dvs_get_property_impl(void *state, int property, void *val, int *len);
int display_dvs_get_property_impl(void *state, int property, void *val, size_t *len);
struct audio_frame * display_dvs_get_audio_frame_impl(void *state);
void display_dvs_put_audio_frame_impl(void *state, struct audio_frame *frame);

View File

@@ -322,8 +322,8 @@ void * display_gl_init(char *fmt, unsigned int flags) {
free(tmp);
}
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
s->tile->data = NULL;
s->frames = 0ul;
@@ -482,7 +482,7 @@ void display_gl_reconfigure(void *state, struct video_desc desc)
s->tile->width = desc.width;
s->tile->height = desc.height;
s->frame->fps = desc.fps;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
s->frame->color_spec = desc.color_spec;
pthread_mutex_lock(&s->lock);
@@ -914,7 +914,7 @@ display_type_t *display_gl_probe(void)
return dt;
}
int display_gl_get_property(void *state, int property, void *val, int *len)
int display_gl_get_property(void *state, int property, void *val, size_t *len)
{
UNUSED(state);
codec_t codecs[] = {UYVY, RGBA, RGB, DXT1, DXT1_YUV, DXT5};

View File

@@ -59,6 +59,6 @@ void display_gl_done(void *state);
struct video_frame *display_gl_getf(void *state);
int display_gl_putf(void *state, char *frame);
void display_gl_reconfigure(void *state, struct video_desc desc);
int display_gl_get_property(void *state, int property, void *val, int *len);
int display_gl_get_property(void *state, int property, void *val, size_t *len);
int display_gl_handle_events(void *arg);

View File

@@ -109,7 +109,7 @@ display_type_t *display_null_probe(void)
return dt;
}
int display_null_get_property(void *state, int property, void *val, int *len)
int display_null_get_property(void *state, int property, void *val, size_t *len)
{
UNUSED(state);
UNUSED(property);

View File

@@ -53,4 +53,4 @@ void display_null_done(void *state);
char *display_null_getf(void *state);
int display_null_putf(void *state, char *frame);
void display_null_reconfigure(void *state, struct video_desc desc);
int display_null_get_property(void *state, int property, void *val, int *len);
int display_null_get_property(void *state, int property, void *val, size_t *len);

View File

@@ -212,7 +212,7 @@ struct state_quicktime {
/* Prototyping */
char *four_char_decode(int format);
static int find_mode(ComponentInstance *ci, int width, int height,
const char * codec_name, double fps, int aux);
const char * codec_name, double fps);
void display_quicktime_audio_init(struct state_quicktime *s);
void display_quicktime_reconfigure_audio(void *state, int quant_samples, int channels,
int sample_rate);
@@ -258,8 +258,7 @@ static void reconf_common(struct state_quicktime *s)
for (i = 0; i < s->devices_cnt; ++i)
{
struct tile *tile = tile_get(s->frame, i % s->frame->grid_width,
i / s->frame->grid_width);
struct tile *tile = vf_get_tile(s->frame, i);
ImageDescriptionHandle imageDesc;
OSErr ret;
@@ -316,8 +315,7 @@ void display_quicktime_run(void *arg)
platform_sem_wait(&s->semaphore);
for (i = 0; i < s->devices_cnt; ++i) {
struct tile *tile = tile_get(s->frame, i % s->frame->grid_width,
i / s->frame->grid_width);
struct tile *tile = vf_get_tile(s->frame, i);
/* TODO: Running DecompressSequenceFrameWhen asynchronously
* in this way introduces a possible race condition!
*/
@@ -594,11 +592,7 @@ void *display_quicktime_init(char *fmt, unsigned int flags)
return NULL;
}
double x_cnt = sqrt(s->devices_cnt);
int x_count = x_cnt - round(x_cnt) == 0.0 ? x_cnt : s->devices_cnt;
int y_count = s->devices_cnt / x_count;
s->frame = vf_alloc(x_count, y_count);
s->frame = vf_alloc(s->devices_cnt);
for (i = 0; i < s->devices_cnt; ++i) {
s->videoDisplayComponentInstance[i] = 0;
@@ -616,12 +610,9 @@ void *display_quicktime_init(char *fmt, unsigned int flags)
}
free(codec_name);
s->frame->color_spec = s->cinfo->codec;
s->frame->aux = 0;
for (i = 0; i < s->devices_cnt; ++i) {
int pos_x = i % x_count;
int pos_y = i / y_count;
struct tile *tile = tile_get(s->frame, pos_x, pos_y);
struct tile *tile = vf_get_tile(i);
/* Open device */
s->videoDisplayComponentInstance[i] = OpenComponent((Component) s->device[i]);
@@ -819,7 +810,7 @@ display_type_t *display_quicktime_probe(void)
return dtype;
}
int display_quicktime_get_property(void *state, int property, void *val, int *len)
int display_quicktime_get_property(void *state, int property, void *val, size_t *len)
{
UNUSED(state);
codec_t codecs[] = {v210, UYVY, RGBA};
@@ -850,6 +841,12 @@ int display_quicktime_get_property(void *state, int property, void *val, int *le
*(int *) val = PITCH_DEFAULT;
*len = sizeof(int);
break;
case DISPLAY_PROPERTY_VIDEO_MODE:
if(s->devices_cnt == 1)
*(int *) val = DISPLAY_PROPERTY_VIDEO_MERGED;
else
*(int *) val = DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES;
default:
return FALSE;
}
@@ -880,14 +877,23 @@ void display_quicktime_reconfigure(void *state, struct video_desc desc)
desc.height, s->cinfo->bpp);
s->frame->color_spec = desc.color_spec;
s->frame->fps = desc.fps;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
for(i = 0; i < s->devices_cnt; ++i) {
int tile_width = desc.width / s->frame->grid_width;
int tile_height = desc.height / s->frame->grid_height;
int pos_x = i % s->frame->grid_width;
int pos_y = i / s->frame->grid_width;
struct tile * tile = tile_get(s->frame, pos_x, pos_y);
int tile_width;
int tile_height;
if(s->devices_cnt == 2) { /* stereo */
tile_width = desc.width / 2;
tile_height = desc.height;
}
if(s->devices_cnt = 4) { /*tiled 4K */
tile_width = desc.width / 2;
tile_height = desc.height / 2;
}
struct tile * tile = vf_get_tile(s->frame, i);
tile->width = tile_width;
tile->height = tile_height;
@@ -904,7 +910,7 @@ void display_quicktime_reconfigure(void *state, struct video_desc desc)
if(!s->mode_set_manually)
s->mode = find_mode(&s->videoDisplayComponentInstance[i],
tile_width, tile_height, codec_name, desc.fps, desc.aux);
tile_width, tile_height, codec_name, desc.fps);
/* Set the display mode */
ret =
QTVideoOutputSetDisplayMode(s->videoDisplayComponentInstance[i],
@@ -952,9 +958,8 @@ void display_quicktime_reconfigure(void *state, struct video_desc desc)
}
static int find_mode(ComponentInstance *ci, int width, int height,
const char * codec_name, double fps, int aux)
const char * codec_name, double fps)
{
UNUSED(aux);
QTAtom atomDisplay = 0, nextAtomDisplay = 0;
QTAtomType type;

View File

@@ -69,7 +69,7 @@ void display_quicktime_done(void *state);
struct video_frame *display_quicktime_getf(void *state);
int display_quicktime_putf(void *state, char *frame);
void display_quicktime_reconfigure(void *state, struct video_desc desc);
int display_quicktime_get_property(void *state, int property, void *val, int *len);
int display_quicktime_get_property(void *state, int property, void *val, size_t *len);
struct audio_frame *display_quicktime_get_audio_frame(void *state);
void display_quicktime_put_audio_frame(void *state, const struct audio_frame *frame);

View File

@@ -131,8 +131,8 @@ void *display_sage_init(char *fmt, unsigned int flags)
s = (struct state_sage *)malloc(sizeof(struct state_sage));
s->magic = MAGIC_SAGE;
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
/* sage init */
//FIXME sem se musi propasovat ty spravne parametry argc argv
@@ -220,7 +220,7 @@ void display_sage_reconfigure(void *state, struct video_desc desc)
s->tile->width = desc.width;
s->tile->height = desc.height;
s->frame->fps = desc.fps;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
s->frame->color_spec = desc.color_spec;
if(s->sage_state) {
@@ -246,7 +246,7 @@ display_type_t *display_sage_probe(void)
return dt;
}
int display_sage_get_property(void *state, int property, void *val, int *len)
int display_sage_get_property(void *state, int property, void *val, size_t *len)
{
UNUSED(state);
codec_t codecs[] = {UYVY, RGBA, RGB, DXT1};

View File

@@ -57,7 +57,7 @@ void display_sage_done(void *state);
struct video_frame *display_sage_getf(void *state);
int display_sage_putf(void *state, char *frame);
void display_sage_reconfigure(void *state, struct video_desc desc);
int display_sage_get_property(void *state, int property, void *val, int *len);
int display_sage_get_property(void *state, int property, void *val, size_t *len);
int display_sage_handle_events(void);

View File

@@ -50,7 +50,9 @@
#include "sage_wrapper.h"
#include <sail.h>
#include <misc.h>
extern "C" {
#include "host.h"
}
void *initSage(int appID, int nodeID, int width, int height, codec_t codec)
{

View File

@@ -158,7 +158,7 @@ static void loadSplashscreen(struct state_sdl *s) {
x_res_x = video_info->current_w;
x_res_y = video_info->current_h;
if(splash_height > tile_get(s->frame, 0, 0)->height || splash_width > tile_get(s->frame, 0, 0)->width)
if(splash_height > vf_get_tile(s->frame, 0)->height || splash_width > vf_get_tile(s->frame, 0)->width)
return;
// create a temporary SDL_Surface with the settings of displaying surface
@@ -435,7 +435,7 @@ void display_sdl_reconfigure(void *state, struct video_desc desc)
s->tile->height = desc.height;
s->frame->fps = desc.fps;
s->frame->aux = desc.aux;
s->frame->interlacing = desc.interlacing;
s->frame->color_spec = desc.color_spec;
fprintf(stdout, "Reconfigure to size %dx%d\n", desc.width,
@@ -614,8 +614,8 @@ void *display_sdl_init(char *fmt, unsigned int flags)
s->buffer_writable_lock = SDL_CreateMutex();
s->buffer_writable_cond = SDL_CreateCond();
s->frame = vf_alloc(1, 1);
s->tile = tile_get(s->frame, 0, 0);
s->frame = vf_alloc(1);
s->tile = vf_get_tile(s->frame, 0);
video_info = SDL_GetVideoInfo();
s->screen_w = video_info->current_w;
@@ -714,7 +714,7 @@ display_type_t *display_sdl_probe(void)
return dt;
}
int display_sdl_get_property(void *state, int property, void *val, int *len)
int display_sdl_get_property(void *state, int property, void *val, size_t *len)
{
struct state_sdl *s = (struct state_sdl *) state;

View File

@@ -57,7 +57,7 @@ struct video_frame *display_sdl_getf (void *state);
int display_sdl_putf (void *state, char *frame);
void display_sdl_reconfigure(void *state, struct video_desc desc);
int display_sdl_get_property(void *state, int property, void *val, int *len);
int display_sdl_get_property(void *state, int property, void *val, size_t *len);
struct audio_frame * display_sdl_get_audio_frame(void *state);
void display_sdl_put_audio_frame(void *state, const struct audio_frame *frame);

View File

@@ -125,10 +125,10 @@ struct vo_postprocess_state *vo_postprocess_init(char *config_string)
}
struct video_frame * vo_postprocess_reconfigure(struct vo_postprocess_state *s,
struct video_desc desc, struct tile_info ti)
struct video_desc desc)
{
if(s) {
return s->handle->reconfigure(s->state, desc, ti);
return s->handle->reconfigure(s->state, desc);
} else {
return NULL;
}
@@ -146,8 +146,8 @@ void vo_postprocess_done(struct vo_postprocess_state *s)
if(s) s->handle->done(s->state);
}
void vo_postprocess_get_out_desc(struct vo_postprocess_state *s, struct video_desc_ti *out)
void vo_postprocess_get_out_desc(struct vo_postprocess_state *s, struct video_desc *out, int *display_mode)
{
if(s) s->handle->get_out_desc(s->state, out);
if(s) s->handle->get_out_desc(s->state, out, display_mode);
}

View File

@@ -59,8 +59,8 @@ typedef void *(*vo_postprocess_init_t)(char *cfg);
*
* @return frame to be written to
*/
typedef struct video_frame * (*vo_postprocess_reconfigure_t)(void *state, struct video_desc desc, struct tile_info);
typedef void (*vo_postprocess_get_out_desc_t)(struct vo_postprocess_state *, struct video_desc_ti *out);
typedef struct video_frame * (*vo_postprocess_reconfigure_t)(void *state, struct video_desc desc);
typedef void (*vo_postprocess_get_out_desc_t)(struct vo_postprocess_state *, struct video_desc *out, int *display_mode);
/**
* Postprocesses video frame
@@ -77,10 +77,10 @@ typedef void (*vo_postprocess_t)(void *state, struct video_frame *in, struct vi
typedef void (*vo_postprocess_done_t)(void *);
struct vo_postprocess_state *vo_postprocess_init(char *config_string);
struct video_frame * vo_postprocess_reconfigure(struct vo_postprocess_state *, struct video_desc, struct tile_info);
void vo_postprocess_get_out_desc(struct vo_postprocess_state *, struct video_desc_ti *out);
struct video_frame * vo_postprocess_reconfigure(struct vo_postprocess_state *, struct video_desc);
void vo_postprocess_get_out_desc(struct vo_postprocess_state *, struct video_desc *out, int *display_mode);
void vo_postprocess(struct vo_postprocess_state *, struct video_frame*, struct video_frame*, int req_pitch);
void compress_done(struct vo_postprocess_state *);
void vo_postprocess_done(struct vo_postprocess_state *s);
void show_vo_postprocess_help(void);

View File

@@ -50,6 +50,7 @@
#include "debug.h"
#include "video_codec.h"
#include "video_display.h" /* DISPLAY_PROPERTY_VIDEO_SEPARATE_FILES */
#include <pthread.h>
#include <stdlib.h>
#include "vo_postprocess/3d-interleaved.h"
@@ -64,31 +65,31 @@ void * interleaved_3d_init(char *config) {
s = (struct state_interleaved_3d *)
malloc(sizeof(struct state_interleaved_3d));
s->in = vf_alloc(2, 1);
s->in = vf_alloc(2);
return s;
}
struct video_frame * interleaved_3d_postprocess_reconfigure(void *state, struct video_desc desc, struct tile_info ti)
struct video_frame * interleaved_3d_postprocess_reconfigure(void *state, struct video_desc desc)
{
struct state_interleaved_3d *s = (struct state_interleaved_3d *) state;
UNUSED(ti);
assert(ti.x_count == 2 && ti.y_count == 1);
assert(desc.video_mode == VIDEO_STEREO);
s->in->color_spec = desc.color_spec;
s->in->fps = desc.fps;
s->in->aux = desc.aux;
tile_get(s->in, 0, 0)->width =
tile_get(s->in, 1, 0)->width = desc.width / 2;
tile_get(s->in, 0, 0)->height =
tile_get(s->in, 1, 0)->height = desc.height;
s->in->interlacing = desc.interlacing;
vf_get_tile(s->in, 0)->width =
vf_get_tile(s->in, 1)->width = desc.width / 2;
vf_get_tile(s->in, 0)->height =
vf_get_tile(s->in, 1)->height = desc.height;
tile_get(s->in, 0, 0)->data_len =
tile_get(s->in, 1, 0)->data_len = vc_get_linesize(desc.width / 2, desc.color_spec)
vf_get_tile(s->in, 0)->data_len =
vf_get_tile(s->in, 1)->data_len = vc_get_linesize(desc.width / 2, desc.color_spec)
* desc.height;
tile_get(s->in, 0, 0)->data = malloc(tile_get(s->in, 0, 0)->data_len);
tile_get(s->in, 1, 0)->data = malloc(tile_get(s->in, 1, 0)->data_len);
vf_get_tile(s->in, 0)->data = malloc(vf_get_tile(s->in, 0)->data_len);
vf_get_tile(s->in, 1)->data = malloc(vf_get_tile(s->in, 1)->data_len);
fprintf(stderr, "xxxxxxxxxxx%d", vf_get_tile(s->in, 0)->data_len);
return s->in;
}
@@ -97,16 +98,16 @@ void interleaved_3d_postprocess(void *state, struct video_frame *in, struct vide
{
int x;
char *out_data = tile_get(out, 0, 0)->data;
int linesize = vc_get_linesize(tile_get(out, 0, 0)->width, out->color_spec);
char *out_data = vf_get_tile(out, 0)->data;
int linesize = vc_get_linesize(vf_get_tile(out, 0)->width, out->color_spec);
/* we compute avg from line k/2*2 and k/2*2+1 for left eye and put
* to (k/2*2)th line. Than we compute avg of same lines number
* and put it to the following line, which creates interleaved stereo */
for (x = 0; x < tile_get(out, 0, 0)->height; ++x) {
for (x = 0; x < vf_get_tile(out, 0)->height; ++x) {
int linepos;
char *line1 = tile_get(in, x % 2, 0)->data + (x / 2) * 2 * linesize;
char *line2 = tile_get(in, x % 2, 0)->data + ((x / 2) * 2 + 1) * linesize;
char *line1 = vf_get_tile(in, x % 2)->data + (x / 2) * 2 * linesize;
char *line2 = vf_get_tile(in, x % 2)->data + ((x / 2) * 2 + 1) * linesize;
for(linepos = 0; linepos < linesize; linepos += 16) {
asm volatile ("movdqu (%0), %%xmm0\n"
@@ -127,22 +128,22 @@ void interleaved_3d_done(void *state)
{
struct state_interleaved_3d *s = (struct state_interleaved_3d *) state;
free(tile_get(s->in, 0, 0)->data);
free(tile_get(s->in, 1, 0)->data);
free(vf_get_tile(s->in, 0)->data);
free(vf_get_tile(s->in, 1)->data);
vf_free(s->in);
free(state);
}
void interleaved_3d_get_out_desc(void *state, struct video_desc_ti *out)
void interleaved_3d_get_out_desc(void *state, struct video_desc *out, int *display_mode)
{
struct state_interleaved_3d *s = (struct state_interleaved_3d *) state;
out->desc.width = tile_get(s->in, 0, 0)->width; /* not *2 !!!!!!*/
out->desc.height = tile_get(s->in, 0, 0)->height;
out->desc.color_spec = s->in->color_spec;
out->desc.aux = s->in->aux;
out->desc.fps = s->in->fps;
out->ti.x_count = s->in->grid_width;
out->ti.y_count = s->in->grid_height;
out->width = vf_get_tile(s->in, 0)->width; /* not *2 !!!!!!*/
out->height = vf_get_tile(s->in, 0)->height;
out->color_spec = s->in->color_spec;
out->interlacing = s->in->interlacing;
out->fps = s->in->fps;
out->video_mode = VIDEO_NORMAL;
*display_mode = DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES;
}

View File

@@ -48,8 +48,8 @@
#include "video_codec.h"
void * interleaved_3d_init(char *config);
struct video_frame * interleaved_3d_postprocess_reconfigure(void *state, struct video_desc desc, struct tile_info tile);
void interleaved_3d_get_out_desc(void *state, struct video_desc_ti *out);
struct video_frame * interleaved_3d_postprocess_reconfigure(void *state, struct video_desc desc);
void interleaved_3d_get_out_desc(void *state, struct video_desc *out, int *display_mode);
void interleaved_3d_postprocess(void *state, struct video_frame *in, struct video_frame *out, int req_pitch);
void interleaved_3d_done(void *state);