71 #define MAX_CBS_4x4 255
73 #define MAX_CBS_2x2 256
76 #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE)
81 memcpy(u , cell->
y, 4);
82 memset(u+4, cell->
u, 4);
83 memset(u+8, cell->
v, 4);
89 static const int offsets[4] = {0, 2, 8, 10};
91 for (cp=0; cp<3; cp++)
93 u[4*4*cp + offsets[i] ] = cb2[qcell->
idx[i]*2*2*3 + 4*cp ];
94 u[4*4*cp + offsets[i]+1] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+1];
95 u[4*4*cp + offsets[i]+4] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+2];
96 u[4*4*cp + offsets[i]+5] = cb2[qcell->
idx[i]*2*2*3 + 4*cp+3];
105 for(cp=0; cp<3; cp++)
108 *u++ = base[(y/2)*4 + (x/2) + 16*cp];
116 static inline int eval_sse(uint8_t *
a, uint8_t *
b,
int count)
121 diff +=
square(*b++ - *a++);
128 static int block_sse(uint8_t **buf1, uint8_t **buf2,
int x1,
int y1,
int x2,
129 int y2,
int *stride1,
int *stride2,
int size)
134 for (k=0; k<3; k++) {
136 for (i=0; i<
size; i++)
137 sse += bias*
eval_sse(buf1[k] + (y1+i)*stride1[k] + x1,
138 buf2[k] + (y2+i)*stride2[k] + x2, size);
150 if (mx < -7 || mx > 7)
153 if (my < -7 || my > 7)
159 if ((
unsigned) mx > enc->
width-size || (
unsigned) my > enc->
height-size)
175 for(cp=0;cp<3;cp++) {
177 sdiff += bias*
eval_sse(a, b, size*size);
253 for (y=0; y<enc->
height; y+=16)
254 for (x=0; x<enc->
width; x+=16)
268 for (cp=0; cp<3; cp++) {
270 for (i=0; i<
dim; i++)
271 for (j=0; j<
dim; j++)
272 *mb++ = frame->
data[cp][(y+i)*stride + x + j];
279 static int index_mb(uint8_t cluster[], uint8_t cb[],
int numCB,
280 int *outIndex,
int dim)
282 int i, lDiff = INT_MAX, pick=0;
285 for (i=0; i<numCB; i++) {
297 #define EVAL_MOTION(MOTION) \
299 diff = eval_motion_dist(enc, j, i, MOTION, blocksize); \
301 if (diff < lowestdiff) { \
320 int diff, lowestdiff, oldbest;
329 int max=(enc->
width/blocksize)*enc->
height/blocksize;
331 if (blocksize == 4) {
339 for (i=0; i<enc->
height; i+=blocksize)
340 for (j=0; j<enc->
width; j+=blocksize) {
349 offset = (i/blocksize)*enc->
width/blocksize + j/blocksize;
350 if (offset < max && offset >= 0)
354 if (offset < max && offset >= 0)
357 offset = (i/blocksize + 1)*enc->
width/blocksize + j/blocksize;
358 if (offset < max && offset >= 0)
361 off[0]= (i/blocksize)*enc->
width/blocksize + j/blocksize - 1;
362 off[1]= off[0] - enc->
width/blocksize + 1;
368 vect.
d[k]=
mid_pred(this_motion[off[0]].d[k],
369 this_motion[off[1]].d[k],
370 this_motion[off[2]].d[k]);
381 while (oldbest != lowestdiff) {
382 oldbest = lowestdiff;
383 for (k=0; k<8; k++) {
385 vect2.
d[0] += offsets[k].
d[0];
386 vect2.
d[1] += offsets[k].
d[1];
391 offset = (i/blocksize)*enc->
width/blocksize + j/blocksize;
392 this_motion[offset] = bestpick;
407 static const int bitsUsed[4] = {2, 10, 10, 34};
428 cluster_index = y*enc->
width/16 + x/4;
468 int i, j, best_dist, divide_bit_use;
470 int bitsUsed[4] = {2, 10, 10, 0};
504 for (i=0; i<4; i++) {
511 bitsUsed[3] = 2 + divide_bit_use;
528 for (i=0; i<4; i++) {
544 tempData->
i2f4[i] = idx;
545 tempData->
f2i4[idx] = i;
557 tempData->
i2f2[i] = idx;
558 tempData->
f2i2[idx] = i;
576 bytestream_put_le32(outp, tempData->
numCB2*6 + tempData->
numCB4*4);
577 bytestream_put_byte(outp, tempData->
numCB4);
578 bytestream_put_byte(outp, tempData->
numCB2);
580 for (i=0; i<tempData->
numCB2; i++) {
582 bytestream_put_byte(outp, enc->
cb2x2[tempData->
f2i2[i]].
u);
583 bytestream_put_byte(outp, enc->
cb2x2[tempData->
f2i2[i]].
v);
586 for (i=0; i<tempData->
numCB4; i++)
588 bytestream_put_byte(outp, tempData->
i2f2[enc->
cb4x4[tempData->
f2i4[i]].
idx[j]]);
595 uint8_t ax = 8 - ((uint8_t) mot.
d[0]);
596 uint8_t ay = 8 - ((uint8_t) mot.
d[1]);
597 return ((ax&15)<<4) | (ay&15);
604 uint8_t argumentSpool[64];
647 bytestream_put_byte(&enc->
out_buf, 0x0);
648 bytestream_put_byte(&enc->
out_buf, 0x0);
650 for (i=0; i<numBlocks; i++) {
684 for (j=0; j<4; j++) {
693 bytestream_put_byte(&spool.
args,
702 bytestream_put_byte(&spool.
args,
718 for (k=0; k<4; k++) {
720 bytestream_put_byte(&spool.
args,
721 tempData->
i2f2[cb_idx]);
724 enc->
cb2x2 + cb_idx);
759 int top,
int left,
int *
stride)
764 for (j=0; j<2; j++) {
765 int x = (top+i)*stride[0] + left + j;
766 *block++ = data[0][x];
767 x = (top+i)*stride[1] + left + j;
784 for (j=0; j<w; j+=4) {
785 for (k=0; k < 2; k++)
786 for (l=0; l < 2; l++)
794 int *points,
int inputCount,
roq_cell *results,
795 int size,
int cbsize)
798 int c_size = size*size/4;
800 int *codebook =
av_malloc(6*c_size*cbsize*
sizeof(
int));
804 closest_cb =
av_malloc(6*c_size*inputCount*
sizeof(
int));
808 ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->
randctx);
809 ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->
randctx);
815 for (i=0; i<cbsize; i++)
816 for (k=0; k<c_size; k++) {
818 results->
y[j] = *buf++;
835 uint8_t *yuvClusters=
av_malloc(
sizeof(
int)*max*6*4);
836 int *points =
av_malloc(max*6*4*
sizeof(
int));
843 for (i=0; i<max*24; i++) {
845 points[i] = bias*yuvClusters[i];
861 for (i=0; i<codebooks->
numCB2; i++)
865 for (i=0; i<codebooks->
numCB4; i++) {
866 for (j=0; j<4; j++) {
887 memset(tempData, 0,
sizeof(*tempData));
905 "Warning, generated a frame too big (%d > 65535), "
906 "try using a smaller qscale value.\n",
946 if ((avctx->
width & 0xf) || (avctx->
height & 0xf)) {
986 bytestream_put_le32(&enc->
out_buf, 8);
989 bytestream_put_byte(&enc->
out_buf, 0x00);
990 bytestream_put_byte(&enc->
out_buf, 0x00);
999 bytestream_put_byte(&enc->
out_buf, 0x08);
1000 bytestream_put_byte(&enc->
out_buf, 0x00);
1001 bytestream_put_byte(&enc->
out_buf, 0x04);
1002 bytestream_put_byte(&enc->
out_buf, 0x00);
1009 uint8_t *buf_start = buf;
1023 if (((enc->
width*enc->
height/64)*138+7)/8 + 256*(6+4) + 8 > buf_size) {
1050 return enc->
out_buf - buf_start;
1077 .supported_framerates = (
const AVRational[]){{30,1}, {0,0}},
static int roq_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
SubcelEvaluation subCels[4]
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
motion_vect * this_motion4
#define EVAL_MOTION(MOTION)
void(* release_buffer)(struct AVCodecContext *c, AVFrame *pic)
Called to release buffers which were allocated with get_buffer.
AVFrame * coded_frame
the picture in the bitstream
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
struct RoqTempData RoqTempdata
Temporary vars.
motion_vect * last_motion4
#define MAX_CBS_4x4
Maximum number of generated 4x4 codebooks.
static int roq_encode_init(AVCodecContext *avctx)
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)
#define RoQ_QUAD_CODEBOOK
static void get_frame_mb(AVFrame *frame, int x, int y, uint8_t mb[], int dim)
Get macroblocks from parts of the image.
unsigned int framesSinceKeyframe
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)
static int init(AVCodecParserContext *s)
#define MAX_CBS_2x2
Maximum number of 2x2 codebooks.
CelEvaluation * cel_evals
static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData)
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
static void unpack_roq_cell(roq_cell *cell, uint8_t u[4 *3])
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
const char * name
Name of the codec implementation.
struct RoqContext RoqContext
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.
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
void ff_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...
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)
int width
picture width / height.
struct RoqTempData * tmpData
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
int quality
quality (between 1 (good) and FF_LAMBDA_MAX (bad))
static void create_cel_evals(RoqContext *enc, RoqTempdata *tempData)
Initialize cel evaluators and set their source coordinates.
static void motion_search(RoqContext *enc, int blocksize)
static void create_clusters(AVFrame *frame, int w, int h, uint8_t *yuvClusters)
Create YUV clusters for the entire image.
static uint8_t motion_arg(motion_vect mot)
static int roq_encode_end(AVCodecContext *avctx)
static int eval_sse(uint8_t *a, uint8_t *b, int count)
static void frame_block_to_cell(uint8_t *block, uint8_t **data, int top, int left, int *stride)
Create a single YUV cell from a 2x2 section of the image.
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
main external API structure.
static void close(AVCodecParserContext *s)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static void generate_codebook(RoqContext *enc, RoqTempdata *tempdata, int *points, int inputCount, roq_cell *results, int size, int cbsize)
static void roq_encode_video(RoqContext *enc)
rational number numerator/denominator
static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, RoqTempdata *tempData)
Get distortion for all options available to a cel.
void ff_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.
static int block_sse(uint8_t **buf1, uint8_t **buf2, int x1, int y1, int x2, int y2, int *stride1, int *stride2, int size)
uint8_t argumentSpool[64]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
common internal api header.
void av_cold av_lfg_init(AVLFG *c, unsigned int seed)
motion_vect * last_motion8
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
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 unpacked_cb4[MAX_CBS_4x4 *4 *4 *3]
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4 *4 *3])
#define FFSWAP(type, a, b)
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)