Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: source/libvpx/vpxenc.c

Issue 168343002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: libvpx: Pull from upstream Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vpxenc.h ('k') | source/libvpx/warnings.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "./vpxenc.h" 11 #include "./vpxenc.h"
12 #include "./vpx_config.h" 12 #include "./vpx_config.h"
13 13
14 #include <assert.h> 14 #include <assert.h>
15 #include <limits.h> 15 #include <limits.h>
16 #include <math.h> 16 #include <math.h>
17 #include <stdarg.h> 17 #include <stdarg.h>
18 #include <stdio.h> 18 #include <stdio.h>
19 #include <stdlib.h> 19 #include <stdlib.h>
20 #include <string.h> 20 #include <string.h>
21 21
22 #include "vpx/vpx_encoder.h" 22 #include "vpx/vpx_encoder.h"
23 #if CONFIG_DECODERS 23 #if CONFIG_DECODERS
24 #include "vpx/vpx_decoder.h" 24 #include "vpx/vpx_decoder.h"
25 #endif 25 #endif
26 26
27 #include "third_party/libyuv/include/libyuv/scale.h" 27 #include "third_party/libyuv/include/libyuv/scale.h"
28 #include "./args.h" 28 #include "./args.h"
29 #include "./ivfenc.h" 29 #include "./ivfenc.h"
30 #include "./tools_common.h"
30 31
31 #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER 32 #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
32 #include "vpx/vp8cx.h" 33 #include "vpx/vp8cx.h"
33 #endif 34 #endif
34 #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER 35 #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
35 #include "vpx/vp8dx.h" 36 #include "vpx/vp8dx.h"
36 #endif 37 #endif
37 38
38 #include "./tools_common.h" 39 #include "vpx/vpx_integer.h"
39 #include "vpx_ports/mem_ops.h" 40 #include "vpx_ports/mem_ops.h"
40 #include "vpx_ports/vpx_timer.h" 41 #include "vpx_ports/vpx_timer.h"
42 #include "./rate_hist.h"
41 #include "./vpxstats.h" 43 #include "./vpxstats.h"
42 #include "./warnings.h" 44 #include "./warnings.h"
43 #include "./webmenc.h" 45 #include "./webmenc.h"
44 #include "./y4minput.h" 46 #include "./y4minput.h"
45 47
46 /* Swallow warnings about unused results of fread/fwrite */ 48 /* Swallow warnings about unused results of fread/fwrite */
47 static size_t wrap_fread(void *ptr, size_t size, size_t nmemb, 49 static size_t wrap_fread(void *ptr, size_t size, size_t nmemb,
48 FILE *stream) { 50 FILE *stream) {
49 return fread(ptr, size, nmemb, stream); 51 return fread(ptr, size, nmemb, stream);
50 } 52 }
51 #define fread wrap_fread 53 #define fread wrap_fread
52 54
53 static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb, 55 static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb,
54 FILE *stream) { 56 FILE *stream) {
55 return fwrite(ptr, size, nmemb, stream); 57 return fwrite(ptr, size, nmemb, stream);
56 } 58 }
57 #define fwrite wrap_fwrite 59 #define fwrite wrap_fwrite
58 60
59 61
60 static const char *exec_name; 62 static const char *exec_name;
61 63
62 static const struct codec_item {
63 char const *name;
64 const vpx_codec_iface_t *(*iface)(void);
65 const vpx_codec_iface_t *(*dx_iface)(void);
66 unsigned int fourcc;
67 } codecs[] = {
68 #if CONFIG_VP8_ENCODER && CONFIG_VP8_DECODER
69 {"vp8", &vpx_codec_vp8_cx, &vpx_codec_vp8_dx, VP8_FOURCC},
70 #elif CONFIG_VP8_ENCODER && !CONFIG_VP8_DECODER
71 {"vp8", &vpx_codec_vp8_cx, NULL, VP8_FOURCC},
72 #endif
73 #if CONFIG_VP9_ENCODER && CONFIG_VP9_DECODER
74 {"vp9", &vpx_codec_vp9_cx, &vpx_codec_vp9_dx, VP9_FOURCC},
75 #elif CONFIG_VP9_ENCODER && !CONFIG_VP9_DECODER
76 {"vp9", &vpx_codec_vp9_cx, NULL, VP9_FOURCC},
77 #endif
78 };
79
80 static void warn_or_exit_on_errorv(vpx_codec_ctx_t *ctx, int fatal, 64 static void warn_or_exit_on_errorv(vpx_codec_ctx_t *ctx, int fatal,
81 const char *s, va_list ap) { 65 const char *s, va_list ap) {
82 if (ctx->err) { 66 if (ctx->err) {
83 const char *detail = vpx_codec_error_detail(ctx); 67 const char *detail = vpx_codec_error_detail(ctx);
84 68
85 vfprintf(stderr, s, ap); 69 vfprintf(stderr, s, ap);
86 fprintf(stderr, ": %s\n", vpx_codec_error(ctx)); 70 fprintf(stderr, ": %s\n", vpx_codec_error(ctx));
87 71
88 if (detail) 72 if (detail)
89 fprintf(stderr, " %s\n", detail); 73 fprintf(stderr, " %s\n", detail);
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 fprintf(stderr, "\nVP8 Specific Options:\n"); 437 fprintf(stderr, "\nVP8 Specific Options:\n");
454 arg_show_usage(stderr, vp8_args); 438 arg_show_usage(stderr, vp8_args);
455 #endif 439 #endif
456 #if CONFIG_VP9_ENCODER 440 #if CONFIG_VP9_ENCODER
457 fprintf(stderr, "\nVP9 Specific Options:\n"); 441 fprintf(stderr, "\nVP9 Specific Options:\n");
458 arg_show_usage(stderr, vp9_args); 442 arg_show_usage(stderr, vp9_args);
459 #endif 443 #endif
460 fprintf(stderr, "\nStream timebase (--timebase):\n" 444 fprintf(stderr, "\nStream timebase (--timebase):\n"
461 " The desired precision of timestamps in the output, expressed\n" 445 " The desired precision of timestamps in the output, expressed\n"
462 " in fractional seconds. Default is 1/1000.\n"); 446 " in fractional seconds. Default is 1/1000.\n");
463 fprintf(stderr, "\n" 447 fprintf(stderr, "\nIncluded encoders:\n\n");
464 "Included encoders:\n"
465 "\n");
466 448
467 for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++) 449 for (i = 0; i < get_vpx_encoder_count(); ++i) {
450 const VpxInterface *const encoder = get_vpx_encoder_by_index(i);
468 fprintf(stderr, " %-6s - %s\n", 451 fprintf(stderr, " %-6s - %s\n",
469 codecs[i].name, 452 encoder->name, vpx_codec_iface_name(encoder->interface()));
470 vpx_codec_iface_name(codecs[i].iface())); 453 }
471 454
472 exit(EXIT_FAILURE); 455 exit(EXIT_FAILURE);
473 } 456 }
474 457
475
476 #define HIST_BAR_MAX 40
477 struct hist_bucket {
478 int low, high, count;
479 };
480
481
482 static int merge_hist_buckets(struct hist_bucket *bucket,
483 int *buckets_,
484 int max_buckets) {
485 int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
486 int buckets = *buckets_;
487 int i;
488
489 /* Find the extrema for this list of buckets */
490 big_bucket = small_bucket = 0;
491 for (i = 0; i < buckets; i++) {
492 if (bucket[i].count < bucket[small_bucket].count)
493 small_bucket = i;
494 if (bucket[i].count > bucket[big_bucket].count)
495 big_bucket = i;
496 }
497
498 /* If we have too many buckets, merge the smallest with an adjacent
499 * bucket.
500 */
501 while (buckets > max_buckets) {
502 int last_bucket = buckets - 1;
503
504 /* merge the small bucket with an adjacent one. */
505 if (small_bucket == 0)
506 merge_bucket = 1;
507 else if (small_bucket == last_bucket)
508 merge_bucket = last_bucket - 1;
509 else if (bucket[small_bucket - 1].count < bucket[small_bucket + 1].count)
510 merge_bucket = small_bucket - 1;
511 else
512 merge_bucket = small_bucket + 1;
513
514 assert(abs(merge_bucket - small_bucket) <= 1);
515 assert(small_bucket < buckets);
516 assert(big_bucket < buckets);
517 assert(merge_bucket < buckets);
518
519 if (merge_bucket < small_bucket) {
520 bucket[merge_bucket].high = bucket[small_bucket].high;
521 bucket[merge_bucket].count += bucket[small_bucket].count;
522 } else {
523 bucket[small_bucket].high = bucket[merge_bucket].high;
524 bucket[small_bucket].count += bucket[merge_bucket].count;
525 merge_bucket = small_bucket;
526 }
527
528 assert(bucket[merge_bucket].low != bucket[merge_bucket].high);
529
530 buckets--;
531
532 /* Remove the merge_bucket from the list, and find the new small
533 * and big buckets while we're at it
534 */
535 big_bucket = small_bucket = 0;
536 for (i = 0; i < buckets; i++) {
537 if (i > merge_bucket)
538 bucket[i] = bucket[i + 1];
539
540 if (bucket[i].count < bucket[small_bucket].count)
541 small_bucket = i;
542 if (bucket[i].count > bucket[big_bucket].count)
543 big_bucket = i;
544 }
545
546 }
547
548 *buckets_ = buckets;
549 return bucket[big_bucket].count;
550 }
551
552
553 static void show_histogram(const struct hist_bucket *bucket,
554 int buckets,
555 int total,
556 int scale) {
557 const char *pat1, *pat2;
558 int i;
559
560 switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
561 case 1:
562 case 2:
563 pat1 = "%4d %2s: ";
564 pat2 = "%4d-%2d: ";
565 break;
566 case 3:
567 pat1 = "%5d %3s: ";
568 pat2 = "%5d-%3d: ";
569 break;
570 case 4:
571 pat1 = "%6d %4s: ";
572 pat2 = "%6d-%4d: ";
573 break;
574 case 5:
575 pat1 = "%7d %5s: ";
576 pat2 = "%7d-%5d: ";
577 break;
578 case 6:
579 pat1 = "%8d %6s: ";
580 pat2 = "%8d-%6d: ";
581 break;
582 case 7:
583 pat1 = "%9d %7s: ";
584 pat2 = "%9d-%7d: ";
585 break;
586 default:
587 pat1 = "%12d %10s: ";
588 pat2 = "%12d-%10d: ";
589 break;
590 }
591
592 for (i = 0; i < buckets; i++) {
593 int len;
594 int j;
595 float pct;
596
597 pct = (float)(100.0 * bucket[i].count / total);
598 len = HIST_BAR_MAX * bucket[i].count / scale;
599 if (len < 1)
600 len = 1;
601 assert(len <= HIST_BAR_MAX);
602
603 if (bucket[i].low == bucket[i].high)
604 fprintf(stderr, pat1, bucket[i].low, "");
605 else
606 fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
607
608 for (j = 0; j < HIST_BAR_MAX; j++)
609 fprintf(stderr, j < len ? "=" : " ");
610 fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
611 }
612 }
613
614
615 static void show_q_histogram(const int counts[64], int max_buckets) {
616 struct hist_bucket bucket[64];
617 int buckets = 0;
618 int total = 0;
619 int scale;
620 int i;
621
622
623 for (i = 0; i < 64; i++) {
624 if (counts[i]) {
625 bucket[buckets].low = bucket[buckets].high = i;
626 bucket[buckets].count = counts[i];
627 buckets++;
628 total += counts[i];
629 }
630 }
631
632 fprintf(stderr, "\nQuantizer Selection:\n");
633 scale = merge_hist_buckets(bucket, &buckets, max_buckets);
634 show_histogram(bucket, buckets, total, scale);
635 }
636
637
638 #define RATE_BINS (100)
639 struct rate_hist {
640 int64_t *pts;
641 int *sz;
642 int samples;
643 int frames;
644 struct hist_bucket bucket[RATE_BINS];
645 int total;
646 };
647
648
649 static void init_rate_histogram(struct rate_hist *hist,
650 const vpx_codec_enc_cfg_t *cfg,
651 const vpx_rational_t *fps) {
652 int i;
653
654 /* Determine the number of samples in the buffer. Use the file's framerate
655 * to determine the number of frames in rc_buf_sz milliseconds, with an
656 * adjustment (5/4) to account for alt-refs
657 */
658 hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
659
660 /* prevent division by zero */
661 if (hist->samples == 0)
662 hist->samples = 1;
663
664 hist->pts = calloc(hist->samples, sizeof(*hist->pts));
665 hist->sz = calloc(hist->samples, sizeof(*hist->sz));
666 for (i = 0; i < RATE_BINS; i++) {
667 hist->bucket[i].low = INT_MAX;
668 hist->bucket[i].high = 0;
669 hist->bucket[i].count = 0;
670 }
671 }
672
673
674 static void destroy_rate_histogram(struct rate_hist *hist) {
675 free(hist->pts);
676 free(hist->sz);
677 }
678
679
680 static void update_rate_histogram(struct rate_hist *hist,
681 const vpx_codec_enc_cfg_t *cfg,
682 const vpx_codec_cx_pkt_t *pkt) {
683 int i, idx;
684 int64_t now, then, sum_sz = 0, avg_bitrate;
685
686 now = pkt->data.frame.pts * 1000
687 * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den;
688
689 idx = hist->frames++ % hist->samples;
690 hist->pts[idx] = now;
691 hist->sz[idx] = (int)pkt->data.frame.sz;
692
693 if (now < cfg->rc_buf_initial_sz)
694 return;
695
696 then = now;
697
698 /* Sum the size over the past rc_buf_sz ms */
699 for (i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--) {
700 int i_idx = (i - 1) % hist->samples;
701
702 then = hist->pts[i_idx];
703 if (now - then > cfg->rc_buf_sz)
704 break;
705 sum_sz += hist->sz[i_idx];
706 }
707
708 if (now == then)
709 return;
710
711 avg_bitrate = sum_sz * 8 * 1000 / (now - then);
712 idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
713 if (idx < 0)
714 idx = 0;
715 if (idx > RATE_BINS - 1)
716 idx = RATE_BINS - 1;
717 if (hist->bucket[idx].low > avg_bitrate)
718 hist->bucket[idx].low = (int)avg_bitrate;
719 if (hist->bucket[idx].high < avg_bitrate)
720 hist->bucket[idx].high = (int)avg_bitrate;
721 hist->bucket[idx].count++;
722 hist->total++;
723 }
724
725
726 static void show_rate_histogram(struct rate_hist *hist,
727 const vpx_codec_enc_cfg_t *cfg,
728 int max_buckets) {
729 int i, scale;
730 int buckets = 0;
731
732 for (i = 0; i < RATE_BINS; i++) {
733 if (hist->bucket[i].low == INT_MAX)
734 continue;
735 hist->bucket[buckets++] = hist->bucket[i];
736 }
737
738 fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz);
739 scale = merge_hist_buckets(hist->bucket, &buckets, max_buckets);
740 show_histogram(hist->bucket, buckets, hist->total, scale);
741 }
742
743 #define mmin(a, b) ((a) < (b) ? (a) : (b)) 458 #define mmin(a, b) ((a) < (b) ? (a) : (b))
744 static void find_mismatch(vpx_image_t *img1, vpx_image_t *img2, 459 static void find_mismatch(const vpx_image_t *const img1,
460 const vpx_image_t *const img2,
745 int yloc[4], int uloc[4], int vloc[4]) { 461 int yloc[4], int uloc[4], int vloc[4]) {
746 const unsigned int bsize = 64; 462 const uint32_t bsize = 64;
747 const unsigned int bsizey = bsize >> img1->y_chroma_shift; 463 const uint32_t bsizey = bsize >> img1->y_chroma_shift;
748 const unsigned int bsizex = bsize >> img1->x_chroma_shift; 464 const uint32_t bsizex = bsize >> img1->x_chroma_shift;
749 const int c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; 465 const uint32_t c_w =
750 const int c_h = (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; 466 (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
751 unsigned int match = 1; 467 const uint32_t c_h =
752 unsigned int i, j; 468 (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
469 int match = 1;
470 uint32_t i, j;
753 yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1; 471 yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
754 for (i = 0, match = 1; match && i < img1->d_h; i += bsize) { 472 for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
755 for (j = 0; match && j < img1->d_w; j += bsize) { 473 for (j = 0; match && j < img1->d_w; j += bsize) {
756 int k, l; 474 int k, l;
757 int si = mmin(i + bsize, img1->d_h) - i; 475 const int si = mmin(i + bsize, img1->d_h) - i;
758 int sj = mmin(j + bsize, img1->d_w) - j; 476 const int sj = mmin(j + bsize, img1->d_w) - j;
759 for (k = 0; match && k < si; k++) 477 for (k = 0; match && k < si; ++k) {
760 for (l = 0; match && l < sj; l++) { 478 for (l = 0; match && l < sj; ++l) {
761 if (*(img1->planes[VPX_PLANE_Y] + 479 if (*(img1->planes[VPX_PLANE_Y] +
762 (i + k) * img1->stride[VPX_PLANE_Y] + j + l) != 480 (i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
763 *(img2->planes[VPX_PLANE_Y] + 481 *(img2->planes[VPX_PLANE_Y] +
764 (i + k) * img2->stride[VPX_PLANE_Y] + j + l)) { 482 (i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
765 yloc[0] = i + k; 483 yloc[0] = i + k;
766 yloc[1] = j + l; 484 yloc[1] = j + l;
767 yloc[2] = *(img1->planes[VPX_PLANE_Y] + 485 yloc[2] = *(img1->planes[VPX_PLANE_Y] +
768 (i + k) * img1->stride[VPX_PLANE_Y] + j + l); 486 (i + k) * img1->stride[VPX_PLANE_Y] + j + l);
769 yloc[3] = *(img2->planes[VPX_PLANE_Y] + 487 yloc[3] = *(img2->planes[VPX_PLANE_Y] +
770 (i + k) * img2->stride[VPX_PLANE_Y] + j + l); 488 (i + k) * img2->stride[VPX_PLANE_Y] + j + l);
771 match = 0; 489 match = 0;
772 break; 490 break;
773 } 491 }
774 } 492 }
493 }
775 } 494 }
776 } 495 }
777 496
778 uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1; 497 uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
779 for (i = 0, match = 1; match && i < c_h; i += bsizey) { 498 for (i = 0, match = 1; match && i < c_h; i += bsizey) {
780 for (j = 0; match && j < c_w; j += bsizex) { 499 for (j = 0; match && j < c_w; j += bsizex) {
781 int k, l; 500 int k, l;
782 int si = mmin(i + bsizey, c_h - i); 501 const int si = mmin(i + bsizey, c_h - i);
783 int sj = mmin(j + bsizex, c_w - j); 502 const int sj = mmin(j + bsizex, c_w - j);
784 for (k = 0; match && k < si; k++) 503 for (k = 0; match && k < si; ++k) {
785 for (l = 0; match && l < sj; l++) { 504 for (l = 0; match && l < sj; ++l) {
786 if (*(img1->planes[VPX_PLANE_U] + 505 if (*(img1->planes[VPX_PLANE_U] +
787 (i + k) * img1->stride[VPX_PLANE_U] + j + l) != 506 (i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
788 *(img2->planes[VPX_PLANE_U] + 507 *(img2->planes[VPX_PLANE_U] +
789 (i + k) * img2->stride[VPX_PLANE_U] + j + l)) { 508 (i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
790 uloc[0] = i + k; 509 uloc[0] = i + k;
791 uloc[1] = j + l; 510 uloc[1] = j + l;
792 uloc[2] = *(img1->planes[VPX_PLANE_U] + 511 uloc[2] = *(img1->planes[VPX_PLANE_U] +
793 (i + k) * img1->stride[VPX_PLANE_U] + j + l); 512 (i + k) * img1->stride[VPX_PLANE_U] + j + l);
794 uloc[3] = *(img2->planes[VPX_PLANE_U] + 513 uloc[3] = *(img2->planes[VPX_PLANE_U] +
795 (i + k) * img2->stride[VPX_PLANE_V] + j + l); 514 (i + k) * img2->stride[VPX_PLANE_U] + j + l);
796 match = 0; 515 match = 0;
797 break; 516 break;
798 } 517 }
799 } 518 }
519 }
800 } 520 }
801 } 521 }
802 vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1; 522 vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
803 for (i = 0, match = 1; match && i < c_h; i += bsizey) { 523 for (i = 0, match = 1; match && i < c_h; i += bsizey) {
804 for (j = 0; match && j < c_w; j += bsizex) { 524 for (j = 0; match && j < c_w; j += bsizex) {
805 int k, l; 525 int k, l;
806 int si = mmin(i + bsizey, c_h - i); 526 const int si = mmin(i + bsizey, c_h - i);
807 int sj = mmin(j + bsizex, c_w - j); 527 const int sj = mmin(j + bsizex, c_w - j);
808 for (k = 0; match && k < si; k++) 528 for (k = 0; match && k < si; ++k) {
809 for (l = 0; match && l < sj; l++) { 529 for (l = 0; match && l < sj; ++l) {
810 if (*(img1->planes[VPX_PLANE_V] + 530 if (*(img1->planes[VPX_PLANE_V] +
811 (i + k) * img1->stride[VPX_PLANE_V] + j + l) != 531 (i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
812 *(img2->planes[VPX_PLANE_V] + 532 *(img2->planes[VPX_PLANE_V] +
813 (i + k) * img2->stride[VPX_PLANE_V] + j + l)) { 533 (i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
814 vloc[0] = i + k; 534 vloc[0] = i + k;
815 vloc[1] = j + l; 535 vloc[1] = j + l;
816 vloc[2] = *(img1->planes[VPX_PLANE_V] + 536 vloc[2] = *(img1->planes[VPX_PLANE_V] +
817 (i + k) * img1->stride[VPX_PLANE_V] + j + l); 537 (i + k) * img1->stride[VPX_PLANE_V] + j + l);
818 vloc[3] = *(img2->planes[VPX_PLANE_V] + 538 vloc[3] = *(img2->planes[VPX_PLANE_V] +
819 (i + k) * img2->stride[VPX_PLANE_V] + j + l); 539 (i + k) * img2->stride[VPX_PLANE_V] + j + l);
820 match = 0; 540 match = 0;
821 break; 541 break;
822 } 542 }
823 } 543 }
544 }
824 } 545 }
825 } 546 }
826 } 547 }
827 548
828 static int compare_img(vpx_image_t *img1, vpx_image_t *img2) 549 static int compare_img(const vpx_image_t *const img1,
829 { 550 const vpx_image_t *const img2) {
830 const int c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; 551 const uint32_t c_w =
831 const int c_h = (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; 552 (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
553 const uint32_t c_h =
554 (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
555 uint32_t i;
832 int match = 1; 556 int match = 1;
833 unsigned int i;
834 557
835 match &= (img1->fmt == img2->fmt); 558 match &= (img1->fmt == img2->fmt);
836 match &= (img1->d_w == img2->d_w); 559 match &= (img1->d_w == img2->d_w);
837 match &= (img1->d_h == img2->d_h); 560 match &= (img1->d_h == img2->d_h);
838 561
839 for (i = 0; i < img1->d_h; i++) 562 for (i = 0; i < img1->d_h; ++i)
840 match &= (memcmp(img1->planes[VPX_PLANE_Y]+i*img1->stride[VPX_PLANE_Y], 563 match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
841 img2->planes[VPX_PLANE_Y]+i*img2->stride[VPX_PLANE_Y], 564 img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
842 img1->d_w) == 0); 565 img1->d_w) == 0);
843 566
844 for (i = 0; i < c_h; i++) 567 for (i = 0; i < c_h; ++i)
845 match &= (memcmp(img1->planes[VPX_PLANE_U]+i*img1->stride[VPX_PLANE_U], 568 match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
846 img2->planes[VPX_PLANE_U]+i*img2->stride[VPX_PLANE_U], 569 img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
847 c_w) == 0); 570 c_w) == 0);
848 571
849 for (i = 0; i < c_h; i++) 572 for (i = 0; i < c_h; ++i)
850 match &= (memcmp(img1->planes[VPX_PLANE_V]+i*img1->stride[VPX_PLANE_U], 573 match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
851 img2->planes[VPX_PLANE_V]+i*img2->stride[VPX_PLANE_U], 574 img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
852 c_w) == 0); 575 c_w) == 0);
853 576
854 return match; 577 return match;
855 } 578 }
856 579
857 580
858 #define NELEMENTS(x) (sizeof(x)/sizeof(x[0])) 581 #define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
859 #define MAX(x,y) ((x)>(y)?(x):(y)) 582 #define MAX(x,y) ((x)>(y)?(x):(y))
860 #if CONFIG_VP8_ENCODER && !CONFIG_VP9_ENCODER 583 #if CONFIG_VP8_ENCODER && !CONFIG_VP9_ENCODER
861 #define ARG_CTRL_CNT_MAX NELEMENTS(vp8_arg_ctrl_map) 584 #define ARG_CTRL_CNT_MAX NELEMENTS(vp8_arg_ctrl_map)
(...skipping 15 matching lines...) Expand all
877 int write_webm; 600 int write_webm;
878 int have_kf_max_dist; 601 int have_kf_max_dist;
879 }; 602 };
880 603
881 604
882 struct stream_state { 605 struct stream_state {
883 int index; 606 int index;
884 struct stream_state *next; 607 struct stream_state *next;
885 struct stream_config config; 608 struct stream_config config;
886 FILE *file; 609 FILE *file;
887 struct rate_hist rate_hist; 610 struct rate_hist *rate_hist;
888 struct EbmlGlobal ebml; 611 struct EbmlGlobal ebml;
889 uint32_t hash; 612 uint32_t hash;
890 uint64_t psnr_sse_total; 613 uint64_t psnr_sse_total;
891 uint64_t psnr_samples_total; 614 uint64_t psnr_samples_total;
892 double psnr_totals[4]; 615 double psnr_totals[4];
893 int psnr_count; 616 int psnr_count;
894 int counts[64]; 617 int counts[64];
895 vpx_codec_ctx_t encoder; 618 vpx_codec_ctx_t encoder;
896 unsigned int frames_out; 619 unsigned int frames_out;
897 uint64_t cx_time; 620 uint64_t cx_time;
(...skipping 19 matching lines...) Expand all
917 die("Error: %s has zero denominator\n", msg); 640 die("Error: %s has zero denominator\n", msg);
918 } 641 }
919 642
920 643
921 static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { 644 static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
922 char **argi, **argj; 645 char **argi, **argj;
923 struct arg arg; 646 struct arg arg;
924 647
925 /* Initialize default parameters */ 648 /* Initialize default parameters */
926 memset(global, 0, sizeof(*global)); 649 memset(global, 0, sizeof(*global));
927 global->codec = codecs; 650 global->codec = get_vpx_encoder_by_index(0);
928 global->passes = 0; 651 global->passes = 0;
929 global->use_i420 = 1; 652 global->use_i420 = 1;
930 /* Assign default deadline to good quality */ 653 /* Assign default deadline to good quality */
931 global->deadline = VPX_DL_GOOD_QUALITY; 654 global->deadline = VPX_DL_GOOD_QUALITY;
932 655
933 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { 656 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
934 arg.argv_step = 1; 657 arg.argv_step = 1;
935 658
936 if (arg_match(&arg, &codecarg, argi)) { 659 if (arg_match(&arg, &codecarg, argi)) {
937 int j, k = -1; 660 global->codec = get_vpx_encoder_by_name(arg.val);
938 661 if (!global->codec)
939 for (j = 0; j < sizeof(codecs) / sizeof(codecs[0]); j++) 662 die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
940 if (!strcmp(codecs[j].name, arg.val))
941 k = j;
942
943 if (k >= 0)
944 global->codec = codecs + k;
945 else
946 die("Error: Unrecognized argument (%s) to --codec\n",
947 arg.val);
948
949 } else if (arg_match(&arg, &passes, argi)) { 663 } else if (arg_match(&arg, &passes, argi)) {
950 global->passes = arg_parse_uint(&arg); 664 global->passes = arg_parse_uint(&arg);
951 665
952 if (global->passes < 1 || global->passes > 2) 666 if (global->passes < 1 || global->passes > 2)
953 die("Error: Invalid number of passes (%d)\n", global->passes); 667 die("Error: Invalid number of passes (%d)\n", global->passes);
954 } else if (arg_match(&arg, &pass_arg, argi)) { 668 } else if (arg_match(&arg, &pass_arg, argi)) {
955 global->pass = arg_parse_uint(&arg); 669 global->pass = arg_parse_uint(&arg);
956 670
957 if (global->pass < 1 || global->pass > 2) 671 if (global->pass < 1 || global->pass > 2)
958 die("Error: Invalid pass selected (%d)\n", 672 die("Error: Invalid pass selected (%d)\n",
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 global->disable_warning_prompt = 1; 715 global->disable_warning_prompt = 1;
1002 else 716 else
1003 argj++; 717 argj++;
1004 } 718 }
1005 719
1006 /* Validate global config */ 720 /* Validate global config */
1007 if (global->passes == 0) { 721 if (global->passes == 0) {
1008 #if CONFIG_VP9_ENCODER 722 #if CONFIG_VP9_ENCODER
1009 // Make default VP9 passes = 2 until there is a better quality 1-pass 723 // Make default VP9 passes = 2 until there is a better quality 1-pass
1010 // encoder 724 // encoder
1011 global->passes = (global->codec->iface == vpx_codec_vp9_cx ? 2 : 1); 725 global->passes = strcmp(global->codec->name, "vp9") == 0 ? 2 : 1;
1012 #else 726 #else
1013 global->passes = 1; 727 global->passes = 1;
1014 #endif 728 #endif
1015 } 729 }
1016 730
1017 if (global->pass) { 731 if (global->pass) {
1018 /* DWIM: Assume the user meant passes=2 if pass=2 is specified */ 732 /* DWIM: Assume the user meant passes=2 if pass=2 is specified */
1019 if (global->pass > global->passes) { 733 if (global->pass > global->passes) {
1020 warn("Assuming --pass=%d implies --passes=%d\n", 734 warn("Assuming --pass=%d implies --passes=%d\n",
1021 global->pass, global->pass); 735 global->pass, global->pass);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 if (!stream) 795 if (!stream)
1082 fatal("Failed to allocate new stream."); 796 fatal("Failed to allocate new stream.");
1083 if (prev) { 797 if (prev) {
1084 memcpy(stream, prev, sizeof(*stream)); 798 memcpy(stream, prev, sizeof(*stream));
1085 stream->index++; 799 stream->index++;
1086 prev->next = stream; 800 prev->next = stream;
1087 } else { 801 } else {
1088 vpx_codec_err_t res; 802 vpx_codec_err_t res;
1089 803
1090 /* Populate encoder configuration */ 804 /* Populate encoder configuration */
1091 res = vpx_codec_enc_config_default(global->codec->iface(), 805 res = vpx_codec_enc_config_default(global->codec->interface(),
1092 &stream->config.cfg, 806 &stream->config.cfg,
1093 global->usage); 807 global->usage);
1094 if (res) 808 if (res)
1095 fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res)); 809 fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res));
1096 810
1097 /* Change the default timebase to a high enough value so that the 811 /* Change the default timebase to a high enough value so that the
1098 * encoder will always create strictly increasing timestamps. 812 * encoder will always create strictly increasing timestamps.
1099 */ 813 */
1100 stream->config.cfg.g_timebase.den = 1000; 814 stream->config.cfg.g_timebase.den = 1000;
1101 815
(...skipping 23 matching lines...) Expand all
1125 static int parse_stream_params(struct VpxEncoderConfig *global, 839 static int parse_stream_params(struct VpxEncoderConfig *global,
1126 struct stream_state *stream, 840 struct stream_state *stream,
1127 char **argv) { 841 char **argv) {
1128 char **argi, **argj; 842 char **argi, **argj;
1129 struct arg arg; 843 struct arg arg;
1130 static const arg_def_t **ctrl_args = no_args; 844 static const arg_def_t **ctrl_args = no_args;
1131 static const int *ctrl_args_map = NULL; 845 static const int *ctrl_args_map = NULL;
1132 struct stream_config *config = &stream->config; 846 struct stream_config *config = &stream->config;
1133 int eos_mark_found = 0; 847 int eos_mark_found = 0;
1134 848
1135 /* Handle codec specific options */ 849 // Handle codec specific options
1136 if (0) { 850 if (0) {
1137 #if CONFIG_VP8_ENCODER 851 #if CONFIG_VP8_ENCODER
1138 } else if (global->codec->iface == vpx_codec_vp8_cx) { 852 } else if (strcmp(global->codec->name, "vp8") == 0) {
1139 ctrl_args = vp8_args; 853 ctrl_args = vp8_args;
1140 ctrl_args_map = vp8_arg_ctrl_map; 854 ctrl_args_map = vp8_arg_ctrl_map;
1141 #endif 855 #endif
1142 #if CONFIG_VP9_ENCODER 856 #if CONFIG_VP9_ENCODER
1143 } else if (global->codec->iface == vpx_codec_vp9_cx) { 857 } else if (strcmp(global->codec->name, "vp9") == 0) {
1144 ctrl_args = vp9_args; 858 ctrl_args = vp9_args;
1145 ctrl_args_map = vp9_arg_ctrl_map; 859 ctrl_args_map = vp9_arg_ctrl_map;
1146 #endif 860 #endif
1147 } 861 }
1148 862
1149 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { 863 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
1150 arg.argv_step = 1; 864 arg.argv_step = 1;
1151 865
1152 /* Once we've found an end-of-stream marker (--) we want to continue 866 /* Once we've found an end-of-stream marker (--) we want to continue
1153 * shifting arguments but not consuming them. 867 * shifting arguments but not consuming them.
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 1055
1342 static void show_stream_config(struct stream_state *stream, 1056 static void show_stream_config(struct stream_state *stream,
1343 struct VpxEncoderConfig *global, 1057 struct VpxEncoderConfig *global,
1344 struct VpxInputContext *input) { 1058 struct VpxInputContext *input) {
1345 1059
1346 #define SHOW(field) \ 1060 #define SHOW(field) \
1347 fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field) 1061 fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field)
1348 1062
1349 if (stream->index == 0) { 1063 if (stream->index == 0) {
1350 fprintf(stderr, "Codec: %s\n", 1064 fprintf(stderr, "Codec: %s\n",
1351 vpx_codec_iface_name(global->codec->iface())); 1065 vpx_codec_iface_name(global->codec->interface()));
1352 fprintf(stderr, "Source file: %s Format: %s\n", input->filename, 1066 fprintf(stderr, "Source file: %s Format: %s\n", input->filename,
1353 input->use_i420 ? "I420" : "YV12"); 1067 input->use_i420 ? "I420" : "YV12");
1354 } 1068 }
1355 if (stream->next || stream->index) 1069 if (stream->next || stream->index)
1356 fprintf(stderr, "\nStream Index: %d\n", stream->index); 1070 fprintf(stderr, "\nStream Index: %d\n", stream->index);
1357 fprintf(stderr, "Destination file: %s\n", stream->config.out_fn); 1071 fprintf(stderr, "Destination file: %s\n", stream->config.out_fn);
1358 fprintf(stderr, "Encoder parameters:\n"); 1072 fprintf(stderr, "Encoder parameters:\n");
1359 1073
1360 SHOW(g_usage); 1074 SHOW(g_usage);
1361 SHOW(g_threads); 1075 SHOW(g_threads);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 1179
1466 static void initialize_encoder(struct stream_state *stream, 1180 static void initialize_encoder(struct stream_state *stream,
1467 struct VpxEncoderConfig *global) { 1181 struct VpxEncoderConfig *global) {
1468 int i; 1182 int i;
1469 int flags = 0; 1183 int flags = 0;
1470 1184
1471 flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0; 1185 flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0;
1472 flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; 1186 flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0;
1473 1187
1474 /* Construct Encoder Context */ 1188 /* Construct Encoder Context */
1475 vpx_codec_enc_init(&stream->encoder, global->codec->iface(), 1189 vpx_codec_enc_init(&stream->encoder, global->codec->interface(),
1476 &stream->config.cfg, flags); 1190 &stream->config.cfg, flags);
1477 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); 1191 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder");
1478 1192
1479 /* Note that we bypass the vpx_codec_control wrapper macro because 1193 /* Note that we bypass the vpx_codec_control wrapper macro because
1480 * we're being clever to store the control IDs in an array. Real 1194 * we're being clever to store the control IDs in an array. Real
1481 * applications will want to make use of the enumerations directly 1195 * applications will want to make use of the enumerations directly
1482 */ 1196 */
1483 for (i = 0; i < stream->config.arg_ctrl_cnt; i++) { 1197 for (i = 0; i < stream->config.arg_ctrl_cnt; i++) {
1484 int ctrl = stream->config.arg_ctrls[i][0]; 1198 int ctrl = stream->config.arg_ctrls[i][0];
1485 int value = stream->config.arg_ctrls[i][1]; 1199 int value = stream->config.arg_ctrls[i][1];
1486 if (vpx_codec_control_(&stream->encoder, ctrl, value)) 1200 if (vpx_codec_control_(&stream->encoder, ctrl, value))
1487 fprintf(stderr, "Error: Tried to set control %d = %d\n", 1201 fprintf(stderr, "Error: Tried to set control %d = %d\n",
1488 ctrl, value); 1202 ctrl, value);
1489 1203
1490 ctx_exit_on_error(&stream->encoder, "Failed to control codec"); 1204 ctx_exit_on_error(&stream->encoder, "Failed to control codec");
1491 } 1205 }
1492 1206
1493 #if CONFIG_DECODERS 1207 #if CONFIG_DECODERS
1494 if (global->test_decode != TEST_DECODE_OFF) { 1208 if (global->test_decode != TEST_DECODE_OFF) {
1495 vpx_codec_dec_init(&stream->decoder, global->codec->dx_iface(), NULL, 0); 1209 const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name);
1210 vpx_codec_dec_init(&stream->decoder, decoder->interface(), NULL, 0);
1496 } 1211 }
1497 #endif 1212 #endif
1498 } 1213 }
1499 1214
1500 1215
1501 static void encode_frame(struct stream_state *stream, 1216 static void encode_frame(struct stream_state *stream,
1502 struct VpxEncoderConfig *global, 1217 struct VpxEncoderConfig *global,
1503 struct vpx_image *img, 1218 struct vpx_image *img,
1504 unsigned int frames_in) { 1219 unsigned int frames_in) {
1505 vpx_codec_pts_t frame_start, next_frame_start; 1220 vpx_codec_pts_t frame_start, next_frame_start;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 static off_t ivf_header_pos = 0; 1284 static off_t ivf_header_pos = 0;
1570 1285
1571 switch (pkt->kind) { 1286 switch (pkt->kind) {
1572 case VPX_CODEC_CX_FRAME_PKT: 1287 case VPX_CODEC_CX_FRAME_PKT:
1573 if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { 1288 if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
1574 stream->frames_out++; 1289 stream->frames_out++;
1575 } 1290 }
1576 if (!global->quiet) 1291 if (!global->quiet)
1577 fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz); 1292 fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz);
1578 1293
1579 update_rate_histogram(&stream->rate_hist, cfg, pkt); 1294 update_rate_histogram(stream->rate_hist, cfg, pkt);
1580 if (stream->config.write_webm) { 1295 if (stream->config.write_webm) {
1581 /* Update the hash */ 1296 /* Update the hash */
1582 if (!stream->ebml.debug) 1297 if (!stream->ebml.debug)
1583 stream->hash = murmur(pkt->data.frame.buf, 1298 stream->hash = murmur(pkt->data.frame.buf,
1584 (int)pkt->data.frame.sz, 1299 (int)pkt->data.frame.sz,
1585 stream->hash); 1300 stream->hash);
1586 1301
1587 write_webm_block(&stream->ebml, cfg, pkt); 1302 write_webm_block(&stream->ebml, cfg, pkt);
1588 } else { 1303 } else {
1589 if (pkt->data.frame.partition_id <= 0) { 1304 if (pkt->data.frame.partition_id <= 0) {
1590 ivf_header_pos = ftello(stream->file); 1305 ivf_header_pos = ftello(stream->file);
1591 fsize = pkt->data.frame.sz; 1306 fsize = pkt->data.frame.sz;
1592 1307
1593 ivf_write_frame_header(stream->file, pkt); 1308 ivf_write_frame_header(stream->file, pkt->data.frame.pts, fsize);
1594 } else { 1309 } else {
1595 fsize += pkt->data.frame.sz; 1310 fsize += pkt->data.frame.sz;
1596 1311
1597 if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { 1312 if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
1598 off_t currpos = ftello(stream->file); 1313 off_t currpos = ftello(stream->file);
1599 fseeko(stream->file, ivf_header_pos, SEEK_SET); 1314 fseeko(stream->file, ivf_header_pos, SEEK_SET);
1600 ivf_write_frame_size(stream->file, fsize); 1315 ivf_write_frame_size(stream->file, fsize);
1601 fseeko(stream->file, currpos, SEEK_SET); 1316 fseeko(stream->file, currpos, SEEK_SET);
1602 } 1317 }
1603 } 1318 }
1604 1319
1605 (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, 1320 (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
1606 stream->file); 1321 stream->file);
1607 } 1322 }
1608 stream->nbytes += pkt->data.raw.sz; 1323 stream->nbytes += pkt->data.raw.sz;
1609 1324
1610 *got_data = 1; 1325 *got_data = 1;
1611 #if CONFIG_DECODERS 1326 #if CONFIG_DECODERS
1612 if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) { 1327 if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) {
1613 vpx_codec_decode(&stream->decoder, pkt->data.frame.buf, 1328 vpx_codec_decode(&stream->decoder, pkt->data.frame.buf,
1614 pkt->data.frame.sz, NULL, 0); 1329 (unsigned int)pkt->data.frame.sz, NULL, 0);
1615 if (stream->decoder.err) { 1330 if (stream->decoder.err) {
1616 warn_or_exit_on_error(&stream->decoder, 1331 warn_or_exit_on_error(&stream->decoder,
1617 global->test_decode == TEST_DECODE_FATAL, 1332 global->test_decode == TEST_DECODE_FATAL,
1618 "Failed to decode frame %d in stream %d", 1333 "Failed to decode frame %d in stream %d",
1619 stream->frames_out + 1, stream->index); 1334 stream->frames_out + 1, stream->index);
1620 stream->mismatch_seen = stream->frames_out + 1; 1335 stream->mismatch_seen = stream->frames_out + 1;
1621 } 1336 }
1622 } 1337 }
1623 #endif 1338 #endif
1624 break; 1339 break;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 } 1386 }
1672 1387
1673 1388
1674 static float usec_to_fps(uint64_t usec, unsigned int frames) { 1389 static float usec_to_fps(uint64_t usec, unsigned int frames) {
1675 return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0); 1390 return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0);
1676 } 1391 }
1677 1392
1678 1393
1679 static void test_decode(struct stream_state *stream, 1394 static void test_decode(struct stream_state *stream,
1680 enum TestDecodeFatality fatal, 1395 enum TestDecodeFatality fatal,
1681 const struct codec_item *codec) { 1396 const VpxInterface *codec) {
1682 vpx_image_t enc_img, dec_img; 1397 vpx_image_t enc_img, dec_img;
1683 1398
1684 if (stream->mismatch_seen) 1399 if (stream->mismatch_seen)
1685 return; 1400 return;
1686 1401
1687 /* Get the internal reference frame */ 1402 /* Get the internal reference frame */
1688 if (codec->fourcc == VP8_FOURCC) { 1403 if (strcmp(codec->name, "vp8") == 0) {
1689 struct vpx_ref_frame ref_enc, ref_dec; 1404 struct vpx_ref_frame ref_enc, ref_dec;
1690 int width, height; 1405 int width, height;
1691 1406
1692 width = (stream->config.cfg.g_w + 15) & ~15; 1407 width = (stream->config.cfg.g_w + 15) & ~15;
1693 height = (stream->config.cfg.g_h + 15) & ~15; 1408 height = (stream->config.cfg.g_h + 15) & ~15;
1694 vpx_img_alloc(&ref_enc.img, VPX_IMG_FMT_I420, width, height, 1); 1409 vpx_img_alloc(&ref_enc.img, VPX_IMG_FMT_I420, width, height, 1);
1695 enc_img = ref_enc.img; 1410 enc_img = ref_enc.img;
1696 vpx_img_alloc(&ref_dec.img, VPX_IMG_FMT_I420, width, height, 1); 1411 vpx_img_alloc(&ref_dec.img, VPX_IMG_FMT_I420, width, height, 1);
1697 dec_img = ref_dec.img; 1412 dec_img = ref_dec.img;
1698 1413
(...skipping 28 matching lines...) Expand all
1727 v[0], v[1], v[2], v[3]); 1442 v[0], v[1], v[2], v[3]);
1728 stream->mismatch_seen = stream->frames_out; 1443 stream->mismatch_seen = stream->frames_out;
1729 } 1444 }
1730 1445
1731 vpx_img_free(&enc_img); 1446 vpx_img_free(&enc_img);
1732 vpx_img_free(&dec_img); 1447 vpx_img_free(&dec_img);
1733 } 1448 }
1734 1449
1735 1450
1736 static void print_time(const char *label, int64_t etl) { 1451 static void print_time(const char *label, int64_t etl) {
1737 int hours, mins, secs; 1452 int64_t hours;
1453 int64_t mins;
1454 int64_t secs;
1738 1455
1739 if (etl >= 0) { 1456 if (etl >= 0) {
1740 hours = etl / 3600; 1457 hours = etl / 3600;
1741 etl -= hours * 3600; 1458 etl -= hours * 3600;
1742 mins = etl / 60; 1459 mins = etl / 60;
1743 etl -= mins * 60; 1460 etl -= mins * 60;
1744 secs = etl; 1461 secs = etl;
1745 1462
1746 fprintf(stderr, "[%3s %2d:%02d:%02d] ", 1463 fprintf(stderr, "[%3s %2"PRId64":%02"PRId64": % 02"PRId64"] ",
1747 label, hours, mins, secs); 1464 label, hours, mins, secs);
1748 } else { 1465 } else {
1749 fprintf(stderr, "[%3s unknown] ", label); 1466 fprintf(stderr, "[%3s unknown] ", label);
1750 } 1467 }
1751 } 1468 }
1752 1469
1753 1470
1754 int main(int argc, const char **argv_) { 1471 int main(int argc, const char **argv_) {
1755 int pass; 1472 int pass;
1756 vpx_image_t raw; 1473 vpx_image_t raw;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 /*The Y4M reader does its own allocation. 1591 /*The Y4M reader does its own allocation.
1875 Just initialize this here to avoid problems if we never read any 1592 Just initialize this here to avoid problems if we never read any
1876 frames.*/ 1593 frames.*/
1877 memset(&raw, 0, sizeof(raw)); 1594 memset(&raw, 0, sizeof(raw));
1878 else 1595 else
1879 vpx_img_alloc(&raw, 1596 vpx_img_alloc(&raw,
1880 input.use_i420 ? VPX_IMG_FMT_I420 1597 input.use_i420 ? VPX_IMG_FMT_I420
1881 : VPX_IMG_FMT_YV12, 1598 : VPX_IMG_FMT_YV12,
1882 input.width, input.height, 32); 1599 input.width, input.height, 32);
1883 1600
1884 FOREACH_STREAM(init_rate_histogram(&stream->rate_hist, 1601 FOREACH_STREAM(stream->rate_hist =
1885 &stream->config.cfg, 1602 init_rate_histogram(&stream->config.cfg,
1886 &global.framerate)); 1603 &global.framerate));
1887 } 1604 }
1888 1605
1889 FOREACH_STREAM(setup_pass(stream, &global, pass)); 1606 FOREACH_STREAM(setup_pass(stream, &global, pass));
1890 FOREACH_STREAM(open_output_file(stream, &global)); 1607 FOREACH_STREAM(open_output_file(stream, &global));
1891 FOREACH_STREAM(initialize_encoder(stream, &global)); 1608 FOREACH_STREAM(initialize_encoder(stream, &global));
1892 1609
1893 frame_avail = 1; 1610 frame_avail = 1;
1894 got_data = 0; 1611 got_data = 0;
1895 1612
1896 while (frame_avail || got_data) { 1613 while (frame_avail || got_data) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 got_data = 0; 1657 got_data = 0;
1941 FOREACH_STREAM(get_cx_data(stream, &global, &got_data)); 1658 FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
1942 1659
1943 if (!got_data && input.length && !streams->frames_out) { 1660 if (!got_data && input.length && !streams->frames_out) {
1944 lagged_count = global.limit ? seen_frames : ftello(input.file); 1661 lagged_count = global.limit ? seen_frames : ftello(input.file);
1945 } else if (input.length) { 1662 } else if (input.length) {
1946 int64_t remaining; 1663 int64_t remaining;
1947 int64_t rate; 1664 int64_t rate;
1948 1665
1949 if (global.limit) { 1666 if (global.limit) {
1950 int frame_in_lagged = (seen_frames - lagged_count) * 1000; 1667 off_t frame_in_lagged = (seen_frames - lagged_count) * 1000;
1951 1668
1952 rate = cx_time ? frame_in_lagged * (int64_t)1000000 / cx_time : 0; 1669 rate = cx_time ? frame_in_lagged * (int64_t)1000000 / cx_time : 0;
1953 remaining = 1000 * (global.limit - global.skip_frames 1670 remaining = 1000 * (global.limit - global.skip_frames
1954 - seen_frames + lagged_count); 1671 - seen_frames + lagged_count);
1955 } else { 1672 } else {
1956 off_t input_pos = ftello(input.file); 1673 off_t input_pos = ftello(input.file);
1957 off_t input_pos_lagged = input_pos - lagged_count; 1674 off_t input_pos_lagged = input_pos - lagged_count;
1958 int64_t limit = input.length; 1675 int64_t limit = input.length;
1959 1676
1960 rate = cx_time ? input_pos_lagged * (int64_t)1000000 / cx_time : 0; 1677 rate = cx_time ? input_pos_lagged * (int64_t)1000000 / cx_time : 0;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 1730
2014 if (global.pass) 1731 if (global.pass)
2015 break; 1732 break;
2016 } 1733 }
2017 1734
2018 if (global.show_q_hist_buckets) 1735 if (global.show_q_hist_buckets)
2019 FOREACH_STREAM(show_q_histogram(stream->counts, 1736 FOREACH_STREAM(show_q_histogram(stream->counts,
2020 global.show_q_hist_buckets)); 1737 global.show_q_hist_buckets));
2021 1738
2022 if (global.show_rate_hist_buckets) 1739 if (global.show_rate_hist_buckets)
2023 FOREACH_STREAM(show_rate_histogram(&stream->rate_hist, 1740 FOREACH_STREAM(show_rate_histogram(stream->rate_hist,
2024 &stream->config.cfg, 1741 &stream->config.cfg,
2025 global.show_rate_hist_buckets)); 1742 global.show_rate_hist_buckets));
2026 FOREACH_STREAM(destroy_rate_histogram(&stream->rate_hist)); 1743 FOREACH_STREAM(destroy_rate_histogram(stream->rate_hist));
2027 1744
2028 #if CONFIG_INTERNAL_STATS 1745 #if CONFIG_INTERNAL_STATS
2029 /* TODO(jkoleszar): This doesn't belong in this executable. Do it for now, 1746 /* TODO(jkoleszar): This doesn't belong in this executable. Do it for now,
2030 * to match some existing utilities. 1747 * to match some existing utilities.
2031 */ 1748 */
2032 if (!(global.pass == 1 && global.passes == 2)) 1749 if (!(global.pass == 1 && global.passes == 2))
2033 FOREACH_STREAM({ 1750 FOREACH_STREAM({
2034 FILE *f = fopen("opsnr.stt", "a"); 1751 FILE *f = fopen("opsnr.stt", "a");
2035 if (stream->mismatch_seen) { 1752 if (stream->mismatch_seen) {
2036 fprintf(f, "First mismatch occurred in frame %d\n", 1753 fprintf(f, "First mismatch occurred in frame %d\n",
2037 stream->mismatch_seen); 1754 stream->mismatch_seen);
2038 } else { 1755 } else {
2039 fprintf(f, "No mismatch detected in recon buffers\n"); 1756 fprintf(f, "No mismatch detected in recon buffers\n");
2040 } 1757 }
2041 fclose(f); 1758 fclose(f);
2042 }); 1759 });
2043 #endif 1760 #endif
2044 1761
2045 vpx_img_free(&raw); 1762 vpx_img_free(&raw);
2046 free(argv); 1763 free(argv);
2047 free(streams); 1764 free(streams);
2048 return res ? EXIT_FAILURE : EXIT_SUCCESS; 1765 return res ? EXIT_FAILURE : EXIT_SUCCESS;
2049 } 1766 }
OLDNEW
« no previous file with comments | « source/libvpx/vpxenc.h ('k') | source/libvpx/warnings.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698