[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