Remove AVFilterBufferRefAudioProps.size, and use nb_samples in its place everywhere. This is required as the size in the audio buffer may be aligned, so it may not contain a well defined number of samples. Also remove the useless planar parameter, which can be deduced from the sample format. This is technically an API and ABI break, but since the audio part of lavfi is not usable now, this should not be a problem in practice.
Unified · Split
| @@ -265,10 +265,9 @@ static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end) · 264 unmodified lines | |||
| 265 | av_get_picture_type_char(ref->video->pict_type)); | 265 | av_get_picture_type_char(ref->video->pict_type)); |
| 266 | } | 266 | } |
| 267 | if (ref->audio) { | 267 | if (ref->audio) { |
| 268 | av_dlog(ctx, " cl:%"PRId64"d sn:%d s:%d sr:%d p:%d", | 268 | av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d", |
| 269 | ref->audio->channel_layout, | 269 | ref->audio->channel_layout, |
| 270 | ref->audio->nb_samples, | 270 | ref->audio->nb_samples, |
| 271 | ref->audio->size, | ||
| 272 | ref->audio->sample_rate, | 271 | ref->audio->sample_rate, |
| 273 | ref->audio->planar); | 272 | ref->audio->planar); |
| 274 | } | 273 | } |
| @@ -368,16 +367,16 @@ fail: · 93 unmodified lines | |||
| 368 | } | 367 | } |
| 369 | 368 | ||
| 370 | AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms, | 369 | AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms, |
| 371 | enum AVSampleFormat sample_fmt, int size, | 370 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 372 | uint64_t channel_layout, int planar) | 371 | uint64_t channel_layout) |
| 373 | { | 372 | { |
| 374 | AVFilterBufferRef *ret = NULL; | 373 | AVFilterBufferRef *ret = NULL; |
| 375 | 374 | ||
| 376 | if (link->dstpad->get_audio_buffer) | 375 | if (link->dstpad->get_audio_buffer) |
| 377 | ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar); | 376 | ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, nb_samples, channel_layout); |
| 378 | 377 | ||
| 379 | if (!ret) | 378 | if (!ret) |
| 380 | ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar); | 379 | ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, nb_samples, channel_layout); |
| 381 | 380 | ||
| 382 | if (ret) | 381 | if (ret) |
| 383 | ret->type = AVMEDIA_TYPE_AUDIO; | 382 | ret->type = AVMEDIA_TYPE_AUDIO; |
| @@ -585,6 +584,9 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) · 201 unmodified lines | |||
| 585 | /* prepare to copy the samples if the buffer has insufficient permissions */ | 584 | /* prepare to copy the samples if the buffer has insufficient permissions */ |
| 586 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || | 585 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || |
| 587 | dst->rej_perms & samplesref->perms) { | 586 | dst->rej_perms & samplesref->perms) { |
| 587 | int i, planar = av_sample_fmt_is_planar(samplesref->format); | ||
| 588 | int planes = !planar ? 1: | ||
| 589 | av_get_channel_layout_nb_channels(samplesref->audio->channel_layout); | ||
| 588 | 590 | ||
| 589 | av_log(link->dst, AV_LOG_DEBUG, | 591 | av_log(link->dst, AV_LOG_DEBUG, |
| 590 | "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n", | 592 | "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n", |
| @@ -592,14 +594,14 @@ void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) · 1 unmodified line | |||
| 592 | 594 | ||
| 593 | link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms, | 595 | link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms, |
| 594 | samplesref->format, | 596 | samplesref->format, |
| 595 | samplesref->audio->size, | 597 | samplesref->audio->nb_samples, |
| 596 | samplesref->audio->channel_layout, | 598 | samplesref->audio->channel_layout); |
| 597 | samplesref->audio->planar); | ||
| 598 | link->cur_buf->pts = samplesref->pts; | 599 | link->cur_buf->pts = samplesref->pts; |
| 599 | link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; | 600 | link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; |
| 600 | 601 | ||
| 601 | /* Copy actual data into new samples buffer */ | 602 | /* Copy actual data into new samples buffer */ |
| 602 | memcpy(link->cur_buf->data[0], samplesref->data[0], samplesref->audio->size); | 603 | for (i = 0; i < planes; i++) |
| 604 | memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], samplesref->linesize[0]); | ||
| 603 | 605 | ||
| 604 | avfilter_unref_buffer(samplesref); | 606 | avfilter_unref_buffer(samplesref); |
| 605 | } else | 607 | } else |
| @@ -109,7 +109,6 @@ typedef struct AVFilterBuffer { · 108 unmodified lines | |||
| 109 | typedef struct AVFilterBufferRefAudioProps { | 109 | typedef struct AVFilterBufferRefAudioProps { |
| 110 | uint64_t channel_layout; ///< channel layout of audio buffer | 110 | uint64_t channel_layout; ///< channel layout of audio buffer |
| 111 | int nb_samples; ///< number of audio samples | 111 | int nb_samples; ///< number of audio samples |
| 112 | int size; ///< audio buffer size | ||
| 113 | uint32_t sample_rate; ///< audio buffer sample rate | 112 | uint32_t sample_rate; ///< audio buffer sample rate |
| 114 | int planar; ///< audio buffer - planar or packed | 113 | int planar; ///< audio buffer - planar or packed |
| 115 | } AVFilterBufferRefAudioProps; | 114 | } AVFilterBufferRefAudioProps; |
| @@ -388,8 +387,8 @@ struct AVFilterPad { · 272 unmodified lines | |||
| 388 | * Input audio pads only. | 387 | * Input audio pads only. |
| 389 | */ | 388 | */ |
| 390 | AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms, | 389 | AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms, |
| 391 | enum AVSampleFormat sample_fmt, int size, | 390 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 392 | uint64_t channel_layout, int planar); | 391 | uint64_t channel_layout); |
| 393 | 392 | ||
| 394 | /** | 393 | /** |
| 395 | * Callback called after the slices of a frame are completely sent. If | 394 | * Callback called after the slices of a frame are completely sent. If |
| @@ -474,8 +473,9 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, · 78 unmodified lines | |||
| 474 | 473 | ||
| 475 | /** default handler for get_audio_buffer() for audio inputs */ | 474 | /** default handler for get_audio_buffer() for audio inputs */ |
| 476 | AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms, | 475 | AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms, |
| 477 | enum AVSampleFormat sample_fmt, int size, | 476 | enum AVSampleFormat sample_fmt, |
| 478 | uint64_t channel_layout, int planar); | 477 | int nb_samples, |
| 478 | uint64_t channel_layout); | ||
| 479 | 479 | ||
| 480 | /** | 480 | /** |
| 481 | * A helper for query_formats() which sets all links to the same list of | 481 | * A helper for query_formats() which sets all links to the same list of |
| @@ -505,8 +505,8 @@ AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, · 23 unmodified lines | |||
| 505 | 505 | ||
| 506 | /** get_audio_buffer() handler for filters which simply pass audio along */ | 506 | /** get_audio_buffer() handler for filters which simply pass audio along */ |
| 507 | AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms, | 507 | AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms, |
| 508 | enum AVSampleFormat sample_fmt, int size, | 508 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 509 | uint64_t channel_layout, int planar); | 509 | uint64_t channel_layout); |
| 510 | 510 | ||
| 511 | /** | 511 | /** |
| 512 | * Filter definition. This defines the pads a filter contains, and all the | 512 | * Filter definition. This defines the pads a filter contains, and all the |
| @@ -690,15 +690,15 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int · 177 unmodified lines | |||
| 690 | * be requested | 690 | * be requested |
| 691 | * @param perms the required access permissions | 691 | * @param perms the required access permissions |
| 692 | * @param sample_fmt the format of each sample in the buffer to allocate | 692 | * @param sample_fmt the format of each sample in the buffer to allocate |
| 693 | * @param size the buffer size in bytes | 693 | * @param nb_samples the number of samples per channel |
| 694 | * @param channel_layout the number and type of channels per sample in the buffer to allocate | 694 | * @param channel_layout the number and type of channels per sample in the buffer to allocate |
| 695 | * @param planar audio data layout - planar or packed | 695 | * @param planar audio data layout - planar or packed |
| 696 | * @return A reference to the samples. This must be unreferenced with | 696 | * @return A reference to the samples. This must be unreferenced with |
| 697 | * avfilter_unref_buffer when you are finished with it. | 697 | * avfilter_unref_buffer when you are finished with it. |
| 698 | */ | 698 | */ |
| 699 | AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms, | 699 | AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms, |
| 700 | enum AVSampleFormat sample_fmt, int size, | 700 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 701 | uint64_t channel_layout, int planar); | 701 | uint64_t channel_layout); |
| 702 | 702 | ||
| 703 | /** | 703 | /** |
| 704 | * Create an audio buffer reference wrapped around an already | 704 | * Create an audio buffer reference wrapped around an already |
| @@ -58,12 +58,13 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per · 57 unmodified lines | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms, | 60 | AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms, |
| 61 | enum AVSampleFormat sample_fmt, int size, | 61 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 62 | uint64_t channel_layout, int planar) | 62 | uint64_t channel_layout) |
| 63 | { | 63 | { |
| 64 | AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer)); | 64 | AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer)); |
| 65 | AVFilterBufferRef *ref = NULL; | 65 | AVFilterBufferRef *ref = NULL; |
| 66 | int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0; | 66 | int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0; |
| 67 | int planar = av_sample_fmt_is_planar(sample_fmt); | ||
| 67 | char *buf; | 68 | char *buf; |
| 68 | 69 | ||
| 69 | if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef)))) | 70 | if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef)))) |
| @@ -77,7 +78,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per · 7 unmodified lines | |||
| 77 | goto fail; | 78 | goto fail; |
| 78 | 79 | ||
| 79 | ref->audio->channel_layout = channel_layout; | 80 | ref->audio->channel_layout = channel_layout; |
| 80 | ref->audio->size = size; | 81 | ref->audio->nb_samples = nb_samples; |
| 81 | ref->audio->planar = planar; | 82 | ref->audio->planar = planar; |
| 82 | 83 | ||
| 83 | /* make sure the buffer gets read permission or it's useless for output */ | 84 | /* make sure the buffer gets read permission or it's useless for output */ |
| @@ -89,8 +90,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per · 5 unmodified lines | |||
| 89 | sample_size = av_get_bytes_per_sample(sample_fmt); | 90 | sample_size = av_get_bytes_per_sample(sample_fmt); |
| 90 | chans_nb = av_get_channel_layout_nb_channels(channel_layout); | 91 | chans_nb = av_get_channel_layout_nb_channels(channel_layout); |
| 91 | 92 | ||
| 92 | per_channel_size = size/chans_nb; | 93 | per_channel_size = nb_samples * sample_size; |
| 93 | ref->audio->nb_samples = per_channel_size/sample_size; | ||
| 94 | 94 | ||
| 95 | /* Set the number of bytes to traverse to reach next sample of a particular channel: | 95 | /* Set the number of bytes to traverse to reach next sample of a particular channel: |
| 96 | * For planar, this is simply the sample size. | 96 | * For planar, this is simply the sample size. |
| @@ -101,7 +101,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per · 4 unmodified lines | |||
| 101 | memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0])); | 101 | memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0])); |
| 102 | 102 | ||
| 103 | /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */ | 103 | /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */ |
| 104 | bufsize = (size + 15)&~15; | 104 | bufsize = (nb_samples * chans_nb * sample_size + 15)&~15; |
| 105 | buf = av_malloc(bufsize); | 105 | buf = av_malloc(bufsize); |
| 106 | if (!buf) | 106 | if (!buf) |
| 107 | goto fail; | 107 | goto fail; |
| @@ -189,9 +189,8 @@ void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *sa · 81 unmodified lines | |||
| 189 | 189 | ||
| 190 | if (outlink) { | 190 | if (outlink) { |
| 191 | outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format, | 191 | outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format, |
| 192 | samplesref->audio->size, | 192 | samplesref->audio->nb_samples, |
| 193 | samplesref->audio->channel_layout, | 193 | samplesref->audio->channel_layout); |
| 194 | samplesref->audio->planar); | ||
| 195 | outlink->out_buf->pts = samplesref->pts; | 194 | outlink->out_buf->pts = samplesref->pts; |
| 196 | outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate; | 195 | outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate; |
| 197 | avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); | 196 | avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
| @@ -293,9 +292,9 @@ AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, · 95 unmodified lines | |||
| 293 | } | 292 | } |
| 294 | 293 | ||
| 295 | AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms, | 294 | AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms, |
| 296 | enum AVSampleFormat sample_fmt, int size, | 295 | enum AVSampleFormat sample_fmt, int nb_samples, |
| 297 | uint64_t channel_layout, int packed) | 296 | uint64_t channel_layout) |
| 298 | { | 297 | { |
| 299 | return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt, | 298 | return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt, |
| 300 | size, channel_layout, packed); | 299 | nb_samples, channel_layout); |
| 301 | } | 300 | } |