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 | fail: | 158 | fail: |
| 159 | av_frame_unref(frame); | 159 | av_frame_unref(frame); |
| 160 | s->internal->last_audio_frame = 0; | ||
| 160 | return ret; | 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 | avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; | 393 | avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; |
| 393 | 394 | ||
| 394 | /* check for valid frame size */ | 395 | /* check for valid frame size */ |
| 395 | if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { | 396 | if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { |
| 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)) { | ||
| 401 | /* if we already got an undersized frame, that must have been the last */ | 397 | /* if we already got an undersized frame, that must have been the last */ |
| 402 | if (avctx->internal->last_audio_frame) { | 398 | if (avctx->internal->last_audio_frame) { |
| 403 | av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); | 399 | av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); |
| 404 | return AVERROR(EINVAL); | 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 | if (src->nb_samples < avctx->frame_size) { | 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 | ret = pad_last_frame(avctx, dst, src); | 409 | ret = pad_last_frame(avctx, dst, src); |
| 409 | if (ret < 0) | 410 | if (ret < 0) |
| 410 | return ret; | 411 | return ret; |
| 411 | |||
| 412 | avctx->internal->last_audio_frame = 1; | ||
| 413 | goto finish; | 412 | goto finish; |
| 414 | } else if (src->nb_samples > avctx->frame_size) { | 413 | } |
| 415 | av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size); | ||
| 416 | return AVERROR(EINVAL); | ||
| 417 | } | 414 | } |
| 418 | } | 415 | } |
| 419 | } | 416 | } |
| @@ -57,8 +57,8 @@ typedef struct AVCodecInternal { · 56 unmodified lines | |||
| 57 | int is_copy; | 57 | int is_copy; |
| 58 | 58 | ||
| 59 | /** | 59 | /** |
| 60 | * An audio frame with less than required samples has been submitted and | 60 | * An audio frame with less than required samples has been submitted (and |
| 61 | * padded with silence. Reject all subsequent frames. | 61 | * potentially padded with silence). Reject all subsequent frames. |
| 62 | */ | 62 | */ |
| 63 | int last_audio_frame; | 63 | int last_audio_frame; |
| 64 | 64 | ||