void schro_opengl_frame_setup (SchroOpenGL *opengl, SchroFrame *frame) { int i; int components; int width, height; SchroFrameFormat format; SchroOpenGLCanvasPool *canvas_pool; SchroOpenGLCanvas *canvas; SCHRO_ASSERT (frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (frame)); components = SCHRO_FRAME_IS_PACKED (frame->format) ? 1 : 3; schro_opengl_lock (opengl); canvas_pool = schro_opengl_get_canvas_pool (opengl); for (i = 0; i < components; ++i) { format = frame->components[i].format; width = frame->components[i].width; height = frame->components[i].height; SCHRO_ASSERT (frame->format == format); canvas = schro_opengl_canvas_pool_pull_or_new (canvas_pool, opengl, format, width, height); // FIXME: hack to store custom data per frame component *((SchroOpenGLCanvas **) frame->components[i].data) = canvas; } schro_opengl_unlock (opengl); }
void schro_memory_domain_memfree (SchroMemoryDomain * domain, void *ptr) { int i; SCHRO_ASSERT (domain != NULL); SCHRO_DEBUG ("free %p", ptr); schro_mutex_lock (domain->mutex); for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) { if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED)) { continue; } if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_IN_USE)) { continue; } if (domain->slots[i].ptr == ptr) { #ifdef MEM_DOMAIN_ALWAYS_FREE domain->free (domain->slots[i].ptr, domain->slots[i].size); domain->slots[i].flags = 0; #else domain->slots[i].flags &= (~SCHRO_MEMORY_DOMAIN_SLOT_IN_USE); #endif schro_mutex_unlock (domain->mutex); return; } } schro_mutex_unlock (domain->mutex); SCHRO_ASSERT (0); }
int main (int argc, char *argv[]) { int i; int j; uint8_t list[N]; int sum1, sum2; srand(time(NULL)); for (i=0;i<100;i++){ SCHRO_ERROR("%d:", i); sum1 = 0; for(j=0;j<N;j++){ list[j]=rand(); SCHRO_ERROR(" %d", list[j]); sum1 += list[j]; } sort_u8 (list, N); sum2 = 0; for(j=0;j<N;j++){ SCHRO_ERROR("* %d", list[j]); sum2 += list[j]; } SCHRO_ASSERT(sum1 == sum2); for(j=0;j<N-1;j++){ SCHRO_ASSERT(list[j] <= list[j+1]); } } return 0; }
void schro_motion_vector_prediction (SchroMotion * motion, int x, int y, int *pred_x, int *pred_y, int mode) { SchroMotionVector *mv; int vx[3]; int vy[3]; int n = 0; SCHRO_ASSERT (mode == 1 || mode == 2); if (x > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x - 1, y); if (mv->using_global == FALSE && (mv->pred_mode & mode)) { vx[n] = mv->u.vec.dx[mode - 1]; vy[n] = mv->u.vec.dy[mode - 1]; n++; } } if (y > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x, y - 1); if (mv->using_global == FALSE && (mv->pred_mode & mode)) { vx[n] = mv->u.vec.dx[mode - 1]; vy[n] = mv->u.vec.dy[mode - 1]; n++; } } if (x > 0 && y > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x - 1, y - 1); if (mv->using_global == FALSE && (mv->pred_mode & mode)) { vx[n] = mv->u.vec.dx[mode - 1]; vy[n] = mv->u.vec.dy[mode - 1]; n++; } } switch (n) { case 0: *pred_x = 0; *pred_y = 0; break; case 1: *pred_x = vx[0]; *pred_y = vy[0]; break; case 2: *pred_x = (vx[0] + vx[1] + 1) >> 1; *pred_y = (vy[0] + vy[1] + 1) >> 1; break; case 3: *pred_x = median3 (vx[0], vx[1], vx[2]); *pred_y = median3 (vy[0], vy[1], vy[2]); break; default: SCHRO_ASSERT (0); } }
void schro_mf_vector_prediction (SchroMotionField * mf, int x, int y, int *pred_x, int *pred_y, int mode) { int x_num_blocks; SchroMotionVector *mv; int vx[3], vy[3]; int n = 0; int ref = mode - 1; SCHRO_ASSERT (mf && pred_x && pred_y); SCHRO_ASSERT (1 == mode || 2 == mode); x_num_blocks = mf->x_num_blocks; if (0 < x) { mv = &mf->motion_vectors[y * x_num_blocks + x - 1]; vx[n] = mv->u.vec.dx[ref]; vy[n] = mv->u.vec.dy[ref]; ++n; } if (0 < y) { mv = &mf->motion_vectors[(y - 1) * x_num_blocks + x]; vx[n] = mv->u.vec.dx[ref]; vy[n] = mv->u.vec.dy[ref]; ++n; } if (0 < x && 0 < y) { mv = &mf->motion_vectors[(y - 1) * x_num_blocks + x - 1]; vx[n] = mv->u.vec.dx[ref]; vy[n] = mv->u.vec.dy[ref]; ++n; } switch (n) { case 0: *pred_x = 0; *pred_y = 0; break; case 1: *pred_x = vx[0]; *pred_y = vy[0]; break; case 2: *pred_x = (vx[0] + vx[1] + 1) >> 1; *pred_y = (vy[0] + vy[1] + 1) >> 1; break; case 3: *pred_x = median3 (vx[0], vx[1], vx[2]); *pred_y = median3 (vy[0], vy[1], vy[2]); break; default: SCHRO_ASSERT (0); } }
static int schro_encoder_encode_slice (SchroEncoderFrame *frame, SchroLowDelay *lowdelay, int slice_x, int slice_y, int slice_bytes, int base_index) { int length_bits; int slice_y_length; int i; int start_bits; int end_bits; int16_t *quant_data = frame->quant_data; start_bits = schro_pack_get_bit_offset (frame->pack); schro_pack_encode_bits (frame->pack, 7, base_index); length_bits = ilog2up(8*slice_bytes); slice_y_length = frame->slice_y_bits - frame->slice_y_trailing_zeros; schro_pack_encode_bits (frame->pack, length_bits, slice_y_length); for(i=0;i<lowdelay->slice_y_size - frame->slice_y_trailing_zeros;i++) { schro_pack_encode_sint (frame->pack, quant_data[i]); } quant_data += lowdelay->slice_y_size; for(i=0;i<lowdelay->slice_uv_size - frame->slice_uv_trailing_zeros/2;i++) { schro_pack_encode_sint (frame->pack, quant_data[i]); schro_pack_encode_sint (frame->pack, quant_data[i+lowdelay->slice_uv_size]); } end_bits = schro_pack_get_bit_offset (frame->pack); SCHRO_DEBUG("total bits %d used bits %d expected %d", slice_bytes*8, end_bits - start_bits, 7 + length_bits + frame->slice_y_bits + frame->slice_uv_bits - frame->slice_y_trailing_zeros - frame->slice_uv_trailing_zeros); SCHRO_ASSERT(end_bits - start_bits == 7 + length_bits + frame->slice_y_bits + frame->slice_uv_bits - frame->slice_y_trailing_zeros - frame->slice_uv_trailing_zeros); if (end_bits - start_bits > slice_bytes*8) { SCHRO_ERROR("slice overran buffer by %d bits (slice_bytes %d base_index %d)", end_bits - start_bits - slice_bytes*8, slice_bytes, base_index); SCHRO_ASSERT(0); } else { int left = slice_bytes*8 - (end_bits - start_bits); for(i=0;i<left; i++) { schro_pack_encode_bit (frame->pack, 1); } } return end_bits - start_bits; }
static void schro_opengl_upsampled_frame_render_quad (SchroOpenGLShader *shader, int x, int y, int quad_width, int quad_height, int total_width, int total_height) { int x_inverse, y_inverse; int four_x = 0, four_y = 0, three_x = 0, three_y = 0, two_x = 0, two_y = 0, one_x = 0, one_y = 0; x_inverse = total_width - x - quad_width; y_inverse = total_height - y - quad_height; if (quad_width == total_width && quad_height < total_height) { four_y = 4; three_y = 3; two_y = 2; one_y = 1; } else if (quad_width < total_width && quad_height == total_height) { four_x = 4; three_x = 3; two_x = 2; one_x = 1; } else { SCHRO_ERROR ("invalid quad to total relation"); SCHRO_ASSERT (0); } SCHRO_ASSERT (x_inverse >= 0); SCHRO_ASSERT (y_inverse >= 0); #define UNIFORM(_number, _operation, __x, __y) \ do { \ if (shader->_number##_##_operation != -1) { \ glUniform2fARB (shader->_number##_##_operation, \ __x < _number##_x ? __x : _number##_x, \ __y < _number##_y ? __y : _number##_y); \ } \ } while (0) UNIFORM (four, decrease, x, y); UNIFORM (three, decrease, x, y); UNIFORM (two, decrease, x, y); UNIFORM (one, decrease, x, y); UNIFORM (one, increase, x_inverse, y_inverse); UNIFORM (two, increase, x_inverse, y_inverse); UNIFORM (three, increase, x_inverse, y_inverse); UNIFORM (four, increase, x_inverse, y_inverse); #undef UNIFORM schro_opengl_render_quad (x, y, quad_width, quad_height); }
void schro_opengl_frame_inverse_iwt_transform (SchroFrame *frame, SchroParams *params) { int i; int width, height; int level; SchroOpenGL *opengl; SchroOpenGLCanvas *canvas; // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[0].data); SCHRO_ASSERT (canvas != NULL); opengl = canvas->opengl; schro_opengl_lock (opengl); for (i = 0; i < 3; ++i) { // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[i].data); SCHRO_ASSERT (canvas != NULL); SCHRO_ASSERT (canvas->opengl == opengl); if (i == 0) { width = params->iwt_luma_width; height = params->iwt_luma_height; } else { width = params->iwt_chroma_width; height = params->iwt_chroma_height; } for (level = params->transform_depth - 1; level >= 0; --level) { SchroFrameData frame_data; frame_data.format = frame->format; frame_data.data = frame->components[i].data; frame_data.width = width >> level; frame_data.height = height >> level; frame_data.stride = frame->components[i].stride << level; schro_opengl_wavelet_inverse_transform (&frame_data, params->wavelet_filter_index); } } schro_opengl_unlock (opengl); }
void schro_opengl_lock (SchroOpenGL * display) { int ret; SCHRO_ASSERT (display->window != None); SCHRO_ASSERT (display->context != NULL); //g_mutex_lock (display->lock); ret = glXMakeCurrent (display->display, display->window, display->context); if (!ret) { SCHRO_ERROR ("glxMakeCurrent failed"); } schro_opengl_check_error (display, __LINE__); }
SchroFrame * schro_opengl_frame_clone_and_push (SchroOpenGL *opengl, SchroMemoryDomain *opengl_domain, SchroFrame *cpu_frame) { SchroFrame *opengl_frame; SCHRO_ASSERT (opengl_domain->flags & SCHRO_MEMORY_DOMAIN_OPENGL); SCHRO_ASSERT (!SCHRO_FRAME_IS_OPENGL (cpu_frame)); opengl_frame = schro_frame_clone (opengl_domain, cpu_frame); schro_opengl_frame_setup (opengl, opengl_frame); schro_opengl_frame_push (opengl_frame, cpu_frame); return opengl_frame; }
SchroFrame * schro_opengl_frame_clone (SchroFrame *opengl_frame) { SchroOpenGLCanvas *canvas; SCHRO_ASSERT (opengl_frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (opengl_frame)); // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) opengl_frame->components[0].data); SCHRO_ASSERT (canvas != NULL); return schro_opengl_frame_new (canvas->opengl, opengl_frame->domain, opengl_frame->format, opengl_frame->width, opengl_frame->height); }
static int schro_subband_pick_quant (SchroEncoderFrame *frame, int component, int i, double lambda) { double x; double min; int j; int j_min; double entropy; double error; SCHRO_ASSERT(frame->have_estimate_tables); j_min = -1; min = 0; for(j=0;j<60;j++){ entropy = frame->est_entropy[component][i][j]; error = frame->est_error[component][i][j]; x = entropy + lambda * error; if (j == 0 || x < min) { j_min = j; min = x; } } return j_min; }
void * schro_memory_domain_alloc (SchroMemoryDomain * domain, int size) { int i; void *ptr; SCHRO_ASSERT (domain != NULL); SCHRO_DEBUG ("alloc %d", size); schro_mutex_lock (domain->mutex); for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) { if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED)) { continue; } if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_IN_USE) { continue; } if (domain->slots[i].size == size) { domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_IN_USE; SCHRO_DEBUG ("got %p", domain->slots[i].ptr); ptr = domain->slots[i].ptr; goto done; } } for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) { if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED) { continue; } domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED; domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_IN_USE; domain->slots[i].size = size; domain->slots[i].ptr = domain->alloc (size); SCHRO_DEBUG ("created %p", domain->slots[i].ptr); ptr = domain->slots[i].ptr; goto done; } SCHRO_ASSERT (0); done: schro_mutex_unlock (domain->mutex); return ptr; }
void schro_opengl_check_error (SchroOpenGL * display, int line) { GLenum err = glGetError (); if (err) { SCHRO_ERROR ("GL Error 0x%x at line %d", (int) err, line); SCHRO_ASSERT (0); } }
void schro_async_run_stage_locked (SchroAsync * async, SchroAsyncStage * stage) { SCHRO_ASSERT (async->task.task_func == NULL); async->task.task_func = stage->task_func; async->task.priv = stage; g_cond_signal (async->thread_cond); }
void schro_async_run_stage_locked (SchroAsync * async, SchroAsyncStage * stage) { SCHRO_ASSERT (async->task.task_func == NULL); async->task.task_func = stage->task_func; async->task.priv = stage; schro_async_signal_scheduler (async); }
void schro_async_run_locked (SchroAsync *async, void (*func)(void *), void *ptr) { SCHRO_ASSERT(async->task_func == NULL); async->task_func = func; async->task_priv = ptr; schro_async_signal_scheduler (async); }
static double schro_frame_component_squared_error (SchroFrameData *a, SchroFrameData *b) { int j; double sum; SCHRO_ASSERT(a->width == b->width); SCHRO_ASSERT(a->height == b->height); sum = 0; for(j=0;j<a->height;j++){ int32_t linesum; oil_sum_square_diff_u8 (&linesum, OFFSET(a->data, a->stride * j), OFFSET(b->data, b->stride * j), a->width); sum += linesum; } return sum; }
void schro_encoder_choose_quantisers_constant_lambda (SchroEncoderFrame *frame) { schro_encoder_generate_subband_histograms (frame); schro_encoder_calc_estimates (frame); SCHRO_ASSERT(frame->have_estimate_tables); frame->base_lambda = frame->encoder->magic_lambda; schro_encoder_lambda_to_entropy (frame, frame->base_lambda); }
void schro_opengl_frame_subtract (SchroFrame *dest, SchroFrame *src) { int i; SCHRO_ASSERT (dest != NULL); SCHRO_ASSERT (src != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (dest)); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (src)); for (i = 0; schro_opengl_frame_subtract_func_list[i].func; ++i) { if (schro_opengl_frame_subtract_func_list[i].dest == dest->format && schro_opengl_frame_subtract_func_list[i].src == src->format) { schro_opengl_frame_subtract_func_list[i].func (dest, src); return; } } SCHRO_ERROR ("subtraction unimplemented (%d -> %d)", src->format, dest->format); SCHRO_ASSERT (0); }
void schro_motion_dc_prediction (SchroMotion * motion, int x, int y, int *pred) { SchroMotionVector *mv; int i; for (i = 0; i < 3; i++) { int sum = 0; int n = 0; if (x > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x - 1, y); if (mv->pred_mode == 0) { sum += mv->u.dc.dc[i]; n++; } } if (y > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x, y - 1); if (mv->pred_mode == 0) { sum += mv->u.dc.dc[i]; n++; } } if (x > 0 && y > 0) { mv = SCHRO_MOTION_GET_BLOCK (motion, x - 1, y - 1); if (mv->pred_mode == 0) { sum += mv->u.dc.dc[i]; n++; } } switch (n) { case 0: pred[i] = 0; break; case 1: pred[i] = (short) sum; break; case 2: pred[i] = (sum + 1) >> 1; break; case 3: pred[i] = schro_divide3 (sum + 1); break; default: SCHRO_ASSERT (0); } } }
void schro_opengl_frame_cleanup (SchroFrame *frame) { int i; int components; SchroOpenGL *opengl; SchroOpenGLCanvasPool *canvas_pool; SchroOpenGLCanvas *canvas; SCHRO_ASSERT (frame != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (frame)); components = SCHRO_FRAME_IS_PACKED (frame->format) ? 1 : 3; // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[0].data); SCHRO_ASSERT (canvas != NULL); opengl = canvas->opengl; schro_opengl_lock (opengl); canvas_pool = schro_opengl_get_canvas_pool (opengl); for (i = 0; i < components; ++i) { // FIXME: hack to store custom data per frame component canvas = *((SchroOpenGLCanvas **) frame->components[i].data); SCHRO_ASSERT (canvas != NULL); SCHRO_ASSERT (canvas->opengl == opengl); schro_opengl_canvas_pool_push_or_free (canvas_pool, canvas); } schro_opengl_unlock (opengl); }
SchroFrame * schro_opengl_frame_new (SchroOpenGL *opengl, SchroMemoryDomain *opengl_domain, SchroFrameFormat format, int width, int height) { SchroFrame *opengl_frame; SCHRO_ASSERT (opengl_domain->flags & SCHRO_MEMORY_DOMAIN_OPENGL); opengl_frame = schro_frame_new_and_alloc (opengl_domain, format, width, height); schro_opengl_frame_setup (opengl, opengl_frame); return opengl_frame; }
static void schro_encoder_dump_subband_curves (SchroEncoderFrame *frame) { SchroParams *params = &frame->params; int i; int component; int pos; SCHRO_ASSERT(frame->have_histograms); for(component=0;component<3;component++){ for(i=0;i<1 + 3*params->transform_depth; i++) { int vol; int16_t *data; int stride; int width, height; int j; SchroHistogram *hist; pos = schro_subband_get_position (i); schro_subband_get (frame->iwt_frame, component, pos, &frame->params, &data, &stride, &width, &height); vol = width * height; hist = &frame->subband_hists[component][i]; for(j=0;j<60;j++){ double est_entropy; double error; double est_error; double arith_entropy; error = measure_error_subband (frame, component, i, j); est_entropy = schro_histogram_estimate_entropy ( &frame->subband_hists[component][i], j, params->is_noarith); est_error = schro_histogram_apply_table (hist, &frame->encoder->intra_hist_tables[j]); arith_entropy = schro_encoder_estimate_subband_arith (frame, component, i, j); schro_dump (SCHRO_DUMP_SUBBAND_CURVE, "%d %d %d %g %g %g %g\n", component, i, j, est_entropy/vol, arith_entropy/vol, est_error/vol, error/vol); } } } }
void schro_memory_domain_free (SchroMemoryDomain * domain) { int i; SCHRO_ASSERT (domain != NULL); for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) { if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED) { domain->free (domain->slots[i].ptr, domain->slots[i].size); } } schro_mutex_free (domain->mutex); schro_free (domain); }
void schro_encoder_choose_quantisers_constant_error (SchroEncoderFrame *frame) { double base_lambda; double error; schro_encoder_generate_subband_histograms (frame); schro_encoder_calc_estimates (frame); SCHRO_ASSERT(frame->have_estimate_tables); error = 255.0 * pow(0.1, frame->encoder->noise_threshold*0.05); error *= frame->params.video_format->width * frame->params.video_format->height; base_lambda = schro_encoder_error_to_lambda (frame, error); frame->base_lambda = base_lambda; SCHRO_DEBUG("LAMBDA: %d %g", frame->frame_number, base_lambda); }
static void schro_encoder_calc_estimates (SchroEncoderFrame *frame) { SchroParams *params = &frame->params; int i; int j; int component; SCHRO_ASSERT(frame->have_histograms); #ifdef DUMP_SUBBAND_CURVES schro_encoder_dump_subband_curves (frame); #endif for(component=0;component<3;component++){ for(i=0;i<1 + 3*params->transform_depth; i++) { for(j=0;j<60;j++){ int vol; int16_t *data; int stride; int width, height; int position; SchroHistogram *hist; position = schro_subband_get_position (i); schro_subband_get (frame->iwt_frame, component, position, &frame->params, &data, &stride, &width, &height); vol = width * height; hist = &frame->subband_hists[component][i]; frame->est_entropy[component][i][j] = schro_histogram_estimate_entropy (hist, j, params->is_noarith); frame->est_error[component][i][j] = schro_histogram_apply_table (hist, &frame->encoder->intra_hist_tables[j]); } } } frame->have_estimate_tables = TRUE; }
void schro_encoder_motion_predict (SchroEncoderFrame *frame) { SchroParams *params = &frame->params; SchroMotionEst *me; int n; int ref; SCHRO_ASSERT(params->x_num_blocks != 0); SCHRO_ASSERT(params->y_num_blocks != 0); SCHRO_ASSERT(params->num_refs > 0); me = schro_motionest_new (frame); frame->motion = schro_motion_new (params, NULL, NULL); me->motion = frame->motion; frame->motion_field_list = schro_list_new_full ((SchroListFreeFunc)schro_motion_field_free, NULL); n = 0; for(ref=0;ref<params->num_refs;ref++){ schro_motionest_rough_scan_nohint (me, 3, ref, 12); schro_motionest_rough_scan_hint (me, 2, ref, 2); schro_motionest_rough_scan_hint (me, 1, ref, 2); } schro_encoder_bigblock_estimation (me); #if 0 if (frame->encoder->enable_phasecorr_estimation) { schro_encoder_phasecorr_estimation (me); } if (params->have_global_motion) { schro_encoder_global_estimation (me); #endif schro_motion_calculate_stats (frame->motion, frame); frame->estimated_mc_bits = schro_motion_estimate_entropy (frame->motion); schro_list_free (frame->motion_field_list); frame->badblock_ratio = (double)me->badblocks/(params->x_num_blocks*params->y_num_blocks/16); schro_motionest_free (me); } void schro_motion_field_lshift (SchroMotionField *mf, int n) { int i,j; SchroMotionVector *mv; for(j=0;j<mf->y_num_blocks;j++){ for(i=0;i<mf->x_num_blocks;i++){ mv = motion_field_get(mf,i,j); if (mv->using_global || mv->pred_mode == 0) continue; if (mv->pred_mode & 3) { mv->dx[0] <<= n; mv->dy[0] <<= n; mv->dx[1] <<= n; mv->dy[1] <<= n; } } } }
static void schro_opengl_frame_combine_with_shader (SchroFrame *dest, SchroFrame *src, int shader_index) { int i; int width, height; SchroOpenGLCanvas *dest_canvas = NULL; SchroOpenGLCanvas *src_canvas = NULL; SchroOpenGL *opengl = NULL; SchroOpenGLShader *shader_copy_u8; SchroOpenGLShader *shader_copy_s16; SchroOpenGLShader *shader_combine; SCHRO_ASSERT (dest != NULL); SCHRO_ASSERT (src != NULL); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (dest)); SCHRO_ASSERT (SCHRO_FRAME_IS_OPENGL (src)); // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[0].data); src_canvas = *((SchroOpenGLCanvas **) src->components[0].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); SCHRO_ASSERT (dest_canvas->opengl == src_canvas->opengl); opengl = src_canvas->opengl; schro_opengl_lock (opengl); shader_copy_u8 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_U8); shader_copy_s16 = schro_opengl_shader_get (opengl, SCHRO_OPENGL_SHADER_COPY_S16); shader_combine = schro_opengl_shader_get (opengl, shader_index); SCHRO_ASSERT (shader_copy_u8); SCHRO_ASSERT (shader_copy_s16); SCHRO_ASSERT (shader_combine); for (i = 0; i < 3; ++i) { // FIXME: hack to store custom data per frame component dest_canvas = *((SchroOpenGLCanvas **) dest->components[i].data); src_canvas = *((SchroOpenGLCanvas **) src->components[i].data); SCHRO_ASSERT (dest_canvas != NULL); SCHRO_ASSERT (src_canvas != NULL); width = MIN (dest->components[i].width, src->components[i].width); height = MIN (dest->components[i].height, src->components[i].height); schro_opengl_setup_viewport (width, height); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[0]); switch (SCHRO_FRAME_FORMAT_DEPTH (dest_canvas->format)) { case SCHRO_FRAME_FORMAT_DEPTH_U8: glUseProgramObjectARB (shader_copy_u8->program); glUniform1iARB (shader_copy_u8->textures[0], 0); break; case SCHRO_FRAME_FORMAT_DEPTH_S16: glUseProgramObjectARB (shader_copy_s16->program); glUniform1iARB (shader_copy_s16->textures[0], 0); break; default: SCHRO_ASSERT (0); break; } schro_opengl_render_quad (0, 0, width, height); SCHRO_OPENGL_CHECK_ERROR glFlush (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, dest_canvas->framebuffers[0]); glUseProgramObjectARB (shader_combine->program); //glActiveTextureARB (GL_TEXTURE0_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, dest_canvas->texture.handles[1]); glUniform1iARB (shader_combine->textures[0], 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, src_canvas->texture.handles[0]); glUniform1iARB (shader_combine->textures[1], 1); glActiveTextureARB (GL_TEXTURE0_ARB); schro_opengl_render_quad (0, 0, width, height); glUseProgramObjectARB (0); SCHRO_OPENGL_CHECK_ERROR glFlush (); } #if SCHRO_OPENGL_UNBIND_TEXTURES glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE1_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glActiveTextureARB (GL_TEXTURE0_ARB); #endif glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); schro_opengl_unlock (opengl); }
int schro_motion_verify (SchroMotion * motion) { int x, y; SchroMotionVector *mv, *sbmv, *bmv; SchroParams *params = motion->params; if (motion->src1 == NULL) { SCHRO_ERROR ("motion->src1 is NULL"); return 0; } for (y = 0; y < params->y_num_blocks; y++) { for (x = 0; x < params->x_num_blocks; x++) { mv = &motion->motion_vectors[y * params->x_num_blocks + x]; sbmv = &motion->motion_vectors[(y & ~3) * params->x_num_blocks + (x & ~3)]; if (mv->split != sbmv->split) { SCHRO_ERROR ("mv(%d,%d) has the wrong split", x, y); return 0; } switch (sbmv->split) { case 0: if (!schro_motion_vector_is_equal (mv, sbmv)) { SCHRO_ERROR ("mv(%d,%d) not equal to superblock mv", x, y); return 0; } break; case 1: bmv = &motion->motion_vectors[(y & ~1) * params->x_num_blocks + (x & ~1)]; if (!schro_motion_vector_is_equal (mv, bmv)) { SCHRO_ERROR ("mv(%d,%d) not equal to 2-block mv", x, y); return 0; } break; case 2: break; default: SCHRO_ERROR ("mv(%d,%d) had bad split %d", sbmv->split); break; } switch (mv->pred_mode) { case 0: { int i; for (i = 0; i < 3; i++) { /* FIXME 8bit */ if (mv->u.dc.dc[i] < -128 || mv->u.dc.dc[i] > 127) { SCHRO_ERROR ("mv(%d,%d) has bad DC value [%d] %d", x, y, i, mv->u.dc.dc[i]); return 0; } } } break; case 1: break; case 2: case 3: if (motion->params->num_refs < 2) { SCHRO_ERROR ("mv(%d,%d) uses non-existent src2", x, y); return 0; } break; default: SCHRO_ASSERT (0); break; } if (params->have_global_motion == FALSE) { if (mv->using_global) { SCHRO_ERROR ("mv(%d,%d) uses global motion (disabled)", x, y); return 0; } } } } return 1; }