diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-06-10 21:34:15 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-06-10 21:34:15 +0200 |
commit | 3630a075132a8d059b16f92a291e523c1bc7ebc9 (patch) | |
tree | 37e9a6cbb8fced1a6e3f34dd348985ff8c081663 | |
parent | 9e724d7216e693ba7af76caee5ccfb98c73d7a4b (diff) | |
parent | bcbb30e2a0f3be3e6b158694687d0fde2f6db625 (diff) | |
download | ffmpeg-3630a075132a8d059b16f92a291e523c1bc7ebc9.tar.gz |
Merge remote-tracking branch 'qatar/master'
* 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>
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/APIchanges | 4 | ||||
-rw-r--r-- | ffmpeg.c | 158 | ||||
-rw-r--r-- | libavcodec/libmp3lame.c | 2 | ||||
-rw-r--r-- | libavutil/audioconvert.c | 41 | ||||
-rw-r--r-- | libavutil/audioconvert.h | 24 | ||||
-rw-r--r-- | libavutil/avutil.h | 2 |
7 files changed, 223 insertions, 10 deletions
@@ -1451,7 +1451,7 @@ 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 --git a/doc/APIchanges b/doc/APIchanges index 15cf379134..eaf287fb70 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -34,6 +34,10 @@ API changes, most recent first: 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() @@ -85,6 +85,15 @@ #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" @@ -170,6 +179,11 @@ static int print_stats = 1; static int debug_ts = 0; static int current_time; +#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 { @@ -254,6 +268,15 @@ typedef struct InputFile { 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 { @@ -3305,6 +3328,125 @@ static int check_keyboard_interaction(int64_t cur_time) 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 */ @@ -3331,6 +3473,11 @@ static int transcode(void) timer_start = av_gettime(); +#if HAVE_THREADS + if ((ret = init_input_threads()) < 0) + goto fail; +#endif + for (; received_sigterm == 0;) { int file_index, ist_index; AVPacket pkt; @@ -3357,12 +3504,13 @@ static int transcode(void) usleep(10000); continue; } + av_log(NULL, AV_LOG_VERBOSE, "No more inputs to read from, finishing.\n"); break; } - /* read a frame from it and output it in the fifo */ is = input_files[file_index]->ctx; - ret = av_read_frame(is, &pkt); + ret = get_input_packet(input_files[file_index], &pkt); + if (ret == AVERROR(EAGAIN)) { no_packet[file_index] = 1; no_packet_count++; @@ -3475,6 +3623,9 @@ static int transcode(void) /* dump report by using the output first video and audio streams */ 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++) { @@ -3519,6 +3670,9 @@ static int transcode(void) fail: av_freep(&no_packet); +#if HAVE_THREADS + free_input_threads(); +#endif if (output_streams) { for (i = 0; i < nb_output_streams; i++) { diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 905d9a0d4c..5019287560 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -305,7 +305,7 @@ AVCodec ff_libmp3lame_encoder = { .supported_samplerates = libmp3lame_sample_rates, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, - 0}, + 0 }, .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), .priv_class = &libmp3lame_class, .defaults = libmp3lame_defaults, diff --git a/libavutil/audioconvert.c b/libavutil/audioconvert.c index 7dc7e9f1a7..e17f52ee59 100644 --- a/libavutil/audioconvert.c +++ b/libavutil/audioconvert.c @@ -182,11 +182,7 @@ void av_get_channel_layout_string(char *buf, int buf_size, 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); } int64_t av_get_default_channel_layout(int nb_channels) { @@ -196,3 +192,38 @@ int64_t av_get_default_channel_layout(int 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; +} diff --git a/libavutil/audioconvert.h b/libavutil/audioconvert.h index 319cc8ab71..03e080cb26 100644 --- a/libavutil/audioconvert.h +++ b/libavutil/audioconvert.h @@ -150,6 +150,30 @@ int av_get_channel_layout_nb_channels(uint64_t channel_layout); 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); + +/** * @} */ diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 2e83d1fd11..02b9c7b2ed 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -153,7 +153,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 56 +#define LIBAVUTIL_VERSION_MINOR 57 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |