| OLD | NEW | 
|---|
| 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 | 11 | 
| 12 /* This is a simple program that encodes YV12 files and generates ivf | 12 /* This is a simple program that encodes YV12 files and generates ivf | 
| 13  * files using the new interface. | 13  * files using the new interface. | 
| 14  */ | 14  */ | 
| 15 #if defined(_WIN32) || !CONFIG_OS_SUPPORT | 15 #if defined(_WIN32) || !CONFIG_OS_SUPPORT | 
| 16 #define USE_POSIX_MMAP 0 | 16 #define USE_POSIX_MMAP 0 | 
| 17 #else | 17 #else | 
| 18 #define USE_POSIX_MMAP 1 | 18 #define USE_POSIX_MMAP 1 | 
| 19 #endif | 19 #endif | 
| 20 | 20 | 
| 21 #include <stdio.h> | 21 #include <stdio.h> | 
| 22 #include <stdlib.h> | 22 #include <stdlib.h> | 
| 23 #include <stdarg.h> | 23 #include <stdarg.h> | 
| 24 #include <string.h> | 24 #include <string.h> | 
| 25 #include <limits.h> | 25 #include <limits.h> | 
|  | 26 #include <assert.h> | 
| 26 #include "vpx/vpx_encoder.h" | 27 #include "vpx/vpx_encoder.h" | 
| 27 #if USE_POSIX_MMAP | 28 #if USE_POSIX_MMAP | 
| 28 #include <sys/types.h> | 29 #include <sys/types.h> | 
| 29 #include <sys/stat.h> | 30 #include <sys/stat.h> | 
| 30 #include <sys/mman.h> | 31 #include <sys/mman.h> | 
| 31 #include <fcntl.h> | 32 #include <fcntl.h> | 
| 32 #include <unistd.h> | 33 #include <unistd.h> | 
| 33 #endif | 34 #endif | 
| 34 #include "vpx_version.h" | 35 #include "vpx_version.h" | 
| 35 #include "vpx/vp8cx.h" | 36 #include "vpx/vp8cx.h" | 
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 249         stats->buf.sz += len; | 250         stats->buf.sz += len; | 
| 250         stats->buf_ptr += len; | 251         stats->buf_ptr += len; | 
| 251     } | 252     } | 
| 252 } | 253 } | 
| 253 | 254 | 
| 254 vpx_fixed_buf_t stats_get(stats_io_t *stats) | 255 vpx_fixed_buf_t stats_get(stats_io_t *stats) | 
| 255 { | 256 { | 
| 256     return stats->buf; | 257     return stats->buf; | 
| 257 } | 258 } | 
| 258 | 259 | 
|  | 260 /* Stereo 3D packed frame format */ | 
|  | 261 typedef enum stereo_format | 
|  | 262 { | 
|  | 263     STEREO_FORMAT_MONO       = 0, | 
|  | 264     STEREO_FORMAT_LEFT_RIGHT = 1, | 
|  | 265     STEREO_FORMAT_BOTTOM_TOP = 2, | 
|  | 266     STEREO_FORMAT_TOP_BOTTOM = 3, | 
|  | 267     STEREO_FORMAT_RIGHT_LEFT = 11 | 
|  | 268 } stereo_format_t; | 
|  | 269 | 
| 259 enum video_file_type | 270 enum video_file_type | 
| 260 { | 271 { | 
| 261     FILE_TYPE_RAW, | 272     FILE_TYPE_RAW, | 
| 262     FILE_TYPE_IVF, | 273     FILE_TYPE_IVF, | 
| 263     FILE_TYPE_Y4M | 274     FILE_TYPE_Y4M | 
| 264 }; | 275 }; | 
| 265 | 276 | 
| 266 struct detect_buffer { | 277 struct detect_buffer { | 
| 267     char buf[4]; | 278     char buf[4]; | 
| 268     size_t buf_read; | 279     size_t buf_read; | 
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 483     unsigned int      cues; | 494     unsigned int      cues; | 
| 484 | 495 | 
| 485 }; | 496 }; | 
| 486 | 497 | 
| 487 | 498 | 
| 488 void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) | 499 void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) | 
| 489 { | 500 { | 
| 490     if(fwrite(buffer_in, 1, len, glob->stream)); | 501     if(fwrite(buffer_in, 1, len, glob->stream)); | 
| 491 } | 502 } | 
| 492 | 503 | 
|  | 504 #define WRITE_BUFFER(s) \ | 
|  | 505 for(i = len-1; i>=0; i--)\ | 
|  | 506 { \ | 
|  | 507     x = *(const s *)buffer_in >> (i * CHAR_BIT); \ | 
|  | 508     Ebml_Write(glob, &x, 1); \ | 
|  | 509 } | 
|  | 510 void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, un
      signed long len) | 
|  | 511 { | 
|  | 512     char x; | 
|  | 513     int i; | 
| 493 | 514 | 
| 494 void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) | 515     /* buffer_size: | 
| 495 { | 516      * 1 - int8_t; | 
| 496     const unsigned char *q = (const unsigned char *)buffer_in + len - 1; | 517      * 2 - int16_t; | 
|  | 518      * 3 - int32_t; | 
|  | 519      * 4 - int64_t; | 
|  | 520      */ | 
|  | 521     switch (buffer_size) | 
|  | 522     { | 
|  | 523         case 1: | 
|  | 524             WRITE_BUFFER(int8_t) | 
|  | 525             break; | 
|  | 526         case 2: | 
|  | 527             WRITE_BUFFER(int16_t) | 
|  | 528             break; | 
|  | 529         case 4: | 
|  | 530             WRITE_BUFFER(int32_t) | 
|  | 531             break; | 
|  | 532         case 8: | 
|  | 533             WRITE_BUFFER(int64_t) | 
|  | 534             break; | 
|  | 535         default: | 
|  | 536             break; | 
|  | 537     } | 
|  | 538 } | 
|  | 539 #undef WRITE_BUFFER | 
| 497 | 540 | 
| 498     for(; len; len--) | 541 /* Need a fixed size serializer for the track ID. libmkv provides a 64 bit | 
| 499         Ebml_Write(glob, q--, 1); |  | 
| 500 } |  | 
| 501 |  | 
| 502 |  | 
| 503 /* Need a fixed size serializer for the track ID. libmkv provdes a 64 bit |  | 
| 504  * one, but not a 32 bit one. | 542  * one, but not a 32 bit one. | 
| 505  */ | 543  */ | 
| 506 static void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, u
      int64_t ui) | 544 static void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, u
      int64_t ui) | 
| 507 { | 545 { | 
| 508     unsigned char sizeSerialized = 4 | 0x80; | 546     unsigned char sizeSerialized = 4 | 0x80; | 
| 509     Ebml_WriteID(glob, class_id); | 547     Ebml_WriteID(glob, class_id); | 
| 510     Ebml_Serialize(glob, &sizeSerialized, 1); | 548     Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); | 
| 511     Ebml_Serialize(glob, &ui, 4); | 549     Ebml_Serialize(glob, &ui, sizeof(ui), 4); | 
| 512 } | 550 } | 
| 513 | 551 | 
| 514 | 552 | 
| 515 static void | 553 static void | 
| 516 Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, | 554 Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, | 
| 517                           unsigned long class_id) | 555                           unsigned long class_id) | 
| 518 { | 556 { | 
| 519     //todo this is always taking 8 bytes, this may need later optimization | 557     //todo this is always taking 8 bytes, this may need later optimization | 
| 520     //this is a key that says lenght unknown | 558     //this is a key that says length unknown | 
| 521     unsigned long long unknownLen =  LITERALU64(0x01FFFFFFFFFFFFFF); | 559     uint64_t unknownLen =  LITERALU64(0x01FFFFFFFFFFFFFF); | 
| 522 | 560 | 
| 523     Ebml_WriteID(glob, class_id); | 561     Ebml_WriteID(glob, class_id); | 
| 524     *ebmlLoc = ftello(glob->stream); | 562     *ebmlLoc = ftello(glob->stream); | 
| 525     Ebml_Serialize(glob, &unknownLen, 8); | 563     Ebml_Serialize(glob, &unknownLen, sizeof(unknownLen), 8); | 
| 526 } | 564 } | 
| 527 | 565 | 
| 528 static void | 566 static void | 
| 529 Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) | 567 Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) | 
| 530 { | 568 { | 
| 531     off_t pos; | 569     off_t pos; | 
| 532     uint64_t size; | 570     uint64_t size; | 
| 533 | 571 | 
| 534     /* Save the current stream pointer */ | 572     /* Save the current stream pointer */ | 
| 535     pos = ftello(glob->stream); | 573     pos = ftello(glob->stream); | 
| 536 | 574 | 
| 537     /* Calculate the size of this element */ | 575     /* Calculate the size of this element */ | 
| 538     size = pos - *ebmlLoc - 8; | 576     size = pos - *ebmlLoc - 8; | 
| 539     size |=  LITERALU64(0x0100000000000000); | 577     size |=  LITERALU64(0x0100000000000000); | 
| 540 | 578 | 
| 541     /* Seek back to the beginning of the element and write the new size */ | 579     /* Seek back to the beginning of the element and write the new size */ | 
| 542     fseeko(glob->stream, *ebmlLoc, SEEK_SET); | 580     fseeko(glob->stream, *ebmlLoc, SEEK_SET); | 
| 543     Ebml_Serialize(glob, &size, 8); | 581     Ebml_Serialize(glob, &size, sizeof(size), 8); | 
| 544 | 582 | 
| 545     /* Reset the stream pointer */ | 583     /* Reset the stream pointer */ | 
| 546     fseeko(glob->stream, pos, SEEK_SET); | 584     fseeko(glob->stream, pos, SEEK_SET); | 
| 547 } | 585 } | 
| 548 | 586 | 
| 549 | 587 | 
| 550 static void | 588 static void | 
| 551 write_webm_seek_element(EbmlGlobal *ebml, unsigned long id, off_t pos) | 589 write_webm_seek_element(EbmlGlobal *ebml, unsigned long id, off_t pos) | 
| 552 { | 590 { | 
| 553     uint64_t offset = pos - ebml->position_reference; | 591     uint64_t offset = pos - ebml->position_reference; | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 599         Ebml_SerializeString(ebml, 0x5741, | 637         Ebml_SerializeString(ebml, 0x5741, | 
| 600             ebml->debug ? "vpxenc" : "vpxenc" VERSION_STRING); | 638             ebml->debug ? "vpxenc" : "vpxenc" VERSION_STRING); | 
| 601         Ebml_EndSubElement(ebml, &startInfo); | 639         Ebml_EndSubElement(ebml, &startInfo); | 
| 602     } | 640     } | 
| 603 } | 641 } | 
| 604 | 642 | 
| 605 | 643 | 
| 606 static void | 644 static void | 
| 607 write_webm_file_header(EbmlGlobal                *glob, | 645 write_webm_file_header(EbmlGlobal                *glob, | 
| 608                        const vpx_codec_enc_cfg_t *cfg, | 646                        const vpx_codec_enc_cfg_t *cfg, | 
| 609                        const struct vpx_rational *fps) | 647                        const struct vpx_rational *fps, | 
|  | 648                        stereo_format_t            stereo_fmt) | 
| 610 { | 649 { | 
| 611     { | 650     { | 
| 612         EbmlLoc start; | 651         EbmlLoc start; | 
| 613         Ebml_StartSubElement(glob, &start, EBML); | 652         Ebml_StartSubElement(glob, &start, EBML); | 
| 614         Ebml_SerializeUnsigned(glob, EBMLVersion, 1); | 653         Ebml_SerializeUnsigned(glob, EBMLVersion, 1); | 
| 615         Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1); //EBML Read Version | 654         Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1); //EBML Read Version | 
| 616         Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4); //EBML Max ID Length | 655         Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4); //EBML Max ID Length | 
| 617         Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8); //EBML Max Size Leng
      th | 656         Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8); //EBML Max Size Leng
      th | 
| 618         Ebml_SerializeString(glob, DocType, "webm"); //Doc Type | 657         Ebml_SerializeString(glob, DocType, "webm"); //Doc Type | 
| 619         Ebml_SerializeUnsigned(glob, DocTypeVersion, 2); //Doc Type Version | 658         Ebml_SerializeUnsigned(glob, DocTypeVersion, 2); //Doc Type Version | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 643                 Ebml_SerializeString(glob, CodecID, "V_VP8"); | 682                 Ebml_SerializeString(glob, CodecID, "V_VP8"); | 
| 644                 { | 683                 { | 
| 645                     unsigned int pixelWidth = cfg->g_w; | 684                     unsigned int pixelWidth = cfg->g_w; | 
| 646                     unsigned int pixelHeight = cfg->g_h; | 685                     unsigned int pixelHeight = cfg->g_h; | 
| 647                     float        frameRate   = (float)fps->num/(float)fps->den; | 686                     float        frameRate   = (float)fps->num/(float)fps->den; | 
| 648 | 687 | 
| 649                     EbmlLoc videoStart; | 688                     EbmlLoc videoStart; | 
| 650                     Ebml_StartSubElement(glob, &videoStart, Video); | 689                     Ebml_StartSubElement(glob, &videoStart, Video); | 
| 651                     Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth); | 690                     Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth); | 
| 652                     Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight); | 691                     Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight); | 
|  | 692                     Ebml_SerializeUnsigned(glob, StereoMode, stereo_fmt); | 
| 653                     Ebml_SerializeFloat(glob, FrameRate, frameRate); | 693                     Ebml_SerializeFloat(glob, FrameRate, frameRate); | 
| 654                     Ebml_EndSubElement(glob, &videoStart); //Video | 694                     Ebml_EndSubElement(glob, &videoStart); //Video | 
| 655                 } | 695                 } | 
| 656                 Ebml_EndSubElement(glob, &start); //Track Entry | 696                 Ebml_EndSubElement(glob, &start); //Track Entry | 
| 657             } | 697             } | 
| 658             Ebml_EndSubElement(glob, &trackStart); | 698             Ebml_EndSubElement(glob, &trackStart); | 
| 659         } | 699         } | 
| 660         // segment element is open | 700         // segment element is open | 
| 661     } | 701     } | 
| 662 } | 702 } | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 721             cue->loc = glob->cluster_pos; | 761             cue->loc = glob->cluster_pos; | 
| 722             glob->cues++; | 762             glob->cues++; | 
| 723         } | 763         } | 
| 724     } | 764     } | 
| 725 | 765 | 
| 726     /* Write the Simple Block */ | 766     /* Write the Simple Block */ | 
| 727     Ebml_WriteID(glob, SimpleBlock); | 767     Ebml_WriteID(glob, SimpleBlock); | 
| 728 | 768 | 
| 729     block_length = pkt->data.frame.sz + 4; | 769     block_length = pkt->data.frame.sz + 4; | 
| 730     block_length |= 0x10000000; | 770     block_length |= 0x10000000; | 
| 731     Ebml_Serialize(glob, &block_length, 4); | 771     Ebml_Serialize(glob, &block_length, sizeof(block_length), 4); | 
| 732 | 772 | 
| 733     track_number = 1; | 773     track_number = 1; | 
| 734     track_number |= 0x80; | 774     track_number |= 0x80; | 
| 735     Ebml_Write(glob, &track_number, 1); | 775     Ebml_Write(glob, &track_number, 1); | 
| 736 | 776 | 
| 737     Ebml_Serialize(glob, &block_timecode, 2); | 777     Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2); | 
| 738 | 778 | 
| 739     flags = 0; | 779     flags = 0; | 
| 740     if(is_keyframe) | 780     if(is_keyframe) | 
| 741         flags |= 0x80; | 781         flags |= 0x80; | 
| 742     if(pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) | 782     if(pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) | 
| 743         flags |= 0x08; | 783         flags |= 0x08; | 
| 744     Ebml_Write(glob, &flags, 1); | 784     Ebml_Write(glob, &flags, 1); | 
| 745 | 785 | 
| 746     Ebml_Write(glob, pkt->data.frame.buf, pkt->data.frame.sz); | 786     Ebml_Write(glob, pkt->data.frame.buf, pkt->data.frame.sz); | 
| 747 } | 787 } | 
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 890 static const arg_def_t rt_dl            = ARG_DEF(NULL, "rt", 0, | 930 static const arg_def_t rt_dl            = ARG_DEF(NULL, "rt", 0, | 
| 891         "Use Realtime Quality Deadline"); | 931         "Use Realtime Quality Deadline"); | 
| 892 static const arg_def_t verbosearg       = ARG_DEF("v", "verbose", 0, | 932 static const arg_def_t verbosearg       = ARG_DEF("v", "verbose", 0, | 
| 893         "Show encoder parameters"); | 933         "Show encoder parameters"); | 
| 894 static const arg_def_t psnrarg          = ARG_DEF(NULL, "psnr", 0, | 934 static const arg_def_t psnrarg          = ARG_DEF(NULL, "psnr", 0, | 
| 895         "Show PSNR in status line"); | 935         "Show PSNR in status line"); | 
| 896 static const arg_def_t framerate        = ARG_DEF(NULL, "fps", 1, | 936 static const arg_def_t framerate        = ARG_DEF(NULL, "fps", 1, | 
| 897         "Stream frame rate (rate/scale)"); | 937         "Stream frame rate (rate/scale)"); | 
| 898 static const arg_def_t use_ivf          = ARG_DEF(NULL, "ivf", 0, | 938 static const arg_def_t use_ivf          = ARG_DEF(NULL, "ivf", 0, | 
| 899         "Output IVF (default is WebM)"); | 939         "Output IVF (default is WebM)"); | 
|  | 940 static const arg_def_t q_hist_n         = ARG_DEF(NULL, "q-hist", 1, | 
|  | 941         "Show quantizer histogram (n-buckets)"); | 
|  | 942 static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1, | 
|  | 943         "Show rate histogram (n-buckets)"); | 
| 900 static const arg_def_t *main_args[] = | 944 static const arg_def_t *main_args[] = | 
| 901 { | 945 { | 
| 902     &debugmode, | 946     &debugmode, | 
| 903     &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline, | 947     &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline, | 
| 904     &best_dl, &good_dl, &rt_dl, | 948     &best_dl, &good_dl, &rt_dl, | 
| 905     &verbosearg, &psnrarg, &use_ivf, &framerate, | 949     &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n, | 
| 906     NULL | 950     NULL | 
| 907 }; | 951 }; | 
| 908 | 952 | 
| 909 static const arg_def_t usage            = ARG_DEF("u", "usage", 1, | 953 static const arg_def_t usage            = ARG_DEF("u", "usage", 1, | 
| 910         "Usage profile number to use"); | 954         "Usage profile number to use"); | 
| 911 static const arg_def_t threads          = ARG_DEF("t", "threads", 1, | 955 static const arg_def_t threads          = ARG_DEF("t", "threads", 1, | 
| 912         "Max number of threads to use"); | 956         "Max number of threads to use"); | 
| 913 static const arg_def_t profile          = ARG_DEF(NULL, "profile", 1, | 957 static const arg_def_t profile          = ARG_DEF(NULL, "profile", 1, | 
| 914         "Bitstream profile number to use"); | 958         "Bitstream profile number to use"); | 
| 915 static const arg_def_t width            = ARG_DEF("w", "width", 1, | 959 static const arg_def_t width            = ARG_DEF("w", "width", 1, | 
| 916         "Frame width"); | 960         "Frame width"); | 
| 917 static const arg_def_t height           = ARG_DEF("h", "height", 1, | 961 static const arg_def_t height           = ARG_DEF("h", "height", 1, | 
| 918         "Frame height"); | 962         "Frame height"); | 
|  | 963 static const struct arg_enum_list stereo_mode_enum[] = { | 
|  | 964     {"mono"      , STEREO_FORMAT_MONO}, | 
|  | 965     {"left-right", STEREO_FORMAT_LEFT_RIGHT}, | 
|  | 966     {"bottom-top", STEREO_FORMAT_BOTTOM_TOP}, | 
|  | 967     {"top-bottom", STEREO_FORMAT_TOP_BOTTOM}, | 
|  | 968     {"right-left", STEREO_FORMAT_RIGHT_LEFT}, | 
|  | 969     {NULL, 0} | 
|  | 970 }; | 
|  | 971 static const arg_def_t stereo_mode      = ARG_DEF_ENUM(NULL, "stereo-mode", 1, | 
|  | 972         "Stereo 3D video format", stereo_mode_enum); | 
| 919 static const arg_def_t timebase         = ARG_DEF(NULL, "timebase", 1, | 973 static const arg_def_t timebase         = ARG_DEF(NULL, "timebase", 1, | 
| 920         "Stream timebase (frame duration)"); | 974         "Output timestamp precision (fractional seconds)"); | 
| 921 static const arg_def_t error_resilient  = ARG_DEF(NULL, "error-resilient", 1, | 975 static const arg_def_t error_resilient  = ARG_DEF(NULL, "error-resilient", 1, | 
| 922         "Enable error resiliency features"); | 976         "Enable error resiliency features"); | 
| 923 static const arg_def_t lag_in_frames    = ARG_DEF(NULL, "lag-in-frames", 1, | 977 static const arg_def_t lag_in_frames    = ARG_DEF(NULL, "lag-in-frames", 1, | 
| 924         "Max number of frames to lag"); | 978         "Max number of frames to lag"); | 
| 925 | 979 | 
| 926 static const arg_def_t *global_args[] = | 980 static const arg_def_t *global_args[] = | 
| 927 { | 981 { | 
| 928     &use_yv12, &use_i420, &usage, &threads, &profile, | 982     &use_yv12, &use_i420, &usage, &threads, &profile, | 
| 929     &width, &height, &timebase, &framerate, &error_resilient, | 983     &width, &height, &stereo_mode, &timebase, &framerate, &error_resilient, | 
| 930     &lag_in_frames, NULL | 984     &lag_in_frames, NULL | 
| 931 }; | 985 }; | 
| 932 | 986 | 
| 933 static const arg_def_t dropframe_thresh   = ARG_DEF(NULL, "drop-frame", 1, | 987 static const arg_def_t dropframe_thresh   = ARG_DEF(NULL, "drop-frame", 1, | 
| 934         "Temporal resampling threshold (buf %)"); | 988         "Temporal resampling threshold (buf %)"); | 
| 935 static const arg_def_t resize_allowed     = ARG_DEF(NULL, "resize-allowed", 1, | 989 static const arg_def_t resize_allowed     = ARG_DEF(NULL, "resize-allowed", 1, | 
| 936         "Spatial resampling enabled (bool)"); | 990         "Spatial resampling enabled (bool)"); | 
| 937 static const arg_def_t resize_up_thresh   = ARG_DEF(NULL, "resize-up", 1, | 991 static const arg_def_t resize_up_thresh   = ARG_DEF(NULL, "resize-up", 1, | 
| 938         "Upscale threshold (buf %)"); | 992         "Upscale threshold (buf %)"); | 
| 939 static const arg_def_t resize_down_thresh = ARG_DEF(NULL, "resize-down", 1, | 993 static const arg_def_t resize_down_thresh = ARG_DEF(NULL, "resize-down", 1, | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1023                                    "AltRef Type"); | 1077                                    "AltRef Type"); | 
| 1024 static const struct arg_enum_list tuning_enum[] = { | 1078 static const struct arg_enum_list tuning_enum[] = { | 
| 1025     {"psnr", VP8_TUNE_PSNR}, | 1079     {"psnr", VP8_TUNE_PSNR}, | 
| 1026     {"ssim", VP8_TUNE_SSIM}, | 1080     {"ssim", VP8_TUNE_SSIM}, | 
| 1027     {NULL, 0} | 1081     {NULL, 0} | 
| 1028 }; | 1082 }; | 
| 1029 static const arg_def_t tune_ssim = ARG_DEF_ENUM(NULL, "tune", 1, | 1083 static const arg_def_t tune_ssim = ARG_DEF_ENUM(NULL, "tune", 1, | 
| 1030                                    "Material to favor", tuning_enum); | 1084                                    "Material to favor", tuning_enum); | 
| 1031 static const arg_def_t cq_level = ARG_DEF(NULL, "cq-level", 1, | 1085 static const arg_def_t cq_level = ARG_DEF(NULL, "cq-level", 1, | 
| 1032                                    "Constrained Quality Level"); | 1086                                    "Constrained Quality Level"); | 
|  | 1087 static const arg_def_t max_intra_rate_pct = ARG_DEF(NULL, "max-intra-rate", 1, | 
|  | 1088         "Max I-frame bitrate (pct)"); | 
| 1033 | 1089 | 
| 1034 static const arg_def_t *vp8_args[] = | 1090 static const arg_def_t *vp8_args[] = | 
| 1035 { | 1091 { | 
| 1036     &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh, | 1092     &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh, | 
| 1037     &token_parts, &arnr_maxframes, &arnr_strength, &arnr_type, | 1093     &token_parts, &arnr_maxframes, &arnr_strength, &arnr_type, | 
| 1038     &tune_ssim, &cq_level, NULL | 1094     &tune_ssim, &cq_level, &max_intra_rate_pct, NULL | 
| 1039 }; | 1095 }; | 
| 1040 static const int vp8_arg_ctrl_map[] = | 1096 static const int vp8_arg_ctrl_map[] = | 
| 1041 { | 1097 { | 
| 1042     VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF, | 1098     VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF, | 
| 1043     VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD, | 1099     VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD, | 
| 1044     VP8E_SET_TOKEN_PARTITIONS, | 1100     VP8E_SET_TOKEN_PARTITIONS, | 
| 1045     VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE, | 1101     VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE, | 
| 1046     VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, 0 | 1102     VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT, 0 | 
| 1047 }; | 1103 }; | 
| 1048 #endif | 1104 #endif | 
| 1049 | 1105 | 
| 1050 static const arg_def_t *no_args[] = { NULL }; | 1106 static const arg_def_t *no_args[] = { NULL }; | 
| 1051 | 1107 | 
| 1052 static void usage_exit() | 1108 static void usage_exit() | 
| 1053 { | 1109 { | 
| 1054     int i; | 1110     int i; | 
| 1055 | 1111 | 
| 1056     fprintf(stderr, "Usage: %s <options> -o dst_filename src_filename \n", | 1112     fprintf(stderr, "Usage: %s <options> -o dst_filename src_filename \n", | 
| 1057             exec_name); | 1113             exec_name); | 
| 1058 | 1114 | 
| 1059     fprintf(stderr, "\nOptions:\n"); | 1115     fprintf(stderr, "\nOptions:\n"); | 
| 1060     arg_show_usage(stdout, main_args); | 1116     arg_show_usage(stdout, main_args); | 
| 1061     fprintf(stderr, "\nEncoder Global Options:\n"); | 1117     fprintf(stderr, "\nEncoder Global Options:\n"); | 
| 1062     arg_show_usage(stdout, global_args); | 1118     arg_show_usage(stdout, global_args); | 
| 1063     fprintf(stderr, "\nRate Control Options:\n"); | 1119     fprintf(stderr, "\nRate Control Options:\n"); | 
| 1064     arg_show_usage(stdout, rc_args); | 1120     arg_show_usage(stdout, rc_args); | 
| 1065     fprintf(stderr, "\nTwopass Rate Control Options:\n"); | 1121     fprintf(stderr, "\nTwopass Rate Control Options:\n"); | 
| 1066     arg_show_usage(stdout, rc_twopass_args); | 1122     arg_show_usage(stdout, rc_twopass_args); | 
| 1067     fprintf(stderr, "\nKeyframe Placement Options:\n"); | 1123     fprintf(stderr, "\nKeyframe Placement Options:\n"); | 
| 1068     arg_show_usage(stdout, kf_args); | 1124     arg_show_usage(stdout, kf_args); | 
| 1069 #if CONFIG_VP8_ENCODER | 1125 #if CONFIG_VP8_ENCODER | 
| 1070     fprintf(stderr, "\nVP8 Specific Options:\n"); | 1126     fprintf(stderr, "\nVP8 Specific Options:\n"); | 
| 1071     arg_show_usage(stdout, vp8_args); | 1127     arg_show_usage(stdout, vp8_args); | 
| 1072 #endif | 1128 #endif | 
|  | 1129     fprintf(stderr, "\nStream timebase (--timebase):\n" | 
|  | 1130             "  The desired precision of timestamps in the output, expressed\n" | 
|  | 1131             "  in fractional seconds. Default is 1/1000.\n"); | 
| 1073     fprintf(stderr, "\n" | 1132     fprintf(stderr, "\n" | 
| 1074            "Included encoders:\n" | 1133            "Included encoders:\n" | 
| 1075            "\n"); | 1134            "\n"); | 
| 1076 | 1135 | 
| 1077     for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++) | 1136     for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++) | 
| 1078         fprintf(stderr, "    %-6s - %s\n", | 1137         fprintf(stderr, "    %-6s - %s\n", | 
| 1079                codecs[i].name, | 1138                codecs[i].name, | 
| 1080                vpx_codec_iface_name(codecs[i].iface)); | 1139                vpx_codec_iface_name(codecs[i].iface)); | 
| 1081 | 1140 | 
| 1082     exit(EXIT_FAILURE); | 1141     exit(EXIT_FAILURE); | 
| 1083 } | 1142 } | 
| 1084 | 1143 | 
|  | 1144 | 
|  | 1145 #define HIST_BAR_MAX 40 | 
|  | 1146 struct hist_bucket | 
|  | 1147 { | 
|  | 1148     int low, high, count; | 
|  | 1149 }; | 
|  | 1150 | 
|  | 1151 | 
|  | 1152 static int merge_hist_buckets(struct hist_bucket *bucket, | 
|  | 1153                               int *buckets_, | 
|  | 1154                               int max_buckets) | 
|  | 1155 { | 
|  | 1156     int small_bucket = 0, merge_bucket = INT_MAX, big_bucket=0; | 
|  | 1157     int buckets = *buckets_; | 
|  | 1158     int i; | 
|  | 1159 | 
|  | 1160     /* Find the extrema for this list of buckets */ | 
|  | 1161     big_bucket = small_bucket = 0; | 
|  | 1162     for(i=0; i < buckets; i++) | 
|  | 1163     { | 
|  | 1164         if(bucket[i].count < bucket[small_bucket].count) | 
|  | 1165             small_bucket = i; | 
|  | 1166         if(bucket[i].count > bucket[big_bucket].count) | 
|  | 1167             big_bucket = i; | 
|  | 1168     } | 
|  | 1169 | 
|  | 1170     /* If we have too many buckets, merge the smallest with an adjacent | 
|  | 1171      * bucket. | 
|  | 1172      */ | 
|  | 1173     while(buckets > max_buckets) | 
|  | 1174     { | 
|  | 1175         int last_bucket = buckets - 1; | 
|  | 1176 | 
|  | 1177         // merge the small bucket with an adjacent one. | 
|  | 1178         if(small_bucket == 0) | 
|  | 1179             merge_bucket = 1; | 
|  | 1180         else if(small_bucket == last_bucket) | 
|  | 1181             merge_bucket = last_bucket - 1; | 
|  | 1182         else if(bucket[small_bucket - 1].count < bucket[small_bucket + 1].count) | 
|  | 1183             merge_bucket = small_bucket - 1; | 
|  | 1184         else | 
|  | 1185             merge_bucket = small_bucket + 1; | 
|  | 1186 | 
|  | 1187         assert(abs(merge_bucket - small_bucket) <= 1); | 
|  | 1188         assert(small_bucket < buckets); | 
|  | 1189         assert(big_bucket < buckets); | 
|  | 1190         assert(merge_bucket < buckets); | 
|  | 1191 | 
|  | 1192         if(merge_bucket < small_bucket) | 
|  | 1193         { | 
|  | 1194             bucket[merge_bucket].high = bucket[small_bucket].high; | 
|  | 1195             bucket[merge_bucket].count += bucket[small_bucket].count; | 
|  | 1196         } | 
|  | 1197         else | 
|  | 1198         { | 
|  | 1199             bucket[small_bucket].high = bucket[merge_bucket].high; | 
|  | 1200             bucket[small_bucket].count += bucket[merge_bucket].count; | 
|  | 1201             merge_bucket = small_bucket; | 
|  | 1202         } | 
|  | 1203 | 
|  | 1204         assert(bucket[merge_bucket].low != bucket[merge_bucket].high); | 
|  | 1205 | 
|  | 1206         buckets--; | 
|  | 1207 | 
|  | 1208         /* Remove the merge_bucket from the list, and find the new small | 
|  | 1209          * and big buckets while we're at it | 
|  | 1210          */ | 
|  | 1211         big_bucket = small_bucket = 0; | 
|  | 1212         for(i=0; i < buckets; i++) | 
|  | 1213         { | 
|  | 1214             if(i > merge_bucket) | 
|  | 1215                 bucket[i] = bucket[i+1]; | 
|  | 1216 | 
|  | 1217             if(bucket[i].count < bucket[small_bucket].count) | 
|  | 1218                 small_bucket = i; | 
|  | 1219             if(bucket[i].count > bucket[big_bucket].count) | 
|  | 1220                 big_bucket = i; | 
|  | 1221         } | 
|  | 1222 | 
|  | 1223     } | 
|  | 1224 | 
|  | 1225     *buckets_ = buckets; | 
|  | 1226     return bucket[big_bucket].count; | 
|  | 1227 } | 
|  | 1228 | 
|  | 1229 | 
|  | 1230 static void show_histogram(const struct hist_bucket *bucket, | 
|  | 1231                            int                       buckets, | 
|  | 1232                            int                       total, | 
|  | 1233                            int                       scale) | 
|  | 1234 { | 
|  | 1235     const char *pat1, *pat2; | 
|  | 1236     int i; | 
|  | 1237 | 
|  | 1238     switch((int)(log(bucket[buckets-1].high)/log(10))+1) | 
|  | 1239     { | 
|  | 1240         case 1: | 
|  | 1241         case 2: | 
|  | 1242             pat1 = "%4d %2s: "; | 
|  | 1243             pat2 = "%4d-%2d: "; | 
|  | 1244             break; | 
|  | 1245         case 3: | 
|  | 1246             pat1 = "%5d %3s: "; | 
|  | 1247             pat2 = "%5d-%3d: "; | 
|  | 1248             break; | 
|  | 1249         case 4: | 
|  | 1250             pat1 = "%6d %4s: "; | 
|  | 1251             pat2 = "%6d-%4d: "; | 
|  | 1252             break; | 
|  | 1253         case 5: | 
|  | 1254             pat1 = "%7d %5s: "; | 
|  | 1255             pat2 = "%7d-%5d: "; | 
|  | 1256             break; | 
|  | 1257         case 6: | 
|  | 1258             pat1 = "%8d %6s: "; | 
|  | 1259             pat2 = "%8d-%6d: "; | 
|  | 1260             break; | 
|  | 1261         case 7: | 
|  | 1262             pat1 = "%9d %7s: "; | 
|  | 1263             pat2 = "%9d-%7d: "; | 
|  | 1264             break; | 
|  | 1265         default: | 
|  | 1266             pat1 = "%12d %10s: "; | 
|  | 1267             pat2 = "%12d-%10d: "; | 
|  | 1268             break; | 
|  | 1269     } | 
|  | 1270 | 
|  | 1271     for(i=0; i<buckets; i++) | 
|  | 1272     { | 
|  | 1273         int len; | 
|  | 1274         int j; | 
|  | 1275         float pct; | 
|  | 1276 | 
|  | 1277         pct = 100.0 * (float)bucket[i].count / (float)total; | 
|  | 1278         len = HIST_BAR_MAX * bucket[i].count / scale; | 
|  | 1279         if(len < 1) | 
|  | 1280             len = 1; | 
|  | 1281         assert(len <= HIST_BAR_MAX); | 
|  | 1282 | 
|  | 1283         if(bucket[i].low == bucket[i].high) | 
|  | 1284             fprintf(stderr, pat1, bucket[i].low, ""); | 
|  | 1285         else | 
|  | 1286             fprintf(stderr, pat2, bucket[i].low, bucket[i].high); | 
|  | 1287 | 
|  | 1288         for(j=0; j<HIST_BAR_MAX; j++) | 
|  | 1289             fprintf(stderr, j<len?"=":" "); | 
|  | 1290         fprintf(stderr, "\t%5d (%6.2f%%)\n",bucket[i].count,pct); | 
|  | 1291     } | 
|  | 1292 } | 
|  | 1293 | 
|  | 1294 | 
|  | 1295 static void show_q_histogram(const int counts[64], int max_buckets) | 
|  | 1296 { | 
|  | 1297     struct hist_bucket bucket[64]; | 
|  | 1298     int buckets = 0; | 
|  | 1299     int total = 0; | 
|  | 1300     int scale; | 
|  | 1301     int i; | 
|  | 1302 | 
|  | 1303 | 
|  | 1304     for(i=0; i<64; i++) | 
|  | 1305     { | 
|  | 1306         if(counts[i]) | 
|  | 1307         { | 
|  | 1308             bucket[buckets].low = bucket[buckets].high = i; | 
|  | 1309             bucket[buckets].count = counts[i]; | 
|  | 1310             buckets++; | 
|  | 1311             total += counts[i]; | 
|  | 1312         } | 
|  | 1313     } | 
|  | 1314 | 
|  | 1315     fprintf(stderr, "\nQuantizer Selection:\n"); | 
|  | 1316     scale = merge_hist_buckets(bucket, &buckets, max_buckets); | 
|  | 1317     show_histogram(bucket, buckets, total, scale); | 
|  | 1318 } | 
|  | 1319 | 
|  | 1320 | 
|  | 1321 #define RATE_BINS (100) | 
|  | 1322 struct rate_hist | 
|  | 1323 { | 
|  | 1324     int64_t            *pts; | 
|  | 1325     int                *sz; | 
|  | 1326     int                 samples; | 
|  | 1327     int                 frames; | 
|  | 1328     struct hist_bucket  bucket[RATE_BINS]; | 
|  | 1329     int                 total; | 
|  | 1330 }; | 
|  | 1331 | 
|  | 1332 | 
|  | 1333 static void init_rate_histogram(struct rate_hist          *hist, | 
|  | 1334                                 const vpx_codec_enc_cfg_t *cfg, | 
|  | 1335                                 const vpx_rational_t      *fps) | 
|  | 1336 { | 
|  | 1337     int i; | 
|  | 1338 | 
|  | 1339     /* Determine the number of samples in the buffer. Use the file's framerate | 
|  | 1340      * to determine the number of frames in rc_buf_sz milliseconds, with an | 
|  | 1341      * adjustment (5/4) to account for alt-refs | 
|  | 1342      */ | 
|  | 1343     hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000; | 
|  | 1344 | 
|  | 1345     // prevent division by zero | 
|  | 1346     if (hist->samples == 0) | 
|  | 1347       hist->samples=1; | 
|  | 1348 | 
|  | 1349     hist->pts = calloc(hist->samples, sizeof(*hist->pts)); | 
|  | 1350     hist->sz = calloc(hist->samples, sizeof(*hist->sz)); | 
|  | 1351     for(i=0; i<RATE_BINS; i++) | 
|  | 1352     { | 
|  | 1353         hist->bucket[i].low = INT_MAX; | 
|  | 1354         hist->bucket[i].high = 0; | 
|  | 1355         hist->bucket[i].count = 0; | 
|  | 1356     } | 
|  | 1357 } | 
|  | 1358 | 
|  | 1359 | 
|  | 1360 static void destroy_rate_histogram(struct rate_hist *hist) | 
|  | 1361 { | 
|  | 1362     free(hist->pts); | 
|  | 1363     free(hist->sz); | 
|  | 1364 } | 
|  | 1365 | 
|  | 1366 | 
|  | 1367 static void update_rate_histogram(struct rate_hist          *hist, | 
|  | 1368                                   const vpx_codec_enc_cfg_t *cfg, | 
|  | 1369                                   const vpx_codec_cx_pkt_t  *pkt) | 
|  | 1370 { | 
|  | 1371     int i, idx; | 
|  | 1372     int64_t now, then, sum_sz = 0, avg_bitrate; | 
|  | 1373 | 
|  | 1374     now = pkt->data.frame.pts * 1000 | 
|  | 1375           * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den; | 
|  | 1376 | 
|  | 1377     idx = hist->frames++ % hist->samples; | 
|  | 1378     hist->pts[idx] = now; | 
|  | 1379     hist->sz[idx] = pkt->data.frame.sz; | 
|  | 1380 | 
|  | 1381     if(now < cfg->rc_buf_initial_sz) | 
|  | 1382         return; | 
|  | 1383 | 
|  | 1384     then = now; | 
|  | 1385 | 
|  | 1386     /* Sum the size over the past rc_buf_sz ms */ | 
|  | 1387     for(i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--) | 
|  | 1388     { | 
|  | 1389         int i_idx = (i-1) % hist->samples; | 
|  | 1390 | 
|  | 1391         then = hist->pts[i_idx]; | 
|  | 1392         if(now - then > cfg->rc_buf_sz) | 
|  | 1393             break; | 
|  | 1394         sum_sz += hist->sz[i_idx]; | 
|  | 1395     } | 
|  | 1396 | 
|  | 1397     if (now == then) | 
|  | 1398         return; | 
|  | 1399 | 
|  | 1400     avg_bitrate = sum_sz * 8 * 1000 / (now - then); | 
|  | 1401     idx = avg_bitrate * (RATE_BINS/2) / (cfg->rc_target_bitrate * 1000); | 
|  | 1402     if(idx < 0) | 
|  | 1403         idx = 0; | 
|  | 1404     if(idx > RATE_BINS-1) | 
|  | 1405         idx = RATE_BINS-1; | 
|  | 1406     if(hist->bucket[idx].low > avg_bitrate) | 
|  | 1407         hist->bucket[idx].low = avg_bitrate; | 
|  | 1408     if(hist->bucket[idx].high < avg_bitrate) | 
|  | 1409         hist->bucket[idx].high = avg_bitrate; | 
|  | 1410     hist->bucket[idx].count++; | 
|  | 1411     hist->total++; | 
|  | 1412 } | 
|  | 1413 | 
|  | 1414 | 
|  | 1415 static void show_rate_histogram(struct rate_hist          *hist, | 
|  | 1416                                 const vpx_codec_enc_cfg_t *cfg, | 
|  | 1417                                 int                        max_buckets) | 
|  | 1418 { | 
|  | 1419     int i, scale; | 
|  | 1420     int buckets = 0; | 
|  | 1421 | 
|  | 1422     for(i = 0; i < RATE_BINS; i++) | 
|  | 1423     { | 
|  | 1424         if(hist->bucket[i].low == INT_MAX) | 
|  | 1425             continue; | 
|  | 1426         hist->bucket[buckets++] = hist->bucket[i]; | 
|  | 1427     } | 
|  | 1428 | 
|  | 1429     fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz); | 
|  | 1430     scale = merge_hist_buckets(hist->bucket, &buckets, max_buckets); | 
|  | 1431     show_histogram(hist->bucket, buckets, hist->total, scale); | 
|  | 1432 } | 
|  | 1433 | 
| 1085 #define ARG_CTRL_CNT_MAX 10 | 1434 #define ARG_CTRL_CNT_MAX 10 | 
| 1086 | 1435 | 
| 1087 |  | 
| 1088 int main(int argc, const char **argv_) | 1436 int main(int argc, const char **argv_) | 
| 1089 { | 1437 { | 
| 1090     vpx_codec_ctx_t        encoder; | 1438     vpx_codec_ctx_t        encoder; | 
| 1091     const char                  *in_fn = NULL, *out_fn = NULL, *stats_fn = NULL; | 1439     const char                  *in_fn = NULL, *out_fn = NULL, *stats_fn = NULL; | 
| 1092     int                    i; | 1440     int                    i; | 
| 1093     FILE                  *infile, *outfile; | 1441     FILE                  *infile, *outfile; | 
| 1094     vpx_codec_enc_cfg_t    cfg; | 1442     vpx_codec_enc_cfg_t    cfg; | 
| 1095     vpx_codec_err_t        res; | 1443     vpx_codec_err_t        res; | 
| 1096     int                    pass, one_pass_only = 0; | 1444     int                    pass, one_pass_only = 0; | 
| 1097     stats_io_t             stats; | 1445     stats_io_t             stats; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 1113     y4m_input                y4m; | 1461     y4m_input                y4m; | 
| 1114     struct vpx_rational      arg_framerate = {30, 1}; | 1462     struct vpx_rational      arg_framerate = {30, 1}; | 
| 1115     int                      arg_have_framerate = 0; | 1463     int                      arg_have_framerate = 0; | 
| 1116     int                      write_webm = 1; | 1464     int                      write_webm = 1; | 
| 1117     EbmlGlobal               ebml = {0}; | 1465     EbmlGlobal               ebml = {0}; | 
| 1118     uint32_t                 hash = 0; | 1466     uint32_t                 hash = 0; | 
| 1119     uint64_t                 psnr_sse_total = 0; | 1467     uint64_t                 psnr_sse_total = 0; | 
| 1120     uint64_t                 psnr_samples_total = 0; | 1468     uint64_t                 psnr_samples_total = 0; | 
| 1121     double                   psnr_totals[4] = {0, 0, 0, 0}; | 1469     double                   psnr_totals[4] = {0, 0, 0, 0}; | 
| 1122     int                      psnr_count = 0; | 1470     int                      psnr_count = 0; | 
|  | 1471     stereo_format_t          stereo_fmt = STEREO_FORMAT_MONO; | 
|  | 1472     int                      counts[64]={0}; | 
|  | 1473     int                      show_q_hist_buckets=0; | 
|  | 1474     int                      show_rate_hist_buckets=0; | 
|  | 1475     struct rate_hist         rate_hist={0}; | 
| 1123 | 1476 | 
| 1124     exec_name = argv_[0]; | 1477     exec_name = argv_[0]; | 
| 1125     ebml.last_pts_ms = -1; | 1478     ebml.last_pts_ms = -1; | 
| 1126 | 1479 | 
| 1127     if (argc < 3) | 1480     if (argc < 3) | 
| 1128         usage_exit(); | 1481         usage_exit(); | 
| 1129 | 1482 | 
| 1130 | 1483 | 
| 1131     /* First parse the codec and usage values, because we want to apply other | 1484     /* First parse the codec and usage values, because we want to apply other | 
| 1132      * parameters on top of the default configuration provided by the codec. | 1485      * parameters on top of the default configuration provided by the codec. | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1196         { | 1549         { | 
| 1197             arg_framerate = arg_parse_rational(&arg); | 1550             arg_framerate = arg_parse_rational(&arg); | 
| 1198             arg_have_framerate = 1; | 1551             arg_have_framerate = 1; | 
| 1199         } | 1552         } | 
| 1200         else if (arg_match(&arg, &use_ivf, argi)) | 1553         else if (arg_match(&arg, &use_ivf, argi)) | 
| 1201             write_webm = 0; | 1554             write_webm = 0; | 
| 1202         else if (arg_match(&arg, &outputfile, argi)) | 1555         else if (arg_match(&arg, &outputfile, argi)) | 
| 1203             out_fn = arg.val; | 1556             out_fn = arg.val; | 
| 1204         else if (arg_match(&arg, &debugmode, argi)) | 1557         else if (arg_match(&arg, &debugmode, argi)) | 
| 1205             ebml.debug = 1; | 1558             ebml.debug = 1; | 
|  | 1559         else if (arg_match(&arg, &q_hist_n, argi)) | 
|  | 1560             show_q_hist_buckets = arg_parse_uint(&arg); | 
|  | 1561         else if (arg_match(&arg, &rate_hist_n, argi)) | 
|  | 1562             show_rate_hist_buckets = arg_parse_uint(&arg); | 
| 1206         else | 1563         else | 
| 1207             argj++; | 1564             argj++; | 
| 1208     } | 1565     } | 
| 1209 | 1566 | 
| 1210     /* Ensure that --passes and --pass are consistent. If --pass is set and --pa
      sses=2, | 1567     /* Ensure that --passes and --pass are consistent. If --pass is set and --pa
      sses=2, | 
| 1211      * ensure --fpf was set. | 1568      * ensure --fpf was set. | 
| 1212      */ | 1569      */ | 
| 1213     if (one_pass_only) | 1570     if (one_pass_only) | 
| 1214     { | 1571     { | 
| 1215         /* DWIM: Assume the user meant passes=2 if pass=2 is specified */ | 1572         /* DWIM: Assume the user meant passes=2 if pass=2 is specified */ | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1252 | 1609 | 
| 1253         if (0); | 1610         if (0); | 
| 1254         else if (arg_match(&arg, &threads, argi)) | 1611         else if (arg_match(&arg, &threads, argi)) | 
| 1255             cfg.g_threads = arg_parse_uint(&arg); | 1612             cfg.g_threads = arg_parse_uint(&arg); | 
| 1256         else if (arg_match(&arg, &profile, argi)) | 1613         else if (arg_match(&arg, &profile, argi)) | 
| 1257             cfg.g_profile = arg_parse_uint(&arg); | 1614             cfg.g_profile = arg_parse_uint(&arg); | 
| 1258         else if (arg_match(&arg, &width, argi)) | 1615         else if (arg_match(&arg, &width, argi)) | 
| 1259             cfg.g_w = arg_parse_uint(&arg); | 1616             cfg.g_w = arg_parse_uint(&arg); | 
| 1260         else if (arg_match(&arg, &height, argi)) | 1617         else if (arg_match(&arg, &height, argi)) | 
| 1261             cfg.g_h = arg_parse_uint(&arg); | 1618             cfg.g_h = arg_parse_uint(&arg); | 
|  | 1619         else if (arg_match(&arg, &stereo_mode, argi)) | 
|  | 1620             stereo_fmt = arg_parse_enum_or_int(&arg); | 
| 1262         else if (arg_match(&arg, &timebase, argi)) | 1621         else if (arg_match(&arg, &timebase, argi)) | 
| 1263             cfg.g_timebase = arg_parse_rational(&arg); | 1622             cfg.g_timebase = arg_parse_rational(&arg); | 
| 1264         else if (arg_match(&arg, &error_resilient, argi)) | 1623         else if (arg_match(&arg, &error_resilient, argi)) | 
| 1265             cfg.g_error_resilient = arg_parse_uint(&arg); | 1624             cfg.g_error_resilient = arg_parse_uint(&arg); | 
| 1266         else if (arg_match(&arg, &lag_in_frames, argi)) | 1625         else if (arg_match(&arg, &lag_in_frames, argi)) | 
| 1267             cfg.g_lag_in_frames = arg_parse_uint(&arg); | 1626             cfg.g_lag_in_frames = arg_parse_uint(&arg); | 
| 1268         else if (arg_match(&arg, &dropframe_thresh, argi)) | 1627         else if (arg_match(&arg, &dropframe_thresh, argi)) | 
| 1269             cfg.rc_dropframe_thresh = arg_parse_uint(&arg); | 1628             cfg.rc_dropframe_thresh = arg_parse_uint(&arg); | 
| 1270         else if (arg_match(&arg, &resize_allowed, argi)) | 1629         else if (arg_match(&arg, &resize_allowed, argi)) | 
| 1271             cfg.rc_resize_allowed = arg_parse_uint(&arg); | 1630             cfg.rc_resize_allowed = arg_parse_uint(&arg); | 
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1501 | 1860 | 
| 1502         if(pass == (one_pass_only ? one_pass_only - 1 : 0)) { | 1861         if(pass == (one_pass_only ? one_pass_only - 1 : 0)) { | 
| 1503             if (file_type == FILE_TYPE_Y4M) | 1862             if (file_type == FILE_TYPE_Y4M) | 
| 1504                 /*The Y4M reader does its own allocation. | 1863                 /*The Y4M reader does its own allocation. | 
| 1505                   Just initialize this here to avoid problems if we never read a
      ny | 1864                   Just initialize this here to avoid problems if we never read a
      ny | 
| 1506                    frames.*/ | 1865                    frames.*/ | 
| 1507                 memset(&raw, 0, sizeof(raw)); | 1866                 memset(&raw, 0, sizeof(raw)); | 
| 1508             else | 1867             else | 
| 1509                 vpx_img_alloc(&raw, arg_use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FM
      T_YV12, | 1868                 vpx_img_alloc(&raw, arg_use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FM
      T_YV12, | 
| 1510                               cfg.g_w, cfg.g_h, 1); | 1869                               cfg.g_w, cfg.g_h, 1); | 
|  | 1870 | 
|  | 1871             init_rate_histogram(&rate_hist, &cfg, &arg_framerate); | 
| 1511         } | 1872         } | 
| 1512 | 1873 | 
| 1513         outfile = strcmp(out_fn, "-") ? fopen(out_fn, "wb") | 1874         outfile = strcmp(out_fn, "-") ? fopen(out_fn, "wb") | 
| 1514                                       : set_binary_mode(stdout); | 1875                                       : set_binary_mode(stdout); | 
| 1515 | 1876 | 
| 1516         if (!outfile) | 1877         if (!outfile) | 
| 1517         { | 1878         { | 
| 1518             fprintf(stderr, "Failed to open output file\n"); | 1879             fprintf(stderr, "Failed to open output file\n"); | 
| 1519             return EXIT_FAILURE; | 1880             return EXIT_FAILURE; | 
| 1520         } | 1881         } | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1550         if (pass) | 1911         if (pass) | 
| 1551         { | 1912         { | 
| 1552             cfg.rc_twopass_stats_in = stats_get(&stats); | 1913             cfg.rc_twopass_stats_in = stats_get(&stats); | 
| 1553         } | 1914         } | 
| 1554 | 1915 | 
| 1555 #endif | 1916 #endif | 
| 1556 | 1917 | 
| 1557         if(write_webm) | 1918         if(write_webm) | 
| 1558         { | 1919         { | 
| 1559             ebml.stream = outfile; | 1920             ebml.stream = outfile; | 
| 1560             write_webm_file_header(&ebml, &cfg, &arg_framerate); | 1921             write_webm_file_header(&ebml, &cfg, &arg_framerate, stereo_fmt); | 
| 1561         } | 1922         } | 
| 1562         else | 1923         else | 
| 1563             write_ivf_file_header(outfile, &cfg, codec->fourcc, 0); | 1924             write_ivf_file_header(outfile, &cfg, codec->fourcc, 0); | 
| 1564 | 1925 | 
| 1565 | 1926 | 
| 1566         /* Construct Encoder Context */ | 1927         /* Construct Encoder Context */ | 
| 1567         vpx_codec_enc_init(&encoder, codec->iface, &cfg, | 1928         vpx_codec_enc_init(&encoder, codec->iface, &cfg, | 
| 1568                            show_psnr ? VPX_CODEC_USE_PSNR : 0); | 1929                            show_psnr ? VPX_CODEC_USE_PSNR : 0); | 
| 1569         ctx_exit_on_error(&encoder, "Failed to initialize encoder"); | 1930         ctx_exit_on_error(&encoder, "Failed to initialize encoder"); | 
| 1570 | 1931 | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1612                           * arg_framerate.den) / cfg.g_timebase.num / arg_framer
      ate.num; | 1973                           * arg_framerate.den) / cfg.g_timebase.num / arg_framer
      ate.num; | 
| 1613             next_frame_start = (cfg.g_timebase.den * (int64_t)(frames_in) | 1974             next_frame_start = (cfg.g_timebase.den * (int64_t)(frames_in) | 
| 1614                                 * arg_framerate.den) | 1975                                 * arg_framerate.den) | 
| 1615                                 / cfg.g_timebase.num / arg_framerate.num; | 1976                                 / cfg.g_timebase.num / arg_framerate.num; | 
| 1616             vpx_codec_encode(&encoder, frame_avail ? &raw : NULL, frame_start, | 1977             vpx_codec_encode(&encoder, frame_avail ? &raw : NULL, frame_start, | 
| 1617                              next_frame_start - frame_start, | 1978                              next_frame_start - frame_start, | 
| 1618                              0, arg_deadline); | 1979                              0, arg_deadline); | 
| 1619             vpx_usec_timer_mark(&timer); | 1980             vpx_usec_timer_mark(&timer); | 
| 1620             cx_time += vpx_usec_timer_elapsed(&timer); | 1981             cx_time += vpx_usec_timer_elapsed(&timer); | 
| 1621             ctx_exit_on_error(&encoder, "Failed to encode frame"); | 1982             ctx_exit_on_error(&encoder, "Failed to encode frame"); | 
|  | 1983 | 
|  | 1984             if(cfg.g_pass != VPX_RC_FIRST_PASS) | 
|  | 1985             { | 
|  | 1986                 int q; | 
|  | 1987 | 
|  | 1988                 vpx_codec_control(&encoder, VP8E_GET_LAST_QUANTIZER_64, &q); | 
|  | 1989                 ctx_exit_on_error(&encoder, "Failed to read quantizer"); | 
|  | 1990                 counts[q]++; | 
|  | 1991             } | 
|  | 1992 | 
| 1622             got_data = 0; | 1993             got_data = 0; | 
| 1623 | 1994 | 
| 1624             while ((pkt = vpx_codec_get_cx_data(&encoder, &iter))) | 1995             while ((pkt = vpx_codec_get_cx_data(&encoder, &iter))) | 
| 1625             { | 1996             { | 
| 1626                 got_data = 1; | 1997                 got_data = 1; | 
| 1627 | 1998 | 
| 1628                 switch (pkt->kind) | 1999                 switch (pkt->kind) | 
| 1629                 { | 2000                 { | 
| 1630                 case VPX_CODEC_CX_FRAME_PKT: | 2001                 case VPX_CODEC_CX_FRAME_PKT: | 
| 1631                     frames_out++; | 2002                     frames_out++; | 
| 1632                     fprintf(stderr, " %6luF", | 2003                     fprintf(stderr, " %6luF", | 
| 1633                             (unsigned long)pkt->data.frame.sz); | 2004                             (unsigned long)pkt->data.frame.sz); | 
| 1634 | 2005 | 
|  | 2006                     update_rate_histogram(&rate_hist, &cfg, pkt); | 
| 1635                     if(write_webm) | 2007                     if(write_webm) | 
| 1636                     { | 2008                     { | 
| 1637                         /* Update the hash */ | 2009                         /* Update the hash */ | 
| 1638                         if(!ebml.debug) | 2010                         if(!ebml.debug) | 
| 1639                             hash = murmur(pkt->data.frame.buf, | 2011                             hash = murmur(pkt->data.frame.buf, | 
| 1640                                           pkt->data.frame.sz, hash); | 2012                                           pkt->data.frame.sz, hash); | 
| 1641 | 2013 | 
| 1642                         write_webm_block(&ebml, &cfg, pkt); | 2014                         write_webm_block(&ebml, &cfg, pkt); | 
| 1643                     } | 2015                     } | 
| 1644                     else | 2016                     else | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1703             fprintf(stderr, " %.3lf", ovpsnr); | 2075             fprintf(stderr, " %.3lf", ovpsnr); | 
| 1704             for (i = 0; i < 4; i++) | 2076             for (i = 0; i < 4; i++) | 
| 1705             { | 2077             { | 
| 1706                 fprintf(stderr, " %.3lf", psnr_totals[i]/psnr_count); | 2078                 fprintf(stderr, " %.3lf", psnr_totals[i]/psnr_count); | 
| 1707             } | 2079             } | 
| 1708         } | 2080         } | 
| 1709 | 2081 | 
| 1710         vpx_codec_destroy(&encoder); | 2082         vpx_codec_destroy(&encoder); | 
| 1711 | 2083 | 
| 1712         fclose(infile); | 2084         fclose(infile); | 
|  | 2085         if (file_type == FILE_TYPE_Y4M) | 
|  | 2086             y4m_input_close(&y4m); | 
| 1713 | 2087 | 
| 1714         if(write_webm) | 2088         if(write_webm) | 
| 1715         { | 2089         { | 
| 1716             write_webm_file_footer(&ebml, hash); | 2090             write_webm_file_footer(&ebml, hash); | 
|  | 2091             free(ebml.cue_list); | 
|  | 2092             ebml.cue_list = NULL; | 
| 1717         } | 2093         } | 
| 1718         else | 2094         else | 
| 1719         { | 2095         { | 
| 1720             if (!fseek(outfile, 0, SEEK_SET)) | 2096             if (!fseek(outfile, 0, SEEK_SET)) | 
| 1721                 write_ivf_file_header(outfile, &cfg, codec->fourcc, frames_out); | 2097                 write_ivf_file_header(outfile, &cfg, codec->fourcc, frames_out); | 
| 1722         } | 2098         } | 
| 1723 | 2099 | 
| 1724         fclose(outfile); | 2100         fclose(outfile); | 
| 1725         stats_close(&stats, arg_passes-1); | 2101         stats_close(&stats, arg_passes-1); | 
| 1726         fprintf(stderr, "\n"); | 2102         fprintf(stderr, "\n"); | 
| 1727 | 2103 | 
| 1728         if (one_pass_only) | 2104         if (one_pass_only) | 
| 1729             break; | 2105             break; | 
| 1730     } | 2106     } | 
| 1731 | 2107 | 
|  | 2108     if (show_q_hist_buckets) | 
|  | 2109         show_q_histogram(counts, show_q_hist_buckets); | 
|  | 2110 | 
|  | 2111     if (show_rate_hist_buckets) | 
|  | 2112         show_rate_histogram(&rate_hist, &cfg, show_rate_hist_buckets); | 
|  | 2113     destroy_rate_histogram(&rate_hist); | 
|  | 2114 | 
| 1732     vpx_img_free(&raw); | 2115     vpx_img_free(&raw); | 
| 1733     free(argv); | 2116     free(argv); | 
| 1734     return EXIT_SUCCESS; | 2117     return EXIT_SUCCESS; | 
| 1735 } | 2118 } | 
| OLD | NEW | 
|---|