73 #define MAX_CBS_4x4 256
75 #define MAX_CBS_2x2 256
78 #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE)
83 memcpy(u , cell->
y, 4);
84 memset(u+4, cell->
u, 4);
85 memset(u+8, cell->
v, 4);
91 static const int offsets[4] = {0, 2, 8, 10};
93 for (cp=0; cp<3; cp++)
95 u[4*4*cp + offsets[i] ] = cb2[qcell->
idx[i]*2*2*3 + 4*cp ];
96 u[4*4*cp + offsets[i]+1] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+1];
97 u[4*4*cp + offsets[i]+4] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+2];
98 u[4*4*cp + offsets[i]+5] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+3];
107 for(cp=0; cp<3; cp++)
110 *u++ = base[(y/2)*4 + (x/2) + 16*cp];
123 diff +=
square(*b++ - *a++);
131 int x2,
int y2,
const int *stride1,
const int *stride2,
int size)
136 for (k=0; k<3; k++) {
138 for (i=0; i<
size; i++)
139 sse += bias*
eval_sse(buf1[k] + (y1+i)*stride1[k] + x1,
140 buf2[k] + (y2+i)*stride2[k] + x2, size);
152 if (mx < -7 || mx > 7)
155 if (my < -7 || my > 7)
161 if ((
unsigned) mx > enc->
width-size || (
unsigned) my > enc->
height-size)
177 for(cp=0;cp<3;cp++) {
179 sdiff += bias*
eval_sse(a, b, size*size);
222 typedef struct RoqTempData
254 for (y=0; y<enc->
height; y+=16)
255 for (x=0; x<enc->
width; x+=16)
271 for (cp=0; cp<3; cp++) {
273 for (i=0; i<
dim; i++)
274 for (j=0; j<
dim; j++)
275 *mb++ = frame->
data[cp][(y+i)*stride + x + j];
283 int *outIndex,
int dim)
285 int i, lDiff = INT_MAX, pick=0;
288 for (i=0; i<numCB; i++) {
300 #define EVAL_MOTION(MOTION) \
302 diff = eval_motion_dist(enc, j, i, MOTION, blocksize); \
304 if (diff < lowestdiff) { \
323 int diff, lowestdiff, oldbest;
332 int max=(enc->
width/blocksize)*enc->
height/blocksize;
334 if (blocksize == 4) {
342 for (i=0; i<enc->
height; i+=blocksize)
343 for (j=0; j<enc->
width; j+=blocksize) {
352 offset = (i/blocksize)*enc->
width/blocksize + j/blocksize;
353 if (offset < max && offset >= 0)
357 if (offset < max && offset >= 0)
360 offset = (i/blocksize + 1)*enc->
width/blocksize + j/blocksize;
361 if (offset < max && offset >= 0)
364 off[0]= (i/blocksize)*enc->
width/blocksize + j/blocksize - 1;
365 off[1]= off[0] - enc->
width/blocksize + 1;
371 vect.
d[k]=
mid_pred(this_motion[off[0]].d[k],
372 this_motion[off[1]].d[k],
373 this_motion[off[2]].d[k]);
384 while (oldbest != lowestdiff) {
385 oldbest = lowestdiff;
386 for (k=0; k<8; k++) {
388 vect2.
d[0] += offsets[k].
d[0];
389 vect2.
d[1] += offsets[k].
d[1];
394 offset = (i/blocksize)*enc->
width/blocksize + j/blocksize;
395 this_motion[offset] = bestpick;
410 static const int bitsUsed[4] = {2, 10, 10, 34};
431 cluster_index = y*enc->
width/16 + x/4;
471 int i, j, best_dist, divide_bit_use;
473 int bitsUsed[4] = {2, 10, 10, 0};
507 for (i=0; i<4; i++) {
514 bitsUsed[3] = 2 + divide_bit_use;
531 for (i=0; i<4; i++) {
547 tempData->
i2f4[i] = idx;
548 tempData->
f2i4[idx] = i;
560 tempData->
i2f2[i] = idx;
561 tempData->
f2i2[idx] = i;
579 bytestream_put_le32(outp, tempData->
numCB2*6 + tempData->
numCB4*4);
580 bytestream_put_byte(outp, tempData->
numCB4);
581 bytestream_put_byte(outp, tempData->
numCB2);
583 for (i=0; i<tempData->
numCB2; i++) {
585 bytestream_put_byte(outp, enc->
cb2x2[tempData->
f2i2[i]].
u);
586 bytestream_put_byte(outp, enc->
cb2x2[tempData->
f2i2[i]].
v);
589 for (i=0; i<tempData->
numCB4; i++)
591 bytestream_put_byte(outp, tempData->
i2f2[enc->
cb4x4[tempData->
f2i4[i]].
idx[j]]);
600 return ((ax&15)<<4) | (ay&15);
649 bytestream_put_byte(&enc->
out_buf, 0x0);
650 bytestream_put_byte(&enc->
out_buf, 0x0);
652 for (i=0; i<numBlocks; i++) {
686 for (j=0; j<4; j++) {
695 bytestream_put_byte(&spool.
args,
704 bytestream_put_byte(&spool.
args,
720 for (k=0; k<4; k++) {
722 bytestream_put_byte(&spool.
args,
723 tempData->
i2f2[cb_idx]);
726 enc->
cb2x2 + cb_idx);
761 int top,
int left,
const int *
stride)
766 for (j=0; j<2; j++) {
767 int x = (top+i)*stride[0] + left + j;
768 *block++ = data[0][x];
769 x = (top+i)*stride[1] + left + j;
786 for (j=0; j<w; j+=4) {
787 for (k=0; k < 2; k++)
788 for (l=0; l < 2; l++)
796 int *points,
int inputCount,
roq_cell *results,
797 int size,
int cbsize)
799 int i, j, k, ret = 0;
800 int c_size = size*size/4;
818 cbsize, 1, closest_cb, &enc->
randctx);
822 cbsize, 1, closest_cb, &enc->
randctx);
827 for (i=0; i<cbsize; i++)
828 for (k=0; k<c_size; k++) {
830 results->
y[j] = *buf++;
854 if (!results4 || !yuvClusters || !points) {
863 for (i=0; i<max*24; i++) {
865 points[i] = bias*yuvClusters[i];
870 results4, 4, (enc->
quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4))) < 0)
889 for (i=0; i<codebooks->
numCB2; i++)
893 for (i=0; i<codebooks->
numCB4; i++) {
894 for (j=0; j<4; j++) {
916 memset(tempData, 0,
sizeof(*tempData));
937 if (enc->
lambda > 100000) {
942 "Warning, generated a frame too big for Quake (%d > 65535), "
943 "now switching to a bigger qscale value.\n",
1001 if ((avctx->
width & 0xf) || (avctx->
height & 0xf)) {
1006 if (avctx->
width > 65535 || avctx->
height > 65535) {
1012 av_log(avctx,
AV_LOG_ERROR,
"Warning: dimensions not power of two, this is not supported by quake\n");
1056 bytestream_put_le32(&enc->
out_buf, 8);
1059 bytestream_put_byte(&enc->
out_buf, 0x00);
1060 bytestream_put_byte(&enc->
out_buf, 0x00);
1069 bytestream_put_byte(&enc->
out_buf, 0x08);
1070 bytestream_put_byte(&enc->
out_buf, 0x00);
1071 bytestream_put_byte(&enc->
out_buf, 0x04);
1072 bytestream_put_byte(&enc->
out_buf, 0x00);
1092 size = ((enc->
width * enc->
height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8;
1127 #define OFFSET(x) offsetof(RoqContext, x)
1128 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1130 {
"quake3_compat",
"Whether to respect known limitations in Quake 3 decoder",
OFFSET(quake3_compat),
AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1,
VE },
SubcelEvaluation subCels[4]
This structure describes decoded (raw) audio or video data.
motion_vect * this_motion4
const AVFrame * frame_to_enc
ptrdiff_t const GLvoid * data
#define EVAL_MOTION(MOTION)
#define LIBAVUTIL_VERSION_INT
static av_cold int init(AVCodecContext *avctx)
static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, int size)
void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell)
static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData)
static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride)
motion_vect * this_motion8
static const AVOption options[]
Macro definitions for various function/variable attributes.
motion_vect * last_motion4
#define MAX_CBS_4x4
Maximum number of generated 4x4 codebooks.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static double cb(void *priv, double x, double y)
static int create_cel_evals(RoqContext *enc, RoqTempdata *tempData)
Initialize cel evaluators and set their source coordinates.
static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, int y, RoqContext *enc, RoqTempdata *tempData)
Get distortion for all options available to a subcel.
static void roq_write_video_info_chunk(RoqContext *enc)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define RoQ_QUAD_CODEBOOK
unsigned int framesSinceKeyframe
int avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state)
Implementation of the Enhanced LBG Algorithm Based on the paper "Neural Networks 14:1219-1237" that c...
uint8_t unpacked_cb2[MAX_CBS_2x2 *2 *2 *3]
void ff_apply_motion_4x4(RoqContext *ri, int x, int y, int deltax, int deltay)
void ff_apply_motion_8x8(RoqContext *ri, int x, int y, int deltax, int deltay)
#define MAX_CBS_2x2
Maximum number of 2x2 codebooks.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void unpack_roq_cell(roq_cell *cell, uint8_t u[4 *3])
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * name
Name of the codec implementation.
static const uint8_t offset[127][2]
static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, int *outIndex, int dim)
Find the codebook with the lowest distortion from an image.
int flags
A combination of AV_PKT_FLAG values.
static int block_sse(uint8_t *const *buf1, uint8_t *const *buf2, int x1, int y1, int x2, int y2, const int *stride1, const int *stride2, int size)
static void frame_block_to_cell(uint8_t *block, uint8_t *const *data, int top, int left, const int *stride)
Create a single YUV cell from a 2x2 section of the image.
static void write_codebooks(RoqContext *enc, RoqTempdata *tempData)
Write codebook chunk.
static void write_typecode(CodingSpool *s, uint8_t type)
static int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size)
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
int width
picture width / height.
struct RoqTempData * tmpData
int quality
quality (between 1 (good) and FF_LAMBDA_MAX (bad))
static void motion_search(RoqContext *enc, int blocksize)
static uint8_t motion_arg(motion_vect mot)
static int roq_encode_video(RoqContext *enc)
static av_cold int roq_encode_end(AVCodecContext *avctx)
int avpriv_init_elbg(int *points, int dim, int numpoints, int *codebook, int numCB, int max_steps, int *closest_cb, AVLFG *rand_state)
Initialize the **codebook vector for the elbg algorithm.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static int eval_sse(const uint8_t *a, const uint8_t *b, int count)
Describe the class of an AVClass context structure.
static int generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData)
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, RoqTempdata *tempData)
Get distortion for all options available to a cel.
uint8_t argumentSpool[64]
static enum AVPixelFormat pix_fmts[]
static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static av_cold int roq_encode_init(AVCodecContext *avctx)
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
static int generate_codebook(RoqContext *enc, RoqTempdata *tempdata, int *points, int inputCount, roq_cell *results, int size, int cbsize)
GLint GLenum GLboolean GLsizei stride
CelEvaluation * cel_evals
common internal api header.
static void get_frame_mb(const AVFrame *frame, int x, int y, uint8_t mb[], int dim)
Get macroblocks from parts of the image.
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
motion_vect * last_motion8
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
static void enlarge_roq_mb4(uint8_t base[3 *16], uint8_t u[3 *64])
void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClusters)
Create YUV clusters for the entire image.
static void * av_mallocz_array(size_t nmemb, size_t size)
uint8_t unpacked_cb4[MAX_CBS_4x4 *4 *4 *3]
#define av_malloc_array(a, b)
static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4 *4 *3])
#define FFSWAP(type, a, b)
static const AVClass roq_class
AVPixelFormat
Pixel format.
This structure stores compressed data.
uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4 *8 *8 *3]
static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks)