mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-23 19:30:05 +00:00
Merge remote-tracking branch 'cigaes/master'
* cigaes/master: lavfi/af_pan: support unknown layouts on input. lavfi/af_pan: support unknown layouts on output. lswr: fix assert failure on unknown layouts. lavfi: parsing helper for unknown channel layouts. lavfi/avfiltergraph: do not reduce incompatible lists. lavfi/avfiltergraph: suggest a solution when format selection fails. lavd/lavfi: support unknown channel layouts. lavf/wavenc: check for a single stream. lavd/alsa: add stream validation lavd/alsa: fix timestamp calculation Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
2ed562d5fa
@ -47,12 +47,17 @@
|
||||
static av_cold int audio_write_header(AVFormatContext *s1)
|
||||
{
|
||||
AlsaData *s = s1->priv_data;
|
||||
AVStream *st;
|
||||
AVStream *st = NULL;
|
||||
unsigned int sample_rate;
|
||||
enum AVCodecID codec_id;
|
||||
int res;
|
||||
|
||||
if (s1->nb_streams != 1 || s1->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
|
||||
av_log(s1, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
st = s1->streams[0];
|
||||
|
||||
sample_rate = st->codec->sample_rate;
|
||||
codec_id = st->codec->codec_id;
|
||||
res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate,
|
||||
@ -80,6 +85,10 @@ static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
|
||||
uint8_t *buf = pkt->data;
|
||||
|
||||
size /= s->frame_size;
|
||||
if (pkt->dts != AV_NOPTS_VALUE)
|
||||
s->timestamp = pkt->dts;
|
||||
s->timestamp += pkt->duration ? pkt->duration : size;
|
||||
|
||||
if (s->reorder_func) {
|
||||
if (size > s->reorder_buf_size)
|
||||
if (ff_alsa_extend_reorder_buf(s, size))
|
||||
@ -112,7 +121,7 @@ audio_get_output_timestamp(AVFormatContext *s1, int stream,
|
||||
snd_pcm_sframes_t delay = 0;
|
||||
*wall = av_gettime();
|
||||
snd_pcm_delay(s->h, &delay);
|
||||
*dts = s1->streams[0]->cur_dts - delay;
|
||||
*dts = s->timestamp - delay;
|
||||
}
|
||||
|
||||
AVOutputFormat ff_alsa_muxer = {
|
||||
|
@ -57,6 +57,7 @@ typedef struct AlsaData {
|
||||
void (*reorder_func)(const void *, void *, int);
|
||||
void *reorder_buf;
|
||||
int reorder_buf_size; ///< in frames
|
||||
int64_t timestamp; ///< current timestamp, without latency applied.
|
||||
} AlsaData;
|
||||
|
||||
/**
|
||||
|
@ -248,6 +248,10 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
|
||||
ret = av_opt_set_int_list(sink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
ret = av_opt_set_int(sink, "all_channel_counts", 1,
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
lavfi->sinks[i] = sink;
|
||||
|
@ -66,7 +66,7 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
(ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0)
|
||||
return ret;
|
||||
if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto"))
|
||||
return ff_parse_channel_layout(&aconvert->out_chlayout, aconvert->channel_layout_str, ctx);
|
||||
return ff_parse_channel_layout(&aconvert->out_chlayout, NULL, aconvert->channel_layout_str, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ typedef struct PanContext {
|
||||
double gain[MAX_CHANNELS][MAX_CHANNELS];
|
||||
int64_t need_renorm;
|
||||
int need_renumber;
|
||||
int nb_input_channels;
|
||||
int nb_output_channels;
|
||||
|
||||
int pure_gains;
|
||||
@ -116,10 +115,10 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
if (!args)
|
||||
return AVERROR(ENOMEM);
|
||||
arg = av_strtok(args, "|", &tokenizer);
|
||||
ret = ff_parse_channel_layout(&pan->out_channel_layout, arg, ctx);
|
||||
ret = ff_parse_channel_layout(&pan->out_channel_layout,
|
||||
&pan->nb_output_channels, arg, ctx);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
pan->nb_output_channels = av_get_channel_layout_nb_channels(pan->out_channel_layout);
|
||||
|
||||
/* parse channel specifications */
|
||||
while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) {
|
||||
@ -239,12 +238,14 @@ static int query_formats(AVFilterContext *ctx)
|
||||
ff_set_common_samplerates(ctx, formats);
|
||||
|
||||
// inlink supports any channel layout
|
||||
layouts = ff_all_channel_layouts();
|
||||
layouts = ff_all_channel_counts();
|
||||
ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
|
||||
|
||||
// outlink supports only requested output channel layout
|
||||
layouts = NULL;
|
||||
ff_add_channel_layout(&layouts, pan->out_channel_layout);
|
||||
ff_add_channel_layout(&layouts,
|
||||
pan->out_channel_layout ? pan->out_channel_layout :
|
||||
FF_COUNT2LAYOUT(pan->nb_output_channels));
|
||||
ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
|
||||
return 0;
|
||||
}
|
||||
@ -257,7 +258,6 @@ static int config_props(AVFilterLink *link)
|
||||
int i, j, k, r;
|
||||
double t;
|
||||
|
||||
pan->nb_input_channels = av_get_channel_layout_nb_channels(link->channel_layout);
|
||||
if (pan->need_renumber) {
|
||||
// input channels were given by their name: renumber them
|
||||
for (i = j = 0; i < MAX_CHANNELS; i++) {
|
||||
@ -271,7 +271,7 @@ static int config_props(AVFilterLink *link)
|
||||
|
||||
// sanity check; can't be done in query_formats since the inlink
|
||||
// channel layout is unknown at that time
|
||||
if (pan->nb_input_channels > SWR_CH_MAX ||
|
||||
if (link->channels > SWR_CH_MAX ||
|
||||
pan->nb_output_channels > SWR_CH_MAX) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"libswresample support a maximum of %d channels. "
|
||||
@ -286,6 +286,10 @@ static int config_props(AVFilterLink *link)
|
||||
0, ctx);
|
||||
if (!pan->swr)
|
||||
return AVERROR(ENOMEM);
|
||||
if (!link->channel_layout)
|
||||
av_opt_set_int(pan->swr, "ich", link->channels, 0);
|
||||
if (!pan->out_channel_layout)
|
||||
av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0);
|
||||
|
||||
// gains are pure, init the channel mapping
|
||||
if (pan->pure_gains) {
|
||||
@ -293,7 +297,7 @@ static int config_props(AVFilterLink *link)
|
||||
// get channel map from the pure gains
|
||||
for (i = 0; i < pan->nb_output_channels; i++) {
|
||||
int ch_id = -1;
|
||||
for (j = 0; j < pan->nb_input_channels; j++) {
|
||||
for (j = 0; j < link->channels; j++) {
|
||||
if (pan->gain[i][j]) {
|
||||
ch_id = j;
|
||||
break;
|
||||
@ -311,7 +315,7 @@ static int config_props(AVFilterLink *link)
|
||||
if (!((pan->need_renorm >> i) & 1))
|
||||
continue;
|
||||
t = 0;
|
||||
for (j = 0; j < pan->nb_input_channels; j++)
|
||||
for (j = 0; j < link->channels; j++)
|
||||
t += pan->gain[i][j];
|
||||
if (t > -1E-5 && t < 1E-5) {
|
||||
// t is almost 0 but not exactly, this is probably a mistake
|
||||
@ -320,7 +324,7 @@ static int config_props(AVFilterLink *link)
|
||||
"Degenerate coefficients while renormalizing\n");
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < pan->nb_input_channels; j++)
|
||||
for (j = 0; j < link->channels; j++)
|
||||
pan->gain[i][j] /= t;
|
||||
}
|
||||
av_opt_set_int(pan->swr, "icl", link->channel_layout, 0);
|
||||
@ -335,7 +339,7 @@ static int config_props(AVFilterLink *link)
|
||||
// summary
|
||||
for (i = 0; i < pan->nb_output_channels; i++) {
|
||||
cur = buf;
|
||||
for (j = 0; j < pan->nb_input_channels; j++) {
|
||||
for (j = 0; j < link->channels; j++) {
|
||||
r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d",
|
||||
j ? " + " : "", pan->gain[i][j], j);
|
||||
cur += FFMIN(buf + sizeof(buf) - cur, r);
|
||||
|
@ -109,7 +109,7 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
|
||||
if (eval->chlayout_str) {
|
||||
int n;
|
||||
ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx);
|
||||
ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
|
@ -68,7 +68,7 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
null->sample_rate_str, ctx)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = ff_parse_channel_layout(&null->channel_layout,
|
||||
if ((ret = ff_parse_channel_layout(&null->channel_layout, NULL,
|
||||
null->channel_layout_str, ctx)) < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -654,6 +654,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref)
|
||||
av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
|
||||
" the link between filters %s and %s.\n", link->src->name,
|
||||
link->dst->name);
|
||||
if (!link->in_channel_layouts->all_counts)
|
||||
av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
|
||||
"supported, try specifying a channel layout using "
|
||||
"'aformat=channel_layouts=something'.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
link->in_channel_layouts->nb_channel_layouts = 1;
|
||||
@ -737,7 +741,8 @@ static int reduce_formats_on_filter(AVFilterContext *filter)
|
||||
if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
|
||||
continue;
|
||||
|
||||
if (fmts->all_layouts) {
|
||||
if (fmts->all_layouts &&
|
||||
(!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
|
||||
/* Turn the infinite list into a singleton */
|
||||
fmts->all_layouts = fmts->all_counts = 0;
|
||||
ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
|
||||
|
@ -615,10 +615,21 @@ int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
|
||||
int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
|
||||
void *log_ctx)
|
||||
{
|
||||
char *tail;
|
||||
int64_t chlayout = av_get_channel_layout(arg);
|
||||
int64_t chlayout, count;
|
||||
|
||||
if (nret) {
|
||||
count = strtol(arg, &tail, 10);
|
||||
if (*tail == 'c' && !tail[1] && count > 0 && count < 63) {
|
||||
*nret = count;
|
||||
*ret = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
chlayout = av_get_channel_layout(arg);
|
||||
if (chlayout == 0) {
|
||||
chlayout = strtol(arg, &tail, 10);
|
||||
if (*tail || chlayout == 0) {
|
||||
@ -627,6 +638,8 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
|
||||
}
|
||||
}
|
||||
*ret = chlayout;
|
||||
if (nret)
|
||||
*nret = av_get_channel_layout_nb_channels(chlayout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -207,11 +207,14 @@ int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx);
|
||||
* Parse a channel layout or a corresponding integer representation.
|
||||
*
|
||||
* @param ret 64bit integer pointer to where the value should be written.
|
||||
* @param nret integer pointer to the number of channels;
|
||||
* if not NULL, then unknown channel layouts are accepted
|
||||
* @param arg string to parse
|
||||
* @param log_ctx log context
|
||||
* @return >= 0 in case of success, a negative AVERROR code on error
|
||||
*/
|
||||
int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx);
|
||||
int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
|
||||
void *log_ctx);
|
||||
|
||||
void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
|
||||
|
||||
|
@ -116,6 +116,11 @@ static int wav_write_header(AVFormatContext *s)
|
||||
AVIOContext *pb = s->pb;
|
||||
int64_t fmt;
|
||||
|
||||
if (s->nb_streams != 1) {
|
||||
av_log(s, AV_LOG_ERROR, "WAVE files have exactly one stream\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (wav->rf64 == RF64_ALWAYS) {
|
||||
ffio_wfourcc(pb, "RF64");
|
||||
avio_wl32(pb, -1); /* RF64 chunk size: use size in ds64 */
|
||||
|
@ -433,8 +433,8 @@ int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mus
|
||||
off = len1 * out->bps;
|
||||
}
|
||||
|
||||
av_assert0(out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
|
||||
av_assert0(in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
|
||||
av_assert0(!s->out_ch_layout || out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
|
||||
av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
|
||||
|
||||
for(out_i=0; out_i<out->ch_count; out_i++){
|
||||
switch(s->matrix_ch[out_i][0]){
|
||||
|
Loading…
Reference in New Issue
Block a user