Esempio n. 1
0
void vf_split(struct video_frame *out, struct video_frame *src,
              unsigned int x_count, unsigned int y_count, int preallocate)
{
        unsigned int               tile_idx, line_idx;
        struct tile        *cur_tiles;
        unsigned int               tile_line = 0;

        out->color_spec = src->color_spec;
        out->fps = src->fps;
        //out->aux = src->aux | AUX_TILED;
        
        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 = 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].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 < vf_get_tile(src, 0)->height; ++line_idx, ++tile_line) {
                unsigned int cur_tile_idx;
                unsigned int byte = 0u;

                if (line_idx % (vf_get_tile(src, 0)->height / y_count) == 0u) /* next tiles*/
                {
                        tile_line = 0u;
                        if (line_idx != 0u)
                                cur_tiles += x_count;
                        if (preallocate) {
                                for (cur_tile_idx = 0u; cur_tile_idx < x_count;
                                               ++cur_tile_idx) {
                                        cur_tiles[cur_tile_idx].data =
                                                malloc(cur_tiles[cur_tile_idx].
                                                                data_len);
                                }
                        }
                }

                for(cur_tile_idx = 0u; cur_tile_idx < x_count; ++cur_tile_idx) {
                        memcpy((void *) &cur_tiles[cur_tile_idx].data[
                                        tile_line *
                                        cur_tiles[cur_tile_idx].linesize],
                                        (void *) &src->tiles[0].data[line_idx *
                                        src->tiles[0].linesize + byte],
                                        cur_tiles[cur_tile_idx].width *
                                        get_bpp(src->color_spec));
                        byte += cur_tiles[cur_tile_idx].width * get_bpp(src->color_spec);
                }
        }
}
Esempio n. 2
0
static void display_sage_run(void *arg)
{
        struct state_sage *s = (struct state_sage *)arg;
        s->magic = MAGIC_SAGE;

        while (!s->should_exit) {
                display_sage_handle_events();

                sem_wait(&s->semaphore);
                if (s->should_exit)
                        break;

                if (s->deinterlace) {
                        vc_deinterlace((unsigned char *) s->tile->data, vc_get_linesize(s->tile->width,
                                                s->frame->color_spec), s->tile->height);
                }

                s->sage_state->swapBuffer(SAGE_NON_BLOCKING);
                sageMessage msg;
                if (s->sage_state->checkMsg(msg, false) > 0) {
                        switch (msg.getCode()) {
                        case APP_QUIT:
                                sage::printLog("Ultragrid: QUIT message");
                                exit_uv(1);
                                break;
                        }
                }

                s->tile->data = (char *) s->sage_state->getBuffer();

                pthread_mutex_lock(&s->buffer_writable_lock);
                s->buffer_writable = 1;
                if(s->grab_waiting) {
                        pthread_cond_broadcast(&s->buffer_writable_cond);
                }
                pthread_mutex_unlock(&s->buffer_writable_lock);

                s->frames++;

                gettimeofday(&s->t, NULL);
                double seconds = tv_diff(s->t, s->t0);
                if (seconds >= 5) {
                        float fps = s->frames / seconds;
                        log_msg(LOG_LEVEL_INFO, "[SAGE] %d frames in %g seconds = %g FPS\n",
                                s->frames, seconds, fps);
                        s->t0 = s->t;
                        s->frames = 0;
                }
        }
}
Esempio n. 3
0
struct video_frame * dxt_glsl_compress(struct module *mod, struct video_frame * tx, int buffer_idx)
{
        struct state_video_compress_rtdxt *s = (struct state_video_compress_rtdxt *) mod->priv_data;
        int i;
        unsigned char *line1, *line2;

        assert(buffer_idx >= 0 && buffer_idx < 2);
        
        unsigned int x;

        gl_context_make_current(&s->gl_context);
        
        if(!s->configured) {
                int ret;
                ret = configure_with(s, tx);
                if(!ret)
                        return NULL;
        }


        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[buffer_idx], 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, s->encoder_input_linesize,
                                        0, 8, 16);
                        line1 += vc_get_linesize(in_tile->width, tx->color_spec);
                        line2 += s->encoder_input_linesize;
                }
                
                if(s->interlaced_input)
                        vc_deinterlace((unsigned char *) s->decoded, s->encoder_input_linesize,
                                        in_tile->height);
                
                dxt_encoder_compress(s->encoder[x],
                                (unsigned char *) s->decoded,
                                (unsigned char *) out_tile->data);
        }

        gl_context_make_current(NULL);
        
        return s->out[buffer_idx];
}
Esempio n. 4
0
static int display_sage_reconfigure(void *state, struct video_desc desc)
{
        struct state_sage *s = (struct state_sage *)state;

        assert(s->magic == MAGIC_SAGE);
        assert(desc.color_spec == RGBA || desc.color_spec == RGB || desc.color_spec == UYVY ||
                        desc.color_spec == DXT1
#ifdef SAGE_NATIVE_DXT5YCOCG
                        || desc.color_spec == DXT5
#endif // SAGE_NATIVE_DXT5YCOCG
                        );
        
        s->tile->width = desc.width;
        s->tile->height = desc.height;
        s->frame->fps = desc.fps;
        s->frame->interlacing = desc.interlacing;
        s->frame->color_spec = desc.color_spec;

        // SAGE fix - SAGE threads apparently do not process signals correctly so we temporarily
        // block all signals while creating SAGE
        sigset_t mask, old_mask;
        sigemptyset(&mask);
        sigaddset(&mask, SIGINT);
        sigaddset(&mask, SIGTERM);
        sigaddset(&mask, SIGHUP);
        pthread_sigmask(SIG_BLOCK, &mask, &old_mask);

        if(s->sage_state) {
                s->sage_state->shutdown();
                //delete s->sage_state; // this used to cause crashes
        }

        s->sage_state = initSage(s->confName, s->fsIP, s->appID, s->nodeID,
                        s->tile->width, s->tile->height, desc.color_spec);

        // calling thread should be able to process signals afterwards
        pthread_sigmask(SIG_UNBLOCK, &old_mask, NULL);

        s->tile->data = (char *) s->sage_state->getBuffer();
        s->tile->data_len = vc_get_linesize(s->tile->width, desc.color_spec) * s->tile->height;

        return TRUE;
}
Esempio n. 5
0
void vf_split_horizontal(struct video_frame *out, struct video_frame *src,
              unsigned int y_count)
{
        unsigned int i;

        for(i = 0u; i < y_count; ++i) {
                //out->aux = src->aux | AUX_TILED;
                out->fps = src->fps;
                out->color_spec = src->color_spec;
                out->tiles[i].width = src->tiles[0].width;
                out->tiles[i].height = src->tiles[0].height / y_count;
                
                out->tiles[i].linesize = vc_get_linesize(out->tiles[i].width,
                                out->color_spec);
                out->tiles[i].data_len = out->tiles[i].linesize * 
                        out->tiles[i].height;
                out->tiles[i].data = src->tiles[0].data + i * out->tiles[i].height 
                        * out->tiles[i].linesize;
        }
}
Esempio n. 6
0
static struct video_frame *filter(void *, struct video_frame *in)
{
        if (in->color_spec != UYVY) {
                log_msg(LOG_LEVEL_WARNING, "Only supporte colorspace for mirror is currently UYVY!\n");
                return in;
        }

        struct video_frame *out = vf_alloc_desc_data(video_desc_from_frame(in));
        out->dispose = vf_free;

        unsigned char *in_data = (unsigned char *) in->tiles[0].data;
        unsigned char *out_data = (unsigned char *) out->tiles[0].data;

        int linesize = vc_get_linesize(in->tiles[0].width, in->color_spec);
        for (unsigned int y = 0; y < in->tiles[0].height; ++y) {
                mirror_line_UYVY(out_data + y * linesize, in_data + y * linesize, linesize);
        }

        VIDEO_FRAME_DISPOSE(in);

        return out;
}
int main(int argc, char **argv)
{
    int stop_at = 0;
    char *yuv_path;
    if (argc == 2) {
        yuv_path = argv[1];
    } else if (argc == 3) {
        yuv_path = argv[1];
        stop_at = atoi(argv[2]);
    } else {
        printf("usage: %s input [max frames]\n", argv[0]);
        return -1;
    }

    printf("[test] initializing streams list\n");
    printf("[test] init_stream_list\n");
    stream_list_t *streams = init_stream_list();
    printf("[test] init_stream\n");
    stream_data_t *stream = init_stream(VIDEO, OUTPUT, 0, ACTIVE, "i2catrocks");
    printf("[test] set_stream_video_data\n");
    printf("[test] add_stream\n");
    add_stream(streams, stream);

    printf("[test] initializing transmitter\n");
    transmitter_t *transmitter = init_transmitter(streams, 20.0);
    start_transmitter(transmitter);

	rtsp_serv_t *server;
	server = malloc(sizeof(rtsp_serv_t));
  
	server->port = 8554;
	server->streams = streams;
	server->transmitter = transmitter;
    
    init_encoder(stream->video);
    
    c_start_server(server);
    c_update_server(server);
       
    // Stuff ... 
    AVFormatContext *pformat_ctx = avformat_alloc_context();
    AVCodecContext codec_ctx;
    int video_stream = -1;
    av_register_all();

    int width = 1280;
    int height = 534;

    load_video(yuv_path, pformat_ctx, &codec_ctx, &video_stream);

    uint8_t *b1 = (uint8_t *)av_malloc(avpicture_get_size(codec_ctx.pix_fmt,
                        codec_ctx.width, codec_ctx.height)*sizeof(uint8_t));
    
    int counter = 0;

    struct timeval a, b;
    video_data_frame_t *decoded_frame;
    
    while(1) {
    
        gettimeofday(&a, NULL);
        
        int ret = read_frame(pformat_ctx, video_stream, &codec_ctx, b1);
        if (stop_at > 0 && counter == stop_at) {
            break;
        }

        if (ret == 0) {
            counter++;
            
            decoded_frame = curr_in_frame(stream->video->decoded_frames);
            if (decoded_frame == NULL){
                continue;
            }
            
            decoded_frame->buffer_len = vc_get_linesize(width, RGB)*height;
            memcpy(decoded_frame->buffer, b1, decoded_frame->buffer_len); 
            
            put_frame(stream->video->decoded_frames);
        } else {
            break;
        }
        gettimeofday(&b, NULL);
        long diff = (b.tv_sec - a.tv_sec)*1000000 + b.tv_usec - a.tv_usec;

        if (diff < 40000) {
            usleep(40000 - diff);
        } else {
            usleep(0);
        }
    }
    debug_msg(" deallocating resources and terminating threads\n");
    av_free(pformat_ctx);
    av_free(b1);
    debug_msg(" done!\n");

    stop_transmitter(transmitter);

    destroy_stream_list(streams);

    return 0;
}
Esempio n. 8
0
static struct video_frame *vidcap_testcard_grab(void *arg, struct audio_frame **audio)
{
        struct testcard_state *state;
        state = (struct testcard_state *)arg;

        std::chrono::steady_clock::time_point curr_time =
                std::chrono::steady_clock::now();

        if (std::chrono::duration_cast<std::chrono::duration<double>>(curr_time - state->last_frame_time).count() <
            1.0 / (double)state->frame->fps) {
                return NULL;
        }

        state->last_frame_time = curr_time;
        state->count++;

        double seconds =
                std::chrono::duration_cast<std::chrono::duration<double>>(curr_time - state->t0).count();
        if (seconds >= 5.0) {
                float fps = state->count / seconds;
                log_msg(LOG_LEVEL_INFO, "[testcard] %d frames in %g seconds = %g FPS\n",
                                state->count, seconds, fps);
                state->t0 = curr_time;
                state->count = 0;
        }

        if (state->grab_audio) {
#ifdef HAVE_LIBSDL_MIXER
                state->audio.data = state->audio_data + state->audio_start;
                if(state->audio_start <= state->audio_end) {
                        int tmp = state->audio_end;
                        state->audio.data_len = tmp - state->audio_start;
                        state->audio_start = tmp;
                } else {
                        state->audio.data_len =
                                AUDIO_BUFFER_SIZE -
                                state->audio_start;
                        state->audio_start = 0;
                }
                if(state->audio.data_len > 0)
                        *audio = &state->audio;
                else
                        *audio = NULL;
#endif
        } else {
                *audio = NULL;
        }

        if(!state->still_image) {
                vf_get_tile(state->frame, 0)->data += state->frame_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;
          memcpy(line, state->frame.data,
          state->frame.src_linesize * 2 + state->pan);
          for (i = 0; i < state->frame.height - 3; i++) {
          memcpy(state->frame.data + i * state->frame.src_linesize,
          state->frame.data + (i + 2) * state->frame.src_linesize +
          state->pan, state->frame.src_linesize);
          }
          memcpy(state->frame.data + i * state->frame.src_linesize,
          state->frame.data + (i + 2) * state->frame.src_linesize +
          state->pan, state->frame.src_linesize - state->pan);
          memcpy(state->frame.data +
          (state->frame.height - 2) * state->frame.src_linesize - state->pan,
          line, state->frame.src_linesize * 2 + state->pan);
#ifdef USE_EPILEPSY
if(!(state->count % 2)) {
unsigned int *p = state->frame.data;
for(i=0; i < state->frame.src_linesize*state->frame.height/4; i++) {
         *p = *p ^ 0x00ffffffL;
         p++;
         }
         }
#endif
*/
        if (state->tiled) {
                /* update tile data instead */
                int i;
                int count = state->tiled->tile_count;

                for (i = 0; i < count; ++i) {
                        /* shift - for semantics of vars refer to configure_tiling*/
                        state->tiled->tiles[i].data += vc_get_linesize(
                                        state->tiled->tiles[i].width, state->tiled->color_spec);
                        /* if out of data, move to beginning
                         * 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->tiles_cnt_vertical) {
                                state->tiled->tiles[i].data = state->tiles_data[i];
                        }
                }

                return state->tiled;
        }
        return state->frame;
}
Esempio n. 9
0
static int configure_tiling(struct testcard_state *s, const char *fmt)
{
        char *tmp, *token, *saveptr = NULL;
        int tile_cnt;
        int x;

        int grid_w, grid_h;

        if(fmt[1] != '=') return 1;

        tmp = strdup(&fmt[2]);
        token = strtok_r(tmp, "x", &saveptr);
        grid_w = atoi(token);
        token = strtok_r(NULL, "x", &saveptr);
        grid_h = atoi(token);
        free(tmp);

        s->tiled = vf_alloc(grid_w * grid_h);
        s->tiles_cnt_horizontal = grid_w;
        s->tiles_cnt_vertical = grid_h;
        s->tiled->color_spec = s->frame->color_spec;
        s->tiled->fps = s->frame->fps;
        s->tiled->interlacing = s->frame->interlacing;

        tile_cnt = grid_w *
                                grid_h;
        assert(tile_cnt >= 1);

        s->tiles_data = (char **) malloc(tile_cnt *
                        sizeof(char *));
        /* split only horizontally!!!!!! */
        vf_split(s->tiled, s->frame, grid_w,
                        1, 1 /*prealloc*/);
        /* for each row, make the tile data correct.
         * .data pointers of same row point to same block,
         * but different row */
        for(x = 0; x < grid_w; ++x) {
                int y;

                s->tiles_data[x] = s->tiled->tiles[x].data;

                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].data =
                        s->tiles_data[x] = (char *) realloc(s->tiled->tiles[x].data,
                                s->tiled->tiles[x].data_len * grid_h * 2);


                memcpy(s->tiled->tiles[x].data + s->tiled->tiles[x].data_len  * grid_h,
                                s->tiled->tiles[x].data, s->tiled->tiles[x].data_len * grid_h);
                /* recopy tiles vertically */
                for(y = 1; y < grid_h; ++y) {
                        memcpy(&s->tiled->tiles[y * grid_w + x],
                                        &s->tiled->tiles[x], sizeof(struct tile));
                        /* make the pointers correct */
                        s->tiles_data[y * grid_w + x] =
                                s->tiles_data[x] +
                                y * s->tiled->tiles[x].height *
                                vc_get_linesize(s->tiled->tiles[x].width, s->tiled->color_spec);

                        s->tiled->tiles[y * grid_w + x].data =
                                s->tiles_data[x] +
                                y * s->tiled->tiles[x].height *
                                vc_get_linesize(s->tiled->tiles[x].width, s->tiled->color_spec);
                }
        }

        return 0;
}
Esempio n. 10
0
struct video_frame * jpeg_compress(struct module *mod, struct video_frame * tx, int buffer_idx)
{
        struct state_video_compress_jpeg *s = (struct state_video_compress_jpeg *) mod->priv_data;
        int i;
        unsigned char *line1, *line2;
        struct video_frame *out;

        unsigned int x;

        cudaSetDevice(cuda_devices[0]);
        
        if(!s->encoder) {
                int ret;
                ret = configure_with(s, tx);
                if(!ret) {
                        return NULL;
                }
        }

        struct video_desc desc;
        desc = video_desc_from_frame(tx);

        // if format changed, reconfigure
        if(!video_desc_eq_excl_param(s->saved_desc, desc, PARAM_INTERLACING)) {
                cleanup_state(s);
                int ret;
                ret = configure_with(s, tx);
                if(!ret) {
                        return NULL;
                }
        }

        out = s->out[buffer_idx];

        for (x = 0; x < tx->tile_count;  ++x) {
                struct tile *in_tile = vf_get_tile(tx, x);
                struct tile *out_tile = vf_get_tile(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, s->encoder_input_linesize,
                                        0, 8, 16);
                        line1 += vc_get_linesize(in_tile->width, tx->color_spec);
                        line2 += s->encoder_input_linesize;
                }
                
                line1 = (unsigned char *) out_tile->data + (in_tile->height - 1) * s->encoder_input_linesize;
                for( ; i < (int) out->tiles[0].height; ++i) {
                        memcpy(line2, line1, s->encoder_input_linesize);
                        line2 += s->encoder_input_linesize;
                }
                
                /*if(s->interlaced_input)
                        vc_deinterlace((unsigned char *) s->decoded, s->encoder_input_linesize,
                                        s->out->tiles[0].height);*/
                
                uint8_t *compressed;
                int size;
                int ret;


                struct gpujpeg_encoder_input encoder_input;
                gpujpeg_encoder_input_set_image(&encoder_input, (uint8_t *) s->decoded);
                ret = gpujpeg_encoder_encode(s->encoder, &encoder_input, &compressed, &size);
                
                if(ret != 0)
                        return NULL;
                
                out_tile->data_len = size;
                memcpy(out_tile->data, compressed, size);
        }
        
        return out;
}
Esempio n. 11
0
struct video_frame * fastdxt_compress(void *args, struct video_frame *tx, int buffer_idx)
{
        /* This thread will be called from main.c and handle the compress_threads */
        struct video_compress *compress = (struct video_compress *)args;
        unsigned int x;
        unsigned char *line1, *line2;
        struct video_frame *out = compress->out[buffer_idx];
        struct tile *out_tile = &out->tiles[0];

        assert(tx->tile_count == 1);
        assert(vf_get_tile(tx, 0)->width % 4 == 0);
        
        pthread_mutex_lock(&(compress->lock));

        if(vf_get_tile(tx, 0)->width != out_tile->width ||
                        vf_get_tile(tx, 0)->height != out_tile->height ||
                        tx->interlacing != compress->interlacing_source ||
                        tx->color_spec != compress->tx_color_spec)
        {
                int ret;
                ret = reconfigure_compress(compress, vf_get_tile(tx, 0)->width, vf_get_tile(tx, 0)->height, tx->color_spec, tx->interlacing, tx->fps);
                if(!ret)
                        return NULL;
        }

        line1 = (unsigned char *) tx->tiles[0].data;
        line2 = compress->output_data;

        for (x = 0; x < out_tile->height; ++x) {
                int src_linesize = vc_get_linesize(out_tile->width, compress->tx_color_spec);
                compress->decoder(line2, line1, out_tile->linesize,
                                0, 8, 16);
                line1 += src_linesize;
                line2 += out_tile->linesize;
        }

        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, out_tile->linesize,
                                out_tile->height);
        }

        compress->buffer_idx = buffer_idx;

        for (x = 0; x < (unsigned int) compress->num_threads; x++) {
                platform_sem_post(&compress->thread_compress[x]);
        }

        for (x = 0; x < (unsigned int) compress->num_threads; x++) {
                platform_sem_wait(&compress->thread_done[x]);
        }

        out_tile->data_len = out_tile->width * compress->dxt_height / 2;
        
        pthread_mutex_unlock(&(compress->lock));

        return out;
}