3
* Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
5
* Authors: struktur AG, Dirk Farin <farin@struktur.de>
7
* This file is part of libde265.
9
* libde265 is free software: you can redistribute it and/or modify
10
* it under the terms of the GNU Lesser General Public License as
11
* published by the Free Software Foundation, either version 3 of
12
* the License, or (at your option) any later version.
14
* libde265 is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public License
20
* along with libde265. If not, see <http://www.gnu.org/licenses/>.
24
#include "libde265/encoder/algo/pb-mv.h"
25
#include "libde265/encoder/algo/coding-options.h"
26
#include "libde265/encoder/encoder-context.h"
33
enc_cb* Algo_PB_MV_Test::analyze(encoder_context* ectx,
34
context_model_table& ctxModel,
36
int PBidx, int x,int y,int w,int h)
38
enum MVTestMode testMode = mParams.testMode();
43
fill_luma_motion_vector_predictors(ectx, ectx->shdr, ectx->img,
44
cb->x,cb->y,1<<cb->log2Size, x,y,w,h,
46
0, 0, // int refIdx, int partIdx,
49
//printf("%d/%d: [%d;%d] [%d;%d]\n",cb->x,cb->y, mvp[0].x,mvp[0].y, mvp[1].x,mvp[1].y);
52
motion_spec& spec = cb->inter.pb[PBidx].spec;
53
MotionVectorSpec& vec = cb->inter.pb[PBidx].motion;
58
spec.inter_pred_idc = PRED_L0;
59
spec.refIdx[0] = vec.refIdx[0] = 0;
62
int value = mParams.range();
70
case MVTestMode_Random:
71
spec.mvd[0][0] = (rand() % (2*value+1)) - value;
72
spec.mvd[0][1] = (rand() % (2*value+1)) - value;
75
case MVTestMode_Horizontal:
80
case MVTestMode_Vertical:
86
spec.mvd[0][0] -= mvp[0].x;
87
spec.mvd[0][1] -= mvp[0].y;
89
vec.mv[0].x = mvp[0].x + spec.mvd[0][0];
90
vec.mv[0].y = mvp[0].y + spec.mvd[0][1];
94
ectx->img->set_mv_info(x,y,w,h, vec);
96
generate_inter_prediction_samples(ectx, ectx->shdr, ectx->prediction,
97
cb->x,cb->y, // int xC,int yC,
98
0,0, // int xB,int yB,
99
1<<cb->log2Size, // int nCS,
101
1<<cb->log2Size, // int nPbW,int nPbH,
104
// TODO estimate rate for sending MV
106
int IntraSplitFlag = 0;
107
int MaxTrafoDepth = ectx->sps.max_transform_hierarchy_depth_inter;
111
assert(mTBSplitAlgo);
112
cb->transform_tree = mTBSplitAlgo->analyze(ectx,ctxModel, ectx->imgdata->input, NULL, cb,
113
cb->x,cb->y,cb->x,cb->y, cb->log2Size,0,
114
0, MaxTrafoDepth, IntraSplitFlag);
116
cb->inter.rqt_root_cbf = ! cb->transform_tree->isZeroBlock();
118
cb->distortion = cb->transform_tree->distortion;
119
cb->rate = cb->transform_tree->rate;
122
const de265_image* input = ectx->imgdata->input;
123
de265_image* img = ectx->prediction;
126
int tbSize = 1<<cb->log2Size;
128
cb->distortion = compute_distortion_ssd(input, img, x0,y0, cb->log2Size, 0);
129
cb->rate = 5; // fake (MV)
131
cb->inter.rqt_root_cbf = 0;
140
int sad(const uint8_t* p1,int stride1,
141
const uint8_t* p2,int stride2,
146
for (int y=0;y<h;y++) {
147
for (int x=0;x<w;x++) {
148
cost += abs_value(*p1 - *p2);
161
enc_cb* Algo_PB_MV_Search::analyze(encoder_context* ectx,
162
context_model_table& ctxModel,
164
int PBidx, int x,int y,int pbW,int pbH)
166
enum MVSearchAlgo searchAlgo = mParams.mvSearchAlgo();
171
fill_luma_motion_vector_predictors(ectx, ectx->shdr, ectx->img,
172
cb->x,cb->y,1<<cb->log2Size, x,y,pbW,pbH,
174
0, 0, // int refIdx, int partIdx,
177
motion_spec& spec = cb->inter.pb[PBidx].spec;
178
MotionVectorSpec& vec = cb->inter.pb[PBidx].motion;
183
spec.inter_pred_idc = PRED_L0;
184
spec.refIdx[0] = vec.refIdx[0] = 0;
185
spec.mvp_l0_flag = 0;
187
int hrange = mParams.hrange();
188
int vrange = mParams.vrange();
190
// previous frame (TODO)
191
const de265_image* refimg = ectx->get_image(ectx->imgdata->frame_number -1);
192
const de265_image* inputimg = ectx->imgdata->input;
194
int w = refimg->get_width();
195
int h = refimg->get_height();
197
int mincost = 0x7fffffff;
199
double lambda = 10.0;
201
double *bits_h = new double[2*hrange+1];
202
double *bits_v = new double[2*vrange+1];
204
for (int i=-hrange;i<=hrange;i++) {
205
int diff = (i - mvp[0].x);
208
if (diff==0) { b=0; }
209
else if (diff==1 || diff==-1) { b=2; }
210
else { b=abs_value(b+2); }
215
for (int i=-vrange;i<=vrange;i++) {
216
int diff = (i - mvp[0].y);
219
if (diff==0) { b=0; }
220
else if (diff==1 || diff==-1) { b=2; }
221
else { b=abs_value(b+2); }
226
for (int my = y-vrange; my<=y+vrange; my++)
227
for (int mx = x-hrange; mx<=x+hrange; mx++)
229
if (mx<0 || mx+pbW>w || my<0 || my+pbH>h) continue;
231
int cost = sad(refimg->get_image_plane_at_pos(0,mx,my),
232
refimg->get_image_stride(0),
233
inputimg->get_image_plane_at_pos(0,x,y),
234
inputimg->get_image_stride(0),
237
int bits = bits_h[mx-x+hrange] + bits_v[my-y+vrange];
239
cost += lambda * bits;
241
//printf("%d %d : %d\n",mx,my,cost);
246
spec.mvd[0][0]=(mx-x)<<2;
247
spec.mvd[0][1]=(my-y)<<2;
251
spec.mvd[0][0] -= mvp[0].x;
252
spec.mvd[0][1] -= mvp[0].y;
254
vec.mv[0].x = mvp[0].x + spec.mvd[0][0];
255
vec.mv[0].y = mvp[0].y + spec.mvd[0][1];
259
ectx->img->set_mv_info(x,y,pbW,pbH, vec);
261
generate_inter_prediction_samples(ectx, ectx->shdr, ectx->prediction,
262
cb->x,cb->y, // int xC,int yC,
263
0,0, // int xB,int yB,
264
1<<cb->log2Size, // int nCS,
266
1<<cb->log2Size, // int nPbW,int nPbH,
269
// --- create residual ---
273
// TODO estimate rate for sending MV
275
int IntraSplitFlag = 0;
276
int MaxTrafoDepth = ectx->sps.max_transform_hierarchy_depth_inter;
280
cb->transform_tree = mTBSplitAlgo->analyze(ectx,ctxModel, ectx->imgdata->input, NULL, cb,
281
cb->x,cb->y,cb->x,cb->y, cb->log2Size,0,
282
0, MaxTrafoDepth, IntraSplitFlag);
284
cb->inter.rqt_root_cbf = ! cb->transform_tree->isZeroBlock();
286
cb->distortion = cb->transform_tree->distortion;
287
cb->rate = cb->transform_tree->rate;
290
const de265_image* input = ectx->imgdata->input;
291
de265_image* img = ectx->img;
294
int tbSize = 1<<cb->log2Size;
296
cb->distortion = compute_distortion_ssd(input, img, x0,y0, cb->log2Size, 0);
297
cb->rate = 5; // fake (MV)
299
cb->inter.rqt_root_cbf = 0;