📄 frame.c
字号:
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 + -