History

multi-res: restore v1.0.0 API

Move the notion of 0 bitrate implying skip deeper into the codec, rather than doing it at the multi-encoder API level. This preserves v1.0.0 ABI compatibility, rather than forcing a bump to v2.0.0 over a minor change. Also, this allows the case where the application can selectively enable and disable the larger resolution(s) without having to reinitialize the codec instace (for instance, if no target is receiving the full resolution stream). It's not clear how deep to push this check. It may be valuable to allow the framerate adaptation code to run, for example. Currently put the check as early as possible for simplicity, should reevaluate this as this feature gains real use.

John Koleszar committed 14 years ago

Commit d72c5361 parent c311b3b4 files · +36 −50Browse files

Unified · Split

4 files
  1. vp8/vp8_cx_iface.c +3 −0
  2. vp8_multi_resolution_encoder.c +29 −43
  3. vpx/src/vpx_encoder.c +2 −3
  4. vpx/vpx_encoder.h +2 −4
vp8/vp8_cx_iface.c+3−0
@@ -757,6 +757,9 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, · 756 unmodified lines
757{757{
758 vpx_codec_err_t res = VPX_CODEC_OK;758 vpx_codec_err_t res = VPX_CODEC_OK;
759 759
760 if (!ctx->cfg.rc_target_bitrate)
761 return res;
762
760 if (img)763 if (img)
761 res = validate_img(ctx, img);764 res = validate_img(ctx, img);
762 765
vp8_multi_resolution_encoder.c+29−43
@@ -224,9 +224,6 @@ int main(int argc, char **argv) · 223 unmodified lines
224 dsf[1] controls down sampling from level 1 to level 2;224 dsf[1] controls down sampling from level 1 to level 2;
225 dsf[2] is not used. */225 dsf[2] is not used. */
226 vpx_rational_t dsf[NUM_ENCODERS] = {{2, 1}, {2, 1}, {1, 1}};226 vpx_rational_t dsf[NUM_ENCODERS] = {{2, 1}, {2, 1}, {1, 1}};
227 /* Encode starting from which resolution level. Normally it is 0 that
228 * means the original(highest) resolution. */
229 int s_lvl = 0;
230 227
231 if(argc!= (5+NUM_ENCODERS))228 if(argc!= (5+NUM_ENCODERS))
232 die("Usage: %s <width> <height> <infile> <outfile(s)> <output psnr?>\n",229 die("Usage: %s <width> <height> <infile> <outfile(s)> <output psnr?>\n",
@@ -240,21 +237,6 @@ int main(int argc, char **argv) · 7 unmodified lines
240 if(width < 16 || width%2 || height <16 || height%2)237 if(width < 16 || width%2 || height <16 || height%2)
241 die("Invalid resolution: %ldx%ld", width, height);238 die("Invalid resolution: %ldx%ld", width, height);
242 239
243 /* Check to see if we need to encode all resolution levels */
244 for (i=0; i<NUM_ENCODERS; i++)
245 {
246 if (target_bitrate[i])
247 break;
248 else
249 s_lvl += 1;
250 }
251
252 if (s_lvl >= NUM_ENCODERS)
253 {
254 printf("No encoding: total number of encoders is 0!");
255 return 0;
256 }
257
258 /* Open input video file for encoding */240 /* Open input video file for encoding */
259 if(!(infile = fopen(argv[3], "rb")))241 if(!(infile = fopen(argv[3], "rb")))
260 die("Failed to open %s for reading", argv[3]);242 die("Failed to open %s for reading", argv[3]);
@@ -262,6 +244,12 @@ int main(int argc, char **argv) · 1 unmodified line
262 /* Open output file for each encoder to output bitstreams */244 /* Open output file for each encoder to output bitstreams */
263 for (i=0; i< NUM_ENCODERS; i++)245 for (i=0; i< NUM_ENCODERS; i++)
264 {246 {
247 if(!target_bitrate[i])
248 {
249 outfile[i] = NULL;
250 continue;
251 }
252
265 if(!(outfile[i] = fopen(argv[i+4], "wb")))253 if(!(outfile[i] = fopen(argv[i+4], "wb")))
266 die("Failed to open %s for writing", argv[i+4]);254 die("Failed to open %s for writing", argv[i+4]);
267 }255 }
@@ -342,15 +330,18 @@ int main(int argc, char **argv) · 74 unmodified lines
342 else330 else
343 read_frame_p = read_frame_by_row;331 read_frame_p = read_frame_by_row;
344 332
333 for (i=0; i< NUM_ENCODERS; i++)
334 if(outfile[i])
335 write_ivf_file_header(outfile[i], &cfg[i], 0);
336
345 /* Initialize multi-encoder */337 /* Initialize multi-encoder */
346 if(vpx_codec_enc_init_multi(&codec[s_lvl], interface, &cfg[s_lvl], s_lvl,338 if(vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS,
347 NUM_ENCODERS,339 (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0]))
348 (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[s_lvl]))340 die_codec(&codec[0], "Failed to initialize encoder");
349 die_codec(&codec[s_lvl], "Failed to initialize encoder");
350 341
351 /* The extra encoding configuration parameters can be set as follows. */342 /* The extra encoding configuration parameters can be set as follows. */
352 /* Set encoding speed */343 /* Set encoding speed */
353 for ( i=s_lvl; i<NUM_ENCODERS; i++)344 for ( i=0; i<NUM_ENCODERS; i++)
354 {345 {
355 int speed = -6;346 int speed = -6;
356 if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed))347 if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed))
@@ -360,25 +351,20 @@ int main(int argc, char **argv) · 3 unmodified lines
360 * better performance. */351 * better performance. */
361 {352 {
362 unsigned int static_thresh = 1000;353 unsigned int static_thresh = 1000;
363 if(vpx_codec_control(&codec[s_lvl], VP8E_SET_STATIC_THRESHOLD,354 if(vpx_codec_control(&codec[0], VP8E_SET_STATIC_THRESHOLD, static_thresh))
364 static_thresh))355 die_codec(&codec[0], "Failed to set static threshold");
365 die_codec(&codec[s_lvl], "Failed to set static threshold");
366 }356 }
367 /* Set static thresh = 0 for other encoders for better quality */357 /* Set static thresh = 0 for other encoders for better quality */
368 for ( i=s_lvl+1; i<NUM_ENCODERS; i++)358 for ( i=1; i<NUM_ENCODERS; i++)
369 {359 {
370 unsigned int static_thresh = 0;360 unsigned int static_thresh = 0;
371 if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD,361 if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, static_thresh))
372 static_thresh))
373 die_codec(&codec[i], "Failed to set static threshold");362 die_codec(&codec[i], "Failed to set static threshold");
374 }363 }
375 364
376 frame_avail = 1;365 frame_avail = 1;
377 got_data = 0;366 got_data = 0;
378 367
379 for (i=s_lvl ; i< NUM_ENCODERS; i++)
380 write_ivf_file_header(outfile[i], &cfg[i], 0);
381
382 while(frame_avail || got_data)368 while(frame_avail || got_data)
383 {369 {
384 vpx_codec_iter_t iter[NUM_ENCODERS]={NULL};370 vpx_codec_iter_t iter[NUM_ENCODERS]={NULL};
@@ -405,11 +391,11 @@ int main(int argc, char **argv) · 20 unmodified lines
405 }391 }
406 392
407 /* Encode each frame at multi-levels */393 /* Encode each frame at multi-levels */
408 if(vpx_codec_encode(&codec[s_lvl], frame_avail? &raw[s_lvl] : NULL,394 if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
409 frame_cnt, 1, flags, arg_deadline))395 frame_cnt, 1, flags, arg_deadline))
410 die_codec(&codec[s_lvl], "Failed to encode frame");396 die_codec(&codec[0], "Failed to encode frame");
411 397
412 for (i=NUM_ENCODERS-1; i>=s_lvl ; i--)398 for (i=NUM_ENCODERS-1; i>=0 ; i--)
413 {399 {
414 got_data = 0;400 got_data = 0;
415 401
@@ -452,10 +438,9 @@ int main(int argc, char **argv) · 36 unmodified lines
452 438
453 fclose(infile);439 fclose(infile);
454 440
455 for (i=s_lvl; i< NUM_ENCODERS; i++)441 printf("Processed %ld frames.\n",(long int)frame_cnt-1);
442 for (i=0; i< NUM_ENCODERS; i++)
456 {443 {
457 printf("Processed %ld frames.\n",(long int)frame_cnt-1);
458
459 /* Calculate PSNR and print it out */444 /* Calculate PSNR and print it out */
460 if ( (show_psnr) && (psnr_count[i]>0) )445 if ( (show_psnr) && (psnr_count[i]>0) )
461 {446 {
@@ -475,16 +460,17 @@ int main(int argc, char **argv) · 13 unmodified lines
475 if(vpx_codec_destroy(&codec[i]))460 if(vpx_codec_destroy(&codec[i]))
476 die_codec(&codec[i], "Failed to destroy codec");461 die_codec(&codec[i], "Failed to destroy codec");
477 462
463 vpx_img_free(&raw[i]);
464
465 if(!outfile[i])
466 continue;
467
478 /* Try to rewrite the file header with the actual frame count */468 /* Try to rewrite the file header with the actual frame count */
479 if(!fseek(outfile[i], 0, SEEK_SET))469 if(!fseek(outfile[i], 0, SEEK_SET))
480 write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1);470 write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1);
481 }
482
483 for (i=0; i< NUM_ENCODERS; i++)
484 {
485 fclose(outfile[i]);471 fclose(outfile[i]);
486 vpx_img_free(&raw[i]);
487 }472 }
473 printf("\n");
488 474
489 return EXIT_SUCCESS;475 return EXIT_SUCCESS;
490}476}
vpx/src/vpx_encoder.c+2−3
@@ -69,7 +69,6 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx, · 68 unmodified lines
69vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,69vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
70 vpx_codec_iface_t *iface,70 vpx_codec_iface_t *iface,
71 vpx_codec_enc_cfg_t *cfg,71 vpx_codec_enc_cfg_t *cfg,
72 int s_lvl,
73 int num_enc,72 int num_enc,
74 vpx_codec_flags_t flags,73 vpx_codec_flags_t flags,
75 vpx_rational_t *dsf,74 vpx_rational_t *dsf,
@@ -100,7 +99,7 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, · 24 unmodified lines
100 99
101 if(!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc)))100 if(!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc)))
102 {101 {
103 for (i = s_lvl; i < num_enc; i++)102 for (i = 0; i < num_enc; i++)
104 {103 {
105 vpx_codec_priv_enc_mr_cfg_t mr_cfg;104 vpx_codec_priv_enc_mr_cfg_t mr_cfg;
106 105
@@ -113,7 +112,7 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, · 6 unmodified lines
113 }112 }
114 113
115 mr_cfg.mr_low_res_mode_info = mem_loc;114 mr_cfg.mr_low_res_mode_info = mem_loc;
116 mr_cfg.mr_total_resolutions = num_enc - s_lvl;115 mr_cfg.mr_total_resolutions = num_enc;
117 mr_cfg.mr_encoder_id = num_enc-1-i;116 mr_cfg.mr_encoder_id = num_enc-1-i;
118 mr_cfg.mr_down_sampling_factor.num = dsf->num;117 mr_cfg.mr_down_sampling_factor.num = dsf->num;
119 mr_cfg.mr_down_sampling_factor.den = dsf->den;118 mr_cfg.mr_down_sampling_factor.den = dsf->den;
vpx/vpx_encoder.h+2−4
@@ -688,7 +688,6 @@ extern "C" { · 687 unmodified lines
688 * \param[in] ctx Pointer to this instance's context.688 * \param[in] ctx Pointer to this instance's context.
689 * \param[in] iface Pointer to the algorithm interface to use.689 * \param[in] iface Pointer to the algorithm interface to use.
690 * \param[in] cfg Configuration to use, if known. May be NULL.690 * \param[in] cfg Configuration to use, if known. May be NULL.
691 * \param[in] s_lvl Starting encoder id. Normally it is 0.
692 * \param[in] num_enc Total number of encoders.691 * \param[in] num_enc Total number of encoders.
693 * \param[in] flags Bitfield of VPX_CODEC_USE_* flags692 * \param[in] flags Bitfield of VPX_CODEC_USE_* flags
694 * \param[in] dsf Pointer to down-sampling factors.693 * \param[in] dsf Pointer to down-sampling factors.
@@ -702,7 +701,6 @@ extern "C" { · 7 unmodified lines
702 vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,701 vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
703 vpx_codec_iface_t *iface,702 vpx_codec_iface_t *iface,
704 vpx_codec_enc_cfg_t *cfg,703 vpx_codec_enc_cfg_t *cfg,
705 int s_lvl,
706 int num_enc,704 int num_enc,
707 vpx_codec_flags_t flags,705 vpx_codec_flags_t flags,
708 vpx_rational_t *dsf,706 vpx_rational_t *dsf,
@@ -713,8 +711,8 @@ extern "C" { · 4 unmodified lines
713 *711 *
714 * Ensures the ABI version parameter is properly set.712 * Ensures the ABI version parameter is properly set.
715 */713 */
716#define vpx_codec_enc_init_multi(ctx, iface, cfg, s_lvl, num_enc, flags, dsf) \714#define vpx_codec_enc_init_multi(ctx, iface, cfg, num_enc, flags, dsf) \
717 vpx_codec_enc_init_multi_ver(ctx, iface, cfg, s_lvl, num_enc, flags, dsf, \715 vpx_codec_enc_init_multi_ver(ctx, iface, cfg, num_enc, flags, dsf, \
718 VPX_ENCODER_ABI_VERSION)716 VPX_ENCODER_ABI_VERSION)
719 717
720 718

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t