| 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 |