aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraddr-see-the-website@aetey.se <addr-see-the-website@aetey.se>2014-01-31 20:06:15 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-02-01 22:32:28 +0100
commit392b0345d6d27d1c3cac85d5b299072db1d09f5f (patch)
tree68b8322e3fc823f527c3545ee86d4550c6eda146
parent80a79f2641367fdc8db37d8ff52438e61c826d8e (diff)
downloadffmpeg-392b0345d6d27d1c3cac85d5b299072db1d09f5f.tar.gz
RoQ-encoder: introducing Quake 3 compatibility option
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/roqvideo.h4
-rw-r--r--libavcodec/roqvideoenc.c30
2 files changed, 27 insertions, 7 deletions
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index 39dda0c88b..3da6eaa991 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -43,6 +43,7 @@ struct RoqTempData;
typedef struct RoqContext {
+ const AVClass *class;
AVCodecContext *avctx;
AVFrame *last_frame;
AVFrame *current_frame;
@@ -69,6 +70,9 @@ typedef struct RoqContext {
const AVFrame *frame_to_enc;
uint8_t *out_buf;
struct RoqTempData *tmpData;
+
+ int quake3_compat; // Quake 3 compatibility option
+
} RoqContext;
#define RoQ_INFO 0x1001
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index 37bd8d5cb6..22ebec67a3 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -57,6 +57,7 @@
#include <string.h>
#include "libavutil/attributes.h"
+#include "libavutil/opt.h"
#include "roqvideo.h"
#include "bytestream.h"
#include "elbg.h"
@@ -69,7 +70,7 @@
* Maximum number of generated 4x4 codebooks. Can't be 256 to workaround a
* Quake 3 bug.
*/
-#define MAX_CBS_4x4 255
+#define MAX_CBS_4x4 256
#define MAX_CBS_2x2 256 ///< Maximum number of 2x2 codebooks.
@@ -540,7 +541,7 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData)
int i, j, idx=0;
/* Make remaps for the final codebook usage */
- for (i=0; i<MAX_CBS_4x4; i++) {
+ for (i=0; i<(enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); i++) {
if (tempData->codebooks.usedCB4[i]) {
tempData->i2f4[i] = idx;
tempData->f2i4[idx] = i;
@@ -847,9 +848,9 @@ static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData)
}
/* Create 4x4 codebooks */
- generate_codebook(enc, tempData, points, max, results4, 4, MAX_CBS_4x4);
+ generate_codebook(enc, tempData, points, max, results4, 4, (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4));
- codebooks->numCB4 = MAX_CBS_4x4;
+ codebooks->numCB4 = (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4);
tempData->closest_cb2 = av_malloc(max*4*sizeof(int));
@@ -901,10 +902,10 @@ static void roq_encode_video(RoqContext *enc)
gather_data_for_cel(tempData->cel_evals + i, enc, tempData);
/* Quake 3 can't handle chunks bigger than 65535 bytes */
- if (tempData->mainChunkSize/8 > 65535) {
+ if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) {
av_log(enc->avctx, AV_LOG_ERROR,
- "Warning, generated a frame too big (%d > 65535), "
- "try using a smaller qscale value.\n",
+ "Warning, generated a frame too big for Quake (%d > 65535), "
+ "now switching to a bigger qscale value.\n",
tempData->mainChunkSize/8);
enc->lambda *= 1.5;
tempData->mainChunkSize = 0;
@@ -1073,6 +1074,20 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
return 0;
}
+#define OFFSET(x) offsetof(RoqContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "quake3_compat", "Whether to respect known limitations in Quake 3 decoder", OFFSET(quake3_compat), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
+ { NULL },
+};
+
+static const AVClass roq_class = {
+ .class_name = "RoQ",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_roq_encoder = {
.name = "roqvideo",
.long_name = NULL_IF_CONFIG_SMALL("id RoQ video"),
@@ -1085,4 +1100,5 @@ AVCodec ff_roq_encoder = {
.supported_framerates = (const AVRational[]){ {30,1}, {0,0} },
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NONE },
+ .priv_class = &roq_class,
};