* changes: Add unit test for ref_frame_info Add key frame group info to SimpleEncode Add ref_frame_info to encode_frame_result Add init/update_frame_indexes() Add GetVectorData()
Unified · Split
| @@ -92,6 +92,8 @@ TEST(SimpleEncode, EncodeFrame) { · 91 unmodified lines | ||
| 92 | 92 | EXPECT_GE(encode_frame_result.psnr, 34) |
| 93 | 93 | << "The psnr is supposed to be greater than 34 given the " |
| 94 | 94 | "target_bitrate 1000 kbps"; |
| 95 | + EXPECT_EQ(encode_frame_result.ref_frame_info, | |
| 96 | + encode_frame_list[group_index].ref_frame_info); | |
| 95 | 97 | total_data_bit_size += encode_frame_result.coding_data_bit_size; |
| 96 | 98 | ++frame_coding_index; |
| 97 | 99 | } |
| @@ -64,6 +64,12 @@ typedef struct { · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | typedef int8_t MV_REFERENCE_FRAME; |
| 66 | 66 | |
| 67 | +static INLINE int mv_ref_frame_to_inter_ref_idx( | |
| 68 | + MV_REFERENCE_FRAME mv_ref_frame) { | |
| 69 | + assert(mv_ref_frame >= LAST_FRAME && mv_ref_frame < MAX_REF_FRAMES); | |
| 70 | + return mv_ref_frame - 1; | |
| 71 | +} | |
| 72 | + | |
| 67 | 73 | // This structure now relates to 8x8 block regions. |
| 68 | 74 | typedef struct MODE_INFO { |
| 69 | 75 | // Common for both INTER and INTRA blocks |
| @@ -69,7 +69,18 @@ typedef struct { · 68 unmodified lines | ||
| 69 | 69 | int mi_rows; |
| 70 | 70 | int mi_cols; |
| 71 | 71 | uint8_t released; |
| 72 | − int frame_index; | |
| 72 | + | |
| 73 | + // Note that frame_index/frame_coding_index are only set by set_frame_index() | |
| 74 | + // on the encoder side. | |
| 75 | + | |
| 76 | + // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side | |
| 77 | + // properly. | |
| 78 | + int frame_index; // Display order in the video, it's equivalent to the | |
| 79 | + // show_idx defined in EncodeFrameInfo. | |
| 80 | +#if CONFIG_RATE_CTRL | |
| 81 | + int frame_coding_index; // The coding order (starting from zero) of this | |
| 82 | + // frame. | |
| 83 | +#endif // CONFIG_RATE_CTRL | |
| 73 | 84 | vpx_codec_frame_buffer_t raw_frame_buffer; |
| 74 | 85 | YV12_BUFFER_CONFIG buf; |
| 75 | 86 | } RefCntBuffer; |
| @@ -226,7 +237,16 @@ typedef struct VP9Common { · 150 unmodified lines | ||
| 226 | 237 | unsigned int frame_context_idx; /* Context to use/update */ |
| 227 | 238 | FRAME_COUNTS counts; |
| 228 | 239 | |
| 240 | + // TODO(angiebird): current_video_frame/current_frame_coding_index into a | |
| 241 | + // structure | |
| 229 | 242 | unsigned int current_video_frame; |
| 243 | +#if CONFIG_RATE_CTRL | |
| 244 | + // Each show or no show frame is assigned with a coding index based on its | |
| 245 | + // coding order (starting from zero). | |
| 246 | + | |
| 247 | + // Current frame's coding index. | |
| 248 | + int current_frame_coding_index; | |
| 249 | +#endif | |
| 230 | 250 | BITSTREAM_PROFILE profile; |
| 231 | 251 | |
| 232 | 252 | // VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3. |
| @@ -254,6 +274,24 @@ typedef struct VP9Common { · 21 unmodified lines | ||
| 254 | 274 | int lf_row; |
| 255 | 275 | } VP9_COMMON; |
| 256 | 276 | |
| 277 | +static INLINE void init_frame_indexes(VP9_COMMON *cm) { | |
| 278 | + cm->current_video_frame = 0; | |
| 279 | +#if CONFIG_RATE_CTRL | |
| 280 | + cm->current_frame_coding_index = 0; | |
| 281 | +#endif // CONFIG_RATE_CTRL | |
| 282 | +} | |
| 283 | + | |
| 284 | +static INLINE void update_frame_indexes(VP9_COMMON *cm, int show_frame) { | |
| 285 | + if (show_frame) { | |
| 286 | + // Don't increment frame counters if this was an altref buffer | |
| 287 | + // update not a real frame | |
| 288 | + ++cm->current_video_frame; | |
| 289 | + } | |
| 290 | +#if CONFIG_RATE_CTRL | |
| 291 | + ++cm->current_frame_coding_index; | |
| 292 | +#endif // CONFIG_RATE_CTRL | |
| 293 | +} | |
| 294 | + | |
| 257 | 295 | typedef struct { |
| 258 | 296 | int frame_width; |
| 259 | 297 | int frame_height; |
| @@ -188,7 +188,7 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) { · 187 unmodified lines | ||
| 188 | 188 | memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
| 189 | 189 | memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map)); |
| 190 | 190 | |
| 191 | − cm->current_video_frame = 0; | |
| 191 | + init_frame_indexes(cm); | |
| 192 | 192 | pbi->ready_for_new_data = 1; |
| 193 | 193 | pbi->common.buffer_pool = pool; |
| 194 | 194 | |
| @@ -2311,7 +2311,7 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, · 2310 unmodified lines | ||
| 2311 | 2311 | |
| 2312 | 2312 | vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc); |
| 2313 | 2313 | |
| 2314 | − cm->current_video_frame = 0; | |
| 2314 | + init_frame_indexes(cm); | |
| 2315 | 2315 | cpi->partition_search_skippable_frame = 0; |
| 2316 | 2316 | cpi->tile_data = NULL; |
| 2317 | 2317 | |
| @@ -4887,6 +4887,9 @@ static void set_frame_index(VP9_COMP *cpi, VP9_COMMON *cm) { · 2569 unmodified lines | ||
| 4887 | 4887 | const GF_GROUP *const gf_group = &cpi->twopass.gf_group; |
| 4888 | 4888 | ref_buffer->frame_index = |
| 4889 | 4889 | cm->current_video_frame + gf_group->arf_src_offset[gf_group->index]; |
| 4890 | +#if CONFIG_RATE_CTRL | |
| 4891 | + ref_buffer->frame_coding_index = cm->current_frame_coding_index; | |
| 4892 | +#endif // CONFIG_RATE_CTRL | |
| 4890 | 4893 | } |
| 4891 | 4894 | } |
| 4892 | 4895 | |
| @@ -5080,9 +5083,22 @@ static void set_mb_wiener_variance(VP9_COMP *cpi) { · 187 unmodified lines | ||
| 5080 | 5083 | cpi->norm_wiener_variance = VPXMAX(1, cpi->norm_wiener_variance); |
| 5081 | 5084 | } |
| 5082 | 5085 | |
| 5083 | −static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, | |
| 5084 | − uint8_t *dest, | |
| 5085 | − unsigned int *frame_flags) { | |
| 5086 | +#if !CONFIG_REALTIME_ONLY | |
| 5087 | +static void update_encode_frame_result( | |
| 5088 | + int ref_frame_flags, FRAME_UPDATE_TYPE update_type, | |
| 5089 | + const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf, | |
| 5090 | + RefCntBuffer *ref_frame_buf[MAX_INTER_REF_FRAMES], int quantize_index, | |
| 5091 | + uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts, | |
| 5092 | +#if CONFIG_RATE_CTRL | |
| 5093 | + const PARTITION_INFO *partition_info, | |
| 5094 | + const MOTION_VECTOR_INFO *motion_vector_info, | |
| 5095 | +#endif // CONFIG_RATE_CTRL | |
| 5096 | + ENCODE_FRAME_RESULT *encode_frame_result); | |
| 5097 | +#endif // !CONFIG_REALTIME_ONLY | |
| 5098 | + | |
| 5099 | +static void encode_frame_to_data_rate( | |
| 5100 | + VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags, | |
| 5101 | + ENCODE_FRAME_RESULT *encode_frame_result) { | |
| 5086 | 5102 | VP9_COMMON *const cm = &cpi->common; |
| 5087 | 5103 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
| 5088 | 5104 | struct segmentation *const seg = &cm->seg; |
| @@ -5247,6 +5263,44 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, · 158 unmodified lines | ||
| 5247 | 5263 | // build the bitstream |
| 5248 | 5264 | vp9_pack_bitstream(cpi, dest, size); |
| 5249 | 5265 | |
| 5266 | +#if CONFIG_REALTIME_ONLY | |
| 5267 | + (void)encode_frame_result; | |
| 5268 | + assert(encode_frame_result == NULL); | |
| 5269 | +#else // CONFIG_REALTIME_ONLY | |
| 5270 | + if (encode_frame_result != NULL) { | |
| 5271 | + const int ref_frame_flags = get_ref_frame_flags(cpi); | |
| 5272 | + const RefCntBuffer *coded_frame_buf = | |
| 5273 | + get_ref_cnt_buffer(cm, cm->new_fb_idx); | |
| 5274 | + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]; | |
| 5275 | + get_ref_frame_bufs(cpi, ref_frame_bufs); | |
| 5276 | + // update_encode_frame_result() depends on twopass.gf_group.index and | |
| 5277 | + // cm->new_fb_idx, cpi->Source, cpi->lst_fb_idx, cpi->gld_fb_idx and | |
| 5278 | + // cpi->alt_fb_idx are updated for current frame and have | |
| 5279 | + // not been updated for the next frame yet. | |
| 5280 | + // The update locations are as follows. | |
| 5281 | + // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero() | |
| 5282 | + // for the first frame in the gf_group and is updated for the next frame at | |
| 5283 | + // vp9_twopass_postencode_update(). | |
| 5284 | + // 2) cpi->Source is updated at the beginning of vp9_get_compressed_data() | |
| 5285 | + // 3) cm->new_fb_idx is updated at the beginning of | |
| 5286 | + // vp9_get_compressed_data() by get_free_fb(cm). | |
| 5287 | + // 4) cpi->lst_fb_idx/gld_fb_idx/alt_fb_idx will be updated for the next | |
| 5288 | + // frame at vp9_update_reference_frames(). | |
| 5289 | + // This function needs to be called before vp9_update_reference_frames(). | |
| 5290 | + // TODO(angiebird): Improve the codebase to make the update of frame | |
| 5291 | + // dependent variables more robust. | |
| 5292 | + update_encode_frame_result( | |
| 5293 | + ref_frame_flags, | |
| 5294 | + cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], | |
| 5295 | + cpi->Source, coded_frame_buf, ref_frame_bufs, vp9_get_quantizer(cpi), | |
| 5296 | + cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, | |
| 5297 | +#if CONFIG_RATE_CTRL | |
| 5298 | + cpi->partition_info, cpi->motion_vector_info, | |
| 5299 | +#endif // CONFIG_RATE_CTRL | |
| 5300 | + encode_frame_result); | |
| 5301 | + } | |
| 5302 | +#endif // CONFIG_REALTIME_ONLY | |
| 5303 | + | |
| 5250 | 5304 | if (cpi->rc.use_post_encode_drop && cm->base_qindex < cpi->rc.worst_quality && |
| 5251 | 5305 | cpi->svc.spatial_layer_id == 0 && post_encode_drop_cbr(cpi, size)) { |
| 5252 | 5306 | restore_coding_context(cpi); |
| @@ -5340,11 +5394,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, · 87 unmodified lines | ||
| 5340 | 5394 | |
| 5341 | 5395 | if (cm->show_frame) { |
| 5342 | 5396 | vp9_swap_mi_and_prev_mi(cm); |
| 5343 | − // Don't increment frame counters if this was an altref buffer | |
| 5344 | − // update not a real frame | |
| 5345 | − ++cm->current_video_frame; | |
| 5346 | 5397 | if (cpi->use_svc) vp9_inc_frame_in_layer(cpi); |
| 5347 | 5398 | } |
| 5399 | + update_frame_indexes(cm, cm->show_frame); | |
| 5348 | 5400 | |
| 5349 | 5401 | if (cpi->use_svc) { |
| 5350 | 5402 | cpi->svc |
| @@ -5370,7 +5422,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, · 19 unmodified lines | ||
| 5370 | 5422 | static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
| 5371 | 5423 | unsigned int *frame_flags) { |
| 5372 | 5424 | vp9_rc_get_svc_params(cpi); |
| 5373 | − encode_frame_to_data_rate(cpi, size, dest, frame_flags); | |
| 5425 | + encode_frame_to_data_rate(cpi, size, dest, frame_flags, | |
| 5426 | + /*encode_frame_result = */ NULL); | |
| 5374 | 5427 | } |
| 5375 | 5428 | |
| 5376 | 5429 | static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
| @@ -5380,17 +5433,19 @@ static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, · 3 unmodified lines | ||
| 5380 | 5433 | } else { |
| 5381 | 5434 | vp9_rc_get_one_pass_vbr_params(cpi); |
| 5382 | 5435 | } |
| 5383 | − encode_frame_to_data_rate(cpi, size, dest, frame_flags); | |
| 5436 | + encode_frame_to_data_rate(cpi, size, dest, frame_flags, | |
| 5437 | + /*encode_frame_result = */ NULL); | |
| 5384 | 5438 | } |
| 5385 | 5439 | |
| 5386 | 5440 | #if !CONFIG_REALTIME_ONLY |
| 5387 | 5441 | static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, |
| 5388 | − unsigned int *frame_flags) { | |
| 5442 | + unsigned int *frame_flags, | |
| 5443 | + ENCODE_FRAME_RESULT *encode_frame_result) { | |
| 5389 | 5444 | cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; |
| 5390 | 5445 | #if CONFIG_MISMATCH_DEBUG |
| 5391 | 5446 | mismatch_move_frame_idx_w(); |
| 5392 | 5447 | #endif |
| 5393 | − encode_frame_to_data_rate(cpi, size, dest, frame_flags); | |
| 5448 | + encode_frame_to_data_rate(cpi, size, dest, frame_flags, encode_frame_result); | |
| 5394 | 5449 | } |
| 5395 | 5450 | #endif // !CONFIG_REALTIME_ONLY |
| 5396 | 5451 | |
| @@ -7249,11 +7304,10 @@ static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer, · 1852 unmodified lines | ||
| 7249 | 7304 | } |
| 7250 | 7305 | } |
| 7251 | 7306 | #endif // CONFIG_RATE_CTRL |
| 7252 | − | |
| 7253 | 7307 | static void update_encode_frame_result( |
| 7254 | − int show_idx, FRAME_UPDATE_TYPE update_type, | |
| 7255 | − const YV12_BUFFER_CONFIG *source_frame, | |
| 7256 | − const YV12_BUFFER_CONFIG *coded_frame, int quantize_index, | |
| 7308 | + int ref_frame_flags, FRAME_UPDATE_TYPE update_type, | |
| 7309 | + const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf, | |
| 7310 | + RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int quantize_index, | |
| 7257 | 7311 | uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts, |
| 7258 | 7312 | #if CONFIG_RATE_CTRL |
| 7259 | 7313 | const PARTITION_INFO *partition_info, |
| @@ -7263,29 +7317,54 @@ static void update_encode_frame_result( · 3 unmodified lines | ||
| 7263 | 7317 | #if CONFIG_RATE_CTRL |
| 7264 | 7318 | PSNR_STATS psnr; |
| 7265 | 7319 | #if CONFIG_VP9_HIGHBITDEPTH |
| 7266 | − vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth, | |
| 7320 | + vpx_calc_highbd_psnr(source_frame, coded_frame_buf->buf, &psnr, bit_depth, | |
| 7267 | 7321 | input_bit_depth); |
| 7268 | 7322 | #else // CONFIG_VP9_HIGHBITDEPTH |
| 7269 | 7323 | (void)bit_depth; |
| 7270 | 7324 | (void)input_bit_depth; |
| 7271 | − vpx_calc_psnr(source_frame, coded_frame, &psnr); | |
| 7325 | + vpx_calc_psnr(source_frame, &coded_frame_buf->buf, &psnr); | |
| 7272 | 7326 | #endif // CONFIG_VP9_HIGHBITDEPTH |
| 7327 | + encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index; | |
| 7328 | + | |
| 7329 | + if (update_type != KF_UPDATE) { | |
| 7330 | + const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, | |
| 7331 | + VP9_GOLD_FLAG, | |
| 7332 | + VP9_ALT_FLAG }; | |
| 7333 | + int i; | |
| 7334 | + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
| 7335 | + assert(ref_frame_bufs[i] != NULL); | |
| 7336 | + encode_frame_result->ref_frame_coding_indexes[i] = | |
| 7337 | + ref_frame_bufs[i]->frame_coding_index; | |
| 7338 | + encode_frame_result->ref_frame_valid_list[i] = | |
| 7339 | + (ref_frame_flags & inter_ref_flags[i]) != 0; | |
| 7340 | + } | |
| 7341 | + } else { | |
| 7342 | + // No reference frame is available when this is a key frame. | |
| 7343 | + int i; | |
| 7344 | + for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
| 7345 | + encode_frame_result->ref_frame_coding_indexes[i] = -1; | |
| 7346 | + encode_frame_result->ref_frame_valid_list[i] = 0; | |
| 7347 | + } | |
| 7348 | + } | |
| 7273 | 7349 | encode_frame_result->psnr = psnr.psnr[0]; |
| 7274 | 7350 | encode_frame_result->sse = psnr.sse[0]; |
| 7275 | 7351 | copy_frame_counts(counts, &encode_frame_result->frame_counts); |
| 7276 | 7352 | encode_frame_result->partition_info = partition_info; |
| 7277 | 7353 | encode_frame_result->motion_vector_info = motion_vector_info; |
| 7278 | 7354 | if (encode_frame_result->coded_frame.allocated) { |
| 7279 | − yv12_buffer_to_image_buffer(coded_frame, &encode_frame_result->coded_frame); | |
| 7355 | + yv12_buffer_to_image_buffer(&coded_frame_buf->buf, | |
| 7356 | + &encode_frame_result->coded_frame); | |
| 7280 | 7357 | } |
| 7281 | 7358 | #else // CONFIG_RATE_CTRL |
| 7359 | + (void)ref_frame_flags; | |
| 7282 | 7360 | (void)bit_depth; |
| 7283 | 7361 | (void)input_bit_depth; |
| 7284 | 7362 | (void)source_frame; |
| 7285 | − (void)coded_frame; | |
| 7363 | + (void)coded_frame_buf; | |
| 7364 | + (void)ref_frame_bufs; | |
| 7286 | 7365 | (void)counts; |
| 7287 | 7366 | #endif // CONFIG_RATE_CTRL |
| 7288 | − encode_frame_result->show_idx = show_idx; | |
| 7367 | + encode_frame_result->show_idx = coded_frame_buf->frame_index; | |
| 7289 | 7368 | encode_frame_result->update_type = update_type; |
| 7290 | 7369 | encode_frame_result->quantize_index = quantize_index; |
| 7291 | 7370 | } |
| @@ -7294,6 +7373,7 @@ static void update_encode_frame_result( · 2 unmodified lines | ||
| 7294 | 7373 | void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) { |
| 7295 | 7374 | encode_frame_result->show_idx = -1; // Actual encoding doesn't happen. |
| 7296 | 7375 | #if CONFIG_RATE_CTRL |
| 7376 | + encode_frame_result->frame_coding_index = -1; | |
| 7297 | 7377 | vp9_zero(encode_frame_result->coded_frame); |
| 7298 | 7378 | encode_frame_result->coded_frame.allocated = 0; |
| 7299 | 7379 | #endif // CONFIG_RATE_CTRL |
| @@ -7575,29 +7655,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, · 275 unmodified lines | ||
| 7575 | 7655 | cpi->td.mb.inv_txfm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; |
| 7576 | 7656 | vp9_first_pass(cpi, source); |
| 7577 | 7657 | } else if (oxcf->pass == 2 && !cpi->use_svc) { |
| 7578 | − Pass2Encode(cpi, size, dest, frame_flags); | |
| 7579 | − // update_encode_frame_result() depends on twopass.gf_group.index and | |
| 7580 | − // cm->new_fb_idx and cpi->Source are updated for current properly and have | |
| 7581 | − // not been updated for the next frame yet. | |
| 7582 | − // The update locations are as follows. | |
| 7583 | − // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero() | |
| 7584 | − // for the first frame in the gf_group and is updated for the next frame at | |
| 7585 | − // vp9_twopass_postencode_update(). | |
| 7586 | − // 2) cpi->Source is updated at the beginning of this function, i.e. | |
| 7587 | − // vp9_get_compressed_data() | |
| 7588 | − // 3) cm->new_fb_idx is updated at the beginning of this function by | |
| 7589 | − // get_free_fb(cm) | |
| 7590 | − // TODO(angiebird): Improve the codebase to make the update of frame | |
| 7591 | − // dependent variables more robust. | |
| 7592 | − update_encode_frame_result( | |
| 7593 | − source->show_idx, | |
| 7594 | − cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], | |
| 7595 | − cpi->Source, get_frame_new_buffer(cm), vp9_get_quantizer(cpi), | |
| 7596 | − cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, | |
| 7597 | −#if CONFIG_RATE_CTRL | |
| 7598 | − cpi->partition_info, cpi->motion_vector_info, | |
| 7599 | −#endif // CONFIG_RATE_CTRL | |
| 7600 | − encode_frame_result); | |
| 7658 | + Pass2Encode(cpi, size, dest, frame_flags, encode_frame_result); | |
| 7601 | 7659 | vp9_twopass_postencode_update(cpi); |
| 7602 | 7660 | } else if (cpi->use_svc) { |
| 7603 | 7661 | SvcEncode(cpi, size, dest, frame_flags); |
| @@ -936,6 +936,9 @@ typedef struct ENCODE_FRAME_RESULT { · 935 unmodified lines | ||
| 936 | 936 | int show_idx; |
| 937 | 937 | FRAME_UPDATE_TYPE update_type; |
| 938 | 938 | #if CONFIG_RATE_CTRL |
| 939 | + int frame_coding_index; | |
| 940 | + int ref_frame_coding_indexes[MAX_INTER_REF_FRAMES]; | |
| 941 | + int ref_frame_valid_list[MAX_INTER_REF_FRAMES]; | |
| 939 | 942 | double psnr; |
| 940 | 943 | uint64_t sse; |
| 941 | 944 | FRAME_COUNTS frame_counts; |
| @@ -1043,10 +1046,22 @@ static INLINE int get_ref_frame_buf_idx(const VP9_COMP *const cpi, · 101 unmodified lines | ||
| 1043 | 1046 | return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : INVALID_IDX; |
| 1044 | 1047 | } |
| 1045 | 1048 | |
| 1046 | −static INLINE RefCntBuffer *get_ref_cnt_buffer(VP9_COMMON *cm, int fb_idx) { | |
| 1049 | +static INLINE RefCntBuffer *get_ref_cnt_buffer(const VP9_COMMON *cm, | |
| 1050 | + int fb_idx) { | |
| 1047 | 1051 | return fb_idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[fb_idx] : NULL; |
| 1048 | 1052 | } |
| 1049 | 1053 | |
| 1054 | +static INLINE void get_ref_frame_bufs( | |
| 1055 | + const VP9_COMP *cpi, RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]) { | |
| 1056 | + const VP9_COMMON *const cm = &cpi->common; | |
| 1057 | + MV_REFERENCE_FRAME ref_frame; | |
| 1058 | + for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) { | |
| 1059 | + int ref_frame_buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); | |
| 1060 | + int inter_ref_idx = mv_ref_frame_to_inter_ref_idx(ref_frame); | |
| 1061 | + ref_frame_bufs[inter_ref_idx] = get_ref_cnt_buffer(cm, ref_frame_buf_idx); | |
| 1062 | + } | |
| 1063 | +} | |
| 1064 | + | |
| 1050 | 1065 | static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer( |
| 1051 | 1066 | const VP9_COMP *const cpi, MV_REFERENCE_FRAME ref_frame) { |
| 1052 | 1067 | const VP9_COMMON *const cm = &cpi->common; |
| @@ -1478,7 +1478,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) { · 1477 unmodified lines | ||
| 1478 | 1478 | fclose(recon_file); |
| 1479 | 1479 | } |
| 1480 | 1480 | |
| 1481 | − ++cm->current_video_frame; | |
| 1481 | + // In the first pass, every frame is considered as a show frame. | |
| 1482 | + update_frame_indexes(cm, /*show_frame=*/1); | |
| 1482 | 1483 | if (cpi->use_svc) vp9_inc_frame_in_layer(cpi); |
| 1483 | 1484 | } |
| 1484 | 1485 | |
| @@ -498,6 +498,14 @@ static void update_encode_frame_result( · 497 unmodified lines | ||
| 498 | 498 | encode_frame_result->coding_data_bit_size = |
| 499 | 499 | encode_frame_result->coding_data_byte_size * 8; |
| 500 | 500 | encode_frame_result->show_idx = encode_frame_info->show_idx; |
| 501 | + encode_frame_result->coding_idx = encode_frame_info->frame_coding_index; | |
| 502 | + assert(kRefFrameTypeMax == MAX_INTER_REF_FRAMES); | |
| 503 | + for (int i = 0; i < kRefFrameTypeMax; ++i) { | |
| 504 | + encode_frame_result->ref_frame_info.coding_indexes[i] = | |
| 505 | + encode_frame_info->ref_frame_coding_indexes[i]; | |
| 506 | + encode_frame_result->ref_frame_info.valid_list[i] = | |
| 507 | + encode_frame_info->ref_frame_valid_list[i]; | |
| 508 | + } | |
| 501 | 509 | encode_frame_result->frame_type = |
| 502 | 510 | get_frame_type_from_update_type(encode_frame_info->update_type); |
| 503 | 511 | encode_frame_result->psnr = encode_frame_info->psnr; |
| @@ -524,9 +532,18 @@ static int IsGroupOfPictureFinished(const GroupOfPicture &group_of_picture) { · 20 unmodified lines | ||
| 524 | 532 | group_of_picture.encode_frame_list.size(); |
| 525 | 533 | } |
| 526 | 534 | |
| 535 | +bool operator==(const RefFrameInfo &a, const RefFrameInfo &b) { | |
| 536 | + bool match = true; | |
| 537 | + for (int i = 0; i < kRefFrameTypeMax; ++i) { | |
| 538 | + match &= a.coding_indexes[i] == b.coding_indexes[i]; | |
| 539 | + match &= a.valid_list[i] == b.valid_list[i]; | |
| 540 | + } | |
| 541 | + return match; | |
| 542 | +} | |
| 543 | + | |
| 527 | 544 | static void InitRefFrameInfo(RefFrameInfo *ref_frame_info) { |
| 528 | 545 | for (int i = 0; i < kRefFrameTypeMax; ++i) { |
| 529 | − ref_frame_info->coding_indexes[i] = 0; | |
| 546 | + ref_frame_info->coding_indexes[i] = -1; | |
| 530 | 547 | ref_frame_info->valid_list[i] = 0; |
| 531 | 548 | } |
| 532 | 549 | } |
| @@ -579,7 +596,7 @@ static void PostUpdateRefFrameInfo(FrameType frame_type, int frame_coding_index, · 46 unmodified lines | ||
| 579 | 596 | } |
| 580 | 597 | |
| 581 | 598 | if (past_index == last_index) { |
| 582 | − ref_frame_valid_list[kRefFrameTypeLast] = 0; | |
| 599 | + ref_frame_valid_list[kRefFrameTypePast] = 0; | |
| 583 | 600 | } |
| 584 | 601 | |
| 585 | 602 | if (future_index == last_index) { |
| @@ -693,7 +710,13 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height, · 107 unmodified lines | ||
| 693 | 710 | frame_rate_den_ = frame_rate_den; |
| 694 | 711 | target_bitrate_ = target_bitrate; |
| 695 | 712 | num_frames_ = num_frames; |
| 713 | + | |
| 696 | 714 | frame_coding_index_ = 0; |
| 715 | + show_frame_count_ = 0; | |
| 716 | + | |
| 717 | + key_frame_group_index_ = 0; | |
| 718 | + key_frame_group_size_ = 0; | |
| 719 | + | |
| 697 | 720 | // TODO(angirbid): Should we keep a file pointer here or keep the file_path? |
| 698 | 721 | assert(infile_path != nullptr); |
| 699 | 722 | in_file_ = fopen(infile_path, "r"); |
| @@ -789,6 +812,14 @@ void SimpleEncode::SetExternalGroupOfPicture( · 89 unmodified lines | ||
| 789 | 812 | external_arf_indexes_ = external_arf_indexes; |
| 790 | 813 | } |
| 791 | 814 | |
| 815 | +template <typename T> | |
| 816 | +T *GetVectorData(const std::vector<T> &v) { | |
| 817 | + if (v.empty()) { | |
| 818 | + return nullptr; | |
| 819 | + } | |
| 820 | + return const_cast<T *>(v.data()); | |
| 821 | +} | |
| 822 | + | |
| 792 | 823 | void SimpleEncode::StartEncode() { |
| 793 | 824 | assert(impl_ptr_->first_pass_stats.size() > 0); |
| 794 | 825 | vpx_rational_t frame_rate = |
| @@ -797,7 +828,7 @@ void SimpleEncode::StartEncode() { · 2 unmodified lines | ||
| 797 | 828 | vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, |
| 798 | 829 | target_bitrate_, VPX_RC_LAST_PASS); |
| 799 | 830 | vpx_fixed_buf_t stats; |
| 800 | − stats.buf = impl_ptr_->first_pass_stats.data(); | |
| 831 | + stats.buf = GetVectorData(impl_ptr_->first_pass_stats); | |
| 801 | 832 | stats.sz = sizeof(impl_ptr_->first_pass_stats[0]) * |
| 802 | 833 | impl_ptr_->first_pass_stats.size(); |
| 803 | 834 | |
| @@ -806,9 +837,15 @@ void SimpleEncode::StartEncode() { · 2 unmodified lines | ||
| 806 | 837 | impl_ptr_->cpi = init_encoder(&oxcf, impl_ptr_->img_fmt); |
| 807 | 838 | vpx_img_alloc(&impl_ptr_->tmp_img, impl_ptr_->img_fmt, frame_width_, |
| 808 | 839 | frame_height_, 1); |
| 840 | + | |
| 809 | 841 | frame_coding_index_ = 0; |
| 842 | + show_frame_count_ = 0; | |
| 843 | + | |
| 810 | 844 | encode_command_set_external_arf_indexes(&impl_ptr_->cpi->encode_command, |
| 811 | − external_arf_indexes_.data()); | |
| 845 | + GetVectorData(external_arf_indexes_)); | |
| 846 | + | |
| 847 | + UpdateKeyFrameGroup(show_frame_count_); | |
| 848 | + | |
| 812 | 849 | UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, |
| 813 | 850 | &group_of_picture_); |
| 814 | 851 | rewind(in_file_); |
| @@ -829,13 +866,26 @@ void SimpleEncode::EndEncode() { · 14 unmodified lines | ||
| 829 | 866 | rewind(in_file_); |
| 830 | 867 | } |
| 831 | 868 | |
| 832 | −int SimpleEncode::GetKeyFrameGroupSize(int key_frame_index) const { | |
| 869 | +void SimpleEncode::UpdateKeyFrameGroup(int key_frame_show_index) { | |
| 833 | 870 | const VP9_COMP *cpi = impl_ptr_->cpi; |
| 834 | − return vp9_get_frames_to_next_key(&cpi->oxcf, &cpi->frame_info, | |
| 835 | − &cpi->twopass.first_pass_info, | |
| 836 | − key_frame_index, cpi->rc.min_gf_interval); | |
| 871 | + key_frame_group_index_ = 0; | |
| 872 | + key_frame_group_size_ = vp9_get_frames_to_next_key( | |
| 873 | + &cpi->oxcf, &cpi->frame_info, &cpi->twopass.first_pass_info, | |
| 874 | + key_frame_show_index, cpi->rc.min_gf_interval); | |
| 875 | + assert(key_frame_group_size_ > 0); | |
| 876 | + // Init the reference frame info when a new key frame group appears. | |
| 877 | + InitRefFrameInfo(&ref_frame_info_); | |
| 878 | +} | |
| 879 | + | |
| 880 | +void SimpleEncode::PostUpdateKeyFrameGroupIndex(FrameType frame_type) { | |
| 881 | + if (frame_type != kFrameTypeAltRef) { | |
| 882 | + // key_frame_group_index_ only counts show frames | |
| 883 | + ++key_frame_group_index_; | |
| 884 | + } | |
| 837 | 885 | } |
| 838 | 886 | |
| 887 | +int SimpleEncode::GetKeyFrameGroupSize() const { return key_frame_group_size_; } | |
| 888 | + | |
| 839 | 889 | GroupOfPicture SimpleEncode::ObserveGroupOfPicture() const { |
| 840 | 890 | return group_of_picture_; |
| 841 | 891 | } |
| @@ -852,8 +902,20 @@ void SimpleEncode::PostUpdateState( · 10 unmodified lines | ||
| 852 | 902 | PostUpdateRefFrameInfo(encode_frame_result.frame_type, frame_coding_index_, |
| 853 | 903 | &ref_frame_info_); |
| 854 | 904 | ++frame_coding_index_; |
| 905 | + if (encode_frame_result.frame_type != kFrameTypeAltRef) { | |
| 906 | + // Only kFrameTypeAltRef is not a show frame | |
| 907 | + ++show_frame_count_; | |
| 908 | + } | |
| 909 | + | |
| 910 | + PostUpdateKeyFrameGroupIndex(encode_frame_result.frame_type); | |
| 911 | + if (key_frame_group_index_ == key_frame_group_size_) { | |
| 912 | + UpdateKeyFrameGroup(show_frame_count_); | |
| 913 | + } | |
| 914 | + | |
| 855 | 915 | IncreaseGroupOfPictureIndex(&group_of_picture_); |
| 856 | 916 | if (IsGroupOfPictureFinished(group_of_picture_)) { |
| 917 | + // This function needs to be called after ref_frame_info_ is updated | |
| 918 | + // properly in PostUpdateRefFrameInfo() and UpdateKeyFrameGroup(). | |
| 857 | 919 | UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, |
| 858 | 920 | &group_of_picture_); |
| 859 | 921 | } |
| @@ -952,7 +1014,8 @@ int SimpleEncode::GetCodingFrameNum() const { · 92 unmodified lines | ||
| 952 | 1014 | target_bitrate_, VPX_RC_LAST_PASS); |
| 953 | 1015 | FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); |
| 954 | 1016 | FIRST_PASS_INFO first_pass_info; |
| 955 | − fps_init_first_pass_info(&first_pass_info, impl_ptr_->first_pass_stats.data(), | |
| 1017 | + fps_init_first_pass_info(&first_pass_info, | |
| 1018 | + GetVectorData(impl_ptr_->first_pass_stats), | |
| 956 | 1019 | num_frames_); |
| 957 | 1020 | return vp9_get_coding_frame_num(external_arf_indexes_.data(), &oxcf, |
| 958 | 1021 | &frame_info, &first_pass_info, |
| @@ -86,6 +86,8 @@ struct RefFrameInfo { · 85 unmodified lines | ||
| 86 | 86 | int valid_list[kRefFrameTypeMax]; |
| 87 | 87 | }; |
| 88 | 88 | |
| 89 | +bool operator==(const RefFrameInfo &a, const RefFrameInfo &b); | |
| 90 | + | |
| 89 | 91 | struct EncodeFrameInfo { |
| 90 | 92 | int show_idx; |
| 91 | 93 | |
| @@ -199,6 +201,8 @@ void output_image_buffer(const ImageBuffer &image_buffer, std::FILE *out_file); · 107 unmodified lines | ||
| 199 | 201 | struct EncodeFrameResult { |
| 200 | 202 | int show_idx; |
| 201 | 203 | FrameType frame_type; |
| 204 | + int coding_idx; | |
| 205 | + RefFrameInfo ref_frame_info; | |
| 202 | 206 | size_t coding_data_bit_size; |
| 203 | 207 | size_t coding_data_byte_size; |
| 204 | 208 | // The EncodeFrame will allocate a buffer, write the coding data into the |
| @@ -304,12 +308,11 @@ class SimpleEncode { · 99 unmodified lines | ||
| 304 | 308 | // This function should be called after StartEncode() or EncodeFrame(). |
| 305 | 309 | void EndEncode(); |
| 306 | 310 | |
| 307 | − // Given a key_frame_index, computes this key frame group's size. | |
| 308 | 311 | // The key frame group size includes one key frame plus the number of |
| 309 | 312 | // following inter frames. Note that the key frame group size only counts the |
| 310 | 313 | // show frames. The number of no show frames like alternate refereces are not |
| 311 | 314 | // counted. |
| 312 | − int GetKeyFrameGroupSize(int key_frame_index) const; | |
| 315 | + int GetKeyFrameGroupSize() const; | |
| 313 | 316 | |
| 314 | 317 | // Provides the group of pictures that the next coding frame is in. |
| 315 | 318 | // Only call this function between StartEncode() and EndEncode() |
| @@ -353,11 +356,30 @@ class SimpleEncode { · 37 unmodified lines | ||
| 353 | 356 | std::vector<int> external_arf_indexes_; |
| 354 | 357 | GroupOfPicture group_of_picture_; |
| 355 | 358 | |
| 359 | + // The key frame group size includes one key frame plus the number of | |
| 360 | + // following inter frames. Note that the key frame group size only counts the | |
| 361 | + // show frames. The number of no show frames like alternate refereces are not | |
| 362 | + // counted. | |
| 363 | + int key_frame_group_size_; | |
| 364 | + | |
| 365 | + // The index for the to-be-coded show frame in the key frame group. | |
| 366 | + int key_frame_group_index_; | |
| 367 | + | |
| 368 | + // Update key_frame_group_size_, reset key_frame_group_index_ and init | |
| 369 | + // ref_frame_info_. | |
| 370 | + void UpdateKeyFrameGroup(int key_frame_show_index); | |
| 371 | + | |
| 372 | + // Update key_frame_group_index_. | |
| 373 | + void PostUpdateKeyFrameGroupIndex(FrameType frame_type); | |
| 374 | + | |
| 356 | 375 | // Each show or no show frame is assigned with a coding index based on its |
| 357 | 376 | // coding order (starting from zero) in the coding process of the entire |
| 358 | 377 | // video. The coding index of the to-be-coded frame. |
| 359 | 378 | int frame_coding_index_; |
| 360 | 379 | |
| 380 | + // Number of show frames we have coded so far. | |
| 381 | + int show_frame_count_; | |
| 382 | + | |
| 361 | 383 | // TODO(angiebird): Do we need to reset ref_frames_info_ when the next key |
| 362 | 384 | // frame appears? |
| 363 | 385 | // Reference frames info of the to-be-coded frame. |