* qatar/master: lavc: make avcodec_init() static on next bump. ac3enc: remove unneeded #include ac3enc: restructure coupling coordinate reuse calculation ac3enc: allow new coupling coordinates to be sent independently for each channel. ac3enc: separate exponent bit counting from exponent grouping. h264: propagate error return values for AV_LOG_ERROR-triggering events aac: Don't attempt to output configure an invalid channel configuration. Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -591,10 +591,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) | |||||
| ac->m4ac.chan_config = i; | ac->m4ac.chan_config = i; | ||||
| if (ac->m4ac.chan_config) { | if (ac->m4ac.chan_config) { | ||||
| if (set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config) < 0 && | |||||
| avctx->error_recognition >= FF_ER_EXPLODE) | |||||
| return AVERROR_INVALIDDATA; | |||||
| output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR); | |||||
| int ret = set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config); | |||||
| if (!ret) | |||||
| output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR); | |||||
| else if (avctx->error_recognition >= FF_ER_EXPLODE) | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | } | ||||
| } | } | ||||
| @@ -526,20 +526,47 @@ static void encode_exponents(AC3EncodeContext *s) | |||||
| } | } | ||||
| /** | |||||
| * Count exponent bits based on bandwidth, coupling, and exponent strategies. | |||||
| */ | |||||
| static int count_exponent_bits(AC3EncodeContext *s) | |||||
| { | |||||
| int blk, ch; | |||||
| int nb_groups, bit_count; | |||||
| bit_count = 0; | |||||
| for (blk = 0; blk < s->num_blocks; blk++) { | |||||
| AC3Block *block = &s->blocks[blk]; | |||||
| for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { | |||||
| int exp_strategy = s->exp_strategy[ch][blk]; | |||||
| int cpl = (ch == CPL_CH); | |||||
| int nb_coefs = block->end_freq[ch] - s->start_freq[ch]; | |||||
| if (exp_strategy == EXP_REUSE) | |||||
| continue; | |||||
| nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs]; | |||||
| bit_count += 4 + (nb_groups * 7); | |||||
| } | |||||
| } | |||||
| return bit_count; | |||||
| } | |||||
| /** | /** | ||||
| * Group exponents. | * Group exponents. | ||||
| * 3 delta-encoded exponents are in each 7-bit group. The number of groups | * 3 delta-encoded exponents are in each 7-bit group. The number of groups | ||||
| * varies depending on exponent strategy and bandwidth. | * varies depending on exponent strategy and bandwidth. | ||||
| */ | */ | ||||
| static void group_exponents(AC3EncodeContext *s) | |||||
| void ff_ac3_group_exponents(AC3EncodeContext *s) | |||||
| { | { | ||||
| int blk, ch, i, cpl; | int blk, ch, i, cpl; | ||||
| int group_size, nb_groups, bit_count; | |||||
| int group_size, nb_groups; | |||||
| uint8_t *p; | uint8_t *p; | ||||
| int delta0, delta1, delta2; | int delta0, delta1, delta2; | ||||
| int exp0, exp1; | int exp0, exp1; | ||||
| bit_count = 0; | |||||
| for (blk = 0; blk < s->num_blocks; blk++) { | for (blk = 0; blk < s->num_blocks; blk++) { | ||||
| AC3Block *block = &s->blocks[blk]; | AC3Block *block = &s->blocks[blk]; | ||||
| for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { | for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { | ||||
| @@ -549,7 +576,6 @@ static void group_exponents(AC3EncodeContext *s) | |||||
| cpl = (ch == CPL_CH); | cpl = (ch == CPL_CH); | ||||
| group_size = exp_strategy + (exp_strategy == EXP_D45); | group_size = exp_strategy + (exp_strategy == EXP_D45); | ||||
| nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]]; | nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]]; | ||||
| bit_count += 4 + (nb_groups * 7); | |||||
| p = block->exp[ch] + s->start_freq[ch] - cpl; | p = block->exp[ch] + s->start_freq[ch] - cpl; | ||||
| /* DC exponent */ | /* DC exponent */ | ||||
| @@ -581,8 +607,6 @@ static void group_exponents(AC3EncodeContext *s) | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| s->exponent_bits = bit_count; | |||||
| } | } | ||||
| @@ -599,8 +623,6 @@ void ff_ac3_process_exponents(AC3EncodeContext *s) | |||||
| encode_exponents(s); | encode_exponents(s); | ||||
| group_exponents(s); | |||||
| emms_c(); | emms_c(); | ||||
| } | } | ||||
| @@ -842,9 +864,9 @@ static void count_frame_bits(AC3EncodeContext *s) | |||||
| if (block->cpl_in_use) { | if (block->cpl_in_use) { | ||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| if (block->channel_in_cpl[ch]) { | if (block->channel_in_cpl[ch]) { | ||||
| if (!s->eac3 || block->new_cpl_coords != 2) | |||||
| if (!s->eac3 || block->new_cpl_coords[ch] != 2) | |||||
| frame_bits++; | frame_bits++; | ||||
| if (block->new_cpl_coords) { | |||||
| if (block->new_cpl_coords[ch]) { | |||||
| frame_bits += 2; | frame_bits += 2; | ||||
| frame_bits += (4 + 4) * s->num_cpl_bands; | frame_bits += (4 + 4) * s->num_cpl_bands; | ||||
| } | } | ||||
| @@ -1095,6 +1117,8 @@ int ff_ac3_compute_bit_allocation(AC3EncodeContext *s) | |||||
| { | { | ||||
| count_frame_bits(s); | count_frame_bits(s); | ||||
| s->exponent_bits = count_exponent_bits(s); | |||||
| bit_alloc_masking(s); | bit_alloc_masking(s); | ||||
| return cbr_bit_allocation(s); | return cbr_bit_allocation(s); | ||||
| @@ -1370,9 +1394,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk) | |||||
| if (block->cpl_in_use) { | if (block->cpl_in_use) { | ||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| if (block->channel_in_cpl[ch]) { | if (block->channel_in_cpl[ch]) { | ||||
| if (!s->eac3 || block->new_cpl_coords != 2) | |||||
| put_bits(&s->pb, 1, block->new_cpl_coords); | |||||
| if (block->new_cpl_coords) { | |||||
| if (!s->eac3 || block->new_cpl_coords[ch] != 2) | |||||
| put_bits(&s->pb, 1, block->new_cpl_coords[ch]); | |||||
| if (block->new_cpl_coords[ch]) { | |||||
| put_bits(&s->pb, 2, block->cpl_master_exp[ch]); | put_bits(&s->pb, 2, block->cpl_master_exp[ch]); | ||||
| for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||||
| put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); | put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); | ||||
| @@ -124,7 +124,7 @@ typedef struct AC3Block { | |||||
| int cpl_in_use; ///< coupling in use for this block (cplinu) | int cpl_in_use; ///< coupling in use for this block (cplinu) | ||||
| uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) | uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) | ||||
| int num_cpl_channels; ///< number of channels in coupling | int num_cpl_channels; ///< number of channels in coupling | ||||
| uint8_t new_cpl_coords; ///< send new coupling coordinates (cplcoe) | |||||
| uint8_t new_cpl_coords[AC3_MAX_CHANNELS]; ///< send new coupling coordinates (cplcoe) | |||||
| uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco) | uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco) | ||||
| int new_snr_offsets; ///< send new SNR offsets | int new_snr_offsets; ///< send new SNR offsets | ||||
| int new_cpl_leak; ///< send new coupling leak info | int new_cpl_leak; ///< send new coupling leak info | ||||
| @@ -256,6 +256,8 @@ void ff_ac3_process_exponents(AC3EncodeContext *s); | |||||
| int ff_ac3_compute_bit_allocation(AC3EncodeContext *s); | int ff_ac3_compute_bit_allocation(AC3EncodeContext *s); | ||||
| void ff_ac3_group_exponents(AC3EncodeContext *s); | |||||
| void ff_ac3_quantize_mantissas(AC3EncodeContext *s); | void ff_ac3_quantize_mantissas(AC3EncodeContext *s); | ||||
| void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame); | void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame); | ||||
| @@ -28,8 +28,6 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "ac3enc.h" | |||||
| /* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */ | /* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */ | ||||
| @@ -202,59 +200,56 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| bnd++; | bnd++; | ||||
| } | } | ||||
| /* calculate coupling coordinates for all blocks for all channels */ | |||||
| for (blk = 0; blk < s->num_blocks; blk++) { | |||||
| AC3Block *block = &s->blocks[blk]; | |||||
| if (!block->cpl_in_use) | |||||
| continue; | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | |||||
| if (!block->channel_in_cpl[ch]) | |||||
| continue; | |||||
| for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | |||||
| cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd], | |||||
| energy[blk][CPL_CH][bnd]); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* determine which blocks to send new coupling coordinates for */ | /* determine which blocks to send new coupling coordinates for */ | ||||
| for (blk = 0; blk < s->num_blocks; blk++) { | for (blk = 0; blk < s->num_blocks; blk++) { | ||||
| AC3Block *block = &s->blocks[blk]; | AC3Block *block = &s->blocks[blk]; | ||||
| AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL; | AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL; | ||||
| int new_coords = 0; | |||||
| CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,}; | |||||
| if (block->cpl_in_use) { | |||||
| /* calculate coupling coordinates for all blocks and calculate the | |||||
| average difference between coordinates in successive blocks */ | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | |||||
| if (!block->channel_in_cpl[ch]) | |||||
| continue; | |||||
| for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | |||||
| cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd], | |||||
| energy[blk][CPL_CH][bnd]); | |||||
| if (blk > 0 && block0->cpl_in_use && | |||||
| block0->channel_in_cpl[ch]) { | |||||
| coord_diff[ch] += fabs(cpl_coords[blk-1][ch][bnd] - | |||||
| cpl_coords[blk ][ch][bnd]); | |||||
| } | |||||
| } | |||||
| coord_diff[ch] /= s->num_cpl_bands; | |||||
| } | |||||
| memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords)); | |||||
| if (block->cpl_in_use) { | |||||
| /* send new coordinates if this is the first block, if previous | /* send new coordinates if this is the first block, if previous | ||||
| * block did not use coupling but this block does, the channels | * block did not use coupling but this block does, the channels | ||||
| * using coupling has changed from the previous block, or the | * using coupling has changed from the previous block, or the | ||||
| * coordinate difference from the last block for any channel is | * coordinate difference from the last block for any channel is | ||||
| * greater than a threshold value. */ | * greater than a threshold value. */ | ||||
| if (blk == 0) { | |||||
| new_coords = 1; | |||||
| } else if (!block0->cpl_in_use) { | |||||
| new_coords = 1; | |||||
| if (blk == 0 || !block0->cpl_in_use) { | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) | |||||
| block->new_cpl_coords[ch] = 1; | |||||
| } else { | } else { | ||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) { | |||||
| new_coords = 1; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (!new_coords) { | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | |||||
| if (block->channel_in_cpl[ch] && coord_diff[ch] > 0.04) { | |||||
| new_coords = 1; | |||||
| break; | |||||
| if (!block->channel_in_cpl[ch]) | |||||
| continue; | |||||
| if (!block0->channel_in_cpl[ch]) { | |||||
| block->new_cpl_coords[ch] = 1; | |||||
| } else { | |||||
| CoefSumType coord_diff = 0; | |||||
| for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | |||||
| coord_diff += fabs(cpl_coords[blk-1][ch][bnd] - | |||||
| cpl_coords[blk ][ch][bnd]); | |||||
| } | } | ||||
| coord_diff /= s->num_cpl_bands; | |||||
| if (coord_diff > 0.03) | |||||
| block->new_cpl_coords[ch] = 1; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| block->new_cpl_coords = new_coords; | |||||
| } | } | ||||
| /* calculate final coupling coordinates, taking into account reusing of | /* calculate final coupling coordinates, taking into account reusing of | ||||
| @@ -262,8 +257,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||||
| blk = 0; | blk = 0; | ||||
| while (blk < s->num_blocks) { | while (blk < s->num_blocks) { | ||||
| int blk1; | |||||
| CoefSumType energy_cpl; | |||||
| int av_uninit(blk1); | |||||
| AC3Block *block = &s->blocks[blk]; | AC3Block *block = &s->blocks[blk]; | ||||
| if (!block->cpl_in_use) { | if (!block->cpl_in_use) { | ||||
| @@ -271,23 +265,18 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| continue; | continue; | ||||
| } | } | ||||
| energy_cpl = energy[blk][CPL_CH][bnd]; | |||||
| blk1 = blk+1; | |||||
| while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) { | |||||
| if (s->blocks[blk1].cpl_in_use) | |||||
| energy_cpl += energy[blk1][CPL_CH][bnd]; | |||||
| blk1++; | |||||
| } | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| CoefType energy_ch; | |||||
| CoefSumType energy_ch, energy_cpl; | |||||
| if (!block->channel_in_cpl[ch]) | if (!block->channel_in_cpl[ch]) | ||||
| continue; | continue; | ||||
| energy_cpl = energy[blk][CPL_CH][bnd]; | |||||
| energy_ch = energy[blk][ch][bnd]; | energy_ch = energy[blk][ch][bnd]; | ||||
| blk1 = blk+1; | blk1 = blk+1; | ||||
| while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) { | |||||
| if (s->blocks[blk1].cpl_in_use) | |||||
| while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { | |||||
| if (s->blocks[blk1].cpl_in_use) { | |||||
| energy_cpl += energy[blk1][CPL_CH][bnd]; | |||||
| energy_ch += energy[blk1][ch][bnd]; | energy_ch += energy[blk1][ch][bnd]; | ||||
| } | |||||
| blk1++; | blk1++; | ||||
| } | } | ||||
| cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); | cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); | ||||
| @@ -299,7 +288,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| /* calculate exponents/mantissas for coupling coordinates */ | /* calculate exponents/mantissas for coupling coordinates */ | ||||
| for (blk = 0; blk < s->num_blocks; blk++) { | for (blk = 0; blk < s->num_blocks; blk++) { | ||||
| AC3Block *block = &s->blocks[blk]; | AC3Block *block = &s->blocks[blk]; | ||||
| if (!block->cpl_in_use || !block->new_cpl_coords) | |||||
| if (!block->cpl_in_use) | |||||
| continue; | continue; | ||||
| clip_coefficients(&s->dsp, cpl_coords[blk][1], s->fbw_channels * 16); | clip_coefficients(&s->dsp, cpl_coords[blk][1], s->fbw_channels * 16); | ||||
| @@ -313,6 +302,9 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| int bnd, min_exp, max_exp, master_exp; | int bnd, min_exp, max_exp, master_exp; | ||||
| if (!block->new_cpl_coords[ch]) | |||||
| continue; | |||||
| /* determine master exponent */ | /* determine master exponent */ | ||||
| min_exp = max_exp = block->cpl_coord_exp[ch][0]; | min_exp = max_exp = block->cpl_coord_exp[ch][0]; | ||||
| for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { | for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { | ||||
| @@ -463,6 +455,8 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame, | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| ff_ac3_group_exponents(s); | |||||
| ff_ac3_quantize_mantissas(s); | ff_ac3_quantize_mantissas(s); | ||||
| ff_ac3_output_frame(s, frame); | ff_ac3_output_frame(s, frame); | ||||
| @@ -3551,21 +3551,22 @@ const char *avcodec_configuration(void); | |||||
| */ | */ | ||||
| const char *avcodec_license(void); | const char *avcodec_license(void); | ||||
| #if FF_API_AVCODEC_INIT | |||||
| /** | /** | ||||
| * Initialize libavcodec. | |||||
| * If called more than once, does nothing. | |||||
| * | |||||
| * @warning This function must be called before any other libavcodec | |||||
| * function. | |||||
| * | |||||
| * @warning This function is not thread-safe. | |||||
| * @deprecated this function is called automatically from avcodec_register() | |||||
| * and avcodec_register_all(), there is no need to call it manually | |||||
| */ | */ | ||||
| attribute_deprecated | |||||
| void avcodec_init(void); | void avcodec_init(void); | ||||
| #endif | |||||
| /** | /** | ||||
| * Register the codec codec and initialize libavcodec. | * Register the codec codec and initialize libavcodec. | ||||
| * | * | ||||
| * @see avcodec_init(), avcodec_register_all() | |||||
| * @warning either this function or avcodec_register_all() must be called | |||||
| * before any other libavcodec functions. | |||||
| * | |||||
| * @see avcodec_register_all() | |||||
| */ | */ | ||||
| void avcodec_register(AVCodec *codec); | void avcodec_register(AVCodec *codec); | ||||
| @@ -99,7 +99,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) | |||||
| for (ch = 1; ch <= s->fbw_channels; ch++) { | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||||
| if (block->channel_in_cpl[ch]) { | if (block->channel_in_cpl[ch]) { | ||||
| if (first_cpl_coords[ch]) { | if (first_cpl_coords[ch]) { | ||||
| block->new_cpl_coords = 2; | |||||
| block->new_cpl_coords[ch] = 2; | |||||
| first_cpl_coords[ch] = 0; | first_cpl_coords[ch] = 0; | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -1194,7 +1194,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex | |||||
| if(!s->current_picture_ptr) return 0; | if(!s->current_picture_ptr) return 0; | ||||
| if(!s->dropable) { | if(!s->dropable) { | ||||
| ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); | |||||
| err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); | |||||
| h->prev_poc_msb = h->poc_msb; | h->prev_poc_msb = h->poc_msb; | ||||
| h->prev_poc_lsb = h->poc_lsb; | h->prev_poc_lsb = h->poc_lsb; | ||||
| } | } | ||||
| @@ -1202,7 +1202,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex | |||||
| h->prev_frame_num = h->frame_num; | h->prev_frame_num = h->frame_num; | ||||
| h->outputed_poc = h->next_outputed_poc; | h->outputed_poc = h->next_outputed_poc; | ||||
| return 0; | |||||
| return err; | |||||
| } | } | ||||
| int ff_h264_frame_start(H264Context *h){ | int ff_h264_frame_start(H264Context *h){ | ||||
| @@ -2340,9 +2340,10 @@ static void init_scan_tables(H264Context *h){ | |||||
| } | } | ||||
| } | } | ||||
| static void field_end(H264Context *h, int in_setup){ | |||||
| static int field_end(H264Context *h, int in_setup){ | |||||
| MpegEncContext * const s = &h->s; | MpegEncContext * const s = &h->s; | ||||
| AVCodecContext * const avctx= s->avctx; | AVCodecContext * const avctx= s->avctx; | ||||
| int err = 0; | |||||
| s->mb_y= 0; | s->mb_y= 0; | ||||
| if (!in_setup && !s->dropable) | if (!in_setup && !s->dropable) | ||||
| @@ -2354,7 +2355,7 @@ static void field_end(H264Context *h, int in_setup){ | |||||
| if(in_setup || !(avctx->active_thread_type&FF_THREAD_FRAME)){ | if(in_setup || !(avctx->active_thread_type&FF_THREAD_FRAME)){ | ||||
| if(!s->dropable) { | if(!s->dropable) { | ||||
| ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); | |||||
| err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); | |||||
| h->prev_poc_msb= h->poc_msb; | h->prev_poc_msb= h->poc_msb; | ||||
| h->prev_poc_lsb= h->poc_lsb; | h->prev_poc_lsb= h->poc_lsb; | ||||
| } | } | ||||
| @@ -2389,6 +2390,8 @@ static void field_end(H264Context *h, int in_setup){ | |||||
| MPV_frame_end(s); | MPV_frame_end(s); | ||||
| h->current_slice=0; | h->current_slice=0; | ||||
| return err; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -2690,7 +2693,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ | |||||
| ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0); | ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0); | ||||
| ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1); | ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1); | ||||
| ff_generate_sliding_window_mmcos(h); | ff_generate_sliding_window_mmcos(h); | ||||
| ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); | |||||
| if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 && | |||||
| s->avctx->error_recognition >= FF_ER_EXPLODE) | |||||
| return AVERROR_INVALIDDATA; | |||||
| /* Error concealment: if a ref is missing, copy the previous ref in its place. | /* Error concealment: if a ref is missing, copy the previous ref in its place. | ||||
| * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions | * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions | ||||
| * about there being no actual duplicates. | * about there being no actual duplicates. | ||||
| @@ -2864,8 +2869,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ | |||||
| } | } | ||||
| } | } | ||||
| if(h->nal_ref_idc) | |||||
| ff_h264_decode_ref_pic_marking(h0, &s->gb); | |||||
| if(h->nal_ref_idc && ff_h264_decode_ref_pic_marking(h0, &s->gb) < 0 && | |||||
| s->avctx->error_recognition >= FF_ER_EXPLODE) | |||||
| return AVERROR_INVALIDDATA; | |||||
| if(FRAME_MBAFF){ | if(FRAME_MBAFF){ | ||||
| ff_h264_fill_mbaff_ref_list(h); | ff_h264_fill_mbaff_ref_list(h); | ||||
| @@ -3490,18 +3496,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ | |||||
| * @param h h264 master context | * @param h h264 master context | ||||
| * @param context_count number of contexts to execute | * @param context_count number of contexts to execute | ||||
| */ | */ | ||||
| static void execute_decode_slices(H264Context *h, int context_count){ | |||||
| static int execute_decode_slices(H264Context *h, int context_count){ | |||||
| MpegEncContext * const s = &h->s; | MpegEncContext * const s = &h->s; | ||||
| AVCodecContext * const avctx= s->avctx; | AVCodecContext * const avctx= s->avctx; | ||||
| H264Context *hx; | H264Context *hx; | ||||
| int i; | int i; | ||||
| if (s->avctx->hwaccel) | |||||
| return; | |||||
| if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) | |||||
| return; | |||||
| if (s->avctx->hwaccel || s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) | |||||
| return 0; | |||||
| if(context_count == 1) { | if(context_count == 1) { | ||||
| decode_slice(avctx, &h); | |||||
| return decode_slice(avctx, &h); | |||||
| } else { | } else { | ||||
| for(i = 1; i < context_count; i++) { | for(i = 1; i < context_count; i++) { | ||||
| hx = h->thread_context[i]; | hx = h->thread_context[i]; | ||||
| @@ -3522,6 +3526,8 @@ static void execute_decode_slices(H264Context *h, int context_count){ | |||||
| for(i = 1; i < context_count; i++) | for(i = 1; i < context_count; i++) | ||||
| h->s.error_count += h->thread_context[i]->s.error_count; | h->s.error_count += h->thread_context[i]->s.error_count; | ||||
| } | } | ||||
| return 0; | |||||
| } | } | ||||
| @@ -499,7 +499,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h) { | |||||
| int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | ||||
| MpegEncContext * const s = &h->s; | MpegEncContext * const s = &h->s; | ||||
| int i, av_uninit(j); | int i, av_uninit(j); | ||||
| int current_ref_assigned=0; | |||||
| int current_ref_assigned=0, err=0; | |||||
| Picture *av_uninit(pic); | Picture *av_uninit(pic); | ||||
| if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) | if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) | ||||
| @@ -518,6 +518,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | |||||
| if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] | if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] | ||||
| || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) | || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) | ||||
| av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); | av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); | ||||
| err = AVERROR_INVALIDDATA; | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| @@ -609,10 +610,12 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | |||||
| "assignment for second field " | "assignment for second field " | ||||
| "in complementary field pair " | "in complementary field pair " | ||||
| "(first field is long term)\n"); | "(first field is long term)\n"); | ||||
| err = AVERROR_INVALIDDATA; | |||||
| } else { | } else { | ||||
| pic= remove_short(h, s->current_picture_ptr->frame_num, 0); | pic= remove_short(h, s->current_picture_ptr->frame_num, 0); | ||||
| if(pic){ | if(pic){ | ||||
| av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); | av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); | ||||
| err = AVERROR_INVALIDDATA; | |||||
| } | } | ||||
| if(h->short_ref_count) | if(h->short_ref_count) | ||||
| @@ -634,6 +637,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | |||||
| "number of reference frames (%d+%d) exceeds max (%d; probably " | "number of reference frames (%d+%d) exceeds max (%d; probably " | ||||
| "corrupt input), discarding one\n", | "corrupt input), discarding one\n", | ||||
| h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count); | h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count); | ||||
| err = AVERROR_INVALIDDATA; | |||||
| if (h->long_ref_count && !h->short_ref_count) { | if (h->long_ref_count && !h->short_ref_count) { | ||||
| for (i = 0; i < 16; ++i) | for (i = 0; i < 16; ++i) | ||||
| @@ -650,7 +654,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ | |||||
| print_short_term(h); | print_short_term(h); | ||||
| print_long_term(h); | print_long_term(h); | ||||
| return 0; | |||||
| return err; | |||||
| } | } | ||||
| int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ | int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ | ||||
| @@ -1144,6 +1144,9 @@ const char *avcodec_license(void) | |||||
| return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; | return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; | ||||
| } | } | ||||
| #if !FF_API_AVCODEC_INIT | |||||
| static | |||||
| #endif | |||||
| void avcodec_init(void) | void avcodec_init(void) | ||||
| { | { | ||||
| static int initialized = 0; | static int initialized = 0; | ||||
| @@ -80,5 +80,8 @@ | |||||
| #ifndef FF_API_VERY_AGGRESSIVE | #ifndef FF_API_VERY_AGGRESSIVE | ||||
| #define FF_API_VERY_AGGRESSIVE (LIBAVCODEC_VERSION_MAJOR < 54) | #define FF_API_VERY_AGGRESSIVE (LIBAVCODEC_VERSION_MAJOR < 54) | ||||
| #endif | #endif | ||||
| #ifndef FF_API_AVCODEC_INIT | |||||
| #define FF_API_AVCODEC_INIT (LIBAVCODEC_VERSION_MAJOR < 54) | |||||
| #endif | |||||
| #endif /* AVCODEC_VERSION_H */ | #endif /* AVCODEC_VERSION_H */ | ||||