Exemplo n.º 1
0
G_GNUC_INTERNAL
void stream_h264_data(display_stream *st)
{
	int width, height;
	uint8_t *data;
	int size = stream_get_current_frame(st, &data);

	stream_get_dimensions(st, &width, &height);

	if(st->stream_width != width || st->stream_height != height) {
		st->stream_width = width;
		st->stream_height = height;

		stream_h264_finit(st);
		stream_h264_init(st);	

		st->rgba_buf = g_malloc0(st->stream_width * st->stream_height * 4);
	}

	st->out_frame = st->rgba_buf;

	av_init_packet(&st->packet);
	st->packet.data = data;
	st->packet.size = size;
	decode_packet(st, width, height);
	av_free_packet(&st->packet);
}
G_GNUC_INTERNAL
void stream_mjpeg_data(display_stream *st)
{
    gboolean back_compat = st->channel->priv->peer_hdr.major_version == 1;
    int width;
    int height;
    uint8_t *dest;
    uint8_t *lines[4];

    stream_get_dimensions(st, &width, &height);
    dest = malloc(width * height * 4);

    if (st->out_frame) {
        free(st->out_frame);
    }
    st->out_frame = dest;

    jpeg_read_header(&st->mjpeg_cinfo, 1);
#ifdef JCS_EXTENSIONS
    // requires jpeg-turbo
    if (back_compat)
        st->mjpeg_cinfo.out_color_space = JCS_EXT_RGBX;
    else
        st->mjpeg_cinfo.out_color_space = JCS_EXT_BGRX;
#else
#warning "You should consider building with libjpeg-turbo"
    st->mjpeg_cinfo.out_color_space = JCS_RGB;
#endif

#ifndef SPICE_QUALITY
    st->mjpeg_cinfo.dct_method = JDCT_IFAST;
    st->mjpeg_cinfo.do_fancy_upsampling = FALSE;
    st->mjpeg_cinfo.do_block_smoothing = FALSE;
    st->mjpeg_cinfo.dither_mode = JDITHER_ORDERED;
#endif
    // TODO: in theory should check cinfo.output_height match with our height
    jpeg_start_decompress(&st->mjpeg_cinfo);
    /* rec_outbuf_height is the recommended size of the output buffer we
     * pass to libjpeg for optimum performance
     */
    if (st->mjpeg_cinfo.rec_outbuf_height > G_N_ELEMENTS(lines)) {
        jpeg_abort_decompress(&st->mjpeg_cinfo);
        g_return_if_reached();
    }

    while (st->mjpeg_cinfo.output_scanline < st->mjpeg_cinfo.output_height) {
        /* only used when JCS_EXTENSIONS is undefined */
        G_GNUC_UNUSED unsigned int lines_read;

        for (unsigned int j = 0; j < st->mjpeg_cinfo.rec_outbuf_height; j++) {
            lines[j] = dest;
#ifdef JCS_EXTENSIONS
            dest += 4 * width;
#else
            dest += 3 * width;
#endif
        }
        lines_read = jpeg_read_scanlines(&st->mjpeg_cinfo, lines,
                                st->mjpeg_cinfo.rec_outbuf_height);
#ifndef JCS_EXTENSIONS
        {
            uint8_t *s = lines[0];
            uint32_t *d = (uint32_t *)s;

            if (back_compat) {
                for (unsigned int j = lines_read * width; j > 0; ) {
                    j -= 1; // reverse order, bad for cache?
                    d[j] = s[j * 3 + 0] |
                        s[j * 3 + 1] << 8 |
                        s[j * 3 + 2] << 16;
                }
            } else {
                for (unsigned int j = lines_read * width; j > 0; ) {
                    j -= 1; // reverse order, bad for cache?
                    d[j] = s[j * 3 + 0] << 16 |
                        s[j * 3 + 1] << 8 |
                        s[j * 3 + 2];
                }
            }
        }
#endif
        dest = &st->out_frame[st->mjpeg_cinfo.output_scanline * width * 4];
    }
    jpeg_finish_decompress(&st->mjpeg_cinfo);
}