Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 10 Jun 2012 19:34:15 +0000 (21:34 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 10 Jun 2012 19:34:15 +0000 (21:34 +0200)
* qatar/master:
  libmp3lame: add missing layout terminator
  avconv: multithreaded demuxing.
  Bump lavu minor and add an APIChanges entry for audioconvert functions.
  audioconvert: add a function for extracting the channel with the given index
  audioconvert: add a function for getting the name of a single channel.
  audioconvert: add a function for getting channel's index in layout
  audioconvert: use av_popcount64 in av_get_channel_layout_nb_channels
  vf_libopencv: add missing headers.
  iac: add missing dependency

Conflicts:
configure
doc/APIchanges
ffmpeg.c
libavcodec/libmp3lame.c
libavutil/avutil.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
configure
doc/APIchanges
ffmpeg.c
libavcodec/libmp3lame.c
libavutil/audioconvert.c
libavutil/audioconvert.h
libavutil/avutil.h

diff --cc configure
+++ b/configure
@@@ -1448,10 -1312,9 +1448,10 @@@ h264_decoder_select="golomb h264chroma 
  h264_dxva2_hwaccel_deps="dxva2api_h"
  h264_dxva2_hwaccel_select="dxva2 h264_decoder"
  h264_vaapi_hwaccel_select="vaapi h264_decoder"
 +h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
  h264_vda_hwaccel_select="vda h264_decoder"
  h264_vdpau_decoder_select="vdpau h264_decoder"
- iac_decoder_select="sinewin"
+ iac_decoder_select="fft mdct sinewin"
  imc_decoder_select="fft mdct sinewin"
  jpegls_decoder_select="golomb"
  jpegls_encoder_select="golomb"
diff --cc doc/APIchanges
@@@ -15,25 -13,10 +15,29 @@@ libavutil:     2011-04-1
  
  API changes, most recent first:
  
 +2012-06-05 - xxxxxxx - lavc 54.24.100
 +  Add pkt_duration field to AVFrame.
 +
 +2012-05-24 - xxxxxxx - lavu 51.54.100
 +  Move AVPALETTE_SIZE and AVPALETTE_COUNT macros from
 +  libavcodec/avcodec.h to libavutil/pixfmt.h.
 +
 +2012-05-07 - xxxxxxx - lavf 54.5.100
 +  Add av_guess_sample_aspect_ratio() function.
 +
 +2012-04-20 - xxxxxxx - lavfi 2.70.100
 +  Add avfilter_unref_bufferp() to avfilter.h.
 +
 +2012-04-12 - xxxxxxx - lavfi 2.68.100
 +  Install libavfilter/asrc_abuffer.h public header.
 +
 +2012-03-26 - a67d9cf - lavfi 2.66.100
 +  Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
 +
+ 2012-xx-xx - xxxxxxx - lavu 51.32.0 - audioconvert.h
+   Add av_get_channel_layout_channel_index(), av_get_channel_name()
+   and av_channel_layout_extract_channel().
  2012-05-25 - e0e0793 - lavu 51.31.0 - opt.h
    Add av_opt_set_bin()
  
diff --cc ffmpeg.c
+++ b/ffmpeg.c
  #include <sys/select.h>
  #endif
  
 +#if HAVE_TERMIOS_H
 +#include <fcntl.h>
 +#include <sys/ioctl.h>
 +#include <sys/time.h>
 +#include <termios.h>
 +#elif HAVE_KBHIT
 +#include <conio.h>
 +#endif
++
+ #if HAVE_THREADS
+ #if HAVE_PTHREADS
+ #include <pthread.h>
+ #else
+ #include "libavcodec/w32pthreads.h"
+ #endif
+ #endif
  #include <time.h>
  
  #include "cmdutils.h"
@@@ -164,13 -145,15 +173,18 @@@ static int nb_frames_drop = 0
  static int input_sync;
  
  static float dts_delta_threshold = 10;
 +static float dts_error_threshold = 3600*30;
  
  static int print_stats = 1;
 +static int debug_ts = 0;
 +static int current_time;
  
 -#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
+ #if HAVE_THREADS
+ /* signal to input threads that they should exit; set by the main thread */
+ static int transcoding_finished;
+ #endif
 +#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
  
  typedef struct InputFilter {
      AVFilterContext    *filter;
@@@ -248,12 -226,21 +262,21 @@@ typedef struct InputStream 
  typedef struct InputFile {
      AVFormatContext *ctx;
      int eof_reached;      /* true if eof reached */
 -    int ist_index;        /* index of first stream in ist_table */
 +    int ist_index;        /* index of first stream in input_streams */
      int buffer_size;      /* current total buffer size */
      int64_t ts_offset;
 -    int nb_streams;       /* number of stream that avconv is aware of; may be different
 +    int nb_streams;       /* number of stream that ffmpeg is aware of; may be different
                               from ctx.nb_streams if new streams appear during av_read_frame() */
      int rate_emu;
+ #if HAVE_THREADS
+     pthread_t thread;           /* thread reading from this file */
+     int finished;               /* the thread has exited */
+     int joined;                 /* the thread has been joined */
+     pthread_mutex_t fifo_lock;  /* lock for access to fifo */
+     pthread_cond_t  fifo_cond;  /* the main thread will signal on this cond after reading from fifo */
+     AVFifoBuffer *fifo;         /* demuxed packets are stored here; freed by the main thread */
+ #endif
  } InputFile;
  
  typedef struct OutputStream {
@@@ -3212,99 -2787,125 +3235,218 @@@ static int select_input_file(uint8_t *n
      return file_index;
  }
  
 +static int check_keyboard_interaction(int64_t cur_time)
 +{
 +    int i, ret, key;
 +    static int64_t last_time;
 +    if (received_nb_signals)
 +        return AVERROR_EXIT;
 +    /* read_key() returns 0 on EOF */
 +    if(cur_time - last_time >= 100000 && !run_as_daemon){
 +        key =  read_key();
 +        last_time = cur_time;
 +    }else
 +        key = -1;
 +    if (key == 'q')
 +        return AVERROR_EXIT;
 +    if (key == '+') av_log_set_level(av_log_get_level()+10);
 +    if (key == '-') av_log_set_level(av_log_get_level()-10);
 +    if (key == 's') qp_hist     ^= 1;
 +    if (key == 'h'){
 +        if (do_hex_dump){
 +            do_hex_dump = do_pkt_dump = 0;
 +        } else if(do_pkt_dump){
 +            do_hex_dump = 1;
 +        } else
 +            do_pkt_dump = 1;
 +        av_log_set_level(AV_LOG_DEBUG);
 +    }
 +    if (key == 'c' || key == 'C'){
 +        char buf[4096], target[64], command[256], arg[256] = {0};
 +        double time;
 +        int k, n = 0;
 +        fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
 +        i = 0;
 +        while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
 +            if (k > 0)
 +                buf[i++] = k;
 +        buf[i] = 0;
 +        if (k > 0 &&
 +            (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
 +            av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
 +                   target, time, command, arg);
 +            for (i = 0; i < nb_filtergraphs; i++) {
 +                FilterGraph *fg = filtergraphs[i];
 +                if (fg->graph) {
 +                    if (time < 0) {
 +                        ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
 +                                                          key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
 +                        fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
 +                    } else {
 +                        ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
 +                    }
 +                }
 +            }
 +        } else {
 +            av_log(NULL, AV_LOG_ERROR,
 +                   "Parse error, at least 3 arguments were expected, "
 +                   "only %d given in string '%s'\n", n, buf);
 +        }
 +    }
 +    if (key == 'd' || key == 'D'){
 +        int debug=0;
 +        if(key == 'D') {
 +            debug = input_streams[0]->st->codec->debug<<1;
 +            if(!debug) debug = 1;
 +            while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
 +                debug += debug;
 +        }else
 +            if(scanf("%d", &debug)!=1)
 +                fprintf(stderr,"error parsing debug value\n");
 +        for(i=0;i<nb_input_streams;i++) {
 +            input_streams[i]->st->codec->debug = debug;
 +        }
 +        for(i=0;i<nb_output_streams;i++) {
 +            OutputStream *ost = output_streams[i];
 +            ost->st->codec->debug = debug;
 +        }
 +        if(debug) av_log_set_level(AV_LOG_DEBUG);
 +        fprintf(stderr,"debug=%d\n", debug);
 +    }
 +    if (key == '?'){
 +        fprintf(stderr, "key    function\n"
 +                        "?      show this help\n"
 +                        "+      increase verbosity\n"
 +                        "-      decrease verbosity\n"
 +                        "c      Send command to filtergraph\n"
 +                        "D      cycle through available debug modes\n"
 +                        "h      dump packets/hex press to cycle through the 3 states\n"
 +                        "q      quit\n"
 +                        "s      Show QP histogram\n"
 +        );
 +    }
 +    return 0;
 +}
 +
+ #if HAVE_THREADS
+ static void *input_thread(void *arg)
+ {
+     InputFile *f = arg;
+     int ret = 0;
+     while (!transcoding_finished && ret >= 0) {
+         AVPacket pkt;
+         ret = av_read_frame(f->ctx, &pkt);
+         if (ret == AVERROR(EAGAIN)) {
+             usleep(10000);
+             ret = 0;
+             continue;
+         } else if (ret < 0)
+             break;
+         pthread_mutex_lock(&f->fifo_lock);
+         while (!av_fifo_space(f->fifo))
+             pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
+         av_dup_packet(&pkt);
+         av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
+         pthread_mutex_unlock(&f->fifo_lock);
+     }
+     f->finished = 1;
+     return NULL;
+ }
+ static void free_input_threads(void)
+ {
+     int i;
+     if (nb_input_files == 1)
+         return;
+     transcoding_finished = 1;
+     for (i = 0; i < nb_input_files; i++) {
+         InputFile *f = input_files[i];
+         AVPacket pkt;
+         if (f->joined)
+             continue;
+         pthread_mutex_lock(&f->fifo_lock);
+         while (av_fifo_size(f->fifo)) {
+             av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+             av_free_packet(&pkt);
+         }
+         pthread_cond_signal(&f->fifo_cond);
+         pthread_mutex_unlock(&f->fifo_lock);
+         pthread_join(f->thread, NULL);
+         f->joined = 1;
+         while (av_fifo_size(f->fifo)) {
+             av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+             av_free_packet(&pkt);
+         }
+         av_fifo_free(f->fifo);
+     }
+ }
+ static int init_input_threads(void)
+ {
+     int i, ret;
+     if (nb_input_files == 1)
+         return 0;
+     for (i = 0; i < nb_input_files; i++) {
+         InputFile *f = input_files[i];
+         if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
+             return AVERROR(ENOMEM);
+         pthread_mutex_init(&f->fifo_lock, NULL);
+         pthread_cond_init (&f->fifo_cond, NULL);
+         if ((ret = pthread_create(&f->thread, NULL, input_thread, f)))
+             return AVERROR(ret);
+     }
+     return 0;
+ }
+ static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
+ {
+     int ret = 0;
+     pthread_mutex_lock(&f->fifo_lock);
+     if (av_fifo_size(f->fifo)) {
+         av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
+         pthread_cond_signal(&f->fifo_cond);
+     } else {
+         if (f->finished)
+             ret = AVERROR_EOF;
+         else
+             ret = AVERROR(EAGAIN);
+     }
+     pthread_mutex_unlock(&f->fifo_lock);
+     return ret;
+ }
+ #endif
+ static int get_input_packet(InputFile *f, AVPacket *pkt)
+ {
+ #if HAVE_THREADS
+     if (nb_input_files > 1)
+         return get_input_packet_mt(f, pkt);
+ #endif
+     return av_read_frame(f->ctx, pkt);
+ }
  /*
   * The following code is the main loop of the file converter
   */
@@@ -3473,8 -3042,11 +3621,11 @@@ static int transcode(void
          av_free_packet(&pkt);
  
          /* dump report by using the output first video and audio streams */
 -        print_report(0, timer_start);
 +        print_report(0, timer_start, cur_time);
      }
+ #if HAVE_THREADS
+     free_input_threads();
+ #endif
  
      /* at the end of stream, we must flush the decoder buffers */
      for (i = 0; i < nb_input_streams; i++) {
Simple merge
@@@ -171,28 -173,57 +171,59 @@@ void av_bprint_channel_layout(struct AV
      }
  }
  
 +void av_get_channel_layout_string(char *buf, int buf_size,
 +                                  int nb_channels, uint64_t channel_layout)
 +{
 +    AVBPrint bp;
 +
 +    av_bprint_init_for_buffer(&bp, buf, buf_size);
 +    av_bprint_channel_layout(&bp, nb_channels, channel_layout);
 +}
 +
  int av_get_channel_layout_nb_channels(uint64_t channel_layout)
  {
-     int count;
-     uint64_t x = channel_layout;
-     for (count = 0; x; count++)
-         x &= x-1; // unset lowest set bit
-     return count;
+     return av_popcount64(channel_layout);
  }
  
 -uint64_t av_get_default_channel_layout(int nb_channels)
 -{
 -    switch(nb_channels) {
 -    case 1: return AV_CH_LAYOUT_MONO;
 -    case 2: return AV_CH_LAYOUT_STEREO;
 -    case 3: return AV_CH_LAYOUT_SURROUND;
 -    case 4: return AV_CH_LAYOUT_QUAD;
 -    case 5: return AV_CH_LAYOUT_5POINT0;
 -    case 6: return AV_CH_LAYOUT_5POINT1;
 -    case 7: return AV_CH_LAYOUT_6POINT1;
 -    case 8: return AV_CH_LAYOUT_7POINT1;
 -    default: return 0;
 -    }
 +int64_t av_get_default_channel_layout(int nb_channels) {
 +    int i;
 +    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
 +        if (nb_channels == channel_layout_map[i].nb_channels)
 +            return channel_layout_map[i].layout;
 +    return 0;
  }
+ int av_get_channel_layout_channel_index(uint64_t channel_layout,
+                                         uint64_t channel)
+ {
+     if (!(channel_layout & channel) ||
+         av_get_channel_layout_nb_channels(channel) != 1)
+         return AVERROR(EINVAL);
+     channel_layout &= channel - 1;
+     return av_get_channel_layout_nb_channels(channel_layout);
+ }
+ const char *av_get_channel_name(uint64_t channel)
+ {
+     int i;
+     if (av_get_channel_layout_nb_channels(channel) != 1)
+         return NULL;
+     for (i = 0; i < 64; i++)
+         if ((1ULL<<i) & channel)
+             return get_channel_name(i);
+     return NULL;
+ }
+ uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
+ {
+     int i;
+     if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+         return 0;
+     for (i = 0; i < 64; i++) {
+         if ((1ULL << i) & channel_layout && !index--)
+             return 1ULL << i;
+     }
+     return 0;
+ }
@@@ -147,9 -141,33 +147,33 @@@ int av_get_channel_layout_nb_channels(u
  /**
   * Return default channel layout for a given number of channels.
   */
 -uint64_t av_get_default_channel_layout(int nb_channels);
 +int64_t av_get_default_channel_layout(int nb_channels);
  
  /**
+  * Get the index of a channel in channel_layout.
+  *
+  * @param channel a channel layout describing exactly one channel which must be
+  *                present in channel_layout.
+  *
+  * @return index of channel in channel_layout on success, a negative AVERROR
+  *         on error.
+  */
+ int av_get_channel_layout_channel_index(uint64_t channel_layout,
+                                         uint64_t channel);
+ /**
+  * Get the channel with the given index in channel_layout.
+  */
+ uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
+ /**
+  * Get the name of a given channel.
+  *
+  * @return channel name on success, NULL on error.
+  */
+ const char *av_get_channel_name(uint64_t channel);
+ /**
   * @}
   */
  
   */
  
  #define LIBAVUTIL_VERSION_MAJOR 51
- #define LIBAVUTIL_VERSION_MINOR 56
 -#define LIBAVUTIL_VERSION_MINOR 32
 -#define LIBAVUTIL_VERSION_MICRO  0
++#define LIBAVUTIL_VERSION_MINOR 57
 +#define LIBAVUTIL_VERSION_MICRO 100
  
  #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                 LIBAVUTIL_VERSION_MINOR, \