Unified · Split
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #endif |
| 38 | 38 | |
| 39 | 39 | #include "libavcodec/avcodec.h" |
| 40 | +#include "libavutil/audioconvert.h" | |
| 40 | 41 | #include "libavutil/mathematics.h" |
| 41 | 42 | #include "libavutil/samplefmt.h" |
| 42 | 43 | |
| @@ -44,6 +45,59 @@ · 1 unmodified line | ||
| 44 | 45 | #define AUDIO_INBUF_SIZE 20480 |
| 45 | 46 | #define AUDIO_REFILL_THRESH 4096 |
| 46 | 47 | |
| 48 | +/* check that a given sample format is supported by the encoder */ | |
| 49 | +static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) | |
| 50 | +{ | |
| 51 | + const enum AVSampleFormat *p = codec->sample_fmts; | |
| 52 | + | |
| 53 | + while (*p != AV_SAMPLE_FMT_NONE) { | |
| 54 | + if (*p == sample_fmt) | |
| 55 | + return 1; | |
| 56 | + p++; | |
| 57 | + } | |
| 58 | + return 0; | |
| 59 | +} | |
| 60 | + | |
| 61 | +/* just pick the highest supported samplerate */ | |
| 62 | +static int select_sample_rate(AVCodec *codec) | |
| 63 | +{ | |
| 64 | + const int *p; | |
| 65 | + int best_samplerate = 0; | |
| 66 | + | |
| 67 | + if (!codec->supported_samplerates) | |
| 68 | + return 44100; | |
| 69 | + | |
| 70 | + p = codec->supported_samplerates; | |
| 71 | + while (*p) { | |
| 72 | + best_samplerate = FFMAX(*p, best_samplerate); | |
| 73 | + p++; | |
| 74 | + } | |
| 75 | + return best_samplerate; | |
| 76 | +} | |
| 77 | + | |
| 78 | +/* select layout with the highest channel count */ | |
| 79 | +static int select_channel_layout(AVCodec *codec) | |
| 80 | +{ | |
| 81 | + const uint64_t *p; | |
| 82 | + uint64_t best_ch_layout = 0; | |
| 83 | + int best_nb_channells = 0; | |
| 84 | + | |
| 85 | + if (!codec->channel_layouts) | |
| 86 | + return AV_CH_LAYOUT_STEREO; | |
| 87 | + | |
| 88 | + p = codec->channel_layouts; | |
| 89 | + while (*p) { | |
| 90 | + int nb_channels = av_get_channel_layout_nb_channels(*p); | |
| 91 | + | |
| 92 | + if (nb_channels > best_nb_channells) { | |
| 93 | + best_ch_layout = *p; | |
| 94 | + best_nb_channells = nb_channels; | |
| 95 | + } | |
| 96 | + p++; | |
| 97 | + } | |
| 98 | + return best_ch_layout; | |
| 99 | +} | |
| 100 | + | |
| 47 | 101 | /* |
| 48 | 102 | * Audio encoding example |
| 49 | 103 | */ |
| @@ -51,11 +105,13 @@ static void audio_encode_example(const char *filename) · 1 unmodified line | ||
| 51 | 105 | { |
| 52 | 106 | AVCodec *codec; |
| 53 | 107 | AVCodecContext *c= NULL; |
| 54 | − int frame_size, i, j, out_size, outbuf_size; | |
| 108 | + AVFrame *frame; | |
| 109 | + AVPacket pkt; | |
| 110 | + int i, j, k, ret, got_output; | |
| 111 | + int buffer_size; | |
| 55 | 112 | FILE *f; |
| 56 | − short *samples; | |
| 113 | + uint16_t *samples; | |
| 57 | 114 | float t, tincr; |
| 58 | − uint8_t *outbuf; | |
| 59 | 115 | |
| 60 | 116 | printf("Audio encoding\n"); |
| 61 | 117 | |
| @@ -70,8 +126,19 @@ static void audio_encode_example(const char *filename) · 8 unmodified lines | ||
| 70 | 126 | |
| 71 | 127 | /* put sample parameters */ |
| 72 | 128 | c->bit_rate = 64000; |
| 73 | − c->sample_rate = 44100; | |
| 74 | − c->channels = 2; | |
| 129 | + | |
| 130 | + /* check that the encoder supports s16 pcm input */ | |
| 131 | + c->sample_fmt = AV_SAMPLE_FMT_S16; | |
| 132 | + if (!check_sample_fmt(codec, c->sample_fmt)) { | |
| 133 | + fprintf(stderr, "encoder does not support %s", | |
| 134 | + av_get_sample_fmt_name(c->sample_fmt)); | |
| 135 | + exit(1); | |
| 136 | + } | |
| 137 | + | |
| 138 | + /* select other audio parameters supported by the encoder */ | |
| 139 | + c->sample_rate = select_sample_rate(codec); | |
| 140 | + c->channel_layout = select_channel_layout(codec); | |
| 141 | + c->channels = av_get_channel_layout_nb_channels(c->channel_layout); | |
| 75 | 142 | |
| 76 | 143 | /* open it */ |
| 77 | 144 | if (avcodec_open2(c, codec, NULL) < 0) { |
| @@ -79,35 +146,71 @@ static void audio_encode_example(const char *filename) · 1 unmodified line | ||
| 79 | 146 | exit(1); |
| 80 | 147 | } |
| 81 | 148 | |
| 82 | − /* the codec gives us the frame size, in samples */ | |
| 83 | − frame_size = c->frame_size; | |
| 84 | − samples = malloc(frame_size * 2 * c->channels); | |
| 85 | − outbuf_size = 10000; | |
| 86 | − outbuf = malloc(outbuf_size); | |
| 87 | − | |
| 88 | 149 | f = fopen(filename, "wb"); |
| 89 | 150 | if (!f) { |
| 90 | 151 | fprintf(stderr, "could not open %s\n", filename); |
| 91 | 152 | exit(1); |
| 92 | 153 | } |
| 93 | 154 | |
| 155 | + /* frame containing input raw audio */ | |
| 156 | + frame = avcodec_alloc_frame(); | |
| 157 | + if (!frame) { | |
| 158 | + fprintf(stderr, "could not allocate audio frame\n"); | |
| 159 | + exit(1); | |
| 160 | + } | |
| 161 | + | |
| 162 | + frame->nb_samples = c->frame_size; | |
| 163 | + frame->format = c->sample_fmt; | |
| 164 | + frame->channel_layout = c->channel_layout; | |
| 165 | + | |
| 166 | + /* the codec gives us the frame size, in samples, | |
| 167 | + * we calculate the size of the samples buffer in bytes */ | |
| 168 | + buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, | |
| 169 | + c->sample_fmt, 0); | |
| 170 | + samples = av_malloc(buffer_size); | |
| 171 | + if (!samples) { | |
| 172 | + fprintf(stderr, "could not allocate %d bytes for samples buffer\n", | |
| 173 | + buffer_size); | |
| 174 | + exit(1); | |
| 175 | + } | |
| 176 | + /* setup the data pointers in the AVFrame */ | |
| 177 | + ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, | |
| 178 | + (const uint8_t*)samples, buffer_size, 0); | |
| 179 | + if (ret < 0) { | |
| 180 | + fprintf(stderr, "could not setup audio frame\n"); | |
| 181 | + exit(1); | |
| 182 | + } | |
| 183 | + | |
| 94 | 184 | /* encode a single tone sound */ |
| 95 | 185 | t = 0; |
| 96 | 186 | tincr = 2 * M_PI * 440.0 / c->sample_rate; |
| 97 | 187 | for(i=0;i<200;i++) { |
| 98 | − for(j=0;j<frame_size;j++) { | |
| 188 | + av_init_packet(&pkt); | |
| 189 | + pkt.data = NULL; // packet data will be allocated by the encoder | |
| 190 | + pkt.size = 0; | |
| 191 | + | |
| 192 | + for (j = 0; j < c->frame_size; j++) { | |
| 99 | 193 | samples[2*j] = (int)(sin(t) * 10000); |
| 100 | − samples[2*j+1] = samples[2*j]; | |
| 194 | + | |
| 195 | + for (k = 1; k < c->channels; k++) | |
| 196 | + samples[2*j + k] = samples[2*j]; | |
| 101 | 197 | t += tincr; |
| 102 | 198 | } |
| 103 | 199 | /* encode the samples */ |
| 104 | − out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); | |
| 105 | − fwrite(outbuf, 1, out_size, f); | |
| 200 | + ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); | |
| 201 | + if (ret < 0) { | |
| 202 | + fprintf(stderr, "error encoding audio frame\n"); | |
| 203 | + exit(1); | |
| 204 | + } | |
| 205 | + if (got_output) { | |
| 206 | + fwrite(pkt.data, 1, pkt.size, f); | |
| 207 | + av_free_packet(&pkt); | |
| 208 | + } | |
| 106 | 209 | } |
| 107 | 210 | fclose(f); |
| 108 | − free(outbuf); | |
| 109 | − free(samples); | |
| 110 | 211 | |
| 212 | + av_freep(&samples); | |
| 213 | + av_freep(&frame); | |
| 111 | 214 | avcodec_close(c); |
| 112 | 215 | av_free(c); |
| 113 | 216 | } |