Merge remote-tracking branch 'qatar/master'

* 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>
pull/2/head
Michael Niedermayer 13 years ago
commit a9aa88df1d
  1. 9
      libavcodec/aacdec.c
  2. 50
      libavcodec/ac3enc.c
  3. 4
      libavcodec/ac3enc.h
  4. 96
      libavcodec/ac3enc_template.c
  5. 17
      libavcodec/avcodec.h
  6. 2
      libavcodec/eac3enc.c
  7. 32
      libavcodec/h264.c
  8. 8
      libavcodec/h264_refs.c
  9. 3
      libavcodec/utils.c
  10. 3
      libavcodec/version.h

@ -591,10 +591,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
ac->m4ac.chan_config = i;
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.
* 3 delta-encoded exponents are in each 7-bit group. The number of groups
* 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 group_size, nb_groups, bit_count;
int group_size, nb_groups;
uint8_t *p;
int delta0, delta1, delta2;
int exp0, exp1;
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++) {
@ -549,7 +576,6 @@ static void group_exponents(AC3EncodeContext *s)
cpl = (ch == CPL_CH);
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]];
bit_count += 4 + (nb_groups * 7);
p = block->exp[ch] + s->start_freq[ch] - cpl;
/* 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);
group_exponents(s);
emms_c();
}
@ -842,9 +864,9 @@ static void count_frame_bits(AC3EncodeContext *s)
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; 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++;
if (block->new_cpl_coords) {
if (block->new_cpl_coords[ch]) {
frame_bits += 2;
frame_bits += (4 + 4) * s->num_cpl_bands;
}
@ -1095,6 +1117,8 @@ int ff_ac3_compute_bit_allocation(AC3EncodeContext *s)
{
count_frame_bits(s);
s->exponent_bits = count_exponent_bits(s);
bit_alloc_masking(s);
return cbr_bit_allocation(s);
@ -1370,9 +1394,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk)
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; 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]);
for (bnd = 0; bnd < s->num_cpl_bands; 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)
uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
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)
int new_snr_offsets; ///< send new SNR offsets
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);
void ff_ac3_group_exponents(AC3EncodeContext *s);
void ff_ac3_quantize_mantissas(AC3EncodeContext *s);
void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame);

@ -28,8 +28,6 @@
#include <stdint.h>
#include "ac3enc.h"
/* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */
@ -202,59 +200,56 @@ static void apply_channel_coupling(AC3EncodeContext *s)
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 */
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
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
* block did not use coupling but this block does, the channels
* using coupling has changed from the previous block, or the
* coordinate difference from the last block for any channel is
* 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 {
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
@ -262,8 +257,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
blk = 0;
while (blk < s->num_blocks) {
int blk1;
CoefSumType energy_cpl;
int av_uninit(blk1);
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use) {
@ -271,23 +265,18 @@ static void apply_channel_coupling(AC3EncodeContext *s)
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++) {
CoefType energy_ch;
CoefSumType energy_ch, energy_cpl;
if (!block->channel_in_cpl[ch])
continue;
energy_cpl = energy[blk][CPL_CH][bnd];
energy_ch = energy[blk][ch][bnd];
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];
}
blk1++;
}
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 */
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || !block->new_cpl_coords)
if (!block->cpl_in_use)
continue;
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++) {
int bnd, min_exp, max_exp, master_exp;
if (!block->new_cpl_coords[ch])
continue;
/* determine master exponent */
min_exp = max_exp = block->cpl_coord_exp[ch][0];
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;
}
ff_ac3_group_exponents(s);
ff_ac3_quantize_mantissas(s);
ff_ac3_output_frame(s, frame);

@ -3551,21 +3551,22 @@ const char *avcodec_configuration(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);
#endif
/**
* 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);

@ -99,7 +99,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
if (first_cpl_coords[ch]) {
block->new_cpl_coords = 2;
block->new_cpl_coords[ch] = 2;
first_cpl_coords[ch] = 0;
}
} else {

@ -1194,7 +1194,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
if(!s->current_picture_ptr) return 0;
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_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->outputed_poc = h->next_outputed_poc;
return 0;
return err;
}
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;
AVCodecContext * const avctx= s->avctx;
int err = 0;
s->mb_y= 0;
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(!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_lsb= h->poc_lsb;
}
@ -2389,6 +2390,8 @@ static void field_end(H264Context *h, int in_setup){
MPV_frame_end(s);
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, 1);
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.
* FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
* 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){
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 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;
AVCodecContext * const avctx= s->avctx;
H264Context *hx;
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) {
decode_slice(avctx, &h);
return decode_slice(avctx, &h);
} else {
for(i = 1; i < context_count; 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++)
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){
MpegEncContext * const s = &h->s;
int i, av_uninit(j);
int current_ref_assigned=0;
int current_ref_assigned=0, err=0;
Picture *av_uninit(pic);
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]
|| h->long_ref[mmco[i].long_arg]->frame_num != frame_num)
av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
err = AVERROR_INVALIDDATA;
continue;
}
}
@ -609,10 +610,12 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
"assignment for second field "
"in complementary field pair "
"(first field is long term)\n");
err = AVERROR_INVALIDDATA;
} else {
pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
if(pic){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
err = AVERROR_INVALIDDATA;
}
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 "
"corrupt input), discarding one\n",
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) {
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_long_term(h);
return 0;
return err;
}
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;
}
#if !FF_API_AVCODEC_INIT
static
#endif
void avcodec_init(void)
{
static int initialized = 0;

@ -80,5 +80,8 @@
#ifndef FF_API_VERY_AGGRESSIVE
#define FF_API_VERY_AGGRESSIVE (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
#ifndef FF_API_AVCODEC_INIT
#define FF_API_AVCODEC_INIT (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
#endif /* AVCODEC_VERSION_H */

Loading…
Cancel
Save