History

avplay: use libavresample for sample format conversion and channel mixing

SDL only supports s16 sample format and a limited number of channel layouts. Some versions of SDL on some systems support 4-channel and 6-channel output, but it's safer overall to downmix any layout with more than 2 channels to stereo.

Justin Ruggles committed 14 years ago

Commit f1ffb011 parent e5b7d771 file · +86 −38Browse files

Unified · Split

avplay.c+86−38
@@ -34,7 +34,7 @@ · 33 unmodified lines
34#include "libavformat/avformat.h"34#include "libavformat/avformat.h"
35#include "libavdevice/avdevice.h"35#include "libavdevice/avdevice.h"
36#include "libswscale/swscale.h"36#include "libswscale/swscale.h"
37#include "libavcodec/audioconvert.h"37#include "libavresample/avresample.h"
38#include "libavutil/opt.h"38#include "libavutil/opt.h"
39#include "libavcodec/avfft.h"39#include "libavcodec/avfft.h"
40 40
@@ -159,8 +159,12 @@ typedef struct VideoState { · 118 unmodified lines
159 int audio_buf_index; /* in bytes */159 int audio_buf_index; /* in bytes */
160 AVPacket audio_pkt_temp;160 AVPacket audio_pkt_temp;
161 AVPacket audio_pkt;161 AVPacket audio_pkt;
162 enum AVSampleFormat audio_src_fmt;162 enum AVSampleFormat sdl_sample_fmt;
163 AVAudioConvert *reformat_ctx;163 uint64_t sdl_channel_layout;
164 int sdl_channels;
165 enum AVSampleFormat resample_sample_fmt;
166 uint64_t resample_channel_layout;
167 AVAudioResampleContext *avr;
164 AVFrame *frame;168 AVFrame *frame;
165 169
166 int show_audio; /* if true, display audio samples */170 int show_audio; /* if true, display audio samples */
@@ -743,7 +747,7 @@ static void video_audio_display(VideoState *s) · 576 unmodified lines
743 nb_freq = 1 << (rdft_bits - 1);747 nb_freq = 1 << (rdft_bits - 1);
744 748
745 /* compute display index : center on currently output samples */749 /* compute display index : center on currently output samples */
746 channels = s->audio_st->codec->channels;750 channels = s->sdl_channels;
747 nb_display_channels = channels;751 nb_display_channels = channels;
748 if (!s->paused) {752 if (!s->paused) {
749 int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq);753 int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq);
@@ -957,8 +961,8 @@ static double get_audio_clock(VideoState *is) · 207 unmodified lines
957 hw_buf_size = audio_write_get_buf_size(is);961 hw_buf_size = audio_write_get_buf_size(is);
958 bytes_per_sec = 0;962 bytes_per_sec = 0;
959 if (is->audio_st) {963 if (is->audio_st) {
960 bytes_per_sec = is->audio_st->codec->sample_rate *964 bytes_per_sec = is->audio_st->codec->sample_rate * is->sdl_channels *
961 2 * is->audio_st->codec->channels;965 av_get_bytes_per_sample(is->sdl_sample_fmt);
962 }966 }
963 if (bytes_per_sec)967 if (bytes_per_sec)
964 pts -= (double)hw_buf_size / bytes_per_sec;968 pts -= (double)hw_buf_size / bytes_per_sec;
@@ -1937,7 +1941,7 @@ static int synchronize_audio(VideoState *is, short *samples, · 972 unmodified lines
1937 int n, samples_size;1941 int n, samples_size;
1938 double ref_clock;1942 double ref_clock;
1939 1943
1940 n = 2 * is->audio_st->codec->channels;1944 n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
1941 samples_size = samples_size1;1945 samples_size = samples_size1;
1942 1946
1943 /* if not master, then we try to remove or add samples to correct the clock */1947 /* if not master, then we try to remove or add samples to correct the clock */
@@ -2018,6 +2022,8 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) · 74 unmodified lines
2018 for (;;) {2022 for (;;) {
2019 /* NOTE: the audio packet can contain several frames */2023 /* NOTE: the audio packet can contain several frames */
2020 while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {2024 while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
2025 int resample_changed, audio_resample;
2026
2021 if (!is->frame) {2027 if (!is->frame) {
2022 if (!(is->frame = avcodec_alloc_frame()))2028 if (!(is->frame = avcodec_alloc_frame()))
2023 return AVERROR(ENOMEM);2029 return AVERROR(ENOMEM);
@@ -2047,39 +2053,67 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) · 23 unmodified lines
2047 is->frame->nb_samples,2053 is->frame->nb_samples,
2048 dec->sample_fmt, 1);2054 dec->sample_fmt, 1);
2049 2055
2050 if (dec->sample_fmt != is->audio_src_fmt) {2056 audio_resample = dec->sample_fmt != is->sdl_sample_fmt ||
2051 if (is->reformat_ctx)2057 dec->channel_layout != is->sdl_channel_layout;
2052 av_audio_convert_free(is->reformat_ctx);2058
2053 is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,2059 resample_changed = dec->sample_fmt != is->resample_sample_fmt ||
2054 dec->sample_fmt, 1, NULL, 0);2060 dec->channel_layout != is->resample_channel_layout;
2055 if (!is->reformat_ctx) {2061
2056 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",2062 if ((!is->avr && audio_resample) || resample_changed) {
2057 av_get_sample_fmt_name(dec->sample_fmt),2063 if (is->avr)
2058 av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));2064 avresample_close(is->avr);
2065 else if (audio_resample) {
2066 int ret;
2067 is->avr = avresample_alloc_context();
2068 if (!is->avr) {
2069 fprintf(stderr, "error allocating AVAudioResampleContext\n");
2059 break;2070 break;
2071 }
2072 av_opt_set_int(is->avr, "in_channel_layout", dec->channel_layout, 0);
2073 av_opt_set_int(is->avr, "in_sample_fmt", dec->sample_fmt, 0);
2074 av_opt_set_int(is->avr, "in_sample_rate", dec->sample_rate, 0);
2075 av_opt_set_int(is->avr, "out_channel_layout", is->sdl_channel_layout, 0);
2076 av_opt_set_int(is->avr, "out_sample_fmt", is->sdl_sample_fmt, 0);
2077 av_opt_set_int(is->avr, "out_sample_rate", dec->sample_rate, 0);
2078 if (av_get_bytes_per_sample(dec->sample_fmt) <= 2)
2079 av_opt_set_int(is->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
2080
2081 if ((ret = avresample_open(is->avr)) < 0) {
2082 fprintf(stderr, "error initializing libavresample\n");
2083 break;
2084 }
2060 }2085 }
2061 is->audio_src_fmt= dec->sample_fmt;2086 is->resample_sample_fmt = dec->sample_fmt;
2087 is->resample_channel_layout = dec->channel_layout;
2062 }2088 }
2063 2089
2064 if (is->reformat_ctx) {2090 if (audio_resample) {
2065 const void *ibuf[6] = { is->frame->data[0] };2091 void *tmp_out;
2066 void *obuf[6];2092 int out_samples, out_size, out_linesize;
2067 int istride[6] = { av_get_bytes_per_sample(dec->sample_fmt) };2093 int osize = av_get_bytes_per_sample(is->sdl_sample_fmt);
2068 int ostride[6] = { 2 };2094 int nb_samples = is->frame->nb_samples;
2069 int len= data_size/istride[0];2095
2070 obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32));2096 out_size = av_samples_get_buffer_size(&out_linesize,
2071 if (!obuf[0]) {2097 is->sdl_channels,
2098 nb_samples,
2099 is->sdl_sample_fmt, 0);
2100 tmp_out = av_realloc(is->audio_buf1, out_size);
2101 if (!tmp_out)
2072 return AVERROR(ENOMEM);2102 return AVERROR(ENOMEM);
2073 }2103 is->audio_buf1 = tmp_out;
2074 is->audio_buf1 = obuf[0];2104
2075 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {2105 out_samples = avresample_convert(is->avr,
2076 printf("av_audio_convert() failed\n");2106 (void **)&is->audio_buf1,
2107 out_linesize, nb_samples,
2108 (void **)is->frame->data,
2109 is->frame->linesize[0],
2110 is->frame->nb_samples);
2111 if (out_samples < 0) {
2112 fprintf(stderr, "avresample_convert() failed\n");
2077 break;2113 break;
2078 }2114 }
2079 is->audio_buf = is->audio_buf1;2115 is->audio_buf = is->audio_buf1;
2080 /* FIXME: existing code assume that data_size equals framesize*channels*22116 data_size = out_samples * osize * is->sdl_channels;
2081 remove this legacy cruft */
2082 data_size = len * 2;
2083 } else {2117 } else {
2084 is->audio_buf = is->frame->data[0];2118 is->audio_buf = is->frame->data[0];
2085 }2119 }
@@ -2087,7 +2121,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) · 1 unmodified line
2087 /* if no pts, then compute it */2121 /* if no pts, then compute it */
2088 pts = is->audio_clock;2122 pts = is->audio_clock;
2089 *pts_ptr = pts;2123 *pts_ptr = pts;
2090 n = 2 * dec->channels;2124 n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
2091 is->audio_clock += (double)data_size /2125 is->audio_clock += (double)data_size /
2092 (double)(n * dec->sample_rate);2126 (double)(n * dec->sample_rate);
2093#ifdef DEBUG2127#ifdef DEBUG
@@ -2206,7 +2240,20 @@ static int stream_component_open(VideoState *is, int stream_index) · 112 unmodified lines
2206 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {2240 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2207 wanted_spec.freq = avctx->sample_rate;2241 wanted_spec.freq = avctx->sample_rate;
2208 wanted_spec.format = AUDIO_S16SYS;2242 wanted_spec.format = AUDIO_S16SYS;
2209 wanted_spec.channels = avctx->channels;2243
2244 if (!avctx->channel_layout)
2245 avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
2246 if (!avctx->channel_layout) {
2247 fprintf(stderr, "unable to guess channel layout\n");
2248 return -1;
2249 }
2250 if (avctx->channels == 1)
2251 is->sdl_channel_layout = AV_CH_LAYOUT_MONO;
2252 else
2253 is->sdl_channel_layout = AV_CH_LAYOUT_STEREO;
2254 is->sdl_channels = av_get_channel_layout_nb_channels(is->sdl_channel_layout);
2255
2256 wanted_spec.channels = is->sdl_channels;
2210 wanted_spec.silence = 0;2257 wanted_spec.silence = 0;
2211 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;2258 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2212 wanted_spec.callback = sdl_audio_callback;2259 wanted_spec.callback = sdl_audio_callback;
@@ -2216,7 +2263,9 @@ static int stream_component_open(VideoState *is, int stream_index) · 3 unmodified lines
2216 return -1;2263 return -1;
2217 }2264 }
2218 is->audio_hw_buf_size = spec.size;2265 is->audio_hw_buf_size = spec.size;
2219 is->audio_src_fmt = AV_SAMPLE_FMT_S16;2266 is->sdl_sample_fmt = AV_SAMPLE_FMT_S16;
2267 is->resample_sample_fmt = is->sdl_sample_fmt;
2268 is->resample_channel_layout = is->sdl_channel_layout;
2220 }2269 }
2221 2270
2222 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;2271 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
@@ -2275,9 +2324,8 @@ static void stream_component_close(VideoState *is, int stream_index) · 52 unmodified lines
2275 2324
2276 packet_queue_end(&is->audioq);2325 packet_queue_end(&is->audioq);
2277 av_free_packet(&is->audio_pkt);2326 av_free_packet(&is->audio_pkt);
2278 if (is->reformat_ctx)2327 if (is->avr)
2279 av_audio_convert_free(is->reformat_ctx);2328 avresample_free(&is->avr);
2280 is->reformat_ctx = NULL;
2281 av_freep(&is->audio_buf1);2329 av_freep(&is->audio_buf1);
2282 is->audio_buf = NULL;2330 is->audio_buf = NULL;
2283 av_freep(&is->frame);2331 av_freep(&is->frame);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t