In particular, check that there is only one small last frame in case the encoder has the AV_CODEC_CAP_SMALL_LAST_FRAME set.
Unified · Split
| @@ -157,6 +157,7 @@ static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src) · 156 unmodified lines | ||
| 157 | 157 | |
| 158 | 158 | fail: |
| 159 | 159 | av_frame_unref(frame); |
| 160 | + s->internal->last_audio_frame = 0; | |
| 160 | 161 | return ret; |
| 161 | 162 | } |
| 162 | 163 | |
| @@ -392,28 +393,24 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) · 229 unmodified lines | ||
| 392 | 393 | avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; |
| 393 | 394 | |
| 394 | 395 | /* check for valid frame size */ |
| 395 | − if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { | |
| 396 | − if (src->nb_samples > avctx->frame_size) { | |
| 397 | − av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n"); | |
| 398 | − return AVERROR(EINVAL); | |
| 399 | − } | |
| 400 | − } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { | |
| 396 | + if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { | |
| 401 | 397 | /* if we already got an undersized frame, that must have been the last */ |
| 402 | 398 | if (avctx->internal->last_audio_frame) { |
| 403 | 399 | av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); |
| 404 | 400 | return AVERROR(EINVAL); |
| 405 | 401 | } |
| 406 | − | |
| 402 | + if (src->nb_samples > avctx->frame_size) { | |
| 403 | + av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) > frame_size (%d)\n", src->nb_samples, avctx->frame_size); | |
| 404 | + return AVERROR(EINVAL); | |
| 405 | + } | |
| 407 | 406 | if (src->nb_samples < avctx->frame_size) { |
| 407 | + avctx->internal->last_audio_frame = 1; | |
| 408 | + if (!(avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)) { | |
| 408 | 409 | ret = pad_last_frame(avctx, dst, src); |
| 409 | 410 | if (ret < 0) |
| 410 | 411 | return ret; |
| 411 | − | |
| 412 | − avctx->internal->last_audio_frame = 1; | |
| 413 | 412 | goto finish; |
| 414 | − } else if (src->nb_samples > avctx->frame_size) { | |
| 415 | − av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size); | |
| 416 | − return AVERROR(EINVAL); | |
| 413 | + } | |
| 417 | 414 | } |
| 418 | 415 | } |
| 419 | 416 | } |
| @@ -57,8 +57,8 @@ typedef struct AVCodecInternal { · 56 unmodified lines | ||
| 57 | 57 | int is_copy; |
| 58 | 58 | |
| 59 | 59 | /** |
| 60 | − * An audio frame with less than required samples has been submitted and | |
| 61 | − * padded with silence. Reject all subsequent frames. | |
| 60 | + * An audio frame with less than required samples has been submitted (and | |
| 61 | + * potentially padded with silence). Reject all subsequent frames. | |
| 62 | 62 | */ |
| 63 | 63 | int last_audio_frame; |
| 64 | 64 | |