tests: fix build on os/x
[schroedinger.git] / schroedinger / schroengine.c
blobd8b18e197181719b2b803bafce3e980b324c43af
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 #include <schroedinger/schro.h>
7 #include <math.h>
9 int schro_engine_get_scene_change_score (SchroEncoder * encoder, int i);
10 void schro_encoder_calculate_allocation (SchroEncoderFrame * frame);
12 /**
13 * schro_engine_check_new_sequence_header:
14 * @encoder: encoder
15 * @frame: encoder frame
17 * Checks if the current picture should be the start of a new access
18 * unit.
20 static void
21 schro_engine_check_new_sequence_header (SchroEncoder * encoder,
22 SchroEncoderFrame * frame)
24 if (encoder->force_sequence_header ||
25 frame->frame_number >= encoder->au_frame + encoder->au_distance) {
26 frame->start_sequence_header = TRUE;
27 encoder->au_frame = frame->frame_number;
28 encoder->force_sequence_header = FALSE;
32 /**
33 * schro_engine_code_picture:
34 * @frame: encoder frame
35 * @is_ref:
36 * @retire:
37 * @num_refs:
38 * @ref0:
39 * @ref1:
41 * Used to set coding order and coding parameters for a picture.
43 static void
44 schro_engine_code_picture (SchroEncoderFrame * frame,
45 int is_ref, int retire, int num_refs, int ref0, int ref1)
47 SchroEncoder *encoder = frame->encoder;
49 SCHRO_DEBUG
50 ("preparing %d as is_ref=%d retire=%d num_refs=%d ref0=%d ref1=%d",
51 frame->frame_number, is_ref, retire, num_refs, ref0, ref1);
53 frame->is_ref = is_ref;
54 frame->retired_picture_number = retire;
55 frame->num_refs = num_refs;
56 frame->picture_number_ref[0] = ref0;
57 frame->picture_number_ref[1] = ref1;
59 frame->stages[SCHRO_ENCODER_FRAME_STAGE_HAVE_GOP].is_done = TRUE;
60 frame->slot = encoder->next_slot++;
62 if (num_refs > 0) {
63 SCHRO_ASSERT (ref0 >= encoder->au_frame);
64 frame->ref_frame[0] = schro_encoder_reference_get (encoder, ref0);
65 SCHRO_ASSERT (frame->ref_frame[0]);
66 schro_encoder_frame_ref (frame->ref_frame[0]);
68 if (num_refs > 1) {
69 SCHRO_ASSERT (ref0 >= encoder->au_frame);
70 frame->ref_frame[1] = schro_encoder_reference_get (encoder, ref1);
71 SCHRO_ASSERT (frame->ref_frame[1]);
72 schro_encoder_frame_ref (frame->ref_frame[1]);
74 if (is_ref) {
75 int i;
76 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
77 if (encoder->reference_pictures[i] == NULL)
78 break;
79 if (encoder->reference_pictures[i]->frame_number == retire) {
80 schro_encoder_frame_unref (encoder->reference_pictures[i]);
81 encoder->reference_pictures[i] = NULL;
82 break;
85 SCHRO_ASSERT (i < SCHRO_LIMIT_REFERENCE_FRAMES);
86 encoder->reference_pictures[i] = frame;
87 schro_encoder_frame_ref (frame);
91 static int
92 subgroup_ready (SchroQueue * queue, int index, int subgroup_length,
93 SchroEncoderFrameStateEnum gop_state)
95 size_t i = index;
96 SchroEncoderFrame *f;
98 for (; index + subgroup_length > i; ++i) {
99 f = queue->elements[i].data;
100 SCHRO_ASSERT (!f->stages[gop_state].is_done);
101 if (!f->stages[gop_state - 1].is_done) {
102 return 0;
105 return 1;
109 * schro_engine_code_intra_bailout_picture:
110 * @frame:
112 * Sets up coding parameters for encoding as a completely independent
113 * non-ref intra picture.
115 #if 0
116 static void
117 schro_engine_code_intra (SchroEncoderFrame * frame, double weight)
119 schro_engine_code_picture (frame, FALSE, -1, 0, -1, -1);
120 frame->presentation_frame = frame->frame_number;
121 frame->picture_weight = weight;
122 frame->gop_length = 1;
124 #endif
126 static void
127 schro_encoder_pick_refs (SchroEncoderFrame * frame,
128 SchroPictureNumber * ptr_ref0, SchroPictureNumber * ptr_ref1)
130 SchroEncoder *encoder = frame->encoder;
131 SchroPictureNumber ref0;
132 SchroPictureNumber ref1;
133 int i;
135 ref0 = SCHRO_PICTURE_NUMBER_INVALID;
136 /* pick the most recent back ref */
137 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
138 if (encoder->reference_pictures[i] == NULL)
139 continue;
140 if (encoder->reference_pictures[i]->frame_number < frame->frame_number &&
141 (ref0 == SCHRO_PICTURE_NUMBER_INVALID ||
142 encoder->reference_pictures[i]->frame_number > ref0)) {
143 ref0 = encoder->reference_pictures[i]->frame_number;
146 SCHRO_ASSERT (ref0 != SCHRO_PICTURE_NUMBER_INVALID);
148 /* pick the earliest forward ref */
149 ref1 = SCHRO_PICTURE_NUMBER_INVALID;
150 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
151 if (encoder->reference_pictures[i] == NULL)
152 continue;
153 if (!encoder->reference_pictures[i]->expired_reference &&
154 encoder->reference_pictures[i]->frame_number > frame->frame_number &&
155 (ref1 == SCHRO_PICTURE_NUMBER_INVALID ||
156 encoder->reference_pictures[i]->frame_number < ref1)) {
157 ref1 = encoder->reference_pictures[i]->frame_number;
161 if (ref1 == SCHRO_PICTURE_NUMBER_INVALID) {
162 /* if there's no fwd ref, pick an older back ref */
163 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
164 if (encoder->reference_pictures[i] == NULL)
165 continue;
166 if (!encoder->reference_pictures[i]->expired_reference &&
167 encoder->reference_pictures[i]->frame_number < ref0 &&
168 (ref1 == SCHRO_PICTURE_NUMBER_INVALID ||
169 encoder->reference_pictures[i]->frame_number > ref1)) {
170 ref1 = encoder->reference_pictures[i]->frame_number;
175 *ptr_ref0 = ref0;
176 *ptr_ref1 = ref1;
179 static void
180 schro_encoder_pick_retire (SchroEncoderFrame * frame,
181 SchroPictureNumber * ptr_retire)
183 SchroEncoder *encoder = frame->encoder;
184 SchroPictureNumber retire;
185 int n_refs = 0;
186 int i;
188 retire = SCHRO_PICTURE_NUMBER_INVALID;
189 /* pick the oldest expired ref */
190 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
191 if (encoder->reference_pictures[i] == NULL)
192 continue;
193 n_refs++;
194 if (encoder->reference_pictures[i]->expired_reference &&
195 (retire == SCHRO_PICTURE_NUMBER_INVALID ||
196 encoder->reference_pictures[i]->frame_number < retire)) {
197 retire = encoder->reference_pictures[i]->frame_number;
201 if (retire == SCHRO_PICTURE_NUMBER_INVALID && n_refs == 3) {
202 /* if we have a full queue, forceably retire something */
203 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
204 if (encoder->reference_pictures[i] == NULL)
205 continue;
206 if (retire == SCHRO_PICTURE_NUMBER_INVALID ||
207 encoder->reference_pictures[i]->frame_number < retire) {
208 retire = encoder->reference_pictures[i]->frame_number;
211 SCHRO_ASSERT (retire != SCHRO_PICTURE_NUMBER_INVALID);
214 *ptr_retire = retire;
217 static void
218 schro_encoder_expire_reference (SchroEncoder * encoder, SchroPictureNumber ref)
220 int i;
222 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
223 if (encoder->reference_pictures[i] == NULL)
224 continue;
225 if (encoder->reference_pictures[i]->frame_number == ref) {
226 encoder->reference_pictures[i]->expired_reference = TRUE;
231 static void
232 schro_encoder_expire_refs_before (SchroEncoder * encoder,
233 SchroPictureNumber ref)
235 int i;
237 for (i = 0; i < SCHRO_LIMIT_REFERENCE_FRAMES; i++) {
238 if (encoder->reference_pictures[i] == NULL)
239 continue;
240 if (encoder->reference_pictures[i]->frame_number < ref) {
241 encoder->reference_pictures[i]->expired_reference = TRUE;
246 static void
247 schro_engine_code_BBBP (SchroEncoder * encoder, int i, int gop_length)
249 SchroEncoderFrame *frame;
250 SchroEncoderFrame *f;
251 int j;
252 SchroPictureNumber ref0;
253 SchroPictureNumber ref1;
254 SchroPictureNumber retire;
256 frame = encoder->frame_queue->elements[i].data;
258 /* BBBP */
259 frame->gop_length = gop_length;
261 f = encoder->frame_queue->elements[i + gop_length - 1].data;
262 if (f->start_sequence_header) {
263 schro_encoder_pick_retire (f, &retire);
265 schro_engine_code_picture (f, TRUE, retire, 0, -1, -1);
266 f->picture_weight = encoder->magic_keyframe_weight;
267 } else {
268 schro_encoder_pick_retire (f, &retire);
269 schro_encoder_pick_refs (f, &ref0, &ref1);
271 schro_engine_code_picture (f, TRUE, retire,
272 (ref1 == SCHRO_PICTURE_NUMBER_INVALID) ? 1 : 2, ref0, ref1);
273 f->picture_weight = encoder->magic_inter_p_weight;
275 schro_encoder_expire_reference (encoder, encoder->last_ref);
276 encoder->last_ref = f->frame_number;
279 for (j = 0; j < gop_length - 1; j++) {
280 f = encoder->frame_queue->elements[i + j].data;
281 schro_encoder_pick_refs (f, &ref0, &ref1);
283 schro_engine_code_picture (f, FALSE, -1, 2, ref0, ref1);
284 f->presentation_frame = f->frame_number;
285 if (j == gop_length - 2) {
286 f->presentation_frame++;
288 f->picture_weight = encoder->magic_inter_b_weight;
291 f = encoder->frame_queue->elements[i + gop_length - 1].data;
292 if (f->start_sequence_header) {
293 schro_encoder_expire_refs_before (encoder, f->frame_number);
298 * schro_engine_get_scene_change_score:
299 * @frame: encoder frame
300 * @i: index
302 * Calculates scene change score for two pictures.
305 schro_engine_get_scene_change_score (SchroEncoder * encoder, int i)
307 SchroEncoderFrame *frame1;
308 SchroEncoderFrame *frame2;
309 double luma;
311 frame1 = encoder->frame_queue->elements[i].data;
312 if (frame1->have_scene_change_score)
313 return TRUE;
315 frame2 = frame1->previous_frame;
316 if (frame2 == NULL) {
317 frame1->scene_change_score = 1.0;
318 frame1->have_scene_change_score = TRUE;
319 return TRUE;
321 if (!(frame2->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done)) {
322 return FALSE;
325 SCHRO_DEBUG ("%g %g", frame1->average_luma, frame2->average_luma);
327 luma = frame1->average_luma - 16.0;
328 if (luma > 0.01) {
329 double mse[3];
330 schro_frame_mean_squared_error (frame1->
331 downsampled_frames[encoder->downsample_levels - 1],
332 frame2->downsampled_frames[encoder->downsample_levels - 1], mse);
333 frame1->scene_change_score = mse[0] / (luma * luma);
334 } else {
335 frame1->scene_change_score = 1.0;
338 SCHRO_DEBUG ("scene change score %g", frame1->scene_change_score);
340 schro_encoder_frame_unref (frame1->previous_frame);
341 frame1->previous_frame = NULL;
343 frame1->have_scene_change_score = TRUE;
344 return TRUE;
349 * schro_engine_pick_output_buffer_size:
350 * @encoder: encoder
351 * @frame: encoder frame
353 * Calculates allocated size of output buffer for a picture. Horribly
354 * inefficient and outdated.
356 static int
357 schro_engine_pick_output_buffer_size (SchroEncoder * encoder,
358 SchroEncoderFrame * frame)
360 int size;
362 size = encoder->video_format.width * encoder->video_format.height;
363 switch (encoder->video_format.chroma_format) {
364 case SCHRO_CHROMA_444:
365 size *= 3;
366 break;
367 case SCHRO_CHROMA_422:
368 size *= 2;
369 break;
370 case SCHRO_CHROMA_420:
371 size += size / 2;
372 break;
373 default:
374 SCHRO_ASSERT (0);
377 /* random scale factor of 2 in order to be safe */
378 size *= 2;
380 return size;
384 * init_params:
385 * @frame: encoder frame
387 * Initializes params structure for picture based on encoder parameters
388 * and some heuristics.
390 void
391 init_params (SchroEncoderFrame * frame)
393 SchroParams *params = &frame->params;
394 SchroEncoder *encoder = frame->encoder;
395 SchroVideoFormat *video_format = params->video_format;
396 int shift;
397 int i;
398 int size;
399 int overlap;
401 params->video_format = &encoder->video_format;
403 schro_params_init (params, params->video_format->index);
405 if ((encoder->enable_noarith && frame->num_refs == 0) || params->is_lowdelay) {
406 params->is_noarith = TRUE;
409 params->transform_depth = encoder->transform_depth;
411 size = encoder->motion_block_size;
412 if (size == 0) {
413 if (video_format->width * video_format->height >= 1920 * 1080) {
414 size = 3;
415 } else if (video_format->width * video_format->height >= 960 * 540) {
416 size = 2;
417 } else {
418 size = 1;
421 switch (size) {
422 default:
423 case 1:
424 params->xbsep_luma = 8;
425 params->ybsep_luma = 8;
426 break;
427 case 2:
428 params->xbsep_luma = 12;
429 params->ybsep_luma = 12;
430 break;
431 case 3:
432 params->xbsep_luma = 16;
433 params->ybsep_luma = 16;
434 break;
436 overlap = encoder->motion_block_overlap;
437 if (overlap == 0) {
438 overlap = 3;
440 switch (overlap) {
441 case 1:
442 params->xblen_luma = params->xbsep_luma;
443 params->yblen_luma = params->ybsep_luma;
444 break;
445 default:
446 case 2:
447 params->xblen_luma = (params->xbsep_luma * 3 / 2) & (~3);
448 params->yblen_luma = (params->ybsep_luma * 3 / 2) & (~3);
449 break;
450 case 3:
451 params->xblen_luma = 2 * params->xbsep_luma;
452 params->yblen_luma = 2 * params->ybsep_luma;
453 break;
456 schro_params_calculate_mc_sizes (params);
457 schro_params_calculate_iwt_sizes (params);
459 switch (encoder->codeblock_size) {
460 case 1: /* small (blocks of size 5x5) */
461 shift = params->transform_depth;
462 params->horiz_codeblocks[0] =
463 MAX (1, (params->iwt_luma_width >> shift) / 5);
464 params->vert_codeblocks[0] =
465 MAX (1, (params->iwt_luma_height >> shift) / 5);
466 for (i = 1; i < params->transform_depth + 1; i++) {
467 shift = params->transform_depth + 1 - i;
468 /* These values are empirically derived from fewer than 2 test results */
469 params->horiz_codeblocks[i] =
470 MAX (1, (params->iwt_luma_width >> shift) / 5);
471 params->vert_codeblocks[i] =
472 MAX (1, (params->iwt_luma_height >> shift) / 5);
473 SCHRO_DEBUG ("codeblocks %d %d %d", i, params->horiz_codeblocks[i],
474 params->vert_codeblocks[i]);
476 break;
477 case 0:
478 default:
479 case 2: /* medium (blocks of size 8x8) */
480 shift = params->transform_depth;
481 params->horiz_codeblocks[0] =
482 MAX (1, (params->iwt_luma_width >> shift) / 8);
483 params->vert_codeblocks[0] =
484 MAX (1, (params->iwt_luma_height >> shift) / 8);
485 for (i = 1; i < params->transform_depth + 1; i++) {
486 shift = params->transform_depth + 1 - i;
487 params->horiz_codeblocks[i] =
488 MAX (1, (params->iwt_luma_width >> shift) / 8);
489 params->vert_codeblocks[i] =
490 MAX (1, (params->iwt_luma_height >> shift) / 8);
491 SCHRO_DEBUG ("codeblocks %d %d %d", i, params->horiz_codeblocks[i],
492 params->vert_codeblocks[i]);
494 break;
495 case 3: /* large (uses spec defaults) */
496 break;
497 case 4: /* full (codeblocks are entire subband) */
498 params->horiz_codeblocks[0] = 1;
499 params->vert_codeblocks[0] = 1;
500 for (i = 1; i < params->transform_depth + 1; i++) {
501 params->horiz_codeblocks[i] = 1;
502 params->vert_codeblocks[i] = 1;
504 break;
507 if (!encoder->enable_dc_multiquant) {
508 /* This is to work around a bug in the decoder that was fixed 8/2008. */
509 params->horiz_codeblocks[0] = 1;
510 params->vert_codeblocks[0] = 1;
513 params->mv_precision = encoder->mv_precision;
514 if (encoder->enable_global_motion) {
515 params->have_global_motion = TRUE;
517 if (encoder->enable_multiquant) {
518 params->codeblock_mode_index = 1;
519 } else {
520 params->codeblock_mode_index = 0;
525 void
526 schro_frame_set_wavelet_params (SchroEncoderFrame * frame)
528 SchroParams *params = &frame->params;
529 SchroEncoder *encoder = frame->encoder;
531 if (params->num_refs > 0) {
532 params->wavelet_filter_index = encoder->inter_wavelet;
533 } else {
534 params->wavelet_filter_index = encoder->intra_wavelet;
537 /* overrides for near-lossless */
538 if (encoder->rate_control == 0) {
539 double offset = 6.0 * (encoder->bit_depth - 8);
540 if (encoder->noise_threshold < 40.0 + offset) {
541 /* do nothing */
542 } else if (encoder->noise_threshold < 47.0 + offset) {
543 params->wavelet_filter_index = 1;
544 } else {
545 params->wavelet_filter_index = 3;
547 } else if (encoder->rate_control == SCHRO_ENCODER_RATE_CONTROL_LOSSLESS) {
548 params->wavelet_filter_index = 3;
552 static double
553 get_alloc (SchroEncoder * encoder, double requested_bits)
555 double x;
556 double y;
557 int must_use_bits;
558 double alloc;
560 must_use_bits = MAX (0, encoder->buffer_level + encoder->bits_per_picture
561 - encoder->buffer_size);
563 x = MAX (0, requested_bits - must_use_bits) /
564 MAX (0, encoder->buffer_size - encoder->bits_per_picture);
566 y = 1 - exp (-x);
568 alloc = must_use_bits + (encoder->buffer_level - must_use_bits) * y;
570 SCHRO_DEBUG ("request %g, level %d/%d, must use %d -> x %g y %g alloc %g",
571 requested_bits,
572 encoder->buffer_level, encoder->buffer_size, must_use_bits, x, y, alloc);
574 return alloc;
578 * schro_encoder_calculate_allocation:
579 * @frame:
581 * Calculates the number of bits to allocate to a picture.
583 void
584 schro_encoder_calculate_allocation (SchroEncoderFrame * frame)
586 SchroEncoder *encoder = frame->encoder;
588 if (encoder->rate_control != SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE) {
589 /* FIXME this function shouldn't be called for CBR */
591 frame->hard_limit_bits = frame->output_buffer_size * 8;
592 frame->allocated_mc_bits = frame->hard_limit_bits;
593 frame->allocated_residual_bits = frame->hard_limit_bits;
594 return;
597 /* FIXME should be fixed elsewhere */
598 if (frame->picture_weight == 0.0)
599 frame->picture_weight = 1.0;
601 if (frame->num_refs == 0) {
602 frame->allocated_mc_bits = 0;
603 frame->allocated_residual_bits = get_alloc (encoder,
604 encoder->bits_per_picture * frame->picture_weight *
605 encoder->magic_allocation_scale);
606 frame->hard_limit_bits = encoder->buffer_level;
607 } else {
608 double weight;
610 frame->allocated_mc_bits = frame->estimated_mc_bits;
612 weight = frame->picture_weight;
613 if (frame->is_ref) {
614 weight += frame->badblock_ratio * encoder->magic_badblock_multiplier_ref;
615 } else {
616 weight +=
617 frame->badblock_ratio * encoder->magic_badblock_multiplier_nonref;
620 frame->allocated_residual_bits = get_alloc (encoder,
621 encoder->bits_per_picture * weight * encoder->magic_allocation_scale);
622 frame->allocated_residual_bits -= frame->estimated_mc_bits;
623 if (frame->allocated_residual_bits < 0) {
624 SCHRO_DEBUG ("allocated residual bits less than 0");
625 frame->allocated_residual_bits = 0;
627 frame->hard_limit_bits = encoder->buffer_level;
632 * init_frame:
633 * @frame:
635 * Initializes a frame prior to any analysis.
637 void
638 schro_encoder_init_frame (SchroEncoderFrame * frame)
640 SchroEncoder *encoder = frame->encoder;
642 frame->params.video_format = &encoder->video_format;
644 frame->need_filtering = (encoder->filtering != 0);
645 switch (encoder->gop_structure) {
646 case SCHRO_ENCODER_GOP_INTRA_ONLY:
647 frame->need_downsampling = FALSE;
648 frame->need_upsampling = FALSE;
649 frame->need_average_luma = FALSE;
650 frame->need_mad = FALSE;
651 break;
652 case SCHRO_ENCODER_GOP_ADAPTIVE:
653 case SCHRO_ENCODER_GOP_BACKREF:
654 case SCHRO_ENCODER_GOP_CHAINED_BACKREF:
655 frame->need_downsampling = TRUE;
656 frame->need_upsampling = (encoder->mv_precision > 0);
657 frame->need_average_luma = TRUE;
658 frame->need_extension = TRUE;
659 frame->need_mad = encoder->enable_scene_change_detection;
660 break;
661 case SCHRO_ENCODER_GOP_BIREF:
662 case SCHRO_ENCODER_GOP_CHAINED_BIREF:
663 frame->need_downsampling = TRUE;
664 frame->need_upsampling = (encoder->mv_precision > 0);
665 frame->need_average_luma = TRUE;
666 frame->need_extension = TRUE;
667 frame->need_mad = encoder->enable_scene_change_detection;
668 break;
669 default:
670 SCHRO_ASSERT (0);
675 /***** tworef *****/
678 * handle_gop_tworef:
679 * @encoder:
680 * @i:
682 * Sets up a minor group of pictures for the tworef engine.
684 void
685 schro_encoder_handle_gop_tworef (SchroEncoder * encoder, int i)
687 SchroEncoderFrame *frame;
688 SchroEncoderFrame *f;
689 int j;
690 int gop_length;
691 //double scs_sum;
693 frame = encoder->frame_queue->elements[i].data;
695 SCHRO_ASSERT (frame->stages[SCHRO_ENCODER_FRAME_STAGE_HAVE_GOP].is_done ==
696 FALSE);
698 if (frame->busy || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done)
699 return;
701 schro_engine_check_new_sequence_header (encoder, frame);
703 gop_length = encoder->magic_subgroup_length;
704 SCHRO_DEBUG ("handling gop from %d to %d (index %d)", encoder->gop_picture,
705 encoder->gop_picture + gop_length - 1, i);
707 if (encoder->end_of_stream) {
708 gop_length = MIN (gop_length, encoder->frame_queue->n - i);
710 //intra_start = frame->start_sequence_header;
711 //scs_sum = 0;
712 for (j = 0; j < gop_length; j++) {
713 if (i + j >= encoder->frame_queue->n) {
714 SCHRO_DEBUG ("not enough pictures in queue");
715 return;
718 f = encoder->frame_queue->elements[i + j].data;
720 SCHRO_ASSERT (f->stages[SCHRO_ENCODER_FRAME_STAGE_HAVE_GOP].is_done ==
721 FALSE);
723 if (f->busy || !f->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done) {
724 SCHRO_DEBUG ("picture %d not ready", i + j);
725 return;
728 if (f->start_sequence_header ||
729 f->frame_number >= encoder->au_frame + encoder->au_distance) {
730 f->start_sequence_header = TRUE;
731 if (encoder->open_gop || j == 0) {
732 gop_length = j + 1;
733 } else {
734 gop_length = j;
736 break;
739 if (encoder->enable_scene_change_detection) {
740 if (!subgroup_ready (encoder->frame_queue, i, gop_length,
741 SCHRO_ENCODER_FRAME_STAGE_HAVE_GOP))
742 return; /*not all frames in subgroup have scene change score calculated */
743 } else {
744 schro_engine_get_scene_change_score (encoder, i + j);
746 schro_dump (SCHRO_DUMP_SCENE_CHANGE, "%d %g %g\n",
747 f->frame_number, f->scene_change_score, f->average_luma);
748 SCHRO_DEBUG ("scene change score %g", f->scene_change_score);
750 if (f->scene_change_score > encoder->magic_scene_change_threshold) {
751 SCHRO_DEBUG ("Scene change detected: score %g for picture %d",
752 f->scene_change_score, f->frame_number);
753 if (j == 0) {
754 /* If the first picture of the proposed subgroup is first
755 * picture of a new shot, we want to encode a sequence header
756 * and an I frame. */
757 f->start_sequence_header = TRUE;
758 gop_length = 1;
759 break;
760 } else {
761 /* If there's a shot change in the middle of the proposed
762 * subgroup, terminate the subgroup early. Also flag that
763 * picture as a new sequence header (not really necessary). */
764 f->start_sequence_header = TRUE;
765 gop_length = j;
768 #if 0
769 scs_sum += f->scene_change_score;
770 if (scs_sum > encoder->magic_scene_change_threshold) {
771 /* matching is getting bad. terminate gop */
772 gop_length = j;
774 #endif
777 SCHRO_DEBUG ("gop length %d", gop_length);
779 for (j = 0; j < gop_length - 1; j++) {
780 f = encoder->frame_queue->elements[i + j].data;
781 SCHRO_ASSERT (f->start_sequence_header == FALSE);
784 if (gop_length == 1) {
785 schro_engine_code_BBBP (encoder, i, gop_length);
786 } else {
787 schro_engine_code_BBBP (encoder, i, gop_length);
790 f = encoder->frame_queue->elements[i + gop_length - 1].data;
791 if (f->start_sequence_header) {
792 encoder->au_frame = f->frame_number;
795 encoder->gop_picture += gop_length;
799 schro_encoder_setup_frame_tworef (SchroEncoderFrame * frame)
801 SchroEncoder *encoder = frame->encoder;
803 frame->output_buffer_size =
804 schro_engine_pick_output_buffer_size (encoder, frame);
805 SCHRO_ASSERT (frame->output_buffer_size != 0);
807 /* set up params - num_refs only */
808 frame->params.num_refs = frame->num_refs;
810 return TRUE;
814 schro_encoder_handle_quants (SchroEncoder * encoder, int i)
816 SchroEncoderFrame *frame;
818 frame = encoder->frame_queue->elements[i].data;
820 if (frame->busy
821 || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_MODE_DECISION].is_done)
822 return FALSE;
824 schro_encoder_calculate_allocation (frame);
825 schro_encoder_choose_quantisers (frame);
826 schro_encoder_estimate_entropy (frame);
828 frame->stages[SCHRO_ENCODER_FRAME_STAGE_HAVE_QUANTS].is_done = TRUE;
830 return TRUE;
833 /**** backref ****/
836 * handle_gop_backref:
837 * @encoder:
838 * @i:
840 * Sets up a minor group of pictures for the backref engine.
842 void
843 schro_encoder_handle_gop_backref (SchroEncoder * encoder, int i)
845 SchroEncoderFrame *frame;
846 SchroPictureNumber retire;
847 SchroPictureNumber ref0;
848 SchroPictureNumber ref1;
850 frame = encoder->frame_queue->elements[i].data;
852 if (frame->busy || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done)
853 return;
855 schro_engine_check_new_sequence_header (encoder, frame);
857 //schro_engine_code_BBBP (encoder, i, 1);
858 if (frame->start_sequence_header) {
859 schro_encoder_pick_retire (frame, &retire);
860 schro_engine_code_picture (frame, TRUE, retire, 0, -1, -1);
861 frame->picture_weight = encoder->magic_keyframe_weight;
862 } else {
863 schro_encoder_pick_retire (frame, &retire);
864 schro_encoder_pick_refs (frame, &ref0, &ref1);
866 schro_engine_code_picture (frame, TRUE, retire,
867 (ref1 == SCHRO_PICTURE_NUMBER_INVALID) ? 1 : 2, ref0, ref1);
868 frame->picture_weight = encoder->magic_inter_p_weight;
870 schro_encoder_expire_reference (encoder, frame->frame_number - 2);
871 frame->presentation_frame = frame->frame_number;
872 frame->picture_weight = 1;
873 encoder->last_ref = frame->frame_number;
875 encoder->gop_picture += 1;
876 if (frame->start_sequence_header) {
877 schro_encoder_expire_refs_before (encoder, frame->frame_number);
882 schro_encoder_setup_frame_backref (SchroEncoderFrame * frame)
884 SchroEncoder *encoder = frame->encoder;
886 frame->output_buffer_size =
887 schro_engine_pick_output_buffer_size (encoder, frame);
889 /* set up params */
890 frame->params.num_refs = frame->num_refs;
892 return TRUE;
895 /*** intra-only ***/
898 * handle_gop_intra_only:
899 * @encoder:
900 * @i:
902 * Sets up GOP structure for an intra picture.
904 void
905 schro_encoder_handle_gop_intra_only (SchroEncoder * encoder, int i)
907 SchroEncoderFrame *frame;
909 frame = encoder->frame_queue->elements[i].data;
911 if (frame->busy || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done)
912 return;
914 schro_engine_check_new_sequence_header (encoder, frame);
916 SCHRO_DEBUG ("handling gop from %d to %d (index %d)", encoder->gop_picture,
917 encoder->gop_picture, i);
919 if (frame->busy || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done) {
920 SCHRO_DEBUG ("picture %d not ready", i);
921 return;
924 schro_engine_code_picture (frame, FALSE, -1, 0, -1, -1);
925 frame->presentation_frame = frame->frame_number;
926 frame->picture_weight = 1.0;
928 encoder->gop_picture++;
932 * setup_params_intra_only:
933 * @frame:
935 * sets up parameters for a picture for intra-only encoding.
938 schro_encoder_setup_frame_intra_only (SchroEncoderFrame * frame)
940 SchroEncoder *encoder = frame->encoder;
942 frame->output_buffer_size =
943 schro_engine_pick_output_buffer_size (encoder, frame);
945 frame->params.num_refs = frame->num_refs;
947 /* set up params */
949 return TRUE;
953 /*** lossless ***/
956 * setup_params_lossless:
957 * @frame:
959 * sets up parameters for a picture for intra-only encoding.
962 schro_encoder_setup_frame_lossless (SchroEncoderFrame * frame)
964 SchroEncoder *encoder = frame->encoder;
965 SchroParams *params;
967 frame->output_buffer_size =
968 schro_engine_pick_output_buffer_size (encoder, frame);
970 frame->params.num_refs = frame->num_refs;
972 /* set up params */
973 params = &frame->params;
975 params->wavelet_filter_index = SCHRO_WAVELET_HAAR_0;
976 params->transform_depth = 3;
978 params->num_refs = frame->num_refs;
979 params->video_format = &encoder->video_format;
980 init_params (frame);
982 params->xbsep_luma = 8;
983 params->xblen_luma = 8;
984 params->ybsep_luma = 8;
985 params->yblen_luma = 8;
986 schro_params_calculate_mc_sizes (params);
988 return TRUE;
991 void
992 schro_encoder_handle_gop_lossless (SchroEncoder * encoder, int i)
994 schro_encoder_handle_gop_backref (encoder, i);
997 /*** low delay ***/
999 void
1000 schro_encoder_handle_gop_lowdelay (SchroEncoder * encoder, int i)
1002 SchroEncoderFrame *frame;
1004 frame = encoder->frame_queue->elements[i].data;
1006 if (frame->busy || !frame->stages[SCHRO_ENCODER_FRAME_STAGE_ANALYSE].is_done)
1007 return;
1009 schro_engine_check_new_sequence_header (encoder, frame);
1011 SCHRO_DEBUG ("handling gop from %d to %d (index %d)", encoder->gop_picture,
1012 encoder->gop_picture, i);
1014 schro_engine_code_picture (frame, FALSE, -1, 0, -1, -1);
1015 frame->presentation_frame = frame->frame_number;
1016 frame->picture_weight = 1.0;
1018 encoder->gop_picture++;
1022 schro_encoder_setup_frame_lowdelay (SchroEncoderFrame * frame)
1024 SchroEncoder *encoder = frame->encoder;
1025 SchroParams *params = &frame->params;
1026 int num;
1027 int denom;
1029 frame->output_buffer_size =
1030 schro_engine_pick_output_buffer_size (encoder, frame);
1032 /* set up params */
1033 params->num_refs = frame->num_refs;
1034 params->is_lowdelay = TRUE;
1036 if (encoder->horiz_slices != 0 && encoder->vert_slices != 0) {
1037 params->n_horiz_slices = encoder->horiz_slices;
1038 params->n_vert_slices = encoder->vert_slices;
1039 } else {
1040 params->n_horiz_slices =
1041 params->iwt_chroma_width >> params->transform_depth;
1042 params->n_vert_slices =
1043 params->iwt_chroma_height >> params->transform_depth;
1045 schro_params_set_default_quant_matrix (params);
1047 num = muldiv64 (encoder->bitrate,
1048 encoder->video_format.frame_rate_denominator,
1049 encoder->video_format.frame_rate_numerator * 8);
1050 denom = params->n_horiz_slices * params->n_vert_slices;
1051 if (encoder->video_format.interlaced_coding) {
1052 denom *= 2;
1054 SCHRO_ASSERT (denom != 0);
1055 schro_utils_reduce_fraction (&num, &denom);
1056 params->slice_bytes_num = num;
1057 params->slice_bytes_denom = denom;
1059 return TRUE;