Compare commits
	
		
			10 Commits
		
	
	
		
			mcw
			...
			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.
 | 
			
		||||
##
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
# 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                 += args.c args.h
 | 
			
		||||
vpxdec.SRCS                 += tools_common.c tools_common.h
 | 
			
		||||
vpxdec.SRCS                 += nestegg/halloc/halloc.h
 | 
			
		||||
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.SRCS                 += $(NESTEGG_SRCS)
 | 
			
		||||
vpxdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
 | 
			
		||||
vpxdec.DESCRIPTION           = Full featured decoder
 | 
			
		||||
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/EbmlWriter.c
 | 
			
		||||
vpxenc.SRCS                 += libmkv/EbmlWriter.h
 | 
			
		||||
vpxenc.SRCS                 += $(LIBYUV_SRCS)
 | 
			
		||||
vpxenc.SRCS                 += $(NESTEGG_SRCS)
 | 
			
		||||
vpxenc.GUID                  = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
 | 
			
		||||
vpxenc.DESCRIPTION           = Full featured encoder
 | 
			
		||||
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.
 | 
			
		||||
GEN_EXAMPLES-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c
 | 
			
		||||
vp8_multi_resolution_encoder.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.SRCS         += $(LIBYUV_SRCS)
 | 
			
		||||
vp8_multi_resolution_encoder.GUID         = 04f8738e-63c8-423b-90fa-7c2703a374de
 | 
			
		||||
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)
 | 
			
		||||
#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) {
 | 
			
		||||
  asm volatile (
 | 
			
		||||
    "1:                                        \n"
 | 
			
		||||
@@ -102,7 +102,7 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, int src_stride,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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) {
 | 
			
		||||
  asm volatile (
 | 
			
		||||
    "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
 | 
			
		||||
//  to load up the every 4th pixel into a 4 different registers.
 | 
			
		||||
// 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) {
 | 
			
		||||
  asm volatile (
 | 
			
		||||
    "1:                                        \n"
 | 
			
		||||
@@ -284,7 +284,7 @@ const unsigned short mult38_div9[8] __attribute__ ((aligned(16))) =
 | 
			
		||||
    65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18 };
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
  asm volatile (
 | 
			
		||||
    "vld1.u8      {q3}, [%3]                   \n"
 | 
			
		||||
 
 | 
			
		||||
@@ -205,6 +205,11 @@ typedef struct macroblockd
 | 
			
		||||
    DECLARE_ALIGNED(16, short,  dequant_y2[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. */
 | 
			
		||||
    BLOCKD block[25];
 | 
			
		||||
    int fullpixel_mask;
 | 
			
		||||
 
 | 
			
		||||
@@ -411,6 +411,10 @@ void encode_mb_row(VP8_COMP *cpi,
 | 
			
		||||
    // for each macroblock col in image
 | 
			
		||||
    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
 | 
			
		||||
        // 1/8th pel units as they are always compared to values
 | 
			
		||||
        // that are in 1/8th pel units
 | 
			
		||||
@@ -1111,6 +1115,8 @@ extern int cnt_pm;
 | 
			
		||||
 | 
			
		||||
extern void vp8_fix_contexts(MACROBLOCKD *x);
 | 
			
		||||
 | 
			
		||||
#include "valgrind/memcheck.h"
 | 
			
		||||
 | 
			
		||||
int vp8cx_encode_inter_macroblock
 | 
			
		||||
(
 | 
			
		||||
    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
 | 
			
		||||
@@ -1130,6 +1136,15 @@ int vp8cx_encode_inter_macroblock
 | 
			
		||||
    else
 | 
			
		||||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        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->search_method = HEX;
 | 
			
		||||
            sf->iterative_sub_pixel = 0;
 | 
			
		||||
            //sf->iterative_sub_pixel = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    if (ref_frame_flags > 7)
 | 
			
		||||
    if (ref_frame_flags > 127)
 | 
			
		||||
        return -1 ;
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3187,8 +3189,11 @@ static void encode_frame_to_data_rate
 | 
			
		||||
        cpi->per_frame_bandwidth  = (int)(cpi->target_bandwidth / cpi->output_frame_rate);
 | 
			
		||||
 | 
			
		||||
    // Default turn off buffer to buffer copying
 | 
			
		||||
    if(!cpi->external_modeinfo)
 | 
			
		||||
    {
 | 
			
		||||
    cm->copy_buffer_to_gf = 0;
 | 
			
		||||
    cm->copy_buffer_to_arf = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Clear zbin over-quant value and mode boost values.
 | 
			
		||||
    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
 | 
			
		||||
    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
 | 
			
		||||
    // 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;
 | 
			
		||||
    else
 | 
			
		||||
        cm->copy_buffer_to_arf  = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    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))
 | 
			
		||||
    {
 | 
			
		||||
        cpi->common.error.setjmp = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -678,7 +678,7 @@ typedef struct VP8_COMP
 | 
			
		||||
    /* Number of MBs per row at lower-resolution level */
 | 
			
		||||
    int    mr_low_res_mb_cols;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    MODE_INFO *external_modeinfo;
 | 
			
		||||
} VP8_COMP;
 | 
			
		||||
 | 
			
		||||
void control_data_rate(VP8_COMP *cpi);
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
#include "rdopt.h"
 | 
			
		||||
#include "vpx_mem/vpx_mem.h"
 | 
			
		||||
#include "vp8/common/systemdependent.h"
 | 
			
		||||
#include "valgrind/memcheck.h"
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VALGRIND_CHECK_VALUE_IS_DEFINED(tot_rate_y);
 | 
			
		||||
    VALGRIND_CHECK_VALUE_IS_DEFINED(total_rd);
 | 
			
		||||
    if(total_rd >= (int64_t)best_rd)
 | 
			
		||||
        return INT_MAX;
 | 
			
		||||
 | 
			
		||||
    *Rate = cost;
 | 
			
		||||
    *rate_y += tot_rate_y;
 | 
			
		||||
    *rate_y = tot_rate_y;
 | 
			
		||||
    *Distortion = 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
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,
 | 
			
		||||
                            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
 | 
			
		||||
{
 | 
			
		||||
    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
 | 
			
		||||
    int                         deprecated_mode;
 | 
			
		||||
    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,
 | 
			
		||||
        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,
 | 
			
		||||
@@ -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[] =
 | 
			
		||||
{
 | 
			
		||||
    {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_CQ_LEVEL,                 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},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,7 @@ struct vpx_codec_alg_priv
 | 
			
		||||
    vpx_image_t             img;
 | 
			
		||||
    int                     img_setup;
 | 
			
		||||
    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)
 | 
			
		||||
@@ -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
 | 
			
		||||
            + 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;
 | 
			
		||||
    }
 | 
			
		||||
@@ -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[] =
 | 
			
		||||
{
 | 
			
		||||
    {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_FRAME_CORRUPTED,      vp8_get_frame_corrupted},
 | 
			
		||||
    {VP8D_GET_LAST_REF_USED,        vp8_get_last_ref_frame},
 | 
			
		||||
    {VP8D_GET_MODE_INFO,            get_mode_info},
 | 
			
		||||
    { -1, NULL},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -178,6 +178,10 @@ enum vp8e_enc_control_id
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    VP8E_SET_MAX_INTRA_BITRATE_PCT,
 | 
			
		||||
 | 
			
		||||
    /*!\brief Mode/mv data */
 | 
			
		||||
    VP8E_SET_MODEINFO,
 | 
			
		||||
    VP8E_GET_LAST_REF_UPDATES
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*!\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_MODEINFO, vpx_fixed_buf_t *)
 | 
			
		||||
VPX_CTRL_USE_TYPE(VP8E_GET_LAST_REF_UPDATES, int *)
 | 
			
		||||
 | 
			
		||||
/*! @} - end defgroup vp8_encoder */
 | 
			
		||||
#include "vpx_codec_impl_bottom.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,8 @@ enum vp8_dec_control_id
 | 
			
		||||
     */
 | 
			
		||||
    VP8D_GET_LAST_REF_USED,
 | 
			
		||||
 | 
			
		||||
    VP8D_GET_MODE_INFO,
 | 
			
		||||
 | 
			
		||||
    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_FRAME_CORRUPTED,    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 */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -134,6 +134,17 @@ extern "C" {
 | 
			
		||||
    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
 | 
			
		||||
     *
 | 
			
		||||
     *  Each codec advertises the capabilities it supports as part of its
 | 
			
		||||
 
 | 
			
		||||
@@ -77,17 +77,6 @@ extern "C" {
 | 
			
		||||
                                                     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
 | 
			
		||||
     *
 | 
			
		||||
     * An integer, which when multiplied by the stream's time base, provides
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										470
									
								
								vpxenc.c
									
									
									
									
									
								
							
							
						
						
									
										470
									
								
								vpxenc.c
									
									
									
									
									
								
							@@ -39,6 +39,10 @@
 | 
			
		||||
#include "y4minput.h"
 | 
			
		||||
#include "libmkv/EbmlWriter.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 */
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
@@ -289,7 +293,8 @@ enum video_file_type
 | 
			
		||||
{
 | 
			
		||||
    FILE_TYPE_RAW,
 | 
			
		||||
    FILE_TYPE_IVF,
 | 
			
		||||
    FILE_TYPE_Y4M
 | 
			
		||||
    FILE_TYPE_Y4M,
 | 
			
		||||
    FILE_TYPE_WEBM
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
{
 | 
			
		||||
    char                 *fn;
 | 
			
		||||
@@ -310,6 +460,7 @@ struct input_state
 | 
			
		||||
    unsigned int          h;
 | 
			
		||||
    struct vpx_rational   framerate;
 | 
			
		||||
    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 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 (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)");
 | 
			
		||||
static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1,
 | 
			
		||||
        "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[] =
 | 
			
		||||
{
 | 
			
		||||
    &debugmode,
 | 
			
		||||
    &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline,
 | 
			
		||||
    &best_dl, &good_dl, &rt_dl,
 | 
			
		||||
    &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n,
 | 
			
		||||
    &read_modemv_arg, &write_modemv_arg,
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -1495,6 +1698,9 @@ struct global_config
 | 
			
		||||
    int                       debug;
 | 
			
		||||
    int                       show_q_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;
 | 
			
		||||
    size_t                    nbytes;
 | 
			
		||||
    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);
 | 
			
		||||
        else if (arg_match(&arg, &rate_hist_n, argi))
 | 
			
		||||
            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
 | 
			
		||||
            argj++;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1639,6 +1853,21 @@ void open_input_file(struct input_state *input)
 | 
			
		||||
    if (!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
 | 
			
		||||
     *  in read_frame().
 | 
			
		||||
     */
 | 
			
		||||
@@ -1943,11 +2172,17 @@ static void set_stream_dimensions(struct stream_state *stream,
 | 
			
		||||
                                  unsigned int w,
 | 
			
		||||
                                  unsigned int h)
 | 
			
		||||
{
 | 
			
		||||
    if ((stream->config.cfg.g_w && stream->config.cfg.g_w != 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_w)
 | 
			
		||||
    {
 | 
			
		||||
        if(!stream->config.cfg.g_h)
 | 
			
		||||
            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)
 | 
			
		||||
                        * global->framerate.den)
 | 
			
		||||
                        / 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_codec_encode(&stream->encoder, img, 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)
 | 
			
		||||
{
 | 
			
		||||
    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                    pass;
 | 
			
		||||
    vpx_image_t            raw;
 | 
			
		||||
    vpx_image_t            raw, junk;
 | 
			
		||||
    int                    frame_avail, got_data;
 | 
			
		||||
 | 
			
		||||
    struct input_state       input = {0};
 | 
			
		||||
    struct input_state       modemv_input = {0};
 | 
			
		||||
    struct global_config     global;
 | 
			
		||||
    struct stream_state     *streams = NULL;
 | 
			
		||||
    char                   **argv, **argi;
 | 
			
		||||
@@ -2300,6 +2735,12 @@ int main(int argc, const char **argv_)
 | 
			
		||||
        int frames_in = 0;
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
         * 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 */
 | 
			
		||||
        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(validate_stream_config(stream));
 | 
			
		||||
 | 
			
		||||
@@ -2356,6 +2800,11 @@ int main(int argc, const char **argv_)
 | 
			
		||||
                                               &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(setup_pass(stream, &global, pass));
 | 
			
		||||
        FOREACH_STREAM(initialize_encoder(stream, &global));
 | 
			
		||||
@@ -2370,6 +2819,8 @@ int main(int argc, const char **argv_)
 | 
			
		||||
            if (!global.limit || frames_in < global.limit)
 | 
			
		||||
            {
 | 
			
		||||
                frame_avail = read_frame(&input, &raw);
 | 
			
		||||
                if(global.read_modemv)
 | 
			
		||||
                    read_frame(&modemv_input, &junk);
 | 
			
		||||
 | 
			
		||||
                if (frame_avail)
 | 
			
		||||
                    frames_in++;
 | 
			
		||||
@@ -2391,6 +2842,10 @@ int main(int argc, const char **argv_)
 | 
			
		||||
            else
 | 
			
		||||
                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);
 | 
			
		||||
            FOREACH_STREAM(encode_frame(stream, &global,
 | 
			
		||||
                                        frame_avail ? &raw : NULL,
 | 
			
		||||
@@ -2401,6 +2856,9 @@ int main(int argc, const char **argv_)
 | 
			
		||||
            FOREACH_STREAM(update_quantizer_histogram(stream));
 | 
			
		||||
 | 
			
		||||
            got_data = 0;
 | 
			
		||||
            if(global.write_modemv)
 | 
			
		||||
                write_multistream_file(streams, &global, &got_data);
 | 
			
		||||
            else
 | 
			
		||||
                FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
 | 
			
		||||
 | 
			
		||||
            fflush(stdout);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user