summaryrefslogtreecommitdiffstats
path: root/ext/jpeg
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2004-10-04 16:53:48 +0000
committerWim Taymans <wim.taymans@gmail.com>2004-10-04 16:53:48 +0000
commitb90716dd184e3a270fc31ab39307548fe16337cc (patch)
treee204108290be35fe11b3ecde34ebbc60396cdb5a /ext/jpeg
parentd2ba80e45ee0a5b90aa2be7571efb92a560bd1c0 (diff)
ext/jpeg/: Updated smoke, new bitstream, allows embedding in ogg.
Original commit message from CVS: * ext/jpeg/gstjpeg.c: (smoke_type_find), (plugin_init): * ext/jpeg/gstsmokedec.c: (gst_smokedec_init), (gst_smokedec_chain): * ext/jpeg/gstsmokedec.h: * ext/jpeg/gstsmokeenc.c: (gst_smokeenc_class_init), (gst_smokeenc_init), (gst_smokeenc_resync), (gst_smokeenc_chain): * ext/jpeg/gstsmokeenc.h: * ext/jpeg/smokecodec.c: (smokecodec_encode_new), (smokecodec_decode_new), (smokecodec_info_free), (smokecodec_set_quality), (smokecodec_get_quality), (smokecodec_set_threshold), (smokecodec_get_threshold), (smokecodec_set_bitrate), (smokecodec_get_bitrate), (find_best_size), (abs_diff), (put), (smokecodec_encode_id), (smokecodec_encode), (smokecodec_parse_id), (smokecodec_parse_header), (smokecodec_decode): * ext/jpeg/smokecodec.h: * ext/jpeg/smokeformat.h: Updated smoke, new bitstream, allows embedding in ogg.
Diffstat (limited to 'ext/jpeg')
-rw-r--r--ext/jpeg/gstjpeg.c22
-rw-r--r--ext/jpeg/gstsmokedec.c56
-rw-r--r--ext/jpeg/gstsmokedec.h3
-rw-r--r--ext/jpeg/gstsmokeenc.c44
-rw-r--r--ext/jpeg/gstsmokeenc.h3
-rw-r--r--ext/jpeg/smokecodec.c130
-rw-r--r--ext/jpeg/smokecodec.h27
-rw-r--r--ext/jpeg/smokeformat.h46
8 files changed, 281 insertions, 50 deletions
diff --git a/ext/jpeg/gstjpeg.c b/ext/jpeg/gstjpeg.c
index 58749534..63c54637 100644
--- a/ext/jpeg/gstjpeg.c
+++ b/ext/jpeg/gstjpeg.c
@@ -19,12 +19,30 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <string.h>
#include "gstjpegdec.h"
#include "gstjpegenc.h"
#include "gstsmokeenc.h"
#include "gstsmokedec.h"
+static GstStaticCaps smoke_caps = GST_STATIC_CAPS ("video/x-smoke");
+
+#define SMOKE_CAPS (gst_static_caps_get(&smoke_caps))
+static void
+smoke_type_find (GstTypeFind * tf, gpointer private)
+{
+ guint8 *data = gst_type_find_peek (tf, 0, 6);
+
+ if (data) {
+ if (data[0] != 0x80)
+ return;
+ if (memcmp (&data[1], "smoke", 5) != 0)
+ return;
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SMOKE_CAPS);
+ }
+}
+
static gboolean
plugin_init (GstPlugin * plugin)
{
@@ -44,6 +62,10 @@ plugin_init (GstPlugin * plugin)
GST_TYPE_SMOKEDEC))
return FALSE;
+ if (!gst_type_find_register (plugin, "video/x-smoke", GST_RANK_PRIMARY,
+ smoke_type_find, NULL, SMOKE_CAPS, NULL))
+ return FALSE;
+
return TRUE;
}
diff --git a/ext/jpeg/gstsmokedec.c b/ext/jpeg/gstsmokedec.c
index 34a86785..184220d7 100644
--- a/ext/jpeg/gstsmokedec.c
+++ b/ext/jpeg/gstsmokedec.c
@@ -29,9 +29,9 @@
/* elementfactory information */
GstElementDetails gst_smokedec_details = {
- "Smoke image decoder",
+ "Smoke video decoder",
"Codec/Decoder/Image",
- "Decode images from Smoke format",
+ "Decode video from Smoke format",
"Wim Taymans <wim@fluendo.com>",
};
@@ -98,7 +98,7 @@ static GstStaticPadTemplate gst_smokedec_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("image/x-smoke, "
+ GST_STATIC_CAPS ("video/x-smoke, "
"width = (int) [ 16, 4096 ], "
"height = (int) [ 16, 4096 ], " "framerate = (double) [ 1, MAX ]")
);
@@ -150,6 +150,7 @@ gst_smokedec_init (GstSmokeDec * smokedec)
smokedec->format = -1;
smokedec->width = -1;
smokedec->height = -1;
+ smokedec->next_time = 0;
}
static GstPadLinkReturn
@@ -189,9 +190,10 @@ gst_smokedec_chain (GstPad * pad, GstData * _data)
gulong size, outsize;
GstBuffer *outbuf;
SmokeCodecFlags flags;
+ GstClockTime time;
- /*GstMeta *meta; */
gint width, height;
+ gint fps_num, fps_denom;
smokedec = GST_SMOKEDEC (GST_OBJECT_PARENT (pad));
@@ -202,17 +204,36 @@ gst_smokedec_chain (GstPad * pad, GstData * _data)
data = (guchar *) GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
+ time = GST_BUFFER_TIMESTAMP (buf);
+
GST_DEBUG ("gst_smokedec_chain: got buffer of %ld bytes in '%s'", size,
GST_OBJECT_NAME (smokedec));
+ if (data[0] == SMOKECODEC_TYPE_ID) {
+ smokecodec_parse_id (smokedec->info, data, size);
+ return;
+ }
+
GST_DEBUG ("gst_smokedec_chain: reading header %08lx", *(gulong *) data);
- smokecodec_parse_header (smokedec->info, data, size, &flags, &width, &height);
+ smokecodec_parse_header (smokedec->info, data, size, &flags, &width, &height,
+ &fps_num, &fps_denom);
outbuf = gst_buffer_new ();
outsize = GST_BUFFER_SIZE (outbuf) = width * height + width * height / 2;
outdata = GST_BUFFER_DATA (outbuf) = g_malloc (outsize);
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+
+ GST_BUFFER_DURATION (outbuf) = GST_SECOND * fps_denom / fps_num;
+ GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
+
+ if (time == GST_CLOCK_TIME_NONE) {
+ if (GST_BUFFER_OFFSET (buf) == -1) {
+ time = smokedec->next_time;
+ } else {
+ time = GST_BUFFER_OFFSET (buf) * GST_BUFFER_DURATION (outbuf);
+ }
+ }
+ GST_BUFFER_TIMESTAMP (outbuf) = time;
+ smokedec->next_time = time + GST_BUFFER_DURATION (outbuf);
if (smokedec->height != height) {
GstCaps *caps;
@@ -223,15 +244,26 @@ gst_smokedec_chain (GstPad * pad, GstData * _data)
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
- "framerate", G_TYPE_DOUBLE, smokedec->fps, NULL);
+ "framerate", G_TYPE_DOUBLE, ((double) fps_num) / fps_denom, NULL);
gst_pad_set_explicit_caps (smokedec->srcpad, caps);
gst_caps_free (caps);
}
- smokecodec_decode (smokedec->info, data, size, outdata);
+ if (smokedec->need_keyframe) {
+ if (flags & SMOKECODEC_KEYFRAME) {
+ smokedec->need_keyframe = FALSE;
+ } else {
+ GST_DEBUG_OBJECT (smokedec, "dropping buffer while waiting for keyframe");
+ gst_buffer_unref (buf);
+ return;
+ }
+ }
- GST_DEBUG ("gst_smokedec_chain: sending buffer");
- gst_pad_push (smokedec->srcpad, GST_DATA (outbuf));
+ if (!smokedec->need_keyframe) {
+ smokecodec_decode (smokedec->info, data, size, outdata);
+ gst_buffer_unref (buf);
- gst_buffer_unref (buf);
+ GST_DEBUG ("gst_smokedec_chain: sending buffer");
+ gst_pad_push (smokedec->srcpad, GST_DATA (outbuf));
+ }
}
diff --git a/ext/jpeg/gstsmokedec.h b/ext/jpeg/gstsmokedec.h
index 15cb89bb..d3e73d90 100644
--- a/ext/jpeg/gstsmokedec.h
+++ b/ext/jpeg/gstsmokedec.h
@@ -55,12 +55,15 @@ struct _GstSmokeDec {
gint width;
gint height;
gdouble fps;
+ GstClockTime next_time;
SmokeCodecInfo *info;
gint threshold;
gint quality;
gint smoothing;
+
+ gboolean need_keyframe;
};
struct _GstSmokeDecClass {
diff --git a/ext/jpeg/gstsmokeenc.c b/ext/jpeg/gstsmokeenc.c
index 8776b6fd..212a8bcc 100644
--- a/ext/jpeg/gstsmokeenc.c
+++ b/ext/jpeg/gstsmokeenc.c
@@ -186,6 +186,7 @@ gst_smokeenc_init (GstSmokeEnc * smokeenc)
smokeenc->width = 0;
smokeenc->height = 0;
smokeenc->frame = 0;
+ smokeenc->need_header = TRUE;
gst_smokeenc_resync (smokeenc);
@@ -264,9 +265,21 @@ gst_smokeenc_link (GstPad * pad, const GstCaps * caps)
static void
gst_smokeenc_resync (GstSmokeEnc * smokeenc)
{
+ GValue fps = { 0 };
+ GValue framerate = { 0 };
+
GST_DEBUG ("gst_smokeenc_resync: resync");
- smokecodec_encode_new (&smokeenc->info, smokeenc->width, smokeenc->height);
+ g_value_init (&fps, G_TYPE_DOUBLE);
+ g_value_init (&framerate, GST_TYPE_FRACTION);
+ g_value_set_double (&fps, smokeenc->fps);
+ g_value_transform (&fps, &framerate);
+
+ smokeenc->fps_num = gst_value_get_fraction_numerator (&framerate);
+ smokeenc->fps_denom = gst_value_get_fraction_denominator (&framerate);
+
+ smokecodec_encode_new (&smokeenc->info, smokeenc->width, smokeenc->height,
+ smokeenc->fps_num, smokeenc->fps_denom);
smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
smokeenc->max_quality);
@@ -292,19 +305,33 @@ gst_smokeenc_chain (GstPad * pad, GstData * _data)
GST_DEBUG ("gst_smokeenc_chain: got buffer of %ld bytes in '%s'", size,
GST_OBJECT_NAME (smokeenc));
+ if (smokeenc->need_header) {
+ outbuf = gst_buffer_new ();
+ outsize = 256;
+ outdata = GST_BUFFER_DATA (outbuf) = g_malloc (outsize);
+ GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+ GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+
+ smokecodec_encode_id (smokeenc->info, outdata, &encsize);
+
+ GST_BUFFER_SIZE (outbuf) = encsize;
+
+ gst_pad_push (smokeenc->srcpad, GST_DATA (outbuf));
+
+ smokeenc->need_header = FALSE;
+ }
+
outbuf = gst_buffer_new ();
outsize = smokeenc->width * smokeenc->height * 3;
outdata = GST_BUFFER_DATA (outbuf) = g_malloc (outsize);
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+ GST_BUFFER_DURATION (outbuf) =
+ smokeenc->fps_denom * GST_SECOND / smokeenc->fps_num;
flags = 0;
- if (smokeenc->frame == 0) {
+ if ((smokeenc->frame % smokeenc->keyframe) == 0) {
flags |= SMOKECODEC_KEYFRAME;
}
-
- smokeenc->frame = (smokeenc->frame + 1) % smokeenc->keyframe;
-
smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
smokeenc->max_quality);
smokecodec_set_threshold (smokeenc->info, smokeenc->threshold);
@@ -312,9 +339,12 @@ gst_smokeenc_chain (GstPad * pad, GstData * _data)
gst_buffer_unref (buf);
GST_BUFFER_SIZE (outbuf) = encsize;
- //memset(GST_BUFFER_DATA(outbuf)+encsize, 0, outsize - encsize);
+ GST_BUFFER_OFFSET (outbuf) = smokeenc->frame;
+ GST_BUFFER_OFFSET_END (outbuf) = smokeenc->frame + 1;
gst_pad_push (smokeenc->srcpad, GST_DATA (outbuf));
+
+ smokeenc->frame++;
}
static void
diff --git a/ext/jpeg/gstsmokeenc.h b/ext/jpeg/gstsmokeenc.h
index c1658cf9..cc1bbeab 100644
--- a/ext/jpeg/gstsmokeenc.h
+++ b/ext/jpeg/gstsmokeenc.h
@@ -57,12 +57,15 @@ struct _GstSmokeEnc {
gint frame;
gint keyframe;
gdouble fps;
+ gint fps_num, fps_denom;
SmokeCodecInfo *info;
gint threshold;
gint min_quality;
gint max_quality;
+
+ gboolean need_header;
};
struct _GstSmokeEncClass {
diff --git a/ext/jpeg/smokecodec.c b/ext/jpeg/smokecodec.c
index cb16827f..fb2dbe6e 100644
--- a/ext/jpeg/smokecodec.c
+++ b/ext/jpeg/smokecodec.c
@@ -34,15 +34,17 @@
#include <jpeglib.h>
#include "smokecodec.h"
+#include "smokeformat.h"
//#define DEBUG(a...) printf( a );
#define DEBUG(a,...)
-
struct _SmokeCodecInfo
{
unsigned int width;
unsigned int height;
+ unsigned int fps_num;
+ unsigned int fps_denom;
unsigned int minquality;
unsigned int maxquality;
@@ -112,7 +114,9 @@ smokecodec_term_source (j_decompress_ptr cinfo)
int
smokecodec_encode_new (SmokeCodecInfo ** info,
- const unsigned int width, const unsigned int height)
+ const unsigned int width,
+ const unsigned int height,
+ const unsigned int fps_num, const unsigned int fps_denom)
{
SmokeCodecInfo *newinfo;
int i, j;
@@ -129,6 +133,8 @@ smokecodec_encode_new (SmokeCodecInfo ** info,
}
newinfo->width = width;
newinfo->height = height;
+ newinfo->fps_num = fps_num;
+ newinfo->fps_denom = fps_denom;
/* setup jpeglib */
memset (&newinfo->cinfo, 0, sizeof (newinfo->cinfo));
@@ -200,7 +206,7 @@ smokecodec_encode_new (SmokeCodecInfo ** info,
int
smokecodec_decode_new (SmokeCodecInfo ** info)
{
- return smokecodec_encode_new (info, 16, 16);
+ return smokecodec_encode_new (info, 16, 16, 1, 1);
}
int
@@ -349,6 +355,25 @@ put (const unsigned char *src, unsigned char *dest,
/* encoding */
SmokeCodecResult
+smokecodec_encode_id (SmokeCodecInfo * info,
+ unsigned char *out, unsigned int *outsize)
+{
+ int i;
+
+ *out++ = SMOKECODEC_TYPE_ID;
+ for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
+ *out++ = SMOKECODEC_ID_STRING[i];
+ }
+ *out++ = 0;
+ *out++ = 1;
+ *out++ = 0;
+
+ *outsize = 9;
+
+ return SMOKECODEC_OK;
+}
+
+SmokeCodecResult
smokecodec_encode (SmokeCodecInfo * info,
const unsigned char *in,
SmokeCodecFlags flags, unsigned char *out, unsigned int *outsize)
@@ -384,13 +409,24 @@ smokecodec_encode (SmokeCodecInfo * info,
max = blocks_w * blocks_h;
+ out[IDX_TYPE] = SMOKECODEC_TYPE_DATA;
+
#define STORE16(var, pos, x) \
- var[pos] = (x >> 8); \
+ var[pos] = (x >> 8); \
var[pos+1] = (x & 0xff);
+#define STORE32(var, pos, x) \
+ var[pos] = ((x >> 24) & 0xff); \
+ var[pos+1] = ((x >> 16) & 0xff); \
+ var[pos+2] = ((x >> 8) & 0xff); \
+ var[pos+3] = (x & 0xff);
/* write dimension */
- STORE16 (out, 0, width);
- STORE16 (out, 2, height);
+ STORE16 (out, IDX_WIDTH, width);
+ STORE16 (out, IDX_HEIGHT, height);
+
+ /* write framerate */
+ STORE32 (out, IDX_FPS_NUM, info->fps_num);
+ STORE32 (out, IDX_FPS_DENOM, info->fps_denom);
if (!(flags & SMOKECODEC_KEYFRAME)) {
int block = 0;
@@ -400,7 +436,7 @@ smokecodec_encode (SmokeCodecInfo * info,
for (j = 0; j < width; j += 2 * DCTSIZE) {
s = abs_diff (ip, op, width);
if (s >= threshold) {
- STORE16 (out, blocks * 2 + 10, block);
+ STORE16 (out, blocks * 2 + IDX_BLOCKS, block);
blocks++;
}
@@ -422,13 +458,13 @@ smokecodec_encode (SmokeCodecInfo * info,
blocks = 0;
encoding = max;
}
- STORE16 (out, 6, blocks);
- out[4] = (flags & 0xff);
+ STORE16 (out, IDX_NUM_BLOCKS, blocks);
+ out[IDX_FLAGS] = (flags & 0xff);
DEBUG ("blocks %d, encoding %d\n", blocks, encoding);
- info->jdest.next_output_byte = &out[blocks * 2 + 12];
- info->jdest.free_in_buffer = (*outsize) - 12;
+ info->jdest.next_output_byte = &out[blocks * 2 + OFFS_PICT];
+ info->jdest.free_in_buffer = (*outsize) - OFFS_PICT;
if (encoding > 0) {
int quality;
@@ -461,7 +497,7 @@ smokecodec_encode (SmokeCodecInfo * info,
if (flags & SMOKECODEC_KEYFRAME)
pos = i;
else
- pos = (out[i * 2 + 10] << 8) | (out[i * 2 + 11]);
+ pos = (out[i * 2 + IDX_BLOCKS] << 8) | (out[i * 2 + IDX_BLOCKS + 1]);
x = pos % (width / (DCTSIZE * 2));
y = pos / (width / (DCTSIZE * 2));
@@ -488,11 +524,10 @@ smokecodec_encode (SmokeCodecInfo * info,
jpeg_finish_compress (&info->cinfo);
}
- size = ((((*outsize) - 12 - info->jdest.free_in_buffer) + 3) & ~3);
- out[8] = size >> 8;
- out[9] = size & 0xff;
+ size = ((((*outsize) - OFFS_PICT - info->jdest.free_in_buffer) + 3) & ~3);
+ STORE16 (out, IDX_SIZE, size);
- *outsize = size + blocks * 2 + 12;
+ *outsize = size + blocks * 2 + OFFS_PICT;
DEBUG ("outsize %d\n", *outsize);
// and decode in reference frame again
@@ -505,24 +540,62 @@ smokecodec_encode (SmokeCodecInfo * info,
return SMOKECODEC_OK;
}
+SmokeCodecResult
+smokecodec_parse_id (SmokeCodecInfo * info,
+ const unsigned char *in, const unsigned int insize)
+{
+ int i;
+
+ if (insize < 4 + strlen (SMOKECODEC_ID_STRING)) {
+ return SMOKECODEC_WRONGVERSION;
+ }
+
+ if (*in++ != SMOKECODEC_TYPE_ID)
+ return SMOKECODEC_ERROR;
+
+ for (i = 0; i < strlen (SMOKECODEC_ID_STRING); i++) {
+ if (*in++ != SMOKECODEC_ID_STRING[i])
+ return SMOKECODEC_ERROR;
+ }
+ if (*in++ != 0 || *in++ != 1 || *in++ != 0)
+ return SMOKECODEC_ERROR;
+
+ return SMOKECODEC_OK;
+}
+
+#define READ16(var, pos, x) \
+ x = var[pos]<<8 | var[pos+1];
+
+#define READ32(var, pos, x) \
+ x = var[pos]<<24 | var[pos+1]<<16 | \
+ var[pos+2]<<8 | var[pos+3];
+
/* decoding */
SmokeCodecResult
smokecodec_parse_header (SmokeCodecInfo * info,
const unsigned char *in,
const unsigned int insize,
- SmokeCodecFlags * flags, unsigned int *width, unsigned int *height)
+ SmokeCodecFlags * flags,
+ unsigned int *width,
+ unsigned int *height, unsigned int *fps_num, unsigned int *fps_denom)
{
- *width = in[0] << 8 | in[1];
- *height = in[2] << 8 | in[3];
- *flags = in[4];
+ READ16 (in, IDX_WIDTH, *width);
+ READ16 (in, IDX_HEIGHT, *height);
+ *flags = in[IDX_FLAGS];
+ READ32 (in, IDX_FPS_NUM, *fps_num);
+ READ32 (in, IDX_FPS_DENOM, *fps_denom);
- if (info->width != *width || info->height != *height) {
+ if (info->width != *width ||
+ info->height != *height ||
+ info->fps_num != *fps_num || info->fps_denom != *fps_denom) {
DEBUG ("new width: %d %d\n", *width, *height);
info->reference = realloc (info->reference, 3 * ((*width) * (*height)) / 2);
info->width = *width;
info->height = *height;
+ info->fps_num = *fps_num;
+ info->fps_denom = *fps_denom;
}
return SMOKECODEC_OK;
@@ -533,6 +606,7 @@ smokecodec_decode (SmokeCodecInfo * info,
const unsigned char *in, const unsigned int insize, unsigned char *out)
{
unsigned int width, height;
+ unsigned int fps_num, fps_denom;
SmokeCodecFlags flags;
int i, j;
int blocks_w, blocks_h;
@@ -542,9 +616,10 @@ smokecodec_decode (SmokeCodecInfo * info,
unsigned char *op;
int res;
- smokecodec_parse_header (info, in, insize, &flags, &width, &height);
+ smokecodec_parse_header (info, in, insize, &flags, &width, &height,
+ &fps_num, &fps_denom);
- blocks = in[6] << 8 | in[7];
+ READ16 (in, IDX_NUM_BLOCKS, blocks);
DEBUG ("blocks %d\n", blocks);
if (flags & SMOKECODEC_KEYFRAME)
@@ -552,12 +627,11 @@ smokecodec_decode (SmokeCodecInfo * info,
else
decoding = blocks;
-
if (decoding > 0) {
- info->jsrc.next_input_byte = &in[blocks * 2 + 12];
- info->jsrc.bytes_in_buffer = insize - (blocks * 2 + 12);
+ info->jsrc.next_input_byte = &in[blocks * 2 + OFFS_PICT];
+ info->jsrc.bytes_in_buffer = insize - (blocks * 2 + OFFS_PICT);
- DEBUG ("header %02x %d\n", in[blocks * 2 + 12], insize);
+ DEBUG ("header %02x %d\n", in[blocks * 2 + OFFS_PICT], insize);
res = jpeg_read_header (&info->dinfo, TRUE);
DEBUG ("header %d %d %d\n", res, info->dinfo.image_width,
info->dinfo.image_height);
@@ -590,7 +664,7 @@ smokecodec_decode (SmokeCodecInfo * info,
if (flags & SMOKECODEC_KEYFRAME)
pos = blockptr;
else
- pos = (in[blockptr * 2 + 10] << 8) | (in[blockptr * 2 + 11]);
+ READ16 (in, blockptr * 2 + IDX_BLOCKS, pos);
x = pos % (width / (DCTSIZE * 2));
y = pos / (width / (DCTSIZE * 2));
diff --git a/ext/jpeg/smokecodec.h b/ext/jpeg/smokecodec.h
index 6ffc5ef8..6c428068 100644
--- a/ext/jpeg/smokecodec.h
+++ b/ext/jpeg/smokecodec.h
@@ -30,11 +30,12 @@ extern "C" {
typedef struct _SmokeCodecInfo SmokeCodecInfo;
typedef enum {
+ SMOKECODEC_WRONGVERSION = -5,
SMOKECODEC_WRONGSIZE = -4,
SMOKECODEC_ERROR = -3,
SMOKECODEC_NOMEM = -2,
SMOKECODEC_NULLPTR = -1,
- SMOKECODEC_OK = 0,
+ SMOKECODEC_OK = 0
} SmokeCodecResult;
typedef enum {
@@ -42,11 +43,21 @@ typedef enum {
SMOKECODEC_MOTION_VECTORS = (1<<1)
} SmokeCodecFlags;
+#define SMOKECODEC_ID_STRING "smoke"
+
+typedef enum {
+ SMOKECODEC_TYPE_ID = 0x80,
+ SMOKECODEC_TYPE_COMMENT = 0x81,
+ SMOKECODEC_TYPE_EXTRA = 0x83,
+ SMOKECODEC_TYPE_DATA = 0x40
+} SmokePacketType;
/* init */
int smokecodec_encode_new (SmokeCodecInfo **info,
const unsigned int width,
- const unsigned int height);
+ const unsigned int height,
+ const unsigned int fps_num,
+ const unsigned int fps_denom);
int smokecodec_decode_new (SmokeCodecInfo **info);
@@ -69,6 +80,10 @@ SmokeCodecResult smokecodec_get_bitrate (SmokeCodecInfo *info,
unsigned int *bitrate);
/* encoding */
+SmokeCodecResult smokecodec_encode_id (SmokeCodecInfo *info,
+ unsigned char *out,
+ unsigned int *outsize);
+
SmokeCodecResult smokecodec_encode (SmokeCodecInfo *info,
const unsigned char *in,
SmokeCodecFlags flags,
@@ -76,12 +91,18 @@ SmokeCodecResult smokecodec_encode (SmokeCodecInfo *info,
unsigned int *outsize);
/* decoding */
+SmokeCodecResult smokecodec_parse_id (SmokeCodecInfo *info,
+ const unsigned char *in,
+ const unsigned int insize);
+
SmokeCodecResult smokecodec_parse_header (SmokeCodecInfo *info,
const unsigned char *in,
const unsigned int insize,
SmokeCodecFlags *flags,
unsigned int *width,
- unsigned int *height);
+ unsigned int *height,
+ unsigned int *fps_num,
+ unsigned int *fps_denom);
SmokeCodecResult smokecodec_decode (SmokeCodecInfo *info,
const unsigned char *in,
diff --git a/ext/jpeg/smokeformat.h b/ext/jpeg/smokeformat.h
new file mode 100644
index 00000000..9e3ca408
--- /dev/null
+++ b/ext/jpeg/smokeformat.h
@@ -0,0 +1,46 @@
+/* Smoke Codec
+ * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __SMOKEFORMAT_H__
+#define __SMOKEFORMAT_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define IDX_TYPE 0
+#define IDX_WIDTH 1
+#define IDX_HEIGHT 3
+#define IDX_FPS_NUM 5
+#define IDX_FPS_DENOM 9
+#define IDX_FLAGS 13
+#define IDX_NUM_BLOCKS 14
+#define IDX_SIZE 16
+#define IDX_BLOCKS 18
+#define OFFS_PICT 18
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __SMOKEFORMAT_H__ */