Showing the changes to libavcodec/api-example.c (1 of 1 file). Show all
Unified · Split
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | #include "libavcodec/avcodec.h" | 39 | #include "libavcodec/avcodec.h" |
| 40 | #include "libavutil/audioconvert.h" | ||
| 40 | #include "libavutil/mathematics.h" | 41 | #include "libavutil/mathematics.h" |
| 41 | #include "libavutil/samplefmt.h" | 42 | #include "libavutil/samplefmt.h" |
| 42 | 43 | ||
| @@ -44,6 +45,59 @@ · 1 unmodified line | |||
| 44 | #define AUDIO_INBUF_SIZE 20480 | 45 | #define AUDIO_INBUF_SIZE 20480 |
| 45 | #define AUDIO_REFILL_THRESH 4096 | 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 | * Audio encoding example | 102 | * Audio encoding example |
| 49 | */ | 103 | */ |
| @@ -51,11 +105,13 @@ static void audio_encode_example(const char *filename) · 1 unmodified line | |||
| 51 | { | 105 | { |
| 52 | AVCodec *codec; | 106 | AVCodec *codec; |
| 53 | AVCodecContext *c= NULL; | 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 | FILE *f; | 112 | FILE *f; |
| 56 | short *samples; | 113 | uint16_t *samples; |
| 57 | float t, tincr; | 114 | float t, tincr; |
| 58 | uint8_t *outbuf; | ||
| 59 | 115 | ||
| 60 | printf("Audio encoding\n"); | 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 | /* put sample parameters */ | 127 | /* put sample parameters */ |
| 72 | c->bit_rate = 64000; | 128 | c->bit_rate = 64000; |
| 73 | c->sample_rate = 44100; | 129 | |
| 74 | c->channels = 2; | 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 | /* open it */ | 143 | /* open it */ |
| 77 | if (avcodec_open2(c, codec, NULL) < 0) { | 144 | if (avcodec_open2(c, codec, NULL) < 0) { |
| @@ -79,35 +146,71 @@ static void audio_encode_example(const char *filename) · 1 unmodified line | |||
| 79 | exit(1); | 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 | f = fopen(filename, "wb"); | 149 | f = fopen(filename, "wb"); |
| 89 | if (!f) { | 150 | if (!f) { |
| 90 | fprintf(stderr, "could not open %s\n", filename); | 151 | fprintf(stderr, "could not open %s\n", filename); |
| 91 | exit(1); | 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 | /* encode a single tone sound */ | 184 | /* encode a single tone sound */ |
| 95 | t = 0; | 185 | t = 0; |
| 96 | tincr = 2 * M_PI * 440.0 / c->sample_rate; | 186 | tincr = 2 * M_PI * 440.0 / c->sample_rate; |
| 97 | for(i=0;i<200;i++) { | 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 | samples[2*j] = (int)(sin(t) * 10000); | 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 | t += tincr; | 197 | t += tincr; |
| 102 | } | 198 | } |
| 103 | /* encode the samples */ | 199 | /* encode the samples */ |
| 104 | out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); | 200 | ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); |
| 105 | fwrite(outbuf, 1, out_size, f); | 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 | fclose(f); | 210 | fclose(f); |
| 108 | free(outbuf); | ||
| 109 | free(samples); | ||
| 110 | 211 | ||
| 212 | av_freep(&samples); | ||
| 213 | av_freep(&frame); | ||
| 111 | avcodec_close(c); | 214 | avcodec_close(c); |
| 112 | av_free(c); | 215 | av_free(c); |
| 113 | } | 216 | } |