Mike Melanson skrev 2011-07-23 00:50:
2) There's a usable Cinepak encoder patch out there. It's chatty but it
does the job. I don't know about the overall quality but given the vintage
of the codec, the encoder is probably doing a good job. Should we push it
in?
I just figured out that the author of this patch is on the list. Tomas H.:
Can you comment about whether you think your Cinepak is suitable for
inclusion?
Well, it produces valid output and seems to live up to what Cinepak was
designed for - decent video at 320x200 and 15 fps in under 1x CD rate
(1200 kbps). It also supports grayscale via PIX_FMT_GRAY8.
320x200 nets around 12 fps encoding speed on my laptop in VirtualBox.
Poking a little at it, it seems MAX_STRIPS > 1 is broken (probably never
bothered testing it).
The output size can be controlled via -qscale, just like some of the
other obscure encoders.
Rebased patch attached.
(just got back from vacation, hence the late reply)
/Tomas
>From 98324fbde7d7ce15c7d74ebf5cce6488b5ce283b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomas=20H=C3=A4rdin?=
Date: Wed, 17 Aug 2011 14:42:56 +0200
Subject: [PATCH] Cinepak encoder
---
libavcodec/Makefile |1 +
libavcodec/allcodecs.c |2 +-
libavcodec/cinepakenc.c | 799 +++
3 files changed, 801 insertions(+), 1 deletions(-)
create mode 100644 libavcodec/cinepakenc.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 36e07a9..ee7f931 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -99,6 +99,7 @@ OBJS-$(CONFIG_CAVS_DECODER)+= cavs.o cavsdec.o cavsdsp.o \
mpeg12data.o mpegvideo.o
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o
+OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o
OBJS-$(CONFIG_CLJR_DECODER)+= cljr.o
OBJS-$(CONFIG_CLJR_ENCODER)+= cljr.o
OBJS-$(CONFIG_COOK_DECODER)+= cook.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index dcef0d6..d11936c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -84,7 +84,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (C93, c93);
REGISTER_DECODER (CAVS, cavs);
REGISTER_DECODER (CDGRAPHICS, cdgraphics);
-REGISTER_DECODER (CINEPAK, cinepak);
+REGISTER_ENCDEC (CINEPAK, cinepak);
REGISTER_DECODER (CLJR, cljr);
REGISTER_DECODER (CSCD, cscd);
REGISTER_DECODER (CYUV, cyuv);
diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c
new file mode 100644
index 000..e1658a7
--- /dev/null
+++ b/libavcodec/cinepakenc.c
@@ -0,0 +1,799 @@
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "libavutil/lfg.h"
+#include "elbg.h"
+
+#define CVID_HEADER_SIZE 10
+#define STRIP_HEADER_SIZE 12
+#define CHUNK_HEADER_SIZE 4
+
+#define MB_SIZE 4 //4x4 MBs
+#define MB_AREA (MB_SIZE*MB_SIZE)
+
+#define VECTOR_MAX 6//six or four entries per vector depending on format
+#define CODEBOOK_MAX 256
+#define CODEBOOK_NUM 5 //five potential codebooks (1, 4, 16, 64, 256) for V1 and V4
+
+#define MAX_STRIPS 1 //Note: having fewer choices regarding the number of strip speeds up encoding (obviously)
+#define MIN_STRIPS 1 //Note: having more strips speeds up encoding the frame (this is less obvious)
+
+typedef enum {
+MODE_V1_ONLY = 0,
+MODE_V1_V4,
+MODE_MC,
+
+MODE_COUNT,
+} CinepakMode;
+
+typedef enum {
+ENC_V1,
+ENC_V4,
+ENC_SKIP
+} mb_encoding;
+
+typedef struct {
+int v1_vector; //index into v1 codebook
+int v1_error; //error when using V1 encoding
+int v4_vector[CODEBOOK_NUM][4]; //indices into v4 codebooks
+int v4_error[CODEBOOK_NUM]; //error when using V4 encodings
+int skip_error; //error when block is skipped (aka copied from last frame)
+mb_encoding best_encoding; //last result from calculate_mode_score()
+} mb_info;
+
+typedef struct {
+int v1_codebook[CODEBOOK_MAX*VECTOR_MAX];
+int *v4_codebook;
+} strip_info;
+
+typedef struct {
+AVCodecContext *avctx;
+unsigned char *pict_bufs[3], *strip_buf, *frame_buf;
+AVFrame last_frame;
+AVFrame best_frame;
+AVFrame scratch_frame;
+enum PixelFormat pix_fmt;
+int w, h;
+int curframe, keyint;
+AVLFG randctx;
+uint64_t lambda;
+int *codebook_input;
+int *codebook_closest;
+mb_info *mb;//MB RD state
+#ifdef CINEPAKENC_DEBUG
+mb_info *best_mb; //TODO: remove. only used for printing stats
+#endif
+int num_v1_mode, num_v4_mode, num_mc_mode;
+int num_v1_encs, num_v4_encs, num_skips;
+} CinepakEncContext;
+
+static av_cold int cinepak_encode_init(AVCodecContext *avctx)
+{
+CinepakEncContext *s = avctx->priv_data;
+int x, mb_count, strip_buf_size, frame_buf_size;
+
+if (avc