Browse code

lavc: pad last audio frame with silence when needed.

Anton Khirnov authored on 2012/05/07 20:55:03
Showing 6 changed files
... ...
@@ -2048,14 +2048,6 @@ static void flush_encoders(void)
2048 2048
 
2049 2049
                     av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
2050 2050
 
2051
-                    /* pad last frame with silence if needed */
2052
-                    if (!(enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME)) {
2053
-                        frame_bytes = enc->frame_size * enc->channels *
2054
-                                      av_get_bytes_per_sample(enc->sample_fmt);
2055
-                        if (allocated_audio_buf_size < frame_bytes)
2056
-                            exit_program(1);
2057
-                        generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
2058
-                    }
2059 2051
                     encode_audio_frame(os, ost, audio_buf, frame_bytes);
2060 2052
                 } else {
2061 2053
                     /* flush encoder with NULL frames until it is done
... ...
@@ -13,6 +13,12 @@ libavutil:     2011-04-18
13 13
 
14 14
 API changes, most recent first:
15 15
 
16
+2012-xx-xx - xxxxxxx - lavc 54.13.1
17
+  For audio formats with fixed frame size, the last frame
18
+  no longer needs to be padded with silence, libavcodec
19
+  will handle this internally (effectively all encoders
20
+  behave as if they had CODEC_CAP_SMALL_LAST_FRAME set).
21
+
16 22
 2012-xx-xx - xxxxxxx - lavc 54.13.0 - avcodec.h
17 23
   Add sample_rate and channel_layout fields to AVFrame.
18 24
 
... ...
@@ -3860,15 +3860,11 @@ int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
3860 3860
  * @param[in] frame AVFrame containing the raw audio data to be encoded.
3861 3861
  *                  May be NULL when flushing an encoder that has the
3862 3862
  *                  CODEC_CAP_DELAY capability set.
3863
- *                  There are 2 codec capabilities that affect the allowed
3864
- *                  values of frame->nb_samples.
3865
- *                  If CODEC_CAP_SMALL_LAST_FRAME is set, then only the final
3866
- *                  frame may be smaller than avctx->frame_size, and all other
3867
- *                  frames must be equal to avctx->frame_size.
3868 3863
  *                  If CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
3869 3864
  *                  can have any number of samples.
3870
- *                  If neither is set, frame->nb_samples must be equal to
3871
- *                  avctx->frame_size for all frames.
3865
+ *                  If it is not set, frame->nb_samples must be equal to
3866
+ *                  avctx->frame_size for all frames except the last.
3867
+ *                  The final frame may be smaller than avctx->frame_size.
3872 3868
  * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
3873 3869
  *                            output packet is non-empty, and to 0 if it is
3874 3870
  *                            empty. If the function returns an error, the
... ...
@@ -70,6 +70,12 @@ typedef struct AVCodecInternal {
70 70
      */
71 71
     int sample_count;
72 72
 #endif
73
+
74
+    /**
75
+     * An audio frame with less than required samples has been submitted and
76
+     * padded with silence. Reject all subsequent frames.
77
+     */
78
+    int last_audio_frame;
73 79
 } AVCodecInternal;
74 80
 
75 81
 struct AVCodecDefault {
... ...
@@ -857,11 +857,58 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
857 857
     }
858 858
 }
859 859
 
860
+/**
861
+ * Pad last frame with silence.
862
+ */
863
+static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
864
+{
865
+    AVFrame *frame = NULL;
866
+    uint8_t *buf   = NULL;
867
+    int ret;
868
+
869
+    if (!(frame = avcodec_alloc_frame()))
870
+        return AVERROR(ENOMEM);
871
+    *frame = *src;
872
+
873
+    if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels,
874
+                                          s->frame_size, s->sample_fmt, 0)) < 0)
875
+        goto fail;
876
+
877
+    if (!(buf = av_malloc(ret))) {
878
+        ret = AVERROR(ENOMEM);
879
+        goto fail;
880
+    }
881
+
882
+    frame->nb_samples = s->frame_size;
883
+    if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt,
884
+                                        buf, ret, 0)) < 0)
885
+        goto fail;
886
+    if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
887
+                               src->nb_samples, s->channels, s->sample_fmt)) < 0)
888
+        goto fail;
889
+    if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
890
+                                      frame->nb_samples - src->nb_samples,
891
+                                      s->channels, s->sample_fmt)) < 0)
892
+        goto fail;
893
+
894
+    *dst = frame;
895
+
896
+    return 0;
897
+
898
+fail:
899
+    if (frame->extended_data != frame->data)
900
+        av_freep(&frame->extended_data);
901
+    av_freep(&buf);
902
+    av_freep(&frame);
903
+    return ret;
904
+}
905
+
860 906
 int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
861 907
                                               AVPacket *avpkt,
862 908
                                               const AVFrame *frame,
863 909
                                               int *got_packet_ptr)
864 910
 {
911
+    AVFrame *padded_frame = NULL;
865 912
     int ret;
866 913
     int user_packet = !!avpkt->data;
867 914
 
... ...
@@ -879,6 +926,16 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
879 879
             if (frame->nb_samples > avctx->frame_size)
880 880
                 return AVERROR(EINVAL);
881 881
         } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
882
+            if (frame->nb_samples < avctx->frame_size &&
883
+                !avctx->internal->last_audio_frame) {
884
+                ret = pad_last_frame(avctx, &padded_frame, frame);
885
+                if (ret < 0)
886
+                    return ret;
887
+
888
+                frame = padded_frame;
889
+                avctx->internal->last_audio_frame = 1;
890
+            }
891
+
882 892
             if (frame->nb_samples != avctx->frame_size)
883 893
                 return AVERROR(EINVAL);
884 894
         }
... ...
@@ -919,6 +976,13 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
919 919
              here to simplify things */
920 920
     avpkt->flags |= AV_PKT_FLAG_KEY;
921 921
 
922
+    if (padded_frame) {
923
+        av_freep(&padded_frame->data[0]);
924
+        if (padded_frame->extended_data != padded_frame->data)
925
+            av_freep(&padded_frame->extended_data);
926
+        av_freep(&padded_frame);
927
+    }
928
+
922 929
     return ret;
923 930
 }
924 931
 
... ...
@@ -28,7 +28,7 @@
28 28
 
29 29
 #define LIBAVCODEC_VERSION_MAJOR 54
30 30
 #define LIBAVCODEC_VERSION_MINOR 13
31
-#define LIBAVCODEC_VERSION_MICRO  0
31
+#define LIBAVCODEC_VERSION_MICRO  1
32 32
 
33 33
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
34 34
                                                LIBAVCODEC_VERSION_MINOR, \