Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 10 Aug 2011 14:29:46 +0000 (16:29 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 10 Aug 2011 14:29:51 +0000 (16:29 +0200)
* 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>
libavcodec/aacdec.c
libavcodec/ac3enc.c
libavcodec/ac3enc.h
libavcodec/ac3enc_template.c
libavcodec/avcodec.h
libavcodec/eac3enc.c
libavcodec/h264.c
libavcodec/h264_refs.c
libavcodec/utils.c
libavcodec/version.h

index 7589bd7..944be9f 100644 (file)
@@ -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;
         }
     }
 
index b17036c..69be683 100644 (file)
@@ -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]);
index 2647204..a9210d7 100644 (file)
@@ -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);
index 103e7b1..7a6d72f 100644 (file)
@@ -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);
index 4bedecf..3a1eef1 100644 (file)
@@ -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);
 
index 75113b2..f3b4418 100644 (file)
@@ -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 {
index 08d66cd..a3d3a4e 100644 (file)
@@ -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;
 }
 
 
index 6794bf3..f61ad5b 100644 (file)
@@ -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){
index e7ccac2..6175d83 100644 (file)
@@ -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;
index bd2f6a5..adb9c95 100644 (file)
@@ -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 */