⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frame.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
            else if ( UBITS( bs->i_bit_in_cache, 11 ) == 8 )            {                /* macroblock_escape */                mba_inc += 33;                mba_local += 33;                bs_flush(bs, 11);            }            else            {                /* EOS or error */                return;            }        }        bs_flush(bs, mba->len);        mba_inc += mba->mba;        mba_local += mba->mba;        while( mba_local-- )        {            NEXT_MACROBLOCK;        }    }}static const uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = {    /* Zig-Zag scan pattern */     0,  1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,    12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,    35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,    58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};static const uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = {    /* Alternate scan pattern */     0, 8,  16, 24,  1,  9,  2, 10, 17, 25, 32, 40, 48, 56, 57, 49,    41, 33, 26, 18,  3, 11,  4, 12, 19, 27, 34, 42, 50, 58, 35, 43,    51, 59, 20, 28,  5, 13,  6, 14, 21, 29, 36, 44, 52, 60, 37, 45,    53, 61, 22, 30,  7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63};static const int16_t default_intra_matrix[64] = {        8, 16, 19, 22, 26, 27, 29, 34,        16, 16, 22, 24, 27, 29, 34, 37,        19, 22, 26, 27, 29, 34, 34, 38,        22, 22, 26, 27, 29, 34, 37, 40,        22, 26, 27, 29, 32, 35, 40, 48,        26, 27, 29, 32, 35, 40, 48, 58,        26, 27, 29, 34, 38, 46, 56, 69,        27, 29, 35, 38, 46, 56, 69, 83};static int mpeg2_header_sequence( transrate_t * tr ){    bs_transrate_t *bs = &tr->bs;    int has_intra = 0, has_non_intra = 0;    int i;    i = (bs->p_c[0] << 16) | (bs->p_c[1] << 8) | bs->p_c[2];    tr->horizontal_size_value = i >> 12;    tr->vertical_size_value = i & 0xfff;    tr->horizontal_size_value = (tr->horizontal_size_value + 15) & ~15;    tr->vertical_size_value = (tr->vertical_size_value + 15) & ~15;    if ( !tr->horizontal_size_value || !tr->vertical_size_value )    {        return -1;    }    if ( tr->mpeg4_matrix )    {        if (bs->p_c[7] & 2)        {            has_intra = 1;            for (i = 0; i < 64; i++)                tr->intra_quantizer_matrix[mpeg2_scan_norm[i]] =                (bs->p_c[i+7] << 7) | (bs->p_c[i+8] >> 1);        }        else        {            for (i = 0; i < 64; i++)                tr->intra_quantizer_matrix[mpeg2_scan_norm[i]] =                default_intra_matrix[i];        }        if (bs->p_c[7+64] & 1)        {            has_non_intra = 1;            for (i = 0; i < 64; i++)                tr->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] =                bs->p_c[i+8+64];        }        else        {            for (i = 0; i < 64; i++)                tr->non_intra_quantizer_matrix[i] = 16;        }    }    /* Write quantization matrices */    memcpy( bs->p_w, bs->p_c, 8 );    bs->p_c += 8;    if ( tr->mpeg4_matrix )    {        memset( &bs->p_w[8], 0, 128 );        bs->p_w[7] |= 2;        bs->p_w[7] &= ~1;        for (i = 0; i < 64; i++)        {            bs->p_w[i+7] |= mpeg4_default_intra_matrix[mpeg2_scan_norm[i]] >> 7;            bs->p_w[i+8] |= mpeg4_default_intra_matrix[mpeg2_scan_norm[i]] << 1;        }        bs->p_w[7+64] |= 1;        for (i = 0; i < 64; i++)        {            bs->p_w[i+8+64] |= mpeg4_default_intra_matrix[mpeg2_scan_norm[i]];        }        bs->p_w += 8 + 128;        bs->p_c += (has_intra + has_non_intra) * 64;    }    else    {        bs->p_w += 8;    }    tr->scan = mpeg2_scan_norm;    return 0;}/////---- end ext mpeg codestatic int do_next_start_code( transrate_t *tr ){    bs_transrate_t *bs = &tr->bs;    uint8_t ID;    // get start code    ID = bs->p_c[0];    /* Copy one byte */    *bs->p_w++ = *bs->p_c++;    if (ID == 0x00) // pic header    {        tr->picture_coding_type = (bs->p_c[1] >> 3) & 0x7;        bs->p_c[1] |= 0x7; bs->p_c[2] = 0xFF; bs->p_c[3] |= 0xF8; // vbv_delay is now 0xFFFF        memcpy(bs->p_w, bs->p_c, 4);        bs->p_c += 4;        bs->p_w += 4;    }    else if (ID == 0xB3) // seq header    {        mpeg2_header_sequence(tr);    }    else if (ID == 0xB5) // extension    {        if ((bs->p_c[0] >> 4) == 0x8) // pic coding ext        {            tr->f_code[0][0] = (bs->p_c[0] & 0xF) - 1;            tr->f_code[0][1] = (bs->p_c[1] >> 4) - 1;            tr->f_code[1][0] = (bs->p_c[1] & 0xF) - 1;            tr->f_code[1][1] = (bs->p_c[2] >> 4) - 1;            /* tr->intra_dc_precision = (bs->p_c[2] >> 2) & 0x3; */            tr->picture_structure = bs->p_c[2] & 0x3;            tr->frame_pred_frame_dct = (bs->p_c[3] >> 6) & 0x1;            tr->concealment_motion_vectors = (bs->p_c[3] >> 5) & 0x1;            tr->q_scale_type = (bs->p_c[3] >> 4) & 0x1;            tr->intra_vlc_format = (bs->p_c[3] >> 3) & 0x1;            if ( (bs->p_c[3] >> 2) & 0x1 )                tr->scan = mpeg2_scan_alt;            memcpy(bs->p_w, bs->p_c, 5);            bs->p_c += 5;            bs->p_w += 5;        }        else        {            *bs->p_w++ = *bs->p_c++;        }    }    else if (ID == 0xB8) // gop header    {        memcpy(bs->p_w, bs->p_c, 4);        bs->p_c += 4;        bs->p_w += 4;    }    else if ((ID >= 0x01) && (ID <= 0xAF)) // slice    {        uint8_t *outTemp = bs->p_w, *inTemp = bs->p_c;        if( tr->qrate != 1.0 )        {            if( !tr->horizontal_size_value || !tr->vertical_size_value )            {                return -1;            }            // init bit buffer            bs->i_bit_in_cache = 0; bs->i_bit_in = 0;            bs->i_bit_out_cache = 0; bs->i_bit_out = BITS_IN_BUF;            // get 32 bits            bs_refill( bs );            bs_refill( bs );            bs_refill( bs );            bs_refill( bs );            // begin bit level recoding            mpeg2_slice(tr, ID);            if (tr->b_error) return -1;            bs_flush_read( bs );            bs_flush_write( bs );            // end bit level recoding            /* Basic sanity checks --Meuuh */            if (bs->p_c > bs->p_r || bs->p_w > bs->p_rw)            {                return -1;            }            /*LOGF("type: %s code: %02i in : %6i out : %6i diff : %6i fact: %2.2f\n",            (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")),            ID,  bs->p_c - inTemp, bs->p_w - outTemp, (bs->p_w - outTemp) - (bs->p_c - inTemp), (float)(bs->p_c - inTemp) / (float)(bs->p_w - outTemp));*/            if (bs->p_w - outTemp > bs->p_c - inTemp) // yes that might happen, rarely            {                /*LOGF("*** slice bigger than before !! (type: %s code: %i in : %i out : %i diff : %i)\n",                (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")),                ID, bs->p_c - inTemp, bs->p_w - outTemp, (bs->p_w - outTemp) - (bs->p_c - inTemp));*/                if ( !tr->mpeg4_matrix )                {                    // in this case, we'll just use the original slice !                    memcpy(outTemp, inTemp, bs->p_c - inTemp);                    bs->p_w = outTemp + (bs->p_c - inTemp);                    // adjust bs->i_byte_out                    bs->i_byte_out -= (bs->p_w - outTemp) - (bs->p_c - inTemp);                }                else                {                    fprintf(stderr, "bad choice for mpeg4-matrix...\n");                }            }        }    }    return 0;}int process_frame( sout_stream_t *p_stream, sout_stream_id_t *id,                   block_t *in, block_t **out, int i_handicap ){    transrate_t *tr = &id->tr;    bs_transrate_t *bs = &tr->bs;    block_t       *p_out;    double        f_drift, f_fact;    int           i_drift;    p_out = block_New( p_stream, in->i_buffer * 3 );    p_out->i_length = in->i_length;    p_out->i_dts    = in->i_dts;    p_out->i_pts    = in->i_pts;    p_out->i_flags  = in->i_flags;    bs->p_rw = bs->p_ow = bs->p_w = p_out->p_buffer;    bs->p_c = bs->p_r = in->p_buffer;    bs->p_r += in->i_buffer + 4;    bs->p_rw += in->i_buffer * 2;    *(in->p_buffer + in->i_buffer) = 0;    *(in->p_buffer + in->i_buffer + 1) = 0;    *(in->p_buffer + in->i_buffer + 2) = 1;    *(in->p_buffer + in->i_buffer + 3) = 0;    /* Calculate how late we are */    bs->i_byte_in = in->i_buffer;    bs->i_byte_out  = 0;    i_drift = tr->i_current_output + tr->i_remaining_input                - tr->i_wanted_output;    f_drift = (double)i_drift / tr->i_wanted_output;    f_fact = (double)(tr->i_wanted_output - tr->i_current_output)                    / tr->i_remaining_input;    if ( in->i_flags & BLOCK_FLAG_TYPE_I )    {        /* This is the last picture of the GOP ; only transrate if we're         * very late. */        if ( 0 && f_drift > 0.085 )        {            tr->i_minimum_error = (f_drift - 0.085) * 50.0 * 50.0;            tr->i_admissible_error = (f_drift - 0.085) * 50.0 * 75.0;            tr->qrate = 1.0 + (f_drift - 0.085) * 50.0;            msg_Warn( p_stream, "transrating I %d/%d",                      tr->i_minimum_error, tr->i_admissible_error );        }        else        {            tr->i_minimum_error = 0;            tr->i_admissible_error = 0;            tr->qrate = 1.0;        }    }    else if ( in->i_flags & BLOCK_FLAG_TYPE_P )    {        if ( f_fact < 0.8 )        {            tr->i_minimum_error = (0.8 - f_fact) * 3000.0 + i_handicap;            tr->i_admissible_error = (0.8 - f_fact) * 3500.0 + i_handicap;            tr->qrate = 1.0 + (0.8 - f_fact) * 70.0;        }        else        {            tr->i_minimum_error = 0;            tr->i_admissible_error = 0;            tr->qrate = 1.0;        }    }    else    {        if ( f_fact < 1.2 )        {            tr->i_minimum_error = (1.2 - f_fact) * 1750.0 + i_handicap;            tr->i_admissible_error = (1.2 - f_fact) * 2250.0 + i_handicap;            tr->qrate = 1.0 + (1.2 - f_fact) * 45.0;        }        else        {            tr->i_minimum_error = 0;            tr->i_admissible_error = 0;            tr->qrate = 1.0;        }    }    tr->new_quantizer_scale = 0;    tr->b_error = 0;    for ( ; ; )    {        uint8_t *p_end = &in->p_buffer[in->i_buffer];        /* Search next start code */        for( ;; )        {            if( bs->p_c < p_end - 3 && bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 1 )            {                /* Next start code */                break;            }            else if( bs->p_c < p_end - 6 &&                     bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 0 &&                     bs->p_c[3] == 0 && bs->p_c[4] == 0 && bs->p_c[5] == 0 )            {                /* remove stuffing (looking for 6 0x00 bytes) */                bs->p_c++;            }            else            {                /* Copy */                *bs->p_w++ = *bs->p_c++;            }            if( bs->p_c >= p_end )            {                break;            }        }        if( bs->p_c >= p_end )        {            break;        }        /* Copy the start code */        memcpy( bs->p_w, bs->p_c, 3 );        bs->p_c += 3;        bs->p_w += 3;        if ( do_next_start_code( tr ) )        {            /* Error */            msg_Err( p_stream, "error in do_next_start_code()" );            block_Release( p_out );            tr->i_remaining_input -= in->i_buffer;            tr->i_current_output += in->i_buffer;            return -1;        }    }    bs->i_byte_out += bs->p_w - bs->p_ow;    p_out->i_buffer = bs->p_w - bs->p_ow;#if 0    if ( in->i_flags & BLOCK_FLAG_TYPE_P && f_fact < 0.8 )    {        double f_ratio = (in->i_buffer - p_out->i_buffer) / in->i_buffer;        if ( f_ratio < (0.8 - f_fact) * 0.1 && i_handicap < 200 )        {            block_Release( p_out );            return process_frame( p_stream, id, in, out, i_handicap + 50 );        }    }    if ( in->i_flags & BLOCK_FLAG_TYPE_B && f_fact < 1.1 )    {        double f_ratio = (double)(in->i_buffer - p_out->i_buffer)                            / in->i_buffer;        if ( f_ratio < (1.1 - f_fact) * 0.1 && i_handicap < 400 )        {#ifdef DEBUG_TRANSRATER            msg_Dbg( p_stream, "%d: %d -> %d big (f: %f d: %f)",                     tr->picture_coding_type, in->i_buffer, p_out->i_buffer,                     f_fact, f_drift);#endif            block_Release( p_out );            return process_frame( p_stream, id, in, out, i_handicap + 100 );        }    }#endif#if 0    {        int toto;        for ( toto = 0; toto < p_out->i_buffer; toto++ )            if (in->p_buffer[toto] != p_out->p_buffer[toto])                msg_Dbg(p_stream, "toto %d %x %x", toto, in->p_buffer[toto], p_out->p_buffer[toto]);    }#endif    block_ChainAppend( out, p_out );    tr->i_remaining_input -= in->i_buffer;    tr->i_current_output += p_out->i_buffer;#ifdef DEBUG_TRANSRATER    msg_Dbg( p_stream, "%d: %d -> %d (%d/%d)",             tr->picture_coding_type, in->i_buffer, p_out->i_buffer,             tr->i_minimum_error, tr->i_admissible_error );#endif    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -