Compare commits
	
		
			10 Commits
		
	
	
		
			javanwhist
			...
			sandbox/jk
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b76c4c6ba7 | ||
| 
						 | 
					7f6a695771 | ||
| 
						 | 
					a764f61f70 | ||
| 
						 | 
					50c5e81c7c | ||
| 
						 | 
					6463c7cf72 | ||
| 
						 | 
					7070dab445 | ||
| 
						 | 
					0a9b65ba1c | ||
| 
						 | 
					0a50a29121 | ||
| 
						 | 
					118b445bab | ||
| 
						 | 
					3e78b5f2b8 | 
							
								
								
									
										32
									
								
								examples.mk
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								examples.mk
									
									
									
									
									
								
							@@ -8,6 +8,20 @@
 | 
				
			|||||||
##  be found in the AUTHORS file in the root of the source tree.
 | 
					##  be found in the AUTHORS file in the root of the source tree.
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LIBYUV_SRCS +=  third_party/libyuv/include/libyuv/basic_types.h  \
 | 
				
			||||||
 | 
					                third_party/libyuv/include/libyuv/cpu_id.h  \
 | 
				
			||||||
 | 
					                third_party/libyuv/include/libyuv/scale.h  \
 | 
				
			||||||
 | 
					                third_party/libyuv/source/row.h \
 | 
				
			||||||
 | 
					                third_party/libyuv/source/scale.c  \
 | 
				
			||||||
 | 
					                third_party/libyuv/source/cpu_id.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NESTEGG_SRCS += nestegg/halloc/halloc.h \
 | 
				
			||||||
 | 
					                nestegg/halloc/src/align.h \
 | 
				
			||||||
 | 
					                nestegg/halloc/src/halloc.c \
 | 
				
			||||||
 | 
					                nestegg/halloc/src/hlist.h \
 | 
				
			||||||
 | 
					                nestegg/halloc/src/macros.h \
 | 
				
			||||||
 | 
					                nestegg/include/nestegg/nestegg.h \
 | 
				
			||||||
 | 
					                nestegg/src/nestegg.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# List of examples to build. UTILS are files that are taken from the source
 | 
					# List of examples to build. UTILS are files that are taken from the source
 | 
				
			||||||
# tree directly, and GEN_EXAMPLES are files that are created from the
 | 
					# tree directly, and GEN_EXAMPLES are files that are created from the
 | 
				
			||||||
@@ -18,13 +32,7 @@ vpxdec.SRCS                 += vpx_ports/vpx_timer.h
 | 
				
			|||||||
vpxdec.SRCS                 += vpx/vpx_integer.h
 | 
					vpxdec.SRCS                 += vpx/vpx_integer.h
 | 
				
			||||||
vpxdec.SRCS                 += args.c args.h
 | 
					vpxdec.SRCS                 += args.c args.h
 | 
				
			||||||
vpxdec.SRCS                 += tools_common.c tools_common.h
 | 
					vpxdec.SRCS                 += tools_common.c tools_common.h
 | 
				
			||||||
vpxdec.SRCS                 += nestegg/halloc/halloc.h
 | 
					vpxdec.SRCS                 += $(NESTEGG_SRCS)
 | 
				
			||||||
vpxdec.SRCS                 += nestegg/halloc/src/align.h
 | 
					 | 
				
			||||||
vpxdec.SRCS                 += nestegg/halloc/src/halloc.c
 | 
					 | 
				
			||||||
vpxdec.SRCS                 += nestegg/halloc/src/hlist.h
 | 
					 | 
				
			||||||
vpxdec.SRCS                 += nestegg/halloc/src/macros.h
 | 
					 | 
				
			||||||
vpxdec.SRCS                 += nestegg/include/nestegg/nestegg.h
 | 
					 | 
				
			||||||
vpxdec.SRCS                 += nestegg/src/nestegg.c
 | 
					 | 
				
			||||||
vpxdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
 | 
					vpxdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
 | 
				
			||||||
vpxdec.DESCRIPTION           = Full featured decoder
 | 
					vpxdec.DESCRIPTION           = Full featured decoder
 | 
				
			||||||
UTILS-$(CONFIG_ENCODERS)    += vpxenc.c
 | 
					UTILS-$(CONFIG_ENCODERS)    += vpxenc.c
 | 
				
			||||||
@@ -35,6 +43,8 @@ vpxenc.SRCS                 += vpx_ports/mem_ops_aligned.h
 | 
				
			|||||||
vpxenc.SRCS                 += libmkv/EbmlIDs.h
 | 
					vpxenc.SRCS                 += libmkv/EbmlIDs.h
 | 
				
			||||||
vpxenc.SRCS                 += libmkv/EbmlWriter.c
 | 
					vpxenc.SRCS                 += libmkv/EbmlWriter.c
 | 
				
			||||||
vpxenc.SRCS                 += libmkv/EbmlWriter.h
 | 
					vpxenc.SRCS                 += libmkv/EbmlWriter.h
 | 
				
			||||||
 | 
					vpxenc.SRCS                 += $(LIBYUV_SRCS)
 | 
				
			||||||
 | 
					vpxenc.SRCS                 += $(NESTEGG_SRCS)
 | 
				
			||||||
vpxenc.GUID                  = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
 | 
					vpxenc.GUID                  = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
 | 
				
			||||||
vpxenc.DESCRIPTION           = Full featured encoder
 | 
					vpxenc.DESCRIPTION           = Full featured encoder
 | 
				
			||||||
UTILS-$(CONFIG_ENCODERS)    += vp8_scalable_patterns.c
 | 
					UTILS-$(CONFIG_ENCODERS)    += vp8_scalable_patterns.c
 | 
				
			||||||
@@ -98,13 +108,7 @@ vp8cx_set_ref.DESCRIPTION           = VP8 set encoder reference frame
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# C file is provided, not generated automatically.
 | 
					# C file is provided, not generated automatically.
 | 
				
			||||||
GEN_EXAMPLES-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c
 | 
					GEN_EXAMPLES-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c
 | 
				
			||||||
vp8_multi_resolution_encoder.SRCS  \
 | 
					vp8_multi_resolution_encoder.SRCS         += $(LIBYUV_SRCS)
 | 
				
			||||||
                         += third_party/libyuv/include/libyuv/basic_types.h  \
 | 
					 | 
				
			||||||
                            third_party/libyuv/include/libyuv/cpu_id.h  \
 | 
					 | 
				
			||||||
                            third_party/libyuv/include/libyuv/scale.h  \
 | 
					 | 
				
			||||||
                            third_party/libyuv/source/row.h \
 | 
					 | 
				
			||||||
                            third_party/libyuv/source/scale.c  \
 | 
					 | 
				
			||||||
                            third_party/libyuv/source/cpu_id.c
 | 
					 | 
				
			||||||
vp8_multi_resolution_encoder.GUID         = 04f8738e-63c8-423b-90fa-7c2703a374de
 | 
					vp8_multi_resolution_encoder.GUID         = 04f8738e-63c8-423b-90fa-7c2703a374de
 | 
				
			||||||
vp8_multi_resolution_encoder.DESCRIPTION  = VP8 Multiple-resolution Encoding
 | 
					vp8_multi_resolution_encoder.DESCRIPTION  = VP8 Multiple-resolution Encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								third_party/libyuv/source/scale.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								third_party/libyuv/source/scale.c
									
									
									
									
										vendored
									
									
								
							@@ -60,7 +60,7 @@ void SetUseReferenceImpl(int use) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined(__ARM_NEON__) && !defined(YUV_DISABLE_ASM)
 | 
					#if defined(__ARM_NEON__) && !defined(YUV_DISABLE_ASM)
 | 
				
			||||||
#define HAS_SCALEROWDOWN2_NEON
 | 
					#define HAS_SCALEROWDOWN2_NEON
 | 
				
			||||||
void ScaleRowDown2_NEON(const uint8* src_ptr, int /* src_stride */,
 | 
					void ScaleRowDown2_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			||||||
                        uint8* dst, int dst_width) {
 | 
					                        uint8* dst, int dst_width) {
 | 
				
			||||||
  asm volatile (
 | 
					  asm volatile (
 | 
				
			||||||
    "1:                                        \n"
 | 
					    "1:                                        \n"
 | 
				
			||||||
@@ -102,7 +102,7 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HAS_SCALEROWDOWN4_NEON
 | 
					#define HAS_SCALEROWDOWN4_NEON
 | 
				
			||||||
static void ScaleRowDown4_NEON(const uint8* src_ptr, int /* src_stride */,
 | 
					static void ScaleRowDown4_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			||||||
                               uint8* dst_ptr, int dst_width) {
 | 
					                               uint8* dst_ptr, int dst_width) {
 | 
				
			||||||
  asm volatile (
 | 
					  asm volatile (
 | 
				
			||||||
    "1:                                        \n"
 | 
					    "1:                                        \n"
 | 
				
			||||||
@@ -160,7 +160,7 @@ static void ScaleRowDown4Int_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			|||||||
// Down scale from 4 to 3 pixels.  Use the neon multilane read/write
 | 
					// Down scale from 4 to 3 pixels.  Use the neon multilane read/write
 | 
				
			||||||
//  to load up the every 4th pixel into a 4 different registers.
 | 
					//  to load up the every 4th pixel into a 4 different registers.
 | 
				
			||||||
// Point samples 32 pixels to 24 pixels.
 | 
					// Point samples 32 pixels to 24 pixels.
 | 
				
			||||||
static void ScaleRowDown34_NEON(const uint8* src_ptr, int /* src_stride */,
 | 
					static void ScaleRowDown34_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			||||||
                                uint8* dst_ptr, int dst_width) {
 | 
					                                uint8* dst_ptr, int dst_width) {
 | 
				
			||||||
  asm volatile (
 | 
					  asm volatile (
 | 
				
			||||||
    "1:                                        \n"
 | 
					    "1:                                        \n"
 | 
				
			||||||
@@ -284,7 +284,7 @@ const unsigned short mult38_div9[8] __attribute__ ((aligned(16))) =
 | 
				
			|||||||
    65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18 };
 | 
					    65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 32 -> 12
 | 
					// 32 -> 12
 | 
				
			||||||
static void ScaleRowDown38_NEON(const uint8* src_ptr, int,
 | 
					static void ScaleRowDown38_NEON(const uint8* src_ptr, int src_stride,
 | 
				
			||||||
                                uint8* dst_ptr, int dst_width) {
 | 
					                                uint8* dst_ptr, int dst_width) {
 | 
				
			||||||
  asm volatile (
 | 
					  asm volatile (
 | 
				
			||||||
    "vld1.u8      {q3}, [%3]                   \n"
 | 
					    "vld1.u8      {q3}, [%3]                   \n"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -205,6 +205,11 @@ typedef struct macroblockd
 | 
				
			|||||||
    DECLARE_ALIGNED(16, short,  dequant_y2[16]);
 | 
					    DECLARE_ALIGNED(16, short,  dequant_y2[16]);
 | 
				
			||||||
    DECLARE_ALIGNED(16, short,  dequant_uv[16]);
 | 
					    DECLARE_ALIGNED(16, short,  dequant_uv[16]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* position of this macroblock */
 | 
				
			||||||
 | 
					    int mbr;
 | 
				
			||||||
 | 
					    int mbc;
 | 
				
			||||||
 | 
					    int mbrc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 16 Y blocks, 4 U, 4 V, 1 DC 2nd order block, each with 16 entries. */
 | 
					    /* 16 Y blocks, 4 U, 4 V, 1 DC 2nd order block, each with 16 entries. */
 | 
				
			||||||
    BLOCKD block[25];
 | 
					    BLOCKD block[25];
 | 
				
			||||||
    int fullpixel_mask;
 | 
					    int fullpixel_mask;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -411,6 +411,10 @@ void encode_mb_row(VP8_COMP *cpi,
 | 
				
			|||||||
    // for each macroblock col in image
 | 
					    // for each macroblock col in image
 | 
				
			||||||
    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
 | 
					    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        xd->mbr = mb_row;
 | 
				
			||||||
 | 
					        xd->mbc = mb_col;
 | 
				
			||||||
 | 
					        xd->mbrc = mb_row * cm->mb_cols + mb_col;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Distance of Mb to the left & right edges, specified in
 | 
					        // Distance of Mb to the left & right edges, specified in
 | 
				
			||||||
        // 1/8th pel units as they are always compared to values
 | 
					        // 1/8th pel units as they are always compared to values
 | 
				
			||||||
        // that are in 1/8th pel units
 | 
					        // that are in 1/8th pel units
 | 
				
			||||||
@@ -1111,6 +1115,8 @@ extern int cnt_pm;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern void vp8_fix_contexts(MACROBLOCKD *x);
 | 
					extern void vp8_fix_contexts(MACROBLOCKD *x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "valgrind/memcheck.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int vp8cx_encode_inter_macroblock
 | 
					int vp8cx_encode_inter_macroblock
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
 | 
					    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
 | 
				
			||||||
@@ -1130,6 +1136,15 @@ int vp8cx_encode_inter_macroblock
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
        x->encode_breakout = cpi->oxcf.encode_breakout;
 | 
					        x->encode_breakout = cpi->oxcf.encode_breakout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cpi->external_modeinfo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        vp8_rd_use_external_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate,
 | 
				
			||||||
 | 
					                                 &distortion, &intra_error);
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate);
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(distortion);
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(intra_error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
    if (cpi->sf.RD)
 | 
					    if (cpi->sf.RD)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int zbin_mode_boost_enabled = cpi->zbin_mode_boost_enabled;
 | 
					        int zbin_mode_boost_enabled = cpi->zbin_mode_boost_enabled;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -859,7 +859,7 @@ void vp8_set_speed_features(VP8_COMP *cpi)
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            sf->auto_filter = 0;                     // Faster selection of loop filter
 | 
					            sf->auto_filter = 0;                     // Faster selection of loop filter
 | 
				
			||||||
            sf->search_method = HEX;
 | 
					            sf->search_method = HEX;
 | 
				
			||||||
            sf->iterative_sub_pixel = 0;
 | 
					            //sf->iterative_sub_pixel = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Speed > 6)
 | 
					        if (Speed > 6)
 | 
				
			||||||
@@ -2449,7 +2449,7 @@ int vp8_use_as_reference(VP8_COMP *cpi, int ref_frame_flags)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
int vp8_update_reference(VP8_COMP *cpi, int ref_frame_flags)
 | 
					int vp8_update_reference(VP8_COMP *cpi, int ref_frame_flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (ref_frame_flags > 7)
 | 
					    if (ref_frame_flags > 127)
 | 
				
			||||||
        return -1 ;
 | 
					        return -1 ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpi->common.refresh_golden_frame = 0;
 | 
					    cpi->common.refresh_golden_frame = 0;
 | 
				
			||||||
@@ -2465,6 +2465,8 @@ int vp8_update_reference(VP8_COMP *cpi, int ref_frame_flags)
 | 
				
			|||||||
    if (ref_frame_flags & VP8_ALT_FLAG)
 | 
					    if (ref_frame_flags & VP8_ALT_FLAG)
 | 
				
			||||||
        cpi->common.refresh_alt_ref_frame = 1;
 | 
					        cpi->common.refresh_alt_ref_frame = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpi->common.copy_buffer_to_gf = (ref_frame_flags >> 3) & 3;
 | 
				
			||||||
 | 
					    cpi->common.copy_buffer_to_arf = (ref_frame_flags >> 5) & 3;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3187,8 +3189,11 @@ static void encode_frame_to_data_rate
 | 
				
			|||||||
        cpi->per_frame_bandwidth  = (int)(cpi->target_bandwidth / cpi->output_frame_rate);
 | 
					        cpi->per_frame_bandwidth  = (int)(cpi->target_bandwidth / cpi->output_frame_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Default turn off buffer to buffer copying
 | 
					    // Default turn off buffer to buffer copying
 | 
				
			||||||
 | 
					    if(!cpi->external_modeinfo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
    cm->copy_buffer_to_gf = 0;
 | 
					    cm->copy_buffer_to_gf = 0;
 | 
				
			||||||
    cm->copy_buffer_to_arf = 0;
 | 
					    cm->copy_buffer_to_arf = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Clear zbin over-quant value and mode boost values.
 | 
					    // Clear zbin over-quant value and mode boost values.
 | 
				
			||||||
    cpi->zbin_over_quant = 0;
 | 
					    cpi->zbin_over_quant = 0;
 | 
				
			||||||
@@ -4063,10 +4068,14 @@ static void encode_frame_to_data_rate
 | 
				
			|||||||
    // For inter frames the current default behavior is that when
 | 
					    // For inter frames the current default behavior is that when
 | 
				
			||||||
    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
 | 
					    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
 | 
				
			||||||
    // This is purely an encoder decision at present.
 | 
					    // This is purely an encoder decision at present.
 | 
				
			||||||
    if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame)
 | 
					    if(!cpi->external_modeinfo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame
 | 
				
			||||||
 | 
					        && !cm->refresh_alt_ref_frame)
 | 
				
			||||||
        cm->copy_buffer_to_arf  = 2;
 | 
					        cm->copy_buffer_to_arf  = 2;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        cm->copy_buffer_to_arf  = 0;
 | 
					        cm->copy_buffer_to_arf  = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
 | 
					    cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4620,7 +4629,12 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cm = &cpi->common;
 | 
					    cm = &cpi->common;
 | 
				
			||||||
 | 
					if(cm->refresh_last_frame && cm->refresh_golden_frame && cm->refresh_alt_ref_frame)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    cm->refresh_golden_frame = 0;
 | 
				
			||||||
 | 
					    cm->refresh_alt_ref_frame = 0;
 | 
				
			||||||
 | 
					    *frame_flags |= 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    if (setjmp(cpi->common.error.jmp))
 | 
					    if (setjmp(cpi->common.error.jmp))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        cpi->common.error.setjmp = 0;
 | 
					        cpi->common.error.setjmp = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -678,7 +678,7 @@ typedef struct VP8_COMP
 | 
				
			|||||||
    /* Number of MBs per row at lower-resolution level */
 | 
					    /* Number of MBs per row at lower-resolution level */
 | 
				
			||||||
    int    mr_low_res_mb_cols;
 | 
					    int    mr_low_res_mb_cols;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    MODE_INFO *external_modeinfo;
 | 
				
			||||||
} VP8_COMP;
 | 
					} VP8_COMP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void control_data_rate(VP8_COMP *cpi);
 | 
					void control_data_rate(VP8_COMP *cpi);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@
 | 
				
			|||||||
#include "rdopt.h"
 | 
					#include "rdopt.h"
 | 
				
			||||||
#include "vpx_mem/vpx_mem.h"
 | 
					#include "vpx_mem/vpx_mem.h"
 | 
				
			||||||
#include "vp8/common/systemdependent.h"
 | 
					#include "vp8/common/systemdependent.h"
 | 
				
			||||||
 | 
					#include "valgrind/memcheck.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);
 | 
					extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -735,11 +736,12 @@ static int rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate,
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VALGRIND_CHECK_VALUE_IS_DEFINED(tot_rate_y);
 | 
				
			||||||
 | 
					    VALGRIND_CHECK_VALUE_IS_DEFINED(total_rd);
 | 
				
			||||||
    if(total_rd >= (int64_t)best_rd)
 | 
					    if(total_rd >= (int64_t)best_rd)
 | 
				
			||||||
        return INT_MAX;
 | 
					        return INT_MAX;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    *Rate = cost;
 | 
					    *Rate = cost;
 | 
				
			||||||
    *rate_y += tot_rate_y;
 | 
					    *rate_y = tot_rate_y;
 | 
				
			||||||
    *Distortion = distortion;
 | 
					    *Distortion = distortion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
 | 
					    return RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
 | 
				
			||||||
@@ -1477,6 +1479,246 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
 | 
				
			|||||||
    return bsi.segment_rd;
 | 
					    return bsi.segment_rd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void rd_reuse_segment(VP8_COMP *cpi, MACROBLOCK *x,
 | 
				
			||||||
 | 
					                             BEST_SEG_INFO *bsi, unsigned int segmentation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    int const *labels;
 | 
				
			||||||
 | 
					    int br = 0;
 | 
				
			||||||
 | 
					    int bd = 0;
 | 
				
			||||||
 | 
					    B_PREDICTION_MODE this_mode;
 | 
				
			||||||
 | 
					    int_mv reused_mv[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int label_count;
 | 
				
			||||||
 | 
					    int this_segment_rd = 0;
 | 
				
			||||||
 | 
					    int label_mv_thresh;
 | 
				
			||||||
 | 
					    int rate = 0;
 | 
				
			||||||
 | 
					    int sbr = 0;
 | 
				
			||||||
 | 
					    int sbd = 0;
 | 
				
			||||||
 | 
					    int segmentyrate = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vp8_variance_fn_ptr_t *v_fn_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT_PLANES t_above, t_left;
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT *ta;
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT *tl;
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT_PLANES t_above_b, t_left_b;
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT *ta_b;
 | 
				
			||||||
 | 
					    ENTROPY_CONTEXT *tl_b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					    vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ta = (ENTROPY_CONTEXT *)&t_above;
 | 
				
			||||||
 | 
					    tl = (ENTROPY_CONTEXT *)&t_left;
 | 
				
			||||||
 | 
					    ta_b = (ENTROPY_CONTEXT *)&t_above_b;
 | 
				
			||||||
 | 
					    tl_b = (ENTROPY_CONTEXT *)&t_left_b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    br = 0;
 | 
				
			||||||
 | 
					    bd = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v_fn_ptr = &cpi->fn_ptr[segmentation];
 | 
				
			||||||
 | 
					    labels = vp8_mbsplits[segmentation];
 | 
				
			||||||
 | 
					    label_count = vp8_mbsplit_count[segmentation];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 64 makes this threshold really big effectively
 | 
				
			||||||
 | 
					    // making it so that we very rarely check mvs on
 | 
				
			||||||
 | 
					    // segments.   setting this to 1 would make mv thresh
 | 
				
			||||||
 | 
					    // roughly equal to what it is for macroblocks
 | 
				
			||||||
 | 
					    label_mv_thresh = 1 * bsi->mvthresh / label_count ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Segmentation method overheads
 | 
				
			||||||
 | 
					    rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);
 | 
				
			||||||
 | 
					    rate += vp8_cost_mv_ref(SPLITMV, bsi->mdcounts);
 | 
				
			||||||
 | 
					    this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
 | 
				
			||||||
 | 
					    br += rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					        reused_mv[i].as_int = x->e_mbd.block[i].bmi.mv.as_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < label_count; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int_mv mode_mv[B_MODE_COUNT];
 | 
				
			||||||
 | 
					        int best_label_rd = INT_MAX;
 | 
				
			||||||
 | 
					        B_PREDICTION_MODE mode_selected = ZERO4X4;
 | 
				
			||||||
 | 
					        int bestlabelyrate = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // search for the best motion vector on this segment
 | 
				
			||||||
 | 
					        for (this_mode = LEFT4X4; this_mode <= NEW4X4 ; this_mode ++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int this_rd;
 | 
				
			||||||
 | 
					            int distortion;
 | 
				
			||||||
 | 
					            int labelyrate;
 | 
				
			||||||
 | 
					            ENTROPY_CONTEXT_PLANES t_above_s, t_left_s;
 | 
				
			||||||
 | 
					            ENTROPY_CONTEXT *ta_s;
 | 
				
			||||||
 | 
					            ENTROPY_CONTEXT *tl_s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            vpx_memcpy(&t_above_s, &t_above, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					            vpx_memcpy(&t_left_s, &t_left, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ta_s = (ENTROPY_CONTEXT *)&t_above_s;
 | 
				
			||||||
 | 
					            tl_s = (ENTROPY_CONTEXT *)&t_left_s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* find the first block for this label */
 | 
				
			||||||
 | 
					            if (this_mode == NEW4X4)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int b;
 | 
				
			||||||
 | 
					                for(b=0; b<16; b++)
 | 
				
			||||||
 | 
					                    if(labels[b] == i) break;
 | 
				
			||||||
 | 
					                mode_mv[NEW4X4].as_int = reused_mv[b].as_int;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
 | 
				
			||||||
 | 
					                               bsi->ref_mv, x->mvcost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Trap vectors that reach beyond the UMV borders
 | 
				
			||||||
 | 
					            if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
 | 
				
			||||||
 | 
					                ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            distortion = vp8_encode_inter_mb_segment(x, labels, i) / 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            labelyrate = rdcost_mbsegment_y(x, labels, i, ta_s, tl_s);
 | 
				
			||||||
 | 
					            rate += labelyrate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this_rd < best_label_rd)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                sbr = rate;
 | 
				
			||||||
 | 
					                sbd = distortion;
 | 
				
			||||||
 | 
					                bestlabelyrate = labelyrate;
 | 
				
			||||||
 | 
					                mode_selected = this_mode;
 | 
				
			||||||
 | 
					                best_label_rd = this_rd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                vpx_memcpy(ta_b, ta_s, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					                vpx_memcpy(tl_b, tl_s, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } /*for each 4x4 mode*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vpx_memcpy(ta, ta_b, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					        vpx_memcpy(tl, tl_b, sizeof(ENTROPY_CONTEXT_PLANES));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
 | 
				
			||||||
 | 
					                    bsi->ref_mv, x->mvcost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        br += sbr;
 | 
				
			||||||
 | 
					        bd += sbd;
 | 
				
			||||||
 | 
					        segmentyrate += bestlabelyrate;
 | 
				
			||||||
 | 
					        this_segment_rd += best_label_rd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this_segment_rd >= bsi->segment_rd)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } /* for each label */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this_segment_rd < bsi->segment_rd)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bsi->r = br;
 | 
				
			||||||
 | 
					        bsi->d = bd;
 | 
				
			||||||
 | 
					        bsi->segment_yrate = segmentyrate;
 | 
				
			||||||
 | 
					        bsi->segment_rd = this_segment_rd;
 | 
				
			||||||
 | 
					        bsi->segment_num = segmentation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // store everything needed to come back to this!!
 | 
				
			||||||
 | 
					        for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
 | 
				
			||||||
 | 
					            bsi->modes[i] = x->partition_info->bmi[i].mode;
 | 
				
			||||||
 | 
					            bsi->eobs[i] = x->e_mbd.eobs[i];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int vp8_rd_reuse_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
 | 
				
			||||||
 | 
					                                           int_mv *best_ref_mv, int best_rd,
 | 
				
			||||||
 | 
					                                           int *mdcounts, int *returntotrate,
 | 
				
			||||||
 | 
					                                           int *returnyrate, int *returndistortion,
 | 
				
			||||||
 | 
					                                           int mvthresh)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    BEST_SEG_INFO bsi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vpx_memset(&bsi, 0, sizeof(bsi));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bsi.segment_rd = best_rd;
 | 
				
			||||||
 | 
					    bsi.ref_mv = best_ref_mv;
 | 
				
			||||||
 | 
					    bsi.mvp.as_int = best_ref_mv->as_int;
 | 
				
			||||||
 | 
					    bsi.mvthresh = mvthresh;
 | 
				
			||||||
 | 
					    bsi.mdcounts = mdcounts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bsi.modes[i] = ZERO4X4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(s = 0; s < BLOCK_4X4; s++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            char set[16] = {0};
 | 
				
			||||||
 | 
					            int smv[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (i=0; i<16; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int p = vp8_mbsplits[s][i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(!set[p])
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    set[p] = 1;
 | 
				
			||||||
 | 
					                    smv[p] = x->e_mbd.block[i].bmi.mv.as_int;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if(smv[p] != x->e_mbd.block[i].bmi.mv.as_int)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if(i==16)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        rd_check_segment(cpi, x, &bsi, s);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* set it to the best */
 | 
				
			||||||
 | 
					    for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BLOCKD *bd = &x->e_mbd.block[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bd->bmi.mv.as_int = bsi.mvs[i].as_int;
 | 
				
			||||||
 | 
					        *bd->eob = bsi.eobs[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *returntotrate = bsi.r;
 | 
				
			||||||
 | 
					    *returndistortion = bsi.d;
 | 
				
			||||||
 | 
					    *returnyrate = bsi.segment_yrate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* save partitions */
 | 
				
			||||||
 | 
					    x->e_mbd.mode_info_context->mbmi.partitioning = bsi.segment_num;
 | 
				
			||||||
 | 
					    x->partition_info->count = vp8_mbsplit_count[bsi.segment_num];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < x->partition_info->count; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        j = vp8_mbsplit_offset[bsi.segment_num][i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x->partition_info->bmi[i].mode = bsi.modes[j];
 | 
				
			||||||
 | 
					        x->partition_info->bmi[i].mv.as_mv = bsi.mvs[j].as_mv;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * used to set x->e_mbd.mode_info_context->mbmi.mv.as_int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    x->partition_info->bmi[15].mv.as_int = bsi.mvs[15].as_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return bsi.segment_rd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//The improved MV prediction
 | 
					//The improved MV prediction
 | 
				
			||||||
void vp8_mv_pred
 | 
					void vp8_mv_pred
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
@@ -1709,6 +1951,591 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					void vp8_rd_use_external_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
 | 
				
			||||||
 | 
					                            int recon_uvoffset, int *returnrate,
 | 
				
			||||||
 | 
					                            int *returndistortion, int *returnintra)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned char *plane[4][3];
 | 
				
			||||||
 | 
					    MODE_INFO *mi;
 | 
				
			||||||
 | 
					    int rate, rate_y, rate_uv;
 | 
				
			||||||
 | 
					    int distortion, distortion_y, distortion_uv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mi = cpi->external_modeinfo + x->e_mbd.mbrc;
 | 
				
			||||||
 | 
					    *x->e_mbd.mode_info_context = *mi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Map partitioning info */
 | 
				
			||||||
 | 
					    if(mi->mbmi.mode == SPLITMV)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x->partition_info->count = vp8_mbsplit_count[mi->mbmi.partitioning];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < x->partition_info->count; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            j = vp8_mbsplit_offset[mi->mbmi.partitioning][i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* TODO: this is mapping a union onto a struct, assume the
 | 
				
			||||||
 | 
					             * data will never be looked at from the wrong context.
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					            x->partition_info->bmi[i].mode = NEW4X4; //mi->bmi[j].as_mode;
 | 
				
			||||||
 | 
					            x->partition_info->bmi[i].mv.as_int = mi->bmi[j].mv.as_int;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * used to set x->e_mbd.mode_info_context->mbmi.mv.as_int
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        x->partition_info->bmi[15].mv.as_int = mi->bmi[15].mv.as_int;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rate = x->mbmode_cost[x->e_mbd.frame_type][mi->mbmi.mode];
 | 
				
			||||||
 | 
					    rate += x->ref_frame_cost[mi->mbmi.ref_frame];
 | 
				
			||||||
 | 
					    if(mi->mbmi.ref_frame == INTRA_FRAME)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        vp8_build_intra_predictors_mby(&x->e_mbd);
 | 
				
			||||||
 | 
					        macro_block_yrd(x, &rate_y, &distortion);
 | 
				
			||||||
 | 
					        //hack
 | 
				
			||||||
 | 
					        rate_uv = rate_y/4;
 | 
				
			||||||
 | 
					        distortion_uv = distortion_y/4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int sign_bias;
 | 
				
			||||||
 | 
					        int_mv best_ref_mv_sb[2];
 | 
				
			||||||
 | 
					        int_mv mode_mv_sb[2][MB_MODE_COUNT];
 | 
				
			||||||
 | 
					        int_mv best_ref_mv;
 | 
				
			||||||
 | 
					        int mdcounts[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
 | 
				
			||||||
 | 
					        x->e_mbd.pre.y_buffer = plane[mi->mbmi.ref_frame][0];
 | 
				
			||||||
 | 
					        x->e_mbd.pre.u_buffer = plane[mi->mbmi.ref_frame][1];
 | 
				
			||||||
 | 
					        x->e_mbd.pre.v_buffer = plane[mi->mbmi.ref_frame][2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Get nearby MV info */
 | 
				
			||||||
 | 
					        sign_bias = vp8_find_near_mvs_bias(&x->e_mbd,
 | 
				
			||||||
 | 
					                                           x->e_mbd.mode_info_context,
 | 
				
			||||||
 | 
					                                           mode_mv_sb,
 | 
				
			||||||
 | 
					                                           best_ref_mv_sb,
 | 
				
			||||||
 | 
					                                           mdcounts,
 | 
				
			||||||
 | 
					                                           mi->mbmi.ref_frame,
 | 
				
			||||||
 | 
					                                           cpi->common.ref_frame_sign_bias);
 | 
				
			||||||
 | 
					        best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(mi->mbmi.mode != ZEROMV)
 | 
				
			||||||
 | 
					            rate += vp8_mv_bit_cost(&mi->mbmi.mv, &best_ref_mv, x->mvcost, 96);
 | 
				
			||||||
 | 
					        rate += vp8_cost_mv_ref(mi->mbmi.mode, mdcounts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.predictor, 16);
 | 
				
			||||||
 | 
					        //rate += vp8_cost_mv_ref(mi->mbmi.mode, mdcounts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Y cost and distortion
 | 
				
			||||||
 | 
					        macro_block_yrd(x, &rate_y, &distortion_y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // UV cost and distortion
 | 
				
			||||||
 | 
					        rd_inter16x16_uv(cpi, x, &rate_uv, &distortion_uv,
 | 
				
			||||||
 | 
					                         cpi->common.full_pixel);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Test for skip blocks */
 | 
				
			||||||
 | 
					    if (cpi->common.mb_no_coeff_skip)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int i, bit=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(i=0; i<24; i++)
 | 
				
			||||||
 | 
					            if(x->e_mbd.eobs[i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                bit = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        if(bit)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            rate_y = 0;
 | 
				
			||||||
 | 
					            rate_uv = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        rate += vp8_cost_bit(cpi->prob_skip_false, bit);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *returnrate = rate + rate_y + rate_uv;
 | 
				
			||||||
 | 
					    *returndistortion = distortion + distortion_y + distortion_uv;
 | 
				
			||||||
 | 
					    *returnintra = (mi->mbmi.ref_frame == INTRA_FRAME)
 | 
				
			||||||
 | 
					                   ? *returndistortion : INT_MAX;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					void vp8_rd_use_external_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
 | 
				
			||||||
 | 
					                            int recon_uvoffset, int *returnrate,
 | 
				
			||||||
 | 
					                            int *returndistortion, int *returnintra)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MODE_INFO *mi = cpi->external_modeinfo + x->e_mbd.mbrc;
 | 
				
			||||||
 | 
					    BLOCK *b = &x->block[0];
 | 
				
			||||||
 | 
					    BLOCKD *d = &x->e_mbd.block[0];
 | 
				
			||||||
 | 
					    MACROBLOCKD *xd = &x->e_mbd;
 | 
				
			||||||
 | 
					    union b_mode_info best_bmodes[16];
 | 
				
			||||||
 | 
					    MB_MODE_INFO best_mbmode;
 | 
				
			||||||
 | 
					    PARTITION_INFO best_partition;
 | 
				
			||||||
 | 
					    int_mv best_ref_mv_sb[2];
 | 
				
			||||||
 | 
					    int_mv mode_mv_sb[2][MB_MODE_COUNT];
 | 
				
			||||||
 | 
					    int_mv best_ref_mv;
 | 
				
			||||||
 | 
					    int_mv *mode_mv;
 | 
				
			||||||
 | 
					    MB_PREDICTION_MODE this_mode;
 | 
				
			||||||
 | 
					    int num00;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    int mdcounts[4];
 | 
				
			||||||
 | 
					    int rate=0;
 | 
				
			||||||
 | 
					    int distortion=0;
 | 
				
			||||||
 | 
					    int best_rd = INT_MAX;
 | 
				
			||||||
 | 
					    int rate2, distortion2;
 | 
				
			||||||
 | 
					    int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly;
 | 
				
			||||||
 | 
					    int rate_y, UNINITIALIZED_IS_SAFE(rate_uv);
 | 
				
			||||||
 | 
					    int distortion_uv;
 | 
				
			||||||
 | 
					    int best_yrd = INT_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MB_PREDICTION_MODE uv_intra_mode;
 | 
				
			||||||
 | 
					    int_mv mvp;
 | 
				
			||||||
 | 
					    int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
 | 
				
			||||||
 | 
					    int saddone=0;
 | 
				
			||||||
 | 
					    int sr=0;    //search range got from mv_pred(). It uses step_param levels. (0-7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned char *plane[4][3];
 | 
				
			||||||
 | 
					    int sign_bias = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mode_mv = mode_mv_sb[sign_bias];
 | 
				
			||||||
 | 
					    best_ref_mv.as_int = 0;
 | 
				
			||||||
 | 
					    vpx_memset(mode_mv_sb, 0, sizeof(mode_mv_sb));
 | 
				
			||||||
 | 
					    vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
 | 
				
			||||||
 | 
					    vpx_memset(&best_bmodes, 0, sizeof(best_bmodes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sign_bias = vp8_find_near_mvs_bias(&x->e_mbd,
 | 
				
			||||||
 | 
					                                           x->e_mbd.mode_info_context,
 | 
				
			||||||
 | 
					                                           mode_mv_sb,
 | 
				
			||||||
 | 
					                                           best_ref_mv_sb,
 | 
				
			||||||
 | 
					                                           mdcounts,
 | 
				
			||||||
 | 
					                                           LAST_FRAME,
 | 
				
			||||||
 | 
					                                           cpi->common.ref_frame_sign_bias);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mode_mv = mode_mv_sb[sign_bias];
 | 
				
			||||||
 | 
					        best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cpi->ref_frame_flags|=0x7;
 | 
				
			||||||
 | 
					    get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *returnintra = INT_MAX;
 | 
				
			||||||
 | 
					    cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x->skip = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
 | 
				
			||||||
 | 
					    rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
 | 
				
			||||||
 | 
					    uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int this_rd = INT_MAX;
 | 
				
			||||||
 | 
					        int disable_skip = 0;
 | 
				
			||||||
 | 
					        int other_cost = 0;
 | 
				
			||||||
 | 
					        int this_ref_frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // These variables hold are rolling total cost and distortion for this mode
 | 
				
			||||||
 | 
					        rate2 = 0;
 | 
				
			||||||
 | 
					        distortion2 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this_mode = mi->mbmi.mode; //JRK
 | 
				
			||||||
 | 
					        this_ref_frame = mi->mbmi.ref_frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
					        memcpy(x->e_mbd.mode_info_context, mi, sizeof(*mi));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.mode = this_mode;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					//if(this_mode == SPLITMV) this_mode=NEWMV;
 | 
				
			||||||
 | 
					        /* everything but intra */
 | 
				
			||||||
 | 
					        if (x->e_mbd.mode_info_context->mbmi.ref_frame)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
 | 
				
			||||||
 | 
					            x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
 | 
				
			||||||
 | 
					            x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (sign_bias != cpi->common.ref_frame_sign_bias[this_ref_frame])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame];
 | 
				
			||||||
 | 
					                mode_mv = mode_mv_sb[sign_bias];
 | 
				
			||||||
 | 
					                best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
 | 
				
			||||||
 | 
					        if (cpi->zbin_mode_boost_enabled)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if ( this_ref_frame == INTRA_FRAME )
 | 
				
			||||||
 | 
					                cpi->zbin_mode_boost = 0;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (this_mode == ZEROMV)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (this_ref_frame != LAST_FRAME)
 | 
				
			||||||
 | 
					                        cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (this_mode == SPLITMV)
 | 
				
			||||||
 | 
					                    cpi->zbin_mode_boost = 0;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    cpi->zbin_mode_boost = MV_ZBIN_BOOST;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            vp8_update_zbin_extra(cpi, x);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate2);
 | 
				
			||||||
 | 
					        switch (this_mode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        case B_PRED:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int tmp_rd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Note the rate value returned here includes the cost of coding the BPRED mode : x->mbmode_cost[x->e_mbd.frame_type][BPRED];
 | 
				
			||||||
 | 
					            tmp_rd = rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y, &distortion, INT_MAX);
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(rate);
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(rate_y);
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(distortion);
 | 
				
			||||||
 | 
					            rate2 += rate;
 | 
				
			||||||
 | 
					            distortion2 += distortion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(tmp_rd < best_yrd)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                rate2 += uv_intra_rate;
 | 
				
			||||||
 | 
					                rate_uv = uv_intra_rate_tokenonly;
 | 
				
			||||||
 | 
					                distortion2 += uv_intra_distortion;
 | 
				
			||||||
 | 
					                distortion_uv = uv_intra_distortion;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this_rd = INT_MAX;
 | 
				
			||||||
 | 
					                disable_skip = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case SPLITMV:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
					            int tmp_rd;
 | 
				
			||||||
 | 
					            int this_rd_thresh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //this_rd_thresh = (this_ref_frame == 1) ? cpi->rd_threshes[THR_NEW1] : cpi->rd_threshes[THR_NEW3];
 | 
				
			||||||
 | 
					            //this_rd_thresh = (this_ref_frame == 2) ? cpi->rd_threshes[THR_NEW2] : this_rd_thresh;
 | 
				
			||||||
 | 
					            this_rd_thresh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					            tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
 | 
				
			||||||
 | 
					                                                     best_yrd, mdcounts,
 | 
				
			||||||
 | 
					                                                     &rate, &rate_y, &distortion, this_rd_thresh) ;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            tmp_rd = vp8_rd_reuse_mbsegmentation(cpi, x, &best_ref_mv,
 | 
				
			||||||
 | 
					                                                 best_yrd, mdcounts,
 | 
				
			||||||
 | 
					                                                 &rate, &rate_y, &distortion, this_rd_thresh) ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(rate);
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(distortion);
 | 
				
			||||||
 | 
					            rate2 += rate;
 | 
				
			||||||
 | 
					            distortion2 += distortion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If even the 'Y' rd value of split is higher than best so far then dont bother looking at UV
 | 
				
			||||||
 | 
					            if (tmp_rd < best_yrd)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Now work out UV cost and add it in
 | 
				
			||||||
 | 
					                rd_inter4x4_uv(cpi, x, &rate_uv, &distortion_uv, cpi->common.full_pixel);
 | 
				
			||||||
 | 
					                rate2 += rate_uv;
 | 
				
			||||||
 | 
					                distortion2 += distortion_uv;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this_rd = INT_MAX;
 | 
				
			||||||
 | 
					                disable_skip = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                x->e_mbd.block[i].bmi = mi->bmi[i];
 | 
				
			||||||
 | 
					                x->e_mbd.block[i].eob = 15;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            x->e_mbd.mode_info_context->mbmi.partitioning = mi->mbmi.partitioning;
 | 
				
			||||||
 | 
					            x->partition_info->count = vp8_mbsplit_count[mi->mbmi.partitioning];
 | 
				
			||||||
 | 
					            for (i = 0; i < x->partition_info->count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                j = vp8_mbsplit_offset[mi->mbmi.partitioning][i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                x->partition_info->bmi[i].mode =
 | 
				
			||||||
 | 
					                    mi->bmi[j].mv.as_int ? NEW4X4 : ZERO4X4;
 | 
				
			||||||
 | 
					                x->partition_info->bmi[i].mv.as_mv = mi->bmi[j].mv.as_mv;
 | 
				
			||||||
 | 
					                distortion2 = vp8_encode_inter_mb_segment(x, vp8_mbsplits[segmentation], i);
 | 
				
			||||||
 | 
					                rate2 = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode], bsi->ref_mv, x->mvcost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate_y);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        case DC_PRED:
 | 
				
			||||||
 | 
					        case V_PRED:
 | 
				
			||||||
 | 
					        case H_PRED:
 | 
				
			||||||
 | 
					        case TM_PRED:
 | 
				
			||||||
 | 
					            x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
 | 
				
			||||||
 | 
					            vp8_build_intra_predictors_mby
 | 
				
			||||||
 | 
					                (&x->e_mbd);
 | 
				
			||||||
 | 
					            macro_block_yrd(x, &rate_y, &distortion) ;
 | 
				
			||||||
 | 
					            rate2 += rate_y;
 | 
				
			||||||
 | 
					            distortion2 += distortion;
 | 
				
			||||||
 | 
					            rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode];
 | 
				
			||||||
 | 
					            rate2 += uv_intra_rate;
 | 
				
			||||||
 | 
					            rate_uv = uv_intra_rate_tokenonly;
 | 
				
			||||||
 | 
					            distortion2 += uv_intra_distortion;
 | 
				
			||||||
 | 
					            distortion_uv = uv_intra_distortion;
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate_y);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case NEWMV:
 | 
				
			||||||
 | 
					            mode_mv[NEWMV].as_int = mi->mbmi.mv.as_int;
 | 
				
			||||||
 | 
					        case NEARESTMV:
 | 
				
			||||||
 | 
					        case NEARMV:
 | 
				
			||||||
 | 
					            // Clip "next_nearest" so that it does not extend to far out of image
 | 
				
			||||||
 | 
					            vp8_clamp_mv2(&mode_mv[this_mode], xd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
 | 
				
			||||||
 | 
					            if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) && (mode_mv[this_mode].as_int == 0))
 | 
				
			||||||
 | 
					                this_mode = ZEROMV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case ZEROMV:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Trap vectors that reach beyond the UMV borders
 | 
				
			||||||
 | 
					            // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
 | 
				
			||||||
 | 
					            // because of the lack of break statements in the previous two cases.
 | 
				
			||||||
 | 
					            if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
 | 
				
			||||||
 | 
					                ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max))
 | 
				
			||||||
 | 
					                assert(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]);
 | 
				
			||||||
 | 
					            vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.predictor, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (cpi->active_map_enabled && x->active_ptr[0] == 0) {
 | 
				
			||||||
 | 
					                x->skip = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (x->encode_breakout)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                unsigned int sse;
 | 
				
			||||||
 | 
					                unsigned int var;
 | 
				
			||||||
 | 
					                int threshold = (xd->block[0].dequant[1]
 | 
				
			||||||
 | 
					                            * xd->block[0].dequant[1] >>4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(threshold < x->encode_breakout)
 | 
				
			||||||
 | 
					                    threshold = x->encode_breakout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var = vp8_variance16x16
 | 
				
			||||||
 | 
					                        (*(b->base_src), b->src_stride,
 | 
				
			||||||
 | 
					                        x->e_mbd.predictor, 16, &sse);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (sse < threshold)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                     unsigned int q2dc = xd->block[24].dequant[0];
 | 
				
			||||||
 | 
					                    /* If theres is no codeable 2nd order dc
 | 
				
			||||||
 | 
					                       or a very small uniform pixel change change */
 | 
				
			||||||
 | 
					                    if ((sse - var < q2dc * q2dc >>4) ||
 | 
				
			||||||
 | 
					                        (sse /2 > var && sse-var < 64))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // Check u and v to make sure skip is ok
 | 
				
			||||||
 | 
					                        int sse2=  VP8_UVSSE(x);
 | 
				
			||||||
 | 
					                        if (sse2 * 2 < threshold)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            x->skip = 1;
 | 
				
			||||||
 | 
					                            distortion2 = sse + sse2;
 | 
				
			||||||
 | 
					                            rate2 = 500;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            /* for best_yrd calculation */
 | 
				
			||||||
 | 
					                            rate_uv = 0;
 | 
				
			||||||
 | 
					                            distortion_uv = sse2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            disable_skip = 1;
 | 
				
			||||||
 | 
					                            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //intermodecost[mode_index] = vp8_cost_mv_ref(this_mode, mdcounts);   // Experimental debug code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Add in the Mv/mode cost
 | 
				
			||||||
 | 
					            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Y cost and distortion
 | 
				
			||||||
 | 
					            macro_block_yrd(x, &rate_y, &distortion);
 | 
				
			||||||
 | 
					            rate2 += rate_y;
 | 
				
			||||||
 | 
					            distortion2 += distortion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // UV cost and distortion
 | 
				
			||||||
 | 
					            rd_inter16x16_uv(cpi, x, &rate_uv, &distortion_uv, cpi->common.full_pixel);
 | 
				
			||||||
 | 
					            rate2 += rate_uv;
 | 
				
			||||||
 | 
					            distortion2 += distortion_uv;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            assert(0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate_y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate2);
 | 
				
			||||||
 | 
					        // Where skip is allowable add in the default per mb cost for the no skip case.
 | 
				
			||||||
 | 
					        // where we then decide to skip we have to delete this and replace it with the
 | 
				
			||||||
 | 
					        // cost of signallying a skip
 | 
				
			||||||
 | 
					        if (cpi->common.mb_no_coeff_skip)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            other_cost += vp8_cost_bit(cpi->prob_skip_false, 0);
 | 
				
			||||||
 | 
					            rate2 += other_cost;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Estimate the reference frame signaling cost and add it
 | 
				
			||||||
 | 
					         * to the rolling cost variable.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        rate2 +=
 | 
				
			||||||
 | 
					            x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate2);
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate_y);
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate_uv);
 | 
				
			||||||
 | 
					        if (!disable_skip)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Test for the condition where skip block will be activated because there are no non zero coefficients and make any necessary adjustment for rate
 | 
				
			||||||
 | 
					            if (cpi->common.mb_no_coeff_skip)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int tteob;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                tteob = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (i = 0; i <= 24; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    tteob += x->e_mbd.eobs[i];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (tteob == 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    rate2 -= (rate_y + rate_uv);
 | 
				
			||||||
 | 
					                    //for best_yrd calculation
 | 
				
			||||||
 | 
					                    rate_uv = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // Back out no skip flag costing and add in skip flag costing
 | 
				
			||||||
 | 
					                    if (cpi->prob_skip_false)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        int prob_skip_cost;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1);
 | 
				
			||||||
 | 
					                        prob_skip_cost -= vp8_cost_bit(cpi->prob_skip_false, 0);
 | 
				
			||||||
 | 
					                        rate2 += prob_skip_cost;
 | 
				
			||||||
 | 
					                        other_cost += prob_skip_cost;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Calculate the final RD estimate for this mode
 | 
				
			||||||
 | 
					            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VALGRIND_CHECK_VALUE_IS_DEFINED(rate2);
 | 
				
			||||||
 | 
					        // Keep record of best intra distortion
 | 
				
			||||||
 | 
					        if (x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *returnintra = distortion2 ;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Did this mode help.. i.i is it the new best mode
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (this_mode <= B_PRED)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode;
 | 
				
			||||||
 | 
					                /* required for left and above block mv */
 | 
				
			||||||
 | 
					                x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            other_cost +=
 | 
				
			||||||
 | 
					            x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Calculate the final y RD estimate for this mode */
 | 
				
			||||||
 | 
					            best_yrd = RDCOST(x->rdmult, x->rddiv, (rate2-rate_uv-other_cost),
 | 
				
			||||||
 | 
					                              (distortion2-distortion_uv));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            VALGRIND_CHECK_VALUE_IS_DEFINED(rate2);
 | 
				
			||||||
 | 
					            *returnrate = rate2;
 | 
				
			||||||
 | 
					            *returndistortion = distortion2;
 | 
				
			||||||
 | 
					            best_rd = this_rd;
 | 
				
			||||||
 | 
					            vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, sizeof(MB_MODE_INFO));
 | 
				
			||||||
 | 
					            vpx_memcpy(&best_partition, x->partition_info, sizeof(PARTITION_INFO));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ((this_mode == B_PRED) || (this_mode == SPLITMV))
 | 
				
			||||||
 | 
					                for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    best_bmodes[i] = x->e_mbd.block[i].bmi;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VALGRIND_CHECK_VALUE_IS_DEFINED(*returnrate);
 | 
				
			||||||
 | 
					    VALGRIND_CHECK_VALUE_IS_DEFINED(*returndistortion);
 | 
				
			||||||
 | 
					    VALGRIND_CHECK_VALUE_IS_DEFINED(*returnintra);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cpi->is_src_frame_alt_ref &&
 | 
				
			||||||
 | 
					        (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.ref_frame = ALTREF_FRAME;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.mb_skip_coeff =
 | 
				
			||||||
 | 
					                                        (cpi->common.mb_no_coeff_skip);
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.partitioning = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // macroblock modes
 | 
				
			||||||
 | 
					    vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (best_mbmode.mode == B_PRED)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					            xd->mode_info_context->bmi[i].as_mode = best_bmodes[i].as_mode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (best_mbmode.mode == SPLITMV)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					            xd->mode_info_context->bmi[i].mv.as_int = best_bmodes[i].mv.as_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x->e_mbd.mode_info_context->mbmi.mv.as_int =
 | 
				
			||||||
 | 
					                                      x->partition_info->bmi[15].mv.as_int;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sign_bias
 | 
				
			||||||
 | 
					        != cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame])
 | 
				
			||||||
 | 
					        best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rd_update_mvcount(cpi, x, &best_ref_mv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
 | 
					void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
 | 
				
			||||||
                            int recon_uvoffset, int *returnrate,
 | 
					                            int recon_uvoffset, int *returnrate,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,6 +77,18 @@ static const struct extraconfig_map extracfg_map[] =
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cx_data_iter
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct vpx_codec_cx_pkt  pkt;
 | 
				
			||||||
 | 
					    int                      frame_out;
 | 
				
			||||||
 | 
					    int                      pkt_list_done;
 | 
				
			||||||
 | 
					    vpx_codec_iter_t         pkt_list_iter;
 | 
				
			||||||
 | 
					    int                      mode_info_done;
 | 
				
			||||||
 | 
					    int                      mode_info_row;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct vpx_codec_alg_priv
 | 
					struct vpx_codec_alg_priv
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    vpx_codec_priv_t        base;
 | 
					    vpx_codec_priv_t        base;
 | 
				
			||||||
@@ -92,6 +104,7 @@ struct vpx_codec_alg_priv
 | 
				
			|||||||
    vpx_codec_pkt_list_decl(64) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
 | 
					    vpx_codec_pkt_list_decl(64) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
 | 
				
			||||||
    int                         deprecated_mode;
 | 
					    int                         deprecated_mode;
 | 
				
			||||||
    unsigned int                fixed_kf_cntr;
 | 
					    unsigned int                fixed_kf_cntr;
 | 
				
			||||||
 | 
					    struct cx_data_iter         cx_data_iter;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -952,7 +965,45 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
 | 
				
			|||||||
static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t  *ctx,
 | 
					static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t  *ctx,
 | 
				
			||||||
        vpx_codec_iter_t      *iter)
 | 
					        vpx_codec_iter_t      *iter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
 | 
					    if(!*iter)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memset(&ctx->cx_data_iter, 0, sizeof(ctx->cx_data_iter));
 | 
				
			||||||
 | 
					        *iter = &ctx->cx_data_iter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(!ctx->cx_data_iter.pkt_list_done)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const vpx_codec_cx_pkt_t *pkt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pkt = vpx_codec_pkt_list_get(&ctx->pkt_list.head,
 | 
				
			||||||
 | 
					                                     &ctx->cx_data_iter.pkt_list_iter);
 | 
				
			||||||
 | 
					        if(pkt)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ctx->cx_data_iter.frame_out = 1;
 | 
				
			||||||
 | 
					            return pkt;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ctx->cx_data_iter.pkt_list_done = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(!ctx->cx_data_iter.frame_out)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    if(!ctx->cx_data_iter.mode_info_done)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        vpx_codec_cx_pkt_t *pkt = &ctx->cx_data_iter.pkt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(ctx->cx_data_iter.mode_info_row < ctx->cpi->common.mb_rows)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            pkt->kind = VPX_CODEC_CUSTOM_PKT;
 | 
				
			||||||
 | 
					            pkt->data.raw.buf = ctx->cpi->common.mi
 | 
				
			||||||
 | 
					                                + ctx->cpi->common.mode_info_stride
 | 
				
			||||||
 | 
					                                * ctx->cx_data_iter.mode_info_row;
 | 
				
			||||||
 | 
					            pkt->data.raw.sz = sizeof(MODE_INFO) * ctx->cpi->common.mb_cols;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ctx->cx_data_iter.mode_info_row++;
 | 
				
			||||||
 | 
					            return pkt;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            ctx->cx_data_iter.mode_info_done = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx,
 | 
					static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx,
 | 
				
			||||||
@@ -1168,6 +1219,38 @@ static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static vpx_codec_err_t set_modeinfo(vpx_codec_alg_priv_t *ctx,
 | 
				
			||||||
 | 
					        int ctr_id,
 | 
				
			||||||
 | 
					        va_list args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vpx_fixed_buf_t *data =  va_arg(args, vpx_fixed_buf_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->cpi->external_modeinfo = data ? data->buf : NULL;
 | 
				
			||||||
 | 
					    return VPX_CODEC_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static vpx_codec_err_t vp8_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
 | 
				
			||||||
 | 
					                                                int ctrl_id,
 | 
				
			||||||
 | 
					                                                va_list args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int *update_info = va_arg(args, int *);
 | 
				
			||||||
 | 
					    VP8_COMP *pbi = ctx->cpi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (update_info)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *update_info = pbi->common.refresh_alt_ref_frame * (int) VP8_ALTR_FRAME
 | 
				
			||||||
 | 
					            + pbi->common.refresh_golden_frame * (int) VP8_GOLD_FRAME
 | 
				
			||||||
 | 
					            + pbi->common.refresh_last_frame * (int) VP8_LAST_FRAME
 | 
				
			||||||
 | 
					            + (pbi->common.copy_buffer_to_gf << 3)
 | 
				
			||||||
 | 
					            + (pbi->common.copy_buffer_to_arf << 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return VPX_CODEC_OK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return VPX_CODEC_INVALID_PARAM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
 | 
					static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    {VP8_SET_REFERENCE,                 vp8e_set_reference},
 | 
					    {VP8_SET_REFERENCE,                 vp8e_set_reference},
 | 
				
			||||||
@@ -1194,6 +1277,8 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
 | 
				
			|||||||
    {VP8E_SET_TUNING,                   set_param},
 | 
					    {VP8E_SET_TUNING,                   set_param},
 | 
				
			||||||
    {VP8E_SET_CQ_LEVEL,                 set_param},
 | 
					    {VP8E_SET_CQ_LEVEL,                 set_param},
 | 
				
			||||||
    {VP8E_SET_MAX_INTRA_BITRATE_PCT,    set_param},
 | 
					    {VP8E_SET_MAX_INTRA_BITRATE_PCT,    set_param},
 | 
				
			||||||
 | 
					    {VP8E_SET_MODEINFO,                 set_modeinfo},
 | 
				
			||||||
 | 
					    {VP8E_GET_LAST_REF_UPDATES,         vp8_get_last_ref_updates},
 | 
				
			||||||
    { -1, NULL},
 | 
					    { -1, NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,7 @@ struct vpx_codec_alg_priv
 | 
				
			|||||||
    vpx_image_t             img;
 | 
					    vpx_image_t             img;
 | 
				
			||||||
    int                     img_setup;
 | 
					    int                     img_setup;
 | 
				
			||||||
    int                     img_avail;
 | 
					    int                     img_avail;
 | 
				
			||||||
 | 
					    vpx_fixed_buf_t         mode_info;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t flags)
 | 
					static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t flags)
 | 
				
			||||||
@@ -692,7 +693,9 @@ static vpx_codec_err_t vp8_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        *update_info = pbi->common.refresh_alt_ref_frame * (int) VP8_ALTR_FRAME
 | 
					        *update_info = pbi->common.refresh_alt_ref_frame * (int) VP8_ALTR_FRAME
 | 
				
			||||||
            + pbi->common.refresh_golden_frame * (int) VP8_GOLD_FRAME
 | 
					            + pbi->common.refresh_golden_frame * (int) VP8_GOLD_FRAME
 | 
				
			||||||
            + pbi->common.refresh_last_frame * (int) VP8_LAST_FRAME;
 | 
					            + pbi->common.refresh_last_frame * (int) VP8_LAST_FRAME
 | 
				
			||||||
 | 
					            + (pbi->common.copy_buffer_to_gf << 3)
 | 
				
			||||||
 | 
					            + (pbi->common.copy_buffer_to_arf << 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return VPX_CODEC_OK;
 | 
					        return VPX_CODEC_OK;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -741,6 +744,43 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static vpx_codec_err_t get_mode_info(vpx_codec_alg_priv_t *ctx,
 | 
				
			||||||
 | 
					                                     int ctrl_id,
 | 
				
			||||||
 | 
					                                     va_list args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vpx_fixed_buf_t **data =  va_arg(args, vpx_fixed_buf_t **);
 | 
				
			||||||
 | 
					    VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi;
 | 
				
			||||||
 | 
					    size_t mi_sz = sizeof(MODE_INFO)*pbi->common.mb_rows * pbi->common.mb_cols;
 | 
				
			||||||
 | 
					    char *buf;
 | 
				
			||||||
 | 
					    size_t buf_stride;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    MODE_INFO *mi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(data)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(ctx->mode_info.sz != mi_sz)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            free(ctx->mode_info.buf);
 | 
				
			||||||
 | 
					            ctx->mode_info.buf = malloc(mi_sz);
 | 
				
			||||||
 | 
					            ctx->mode_info.sz = mi_sz;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mi = pbi->common.mi;
 | 
				
			||||||
 | 
					        buf = ctx->mode_info.buf;
 | 
				
			||||||
 | 
					        buf_stride = pbi->common.mb_cols * sizeof(MODE_INFO);
 | 
				
			||||||
 | 
					        for(i=0; i<pbi->common.mb_rows; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            memcpy(buf, mi, buf_stride);
 | 
				
			||||||
 | 
					            buf += buf_stride;
 | 
				
			||||||
 | 
					            mi += pbi->common.mode_info_stride;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        *data = &ctx->mode_info;
 | 
				
			||||||
 | 
					        return VPX_CODEC_OK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return VPX_CODEC_INVALID_PARAM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
 | 
					vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    {VP8_SET_REFERENCE,             vp8_set_reference},
 | 
					    {VP8_SET_REFERENCE,             vp8_set_reference},
 | 
				
			||||||
@@ -753,6 +793,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
 | 
				
			|||||||
    {VP8D_GET_LAST_REF_UPDATES,     vp8_get_last_ref_updates},
 | 
					    {VP8D_GET_LAST_REF_UPDATES,     vp8_get_last_ref_updates},
 | 
				
			||||||
    {VP8D_GET_FRAME_CORRUPTED,      vp8_get_frame_corrupted},
 | 
					    {VP8D_GET_FRAME_CORRUPTED,      vp8_get_frame_corrupted},
 | 
				
			||||||
    {VP8D_GET_LAST_REF_USED,        vp8_get_last_ref_frame},
 | 
					    {VP8D_GET_LAST_REF_USED,        vp8_get_last_ref_frame},
 | 
				
			||||||
 | 
					    {VP8D_GET_MODE_INFO,            get_mode_info},
 | 
				
			||||||
    { -1, NULL},
 | 
					    { -1, NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -178,6 +178,10 @@ enum vp8e_enc_control_id
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    VP8E_SET_MAX_INTRA_BITRATE_PCT,
 | 
					    VP8E_SET_MAX_INTRA_BITRATE_PCT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!\brief Mode/mv data */
 | 
				
			||||||
 | 
					    VP8E_SET_MODEINFO,
 | 
				
			||||||
 | 
					    VP8E_GET_LAST_REF_UPDATES
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!\brief vpx 1-D scaling mode
 | 
					/*!\brief vpx 1-D scaling mode
 | 
				
			||||||
@@ -311,6 +315,8 @@ VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64,  int *)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTRA_BITRATE_PCT, unsigned int)
 | 
					VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTRA_BITRATE_PCT, unsigned int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VPX_CTRL_USE_TYPE(VP8E_SET_MODEINFO, vpx_fixed_buf_t *)
 | 
				
			||||||
 | 
					VPX_CTRL_USE_TYPE(VP8E_GET_LAST_REF_UPDATES, int *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @} - end defgroup vp8_encoder */
 | 
					/*! @} - end defgroup vp8_encoder */
 | 
				
			||||||
#include "vpx_codec_impl_bottom.h"
 | 
					#include "vpx_codec_impl_bottom.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,6 +60,8 @@ enum vp8_dec_control_id
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    VP8D_GET_LAST_REF_USED,
 | 
					    VP8D_GET_LAST_REF_USED,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VP8D_GET_MODE_INFO,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VP8_DECODER_CTRL_ID_MAX
 | 
					    VP8_DECODER_CTRL_ID_MAX
 | 
				
			||||||
} ;
 | 
					} ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,6 +77,7 @@ enum vp8_dec_control_id
 | 
				
			|||||||
VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES,   int *)
 | 
					VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES,   int *)
 | 
				
			||||||
VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED,    int *)
 | 
					VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED,    int *)
 | 
				
			||||||
VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED,      int *)
 | 
					VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED,      int *)
 | 
				
			||||||
 | 
					VPX_CTRL_USE_TYPE(VP8D_GET_MODE_INFO,          vpx_fixed_buf_t **)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @} - end defgroup vp8_decoder */
 | 
					/*! @} - end defgroup vp8_decoder */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -134,6 +134,17 @@ extern "C" {
 | 
				
			|||||||
    vpx_codec_err_t;
 | 
					    vpx_codec_err_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!\brief Generic fixed size buffer structure
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This structure is able to hold a reference to any fixed size buffer.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef struct vpx_fixed_buf
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        void          *buf; /**< Pointer to the data */
 | 
				
			||||||
 | 
					        size_t         sz;  /**< Length of the buffer, in chars */
 | 
				
			||||||
 | 
					    } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*! \brief Codec capabilities bitfield
 | 
					    /*! \brief Codec capabilities bitfield
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     *  Each codec advertises the capabilities it supports as part of its
 | 
					     *  Each codec advertises the capabilities it supports as part of its
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,17 +77,6 @@ extern "C" {
 | 
				
			|||||||
                                                     partition at a time. */
 | 
					                                                     partition at a time. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*!\brief Generic fixed size buffer structure
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * This structure is able to hold a reference to any fixed size buffer.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    typedef struct vpx_fixed_buf
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        void          *buf; /**< Pointer to the data */
 | 
					 | 
				
			||||||
        size_t         sz;  /**< Length of the buffer, in chars */
 | 
					 | 
				
			||||||
    } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*!\brief Time Stamp Type
 | 
					    /*!\brief Time Stamp Type
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * An integer, which when multiplied by the stream's time base, provides
 | 
					     * An integer, which when multiplied by the stream's time base, provides
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										474
									
								
								vpxenc.c
									
									
									
									
									
								
							
							
						
						
									
										474
									
								
								vpxenc.c
									
									
									
									
									
								
							@@ -39,6 +39,10 @@
 | 
				
			|||||||
#include "y4minput.h"
 | 
					#include "y4minput.h"
 | 
				
			||||||
#include "libmkv/EbmlWriter.h"
 | 
					#include "libmkv/EbmlWriter.h"
 | 
				
			||||||
#include "libmkv/EbmlIDs.h"
 | 
					#include "libmkv/EbmlIDs.h"
 | 
				
			||||||
 | 
					#include "third_party/libyuv/include/libyuv/scale.h"
 | 
				
			||||||
 | 
					#include "nestegg/include/nestegg/nestegg.h"
 | 
				
			||||||
 | 
					#include "vpx/vpx_decoder.h"
 | 
				
			||||||
 | 
					#include "vpx/vp8dx.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Need special handling of these functions on Windows */
 | 
					/* Need special handling of these functions on Windows */
 | 
				
			||||||
#if defined(_MSC_VER)
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
@@ -289,7 +293,8 @@ enum video_file_type
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    FILE_TYPE_RAW,
 | 
					    FILE_TYPE_RAW,
 | 
				
			||||||
    FILE_TYPE_IVF,
 | 
					    FILE_TYPE_IVF,
 | 
				
			||||||
    FILE_TYPE_Y4M
 | 
					    FILE_TYPE_Y4M,
 | 
				
			||||||
 | 
					    FILE_TYPE_WEBM
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct detect_buffer {
 | 
					struct detect_buffer {
 | 
				
			||||||
@@ -299,6 +304,151 @@ struct detect_buffer {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct webm_ctx
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FILE           *infile;
 | 
				
			||||||
 | 
					    nestegg        *nestegg_ctx;
 | 
				
			||||||
 | 
					    nestegg_packet *pkt;
 | 
				
			||||||
 | 
					    unsigned int    chunk;
 | 
				
			||||||
 | 
					    unsigned int    chunks;
 | 
				
			||||||
 | 
					    unsigned int    video_track;
 | 
				
			||||||
 | 
					    vpx_codec_ctx_t decoder;
 | 
				
			||||||
 | 
					    unsigned char  *buf;
 | 
				
			||||||
 | 
					    size_t          buf_sz;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					nestegg_read_cb(void *buffer, size_t length, void *userdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    FILE *f = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(fread(buffer, 1, length, f) < length)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (ferror(f))
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if (feof(f))
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					nestegg_seek_cb(int64_t offset, int whence, void * userdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch(whence) {
 | 
				
			||||||
 | 
					        case NESTEGG_SEEK_SET: whence = SEEK_SET; break;
 | 
				
			||||||
 | 
					        case NESTEGG_SEEK_CUR: whence = SEEK_CUR; break;
 | 
				
			||||||
 | 
					        case NESTEGG_SEEK_END: whence = SEEK_END; break;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return fseek(userdata, offset, whence)? -1 : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t
 | 
				
			||||||
 | 
					nestegg_tell_cb(void * userdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return ftell(userdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					webm_guess_framerate(struct webm_ctx  *input,
 | 
				
			||||||
 | 
					                     unsigned int     *fps_den,
 | 
				
			||||||
 | 
					                     unsigned int     *fps_num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					    uint64_t     tstamp=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Guess the framerate. Read up to 1 second, or 50 video packets,
 | 
				
			||||||
 | 
					     * whichever comes first.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    for(i=0; tstamp < 1000000000 && i < 50;)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        nestegg_packet * pkt;
 | 
				
			||||||
 | 
					        unsigned int track;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(nestegg_read_packet(input->nestegg_ctx, &pkt) <= 0)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nestegg_packet_track(pkt, &track);
 | 
				
			||||||
 | 
					        if(track == input->video_track)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            nestegg_packet_tstamp(pkt, &tstamp);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nestegg_free_packet(pkt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(nestegg_track_seek(input->nestegg_ctx, input->video_track, 0))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *fps_num = (i - 1) * 1000000;
 | 
				
			||||||
 | 
					    *fps_den = tstamp / 1000;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					fail:
 | 
				
			||||||
 | 
					    nestegg_destroy(input->nestegg_ctx);
 | 
				
			||||||
 | 
					    input->nestegg_ctx = NULL;
 | 
				
			||||||
 | 
					    rewind(input->infile);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					file_is_webm(struct webm_ctx  *input,
 | 
				
			||||||
 | 
					             unsigned int     *width,
 | 
				
			||||||
 | 
					             unsigned int     *height,
 | 
				
			||||||
 | 
					             unsigned int     *fps_den,
 | 
				
			||||||
 | 
					             unsigned int     *fps_num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned int i, n;
 | 
				
			||||||
 | 
					    int          track_type = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb,
 | 
				
			||||||
 | 
					                     input->infile};
 | 
				
			||||||
 | 
					    nestegg_video_params params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(nestegg_init(&input->nestegg_ctx, io, NULL))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(nestegg_track_count(input->nestegg_ctx, &n))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(i=0; i<n; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        track_type = nestegg_track_type(input->nestegg_ctx, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(track_type == NESTEGG_TRACK_VIDEO)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        else if(track_type < 0)
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(nestegg_track_codec_id(input->nestegg_ctx, i) != NESTEGG_CODEC_VP8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fprintf(stderr, "Not VP8 video, quitting.\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input->video_track = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(nestegg_track_video_params(input->nestegg_ctx, i, ¶ms))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(webm_guess_framerate(input, fps_den, fps_num))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *width = params.width;
 | 
				
			||||||
 | 
					    *height = params.height;
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					fail:
 | 
				
			||||||
 | 
					    input->nestegg_ctx = NULL;
 | 
				
			||||||
 | 
					    rewind(input->infile);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct input_state
 | 
					struct input_state
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char                 *fn;
 | 
					    char                 *fn;
 | 
				
			||||||
@@ -310,6 +460,7 @@ struct input_state
 | 
				
			|||||||
    unsigned int          h;
 | 
					    unsigned int          h;
 | 
				
			||||||
    struct vpx_rational   framerate;
 | 
					    struct vpx_rational   framerate;
 | 
				
			||||||
    int                   use_i420;
 | 
					    int                   use_i420;
 | 
				
			||||||
 | 
					    struct webm_ctx       webm;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -323,6 +474,53 @@ static int read_frame(struct input_state *input, vpx_image_t *img)
 | 
				
			|||||||
    int plane = 0;
 | 
					    int plane = 0;
 | 
				
			||||||
    int shortread = 0;
 | 
					    int shortread = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (file_type == FILE_TYPE_WEBM)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        struct webm_ctx *webm = &input->webm;
 | 
				
			||||||
 | 
					        unsigned int p,r;
 | 
				
			||||||
 | 
					        vpx_image_t *src;
 | 
				
			||||||
 | 
					        vpx_codec_iter_t iter = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(webm->chunk >= webm->chunks)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            unsigned int track;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            do
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                /* End of this packet, get another. */
 | 
				
			||||||
 | 
					                if(webm->pkt)
 | 
				
			||||||
 | 
					                    nestegg_free_packet(webm->pkt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(nestegg_read_packet(webm->nestegg_ctx, &webm->pkt) <= 0
 | 
				
			||||||
 | 
					                   || nestegg_packet_track(webm->pkt, &track))
 | 
				
			||||||
 | 
					                    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } while(track != webm->video_track);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(nestegg_packet_count(webm->pkt, &webm->chunks))
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            webm->chunk = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(nestegg_packet_data(webm->pkt, webm->chunk,
 | 
				
			||||||
 | 
					                               &webm->buf, &webm->buf_sz))
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        webm->chunk++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (vpx_codec_decode(&webm->decoder, webm->buf, webm->buf_sz, NULL, 0))
 | 
				
			||||||
 | 
					            fatal("decode failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((src = vpx_codec_get_frame(&webm->decoder, &iter)))
 | 
				
			||||||
 | 
					            for(p=0; p<3; p++)
 | 
				
			||||||
 | 
					                for(r=0; r<img->d_h >> (p>0); r++)
 | 
				
			||||||
 | 
					                    memcpy(img->planes[p] + r * img->stride[p],
 | 
				
			||||||
 | 
					                           src->planes[p] + r * src->stride[p],
 | 
				
			||||||
 | 
					                           img->d_w >> (p>0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return !!src;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
    if (file_type == FILE_TYPE_Y4M)
 | 
					    if (file_type == FILE_TYPE_Y4M)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (y4m_input_fetch_frame(y4m, f, img) < 1)
 | 
					        if (y4m_input_fetch_frame(y4m, f, img) < 1)
 | 
				
			||||||
@@ -984,12 +1182,17 @@ static const arg_def_t q_hist_n         = ARG_DEF(NULL, "q-hist", 1,
 | 
				
			|||||||
        "Show quantizer histogram (n-buckets)");
 | 
					        "Show quantizer histogram (n-buckets)");
 | 
				
			||||||
static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1,
 | 
					static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1,
 | 
				
			||||||
        "Show rate histogram (n-buckets)");
 | 
					        "Show rate histogram (n-buckets)");
 | 
				
			||||||
 | 
					static const arg_def_t read_modemv_arg  = ARG_DEF(NULL, "read-modemv", 1,
 | 
				
			||||||
 | 
					        "Read modes/mvs");
 | 
				
			||||||
 | 
					static const arg_def_t write_modemv_arg  = ARG_DEF(NULL, "write-modemv", 0,
 | 
				
			||||||
 | 
					        "Write modes/mvs");
 | 
				
			||||||
static const arg_def_t *main_args[] =
 | 
					static const arg_def_t *main_args[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    &debugmode,
 | 
					    &debugmode,
 | 
				
			||||||
    &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline,
 | 
					    &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline,
 | 
				
			||||||
    &best_dl, &good_dl, &rt_dl,
 | 
					    &best_dl, &good_dl, &rt_dl,
 | 
				
			||||||
    &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n,
 | 
					    &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n,
 | 
				
			||||||
 | 
					    &read_modemv_arg, &write_modemv_arg,
 | 
				
			||||||
    NULL
 | 
					    NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1495,6 +1698,9 @@ struct global_config
 | 
				
			|||||||
    int                       debug;
 | 
					    int                       debug;
 | 
				
			||||||
    int                       show_q_hist_buckets;
 | 
					    int                       show_q_hist_buckets;
 | 
				
			||||||
    int                       show_rate_hist_buckets;
 | 
					    int                       show_rate_hist_buckets;
 | 
				
			||||||
 | 
					    int                       read_modemv;
 | 
				
			||||||
 | 
					    int                       write_modemv;
 | 
				
			||||||
 | 
					    const char               *modemv_file;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1530,6 +1736,7 @@ struct stream_state
 | 
				
			|||||||
    uint64_t                  cx_time;
 | 
					    uint64_t                  cx_time;
 | 
				
			||||||
    size_t                    nbytes;
 | 
					    size_t                    nbytes;
 | 
				
			||||||
    stats_io_t                stats;
 | 
					    stats_io_t                stats;
 | 
				
			||||||
 | 
					    struct vpx_image         *img;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1609,6 +1816,13 @@ static void parse_global_config(struct global_config *global, char **argv)
 | 
				
			|||||||
            global->show_q_hist_buckets = arg_parse_uint(&arg);
 | 
					            global->show_q_hist_buckets = arg_parse_uint(&arg);
 | 
				
			||||||
        else if (arg_match(&arg, &rate_hist_n, argi))
 | 
					        else if (arg_match(&arg, &rate_hist_n, argi))
 | 
				
			||||||
            global->show_rate_hist_buckets = arg_parse_uint(&arg);
 | 
					            global->show_rate_hist_buckets = arg_parse_uint(&arg);
 | 
				
			||||||
 | 
					        else if (arg_match(&arg, &read_modemv_arg, argi))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            global->read_modemv = 1;
 | 
				
			||||||
 | 
					            global->modemv_file = arg.val;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (arg_match(&arg, &write_modemv_arg, argi))
 | 
				
			||||||
 | 
					            global->write_modemv = 1;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            argj++;
 | 
					            argj++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -1639,6 +1853,21 @@ void open_input_file(struct input_state *input)
 | 
				
			|||||||
    if (!input->file)
 | 
					    if (!input->file)
 | 
				
			||||||
        fatal("Failed to open input file");
 | 
					        fatal("Failed to open input file");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(strstr(input->fn, ".webm"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        input->webm.infile = input->file;
 | 
				
			||||||
 | 
					        input->file_type = FILE_TYPE_WEBM;
 | 
				
			||||||
 | 
					        if(!file_is_webm(&input->webm,
 | 
				
			||||||
 | 
					                         &input->w, &input->h,
 | 
				
			||||||
 | 
					                         &input->framerate.den,
 | 
				
			||||||
 | 
					                         &input->framerate.num))
 | 
				
			||||||
 | 
					            fatal("Couldn't open webm file");
 | 
				
			||||||
 | 
					        if (vpx_codec_dec_init(&input->webm.decoder,
 | 
				
			||||||
 | 
					                               &vpx_codec_vp8_dx_algo, NULL, 0))
 | 
				
			||||||
 | 
					            fatal("Couldn't init decoder");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* For RAW input sources, these bytes will applied on the first frame
 | 
					    /* For RAW input sources, these bytes will applied on the first frame
 | 
				
			||||||
     *  in read_frame().
 | 
					     *  in read_frame().
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -1943,11 +2172,17 @@ static void set_stream_dimensions(struct stream_state *stream,
 | 
				
			|||||||
                                  unsigned int w,
 | 
					                                  unsigned int w,
 | 
				
			||||||
                                  unsigned int h)
 | 
					                                  unsigned int h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if ((stream->config.cfg.g_w && stream->config.cfg.g_w != w)
 | 
					    if(!stream->config.cfg.g_w)
 | 
				
			||||||
        ||(stream->config.cfg.g_h && stream->config.cfg.g_h != h))
 | 
					    {
 | 
				
			||||||
        fatal("Stream %d: Resizing not yet supported", stream->index);
 | 
					        if(!stream->config.cfg.g_h)
 | 
				
			||||||
    stream->config.cfg.g_w = w;
 | 
					            stream->config.cfg.g_w = w;
 | 
				
			||||||
    stream->config.cfg.g_h = h;
 | 
					        else
 | 
				
			||||||
 | 
					            stream->config.cfg.g_w = w * stream->config.cfg.g_h / h;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(!stream->config.cfg.g_h)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        stream->config.cfg.g_h = h * stream->config.cfg.g_w / w;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2117,6 +2352,26 @@ static void encode_frame(struct stream_state  *stream,
 | 
				
			|||||||
    next_frame_start = (cfg->g_timebase.den * (int64_t)(frames_in)
 | 
					    next_frame_start = (cfg->g_timebase.den * (int64_t)(frames_in)
 | 
				
			||||||
                        * global->framerate.den)
 | 
					                        * global->framerate.den)
 | 
				
			||||||
                        / cfg->g_timebase.num / global->framerate.num;
 | 
					                        / cfg->g_timebase.num / global->framerate.num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Scale if necessary */
 | 
				
			||||||
 | 
					    if(img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(!stream->img)
 | 
				
			||||||
 | 
					            stream->img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420,
 | 
				
			||||||
 | 
					                                        cfg->g_w, cfg->g_h, 16);
 | 
				
			||||||
 | 
					        I420Scale(img->planes[PLANE_Y], img->stride[PLANE_Y],
 | 
				
			||||||
 | 
					                  img->planes[PLANE_U], img->stride[PLANE_U],
 | 
				
			||||||
 | 
					                  img->planes[PLANE_V], img->stride[PLANE_V],
 | 
				
			||||||
 | 
					                  img->d_w, img->d_h,
 | 
				
			||||||
 | 
					                  stream->img->planes[PLANE_Y], stream->img->stride[PLANE_Y],
 | 
				
			||||||
 | 
					                  stream->img->planes[PLANE_U], stream->img->stride[PLANE_U],
 | 
				
			||||||
 | 
					                  stream->img->planes[PLANE_V], stream->img->stride[PLANE_V],
 | 
				
			||||||
 | 
					                  stream->img->d_w, stream->img->d_h,
 | 
				
			||||||
 | 
					                  kFilterBox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        img = stream->img;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vpx_usec_timer_start(&timer);
 | 
					    vpx_usec_timer_start(&timer);
 | 
				
			||||||
    vpx_codec_encode(&stream->encoder, img, frame_start,
 | 
					    vpx_codec_encode(&stream->encoder, img, frame_start,
 | 
				
			||||||
                     next_frame_start - frame_start,
 | 
					                     next_frame_start - frame_start,
 | 
				
			||||||
@@ -2211,6 +2466,128 @@ static void get_cx_data(struct stream_state  *stream,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct link_record
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t sz;
 | 
				
			||||||
 | 
					    uint16_t w;
 | 
				
			||||||
 | 
					    uint16_t h;
 | 
				
			||||||
 | 
					    int      refs_updated;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					write_multistream_file(struct stream_state  *streams,
 | 
				
			||||||
 | 
					                       struct global_config *global,
 | 
				
			||||||
 | 
					                       int                  *got_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const vpx_codec_cx_pkt_t *pkt;
 | 
				
			||||||
 | 
					    vpx_codec_cx_pkt_t outpkt = {0};
 | 
				
			||||||
 | 
					    int newsz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FOREACH_STREAM({
 | 
				
			||||||
 | 
					    vpx_codec_iter_t iter = NULL;
 | 
				
			||||||
 | 
					    const struct vpx_codec_enc_cfg *cfg = &stream->config.cfg;
 | 
				
			||||||
 | 
					    struct link_record link = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vpx_codec_control(&stream->encoder, VP8E_GET_LAST_REF_UPDATES, &link.refs_updated);
 | 
				
			||||||
 | 
					    ctx_exit_on_error(&stream->encoder, "Failed to get refs");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ((pkt = vpx_codec_get_cx_data(&stream->encoder, &iter)))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *got_data = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (pkt->kind)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        case VPX_CODEC_CX_FRAME_PKT:
 | 
				
			||||||
 | 
					            stream->frames_out++;
 | 
				
			||||||
 | 
					            fprintf(stderr, " %6luF",
 | 
				
			||||||
 | 
					                    (unsigned long)pkt->data.frame.sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            update_rate_histogram(&stream->rate_hist, cfg, pkt);
 | 
				
			||||||
 | 
					            stream->nbytes += pkt->data.raw.sz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(stream == streams)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                outpkt = *pkt;
 | 
				
			||||||
 | 
					                outpkt.data.raw.buf = malloc(outpkt.data.raw.sz);
 | 
				
			||||||
 | 
					                memcpy(outpkt.data.raw.buf, pkt->data.raw.buf, pkt->data.raw.sz);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case VPX_CODEC_STATS_PKT:
 | 
				
			||||||
 | 
					            stream->frames_out++;
 | 
				
			||||||
 | 
					            fprintf(stderr, " %6luS",
 | 
				
			||||||
 | 
					                   (unsigned long)pkt->data.twopass_stats.sz);
 | 
				
			||||||
 | 
					            stats_write(&stream->stats,
 | 
				
			||||||
 | 
					                        pkt->data.twopass_stats.buf,
 | 
				
			||||||
 | 
					                        pkt->data.twopass_stats.sz);
 | 
				
			||||||
 | 
					            stream->nbytes += pkt->data.raw.sz;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case VPX_CODEC_PSNR_PKT:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (global->show_psnr)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                stream->psnr_sse_total += pkt->data.psnr.sse[0];
 | 
				
			||||||
 | 
					                stream->psnr_samples_total += pkt->data.psnr.samples[0];
 | 
				
			||||||
 | 
					                for (i = 0; i < 4; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    fprintf(stderr, "%.3lf ", pkt->data.psnr.psnr[i]);
 | 
				
			||||||
 | 
					                    stream->psnr_totals[i] += pkt->data.psnr.psnr[i];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                stream->psnr_count++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            /* Append other data packets to outpkt */
 | 
				
			||||||
 | 
					            newsz = outpkt.data.raw.sz + pkt->data.raw.sz;
 | 
				
			||||||
 | 
					            outpkt.data.raw.buf = realloc(outpkt.data.raw.buf, newsz);
 | 
				
			||||||
 | 
					            memcpy((char*)outpkt.data.raw.buf + outpkt.data.raw.sz,
 | 
				
			||||||
 | 
					                   pkt->data.raw.buf, pkt->data.raw.sz);
 | 
				
			||||||
 | 
					            outpkt.data.raw.sz = newsz;
 | 
				
			||||||
 | 
					            link.sz += pkt->data.raw.sz;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(link.sz)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        link.w = cfg->g_w;
 | 
				
			||||||
 | 
					        link.h = cfg->g_h;
 | 
				
			||||||
 | 
					        link.sz |= (stream == streams)?0:(1<<31);
 | 
				
			||||||
 | 
					        newsz = outpkt.data.raw.sz + sizeof(link);
 | 
				
			||||||
 | 
					        outpkt.data.raw.buf = realloc(outpkt.data.raw.buf, newsz);
 | 
				
			||||||
 | 
					        memcpy((char*)outpkt.data.raw.buf + outpkt.data.raw.sz,
 | 
				
			||||||
 | 
					               &link, sizeof(link));
 | 
				
			||||||
 | 
					        outpkt.data.raw.sz = newsz;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    if(outpkt.data.raw.sz)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const struct vpx_codec_enc_cfg *cfg = &streams->config.cfg;
 | 
				
			||||||
 | 
					        struct stream_state  *stream = streams;
 | 
				
			||||||
 | 
					        const vpx_codec_cx_pkt_t *pkt = &outpkt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(stream->config.write_webm)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* Update the hash */
 | 
				
			||||||
 | 
					            if(!stream->ebml.debug)
 | 
				
			||||||
 | 
					                stream->hash = murmur(pkt->data.frame.buf,
 | 
				
			||||||
 | 
					                                      pkt->data.frame.sz, stream->hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            write_webm_block(&streams->ebml, cfg, pkt);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            write_ivf_frame_header(stream->file, pkt);
 | 
				
			||||||
 | 
					            if(fwrite(pkt->data.frame.buf, 1,
 | 
				
			||||||
 | 
					                      pkt->data.frame.sz, stream->file));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        free(outpkt.data.raw.buf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void show_psnr(struct stream_state  *stream)
 | 
					static void show_psnr(struct stream_state  *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
@@ -2238,13 +2615,71 @@ float usec_to_fps(uint64_t usec, unsigned int frames)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_modeinfo(struct stream_state *stream,
 | 
				
			||||||
 | 
					                         struct input_state  *input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct webm_ctx     *webm = &input->webm;
 | 
				
			||||||
 | 
					    unsigned char *ptr;
 | 
				
			||||||
 | 
					    struct link_record link;
 | 
				
			||||||
 | 
					    int again;
 | 
				
			||||||
 | 
					    int refs=0;
 | 
				
			||||||
 | 
					    int mi_set = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, NULL);
 | 
				
			||||||
 | 
					    ptr = webm->buf + webm->buf_sz;
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ptr -= sizeof(link);
 | 
				
			||||||
 | 
					        memcpy(&link, ptr, sizeof(link));
 | 
				
			||||||
 | 
					        again = link.sz >> 31;
 | 
				
			||||||
 | 
					        link.sz &= ~(1<<31);
 | 
				
			||||||
 | 
					        ptr -= link.sz;
 | 
				
			||||||
 | 
					        if(link.w == stream->config.cfg.g_w
 | 
				
			||||||
 | 
					           && link.h == stream->config.cfg.g_h)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            vpx_fixed_buf_t modeinfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            modeinfo.buf = ptr;
 | 
				
			||||||
 | 
					            modeinfo.sz = link.sz;
 | 
				
			||||||
 | 
					            vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, &modeinfo);
 | 
				
			||||||
 | 
					            vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, link.refs_updated);
 | 
				
			||||||
 | 
					            ctx_exit_on_error(&stream->encoder, "Failed to set refs");
 | 
				
			||||||
 | 
					            mi_set = 1;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if((link.w|link.sz)&0xF)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        if(link.w > 16383 || link.h > 16383)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    } while(again);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!mi_set
 | 
				
			||||||
 | 
					       && stream->config.cfg.g_w == input->w
 | 
				
			||||||
 | 
					       && stream->config.cfg.g_h == input->h)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        vpx_fixed_buf_t *modeinfo;
 | 
				
			||||||
 | 
					        int refs_updated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vpx_codec_control(&webm->decoder, VP8D_GET_MODE_INFO, &modeinfo);
 | 
				
			||||||
 | 
					        ctx_exit_on_error(&webm->decoder, "Failed to get mode info");
 | 
				
			||||||
 | 
					        vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, modeinfo);
 | 
				
			||||||
 | 
					        ctx_exit_on_error(&webm->decoder, "Failed to set mode info");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vpx_codec_control(&webm->decoder, VP8D_GET_LAST_REF_UPDATES, &refs_updated);
 | 
				
			||||||
 | 
					        ctx_exit_on_error(&webm->decoder, "Failed to get ref updates");
 | 
				
			||||||
 | 
					        vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, refs_updated);
 | 
				
			||||||
 | 
					        ctx_exit_on_error(&stream->encoder, "Failed to set ref updates");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, const char **argv_)
 | 
					int main(int argc, const char **argv_)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int                    pass;
 | 
					    int                    pass;
 | 
				
			||||||
    vpx_image_t            raw;
 | 
					    vpx_image_t            raw, junk;
 | 
				
			||||||
    int                    frame_avail, got_data;
 | 
					    int                    frame_avail, got_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct input_state       input = {0};
 | 
					    struct input_state       input = {0};
 | 
				
			||||||
 | 
					    struct input_state       modemv_input = {0};
 | 
				
			||||||
    struct global_config     global;
 | 
					    struct global_config     global;
 | 
				
			||||||
    struct stream_state     *streams = NULL;
 | 
					    struct stream_state     *streams = NULL;
 | 
				
			||||||
    char                   **argv, **argi;
 | 
					    char                   **argv, **argi;
 | 
				
			||||||
@@ -2300,6 +2735,12 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
        int frames_in = 0;
 | 
					        int frames_in = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        open_input_file(&input);
 | 
					        open_input_file(&input);
 | 
				
			||||||
 | 
					        if(global.read_modemv)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            modemv_input = input;
 | 
				
			||||||
 | 
					            modemv_input.fn = global.modemv_file;
 | 
				
			||||||
 | 
					            open_input_file(&modemv_input);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* If the input file doesn't specify its w/h (raw files), try to get
 | 
					        /* If the input file doesn't specify its w/h (raw files), try to get
 | 
				
			||||||
         * the data from the first stream's configuration.
 | 
					         * the data from the first stream's configuration.
 | 
				
			||||||
@@ -2315,6 +2756,9 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Update stream configurations from the input file's parameters */
 | 
					        /* Update stream configurations from the input file's parameters */
 | 
				
			||||||
 | 
					        if(!input.w || !input.h)
 | 
				
			||||||
 | 
					            fatal("Specify stream dimensions with --width (-w) "
 | 
				
			||||||
 | 
					                  " and --height (-h)");
 | 
				
			||||||
        FOREACH_STREAM(set_stream_dimensions(stream, input.w, input.h));
 | 
					        FOREACH_STREAM(set_stream_dimensions(stream, input.w, input.h));
 | 
				
			||||||
        FOREACH_STREAM(validate_stream_config(stream));
 | 
					        FOREACH_STREAM(validate_stream_config(stream));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2356,6 +2800,11 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
                                               &global.framerate));
 | 
					                                               &global.framerate));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(global.read_modemv)
 | 
				
			||||||
 | 
					            vpx_img_alloc(&junk,
 | 
				
			||||||
 | 
					                          input.use_i420 ? VPX_IMG_FMT_I420
 | 
				
			||||||
 | 
					                                         : VPX_IMG_FMT_YV12,
 | 
				
			||||||
 | 
					                          input.w, input.h, 1);
 | 
				
			||||||
        FOREACH_STREAM(open_output_file(stream, &global));
 | 
					        FOREACH_STREAM(open_output_file(stream, &global));
 | 
				
			||||||
        FOREACH_STREAM(setup_pass(stream, &global, pass));
 | 
					        FOREACH_STREAM(setup_pass(stream, &global, pass));
 | 
				
			||||||
        FOREACH_STREAM(initialize_encoder(stream, &global));
 | 
					        FOREACH_STREAM(initialize_encoder(stream, &global));
 | 
				
			||||||
@@ -2370,6 +2819,8 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
            if (!global.limit || frames_in < global.limit)
 | 
					            if (!global.limit || frames_in < global.limit)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                frame_avail = read_frame(&input, &raw);
 | 
					                frame_avail = read_frame(&input, &raw);
 | 
				
			||||||
 | 
					                if(global.read_modemv)
 | 
				
			||||||
 | 
					                    read_frame(&modemv_input, &junk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (frame_avail)
 | 
					                if (frame_avail)
 | 
				
			||||||
                    frames_in++;
 | 
					                    frames_in++;
 | 
				
			||||||
@@ -2391,6 +2842,10 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
            else
 | 
					            else
 | 
				
			||||||
                frame_avail = 0;
 | 
					                frame_avail = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Update mode/mv info if available */
 | 
				
			||||||
 | 
					            if(modemv_input.file_type == FILE_TYPE_WEBM && global.read_modemv)
 | 
				
			||||||
 | 
					                FOREACH_STREAM(set_modeinfo(stream, &modemv_input));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vpx_usec_timer_start(&timer);
 | 
					            vpx_usec_timer_start(&timer);
 | 
				
			||||||
            FOREACH_STREAM(encode_frame(stream, &global,
 | 
					            FOREACH_STREAM(encode_frame(stream, &global,
 | 
				
			||||||
                                        frame_avail ? &raw : NULL,
 | 
					                                        frame_avail ? &raw : NULL,
 | 
				
			||||||
@@ -2401,7 +2856,10 @@ int main(int argc, const char **argv_)
 | 
				
			|||||||
            FOREACH_STREAM(update_quantizer_histogram(stream));
 | 
					            FOREACH_STREAM(update_quantizer_histogram(stream));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            got_data = 0;
 | 
					            got_data = 0;
 | 
				
			||||||
            FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
 | 
					            if(global.write_modemv)
 | 
				
			||||||
 | 
					                write_multistream_file(streams, &global, &got_data);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fflush(stdout);
 | 
					            fflush(stdout);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user