[Spice-devel] [spice-html5] implement handing of MJPEG display streams

Aric Stewart aric at codeweavers.com
Thu Sep 6 07:13:58 PDT 2012


Checking in here.  Looks like Jeremy acked this but it never got pushed?

Could someone help me with that?

thanks!
-aric

On 8/27/12 10:59 AM, Aric Stewart wrote:
> Signed-off-by: Aric Stewart <aric at codeweavers.com>
> ---
> display.js  |   66 ++++++++++++++++++++++++++++++++++++++++++
> enums.js    |    2 +
> spicemsg.js |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 160 insertions(+), 0 deletions(-)
> 
> diff --git a/display.js b/display.js
> index 3efabb1..dd0a2e2 100644
> --- a/display.js
> +++ b/display.js
> @@ -421,6 +421,72 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
>          return true;
>      }
> 
> +    if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
> +    {
> +        var m = new SpiceMsgDisplayStreamCreate(msg.data);
> +        DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id" + m.id);
> +        if (!this.streams)
> +            this.streams = new Array();
> +        if (this.streams[m.id])
> +            console.log("Stream already exists");
> +        else
> +            this.streams[m.id] = m;
> +        if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
> +            console.log("Unhandled stream codec: "+m.codec_type);
> +        return true;
> +    }
> +
> +    if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
> +    {
> +        var m = new SpiceMsgDisplayStreamData(msg.data);
> +        if (!this.streams[m.base.id])
> +        {
> +            console.log("no stream for data");
> +            return false;
> +        }
> +        if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
> +        {
> +            var tmpstr = "data:image/jpeg,";
> +            var img = new Image;
> +            var i;
> +            for (i = 0; i < m.data.length; i++)
> +            {
> +                tmpstr +=  '%';
> +                if (m.data[i] < 16)
> +                tmpstr += '0';
> +                tmpstr += m.data[i].toString(16);
> +            }
> +            var strm_base = new SpiceMsgDisplayBase();
> +            strm_base.surface_id = this.streams[m.base.id].surface_id;
> +            strm_base.box = this.streams[m.base.id].dest;
> +            strm_base.clip = this.streams[m.base.id].clip;
> +            img.o =
> +                { base: strm_base,
> +                  tag: "mjpeg." + m.base.id,
> +                  descriptor: null,
> +                  sc : this,
> +                };
> +            img.onload = handle_draw_jpeg_onload;
> +            img.src = tmpstr;
> +        }
> +        return true;
> +    }
> +
> +    if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
> +    {
> +        var m = new SpiceMsgDisplayStreamClip(msg.data);
> +        DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
> +        this.streams[m.id].clip = m.clip;
> +        return true;
> +    }
> +
> +    if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
> +    {
> +        var m = new SpiceMsgDisplayStreamDestroy(msg.data);
> +        DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
> +        this.streams[m.id] = undefined;
> +        return true;
> +    }
> 
>      return false;
> }
> diff --git a/enums.js b/enums.js
> index cbf9056..fa541a4 100644
> --- a/enums.js
> +++ b/enums.js
> @@ -278,3 +278,5 @@ var SPICE_CURSOR_TYPE_ALPHA     = 0,
>      SPICE_CURSOR_TYPE_COLOR16   = 4,
>      SPICE_CURSOR_TYPE_COLOR24   = 5,
>      SPICE_CURSOR_TYPE_COLOR32   = 6;
> +
> +var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
> diff --git a/spicemsg.js b/spicemsg.js
> index 79c76bc..31e54a0 100644
> --- a/spicemsg.js
> +++ b/spicemsg.js
> @@ -789,3 +789,95 @@ function SpiceMsgcKeyUp(e)
> /* Use the same functions as for KeyDown */
> SpiceMsgcKeyUp.prototype.to_buffer = SpiceMsgcKeyDown.prototype.to_buffer;
> SpiceMsgcKeyUp.prototype.buffer_size = SpiceMsgcKeyDown.prototype.buffer_size;
> +
> +function SpiceMsgDisplayStreamCreate(a, at)
> +{
> +    this.from_buffer(a, at);
> +}
> +
> +SpiceMsgDisplayStreamCreate.prototype =
> +{
> +    from_buffer: function(a, at)
> +    {
> +        at = at || 0;
> +        var dv = new SpiceDataView(a);
> +        this.surface_id = dv.getUint32(at, true); at += 4;
> +        this.id = dv.getUint32(at, true); at += 4;
> +        this.flags = dv.getUint8(at, true); at += 1;
> +        this.codec_type = dv.getUint8(at, true); at += 1;
> +        /*stamp */ at += 8;
> +        this.stream_width = dv.getUint32(at, true); at += 4;
> +        this.stream_height = dv.getUint32(at, true); at += 4;
> +        this.src_width = dv.getUint32(at, true); at += 4;
> +        this.src_height = dv.getUint32(at, true); at += 4;
> +
> +        this.dest = new SpiceRect;
> +        at = this.dest.from_dv(dv, at, a);
> +        this.clip = new SpiceClip;
> +        this.clip.from_dv(dv, at, a);
> +    },
> +}
> +
> +function SpiceStreamDataHeader(a, at)
> +{
> +}
> +
> +SpiceStreamDataHeader.prototype =
> +{
> +    from_dv : function(dv, at, mb)
> +    {
> +        this.id = dv.getUint32(at, true); at += 4;
> +        this.multi_media_time = dv.getUint32(at, true); at += 4;
> +        return at;
> +    },
> +}
> +
> +function SpiceMsgDisplayStreamData(a, at)
> +{
> +    this.from_buffer(a, at);
> +}
> +
> +SpiceMsgDisplayStreamData.prototype =
> +{
> +    from_buffer: function(a, at)
> +    {
> +        at = at || 0;
> +        var dv = new SpiceDataView(a);
> +        this.base = new SpiceStreamDataHeader;
> +        at = this.base.from_dv(dv, at, a);
> +        this.data_size = dv.getUint32(at, true); at += 4;
> +        this.data = dv.u8.subarray(at, at + this.data_size);
> +    },
> +}
> +
> +function SpiceMsgDisplayStreamClip(a, at)
> +{
> +    this.from_buffer(a, at);
> +}
> +
> +SpiceMsgDisplayStreamClip.prototype =
> +{
> +    from_buffer: function(a, at)
> +    {
> +        at = at || 0;
> +        var dv = new SpiceDataView(a);
> +        this.id = dv.getUint32(at, true); at += 4;
> +        this.clip = new SpiceClip;
> +        this.clip.from_dv(dv, at, a);
> +    },
> +}
> +
> +function SpiceMsgDisplayStreamDestroy(a, at)
> +{
> +    this.from_buffer(a, at);
> +}
> +
> +SpiceMsgDisplayStreamDestroy.prototype =
> +{
> +    from_buffer: function(a, at)
> +    {
> +        at = at || 0;
> +        var dv = new SpiceDataView(a);
> +        this.id = dv.getUint32(at, true); at += 4;
> +    },
> +}


More information about the Spice-devel mailing list