Advertisement
Guest User

resampler issues

a guest
Jul 11th, 2016
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.88 KB | None | 0 0
  1. #include <libavformat/avformat.h>
  2. #include <libavutil/samplefmt.h>
  3. #include <libavutil/opt.h>
  4. #include <libswresample/swresample.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7.  
  8. const char* get_str_err(const int err) {
  9.     static char buf[1024];
  10.     if (av_strerror(err, buf, sizeof(buf))) {
  11.         strcpy(buf, "Couldn't get a proper error!");
  12.     }
  13.     return buf;
  14. }
  15.  
  16. int main(int argc, char **argv) {
  17.     int err;
  18.  
  19.     av_register_all();
  20.  
  21.     // setup format context
  22.     AVFormatContext *fctx = NULL;
  23.     if ((err = avformat_open_input(&fctx, argv[1], NULL, NULL)) < 0) {
  24.         fprintf(stderr, "Couldn't open input: %s\n", get_str_err(err));
  25.         return err;
  26.     }
  27.     if ((err = avformat_find_stream_info(fctx, NULL)) < 0) {
  28.         fprintf(stderr, "Couldn't find stream info: %s\n", get_str_err(err));
  29.         return err;
  30.     }
  31.  
  32.     // find codec and stream ID
  33.     AVCodec *decoder = NULL;
  34.     int stream_id = av_find_best_stream(fctx, AVMEDIA_TYPE_AUDIO, -1, -1, &decoder, 0);
  35.     if (stream_id < 0) {
  36.         err = stream_id;
  37.         fprintf(stderr, "Couldn't find best stream: %s\n", get_str_err(err));
  38.         return err;
  39.     }
  40.     AVStream *stream = fctx->streams[stream_id];
  41.     AVCodecContext *codec_ctx = stream->codec;
  42.  
  43.     // setup codec context
  44.     if ((err = avcodec_open2(codec_ctx, decoder, NULL)) < 0) {
  45.         fprintf(stderr, "Couldn't open codec: %s\n", get_str_err(err));
  46.         return err;
  47.     }
  48.  
  49.     // setup resampler
  50.     int64_t dst_channel_layout = av_get_default_channel_layout(codec_ctx->channels);
  51.     enum AVSampleFormat dst_sample_fmt = AV_SAMPLE_FMT_S16;
  52.     int dst_sample_rate = 48000;
  53.  
  54.     int64_t src_channel_layout = codec_ctx->channel_layout;
  55.     enum AVSampleFormat src_sample_fmt = codec_ctx->sample_fmt;
  56.     int src_sample_rate = codec_ctx->sample_rate;
  57.  
  58.     SwrContext *resampler = swr_alloc_set_opts(NULL,
  59.                                                dst_channel_layout,
  60.                                                dst_sample_fmt,
  61.                                                dst_sample_rate,
  62.                                                src_channel_layout,
  63.                                                src_sample_fmt,
  64.                                                src_sample_rate,
  65.                                                0,
  66.                                                NULL);
  67.  
  68.     if ((err = swr_init(resampler)) < 0) {
  69.         fprintf(stderr, "Couldn't init resampler: %s\n", get_str_err(err));
  70.         return err;
  71.     }
  72.  
  73.     // allocate frames
  74.     AVFrame *decoded = av_frame_alloc();
  75.     AVFrame *encoded = av_frame_alloc();
  76.     AVPacket packet;
  77.     int got_frame = 0;
  78.  
  79.     int total_samples = 0;
  80.  
  81.     while (1) {
  82.         if ((err = av_read_frame(fctx, &packet)) < 0) {break;}
  83.         av_packet_rescale_ts(&packet, fctx->streams[stream_id]->time_base,
  84.                                       codec_ctx->time_base);
  85.         if (packet.stream_index != stream_id) {continue;}
  86.         int total_length = 0;
  87.  
  88.         int len = avcodec_decode_audio4(codec_ctx, decoded, &got_frame, &packet);
  89.         if (len == 0) {break;} //nothing left
  90.  
  91.         if (got_frame) {
  92.             av_frame_set_sample_rate(encoded, dst_sample_rate);
  93.             if (encoded->data[0] == NULL) {
  94.                 encoded->format = dst_sample_fmt;
  95.                 encoded->nb_samples = decoded->nb_samples;
  96.                 av_frame_set_channel_layout(encoded, dst_channel_layout);
  97.                 av_frame_get_buffer(encoded, 0);
  98.             }
  99.             if ((err = swr_convert_frame(resampler, encoded, decoded)) < 0) {
  100.                 fprintf(stderr, "Couldn't resample frame: %s\n", get_str_err(err));
  101.                 return err;
  102.             }
  103.             int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, encoded->nb_samples, codec_ctx->sample_fmt, 1);
  104.             fwrite(encoded->data[0], 1, data_size, stdout);
  105.             total_samples += encoded->nb_samples;
  106.         }
  107.     }
  108.  
  109.     while (swr_get_delay(resampler, 1) > 0) {
  110.         av_frame_set_sample_rate(encoded, dst_sample_rate);
  111.         if (encoded->data[0] == NULL) {
  112.             encoded->format = dst_sample_fmt;
  113.             encoded->nb_samples = decoded->nb_samples;
  114.             av_frame_set_channel_layout(encoded, dst_channel_layout);
  115.             av_frame_get_buffer(encoded, 0);
  116.         }
  117.         if ((err = swr_convert_frame(resampler, encoded, NULL)) < 0) {
  118.             fprintf(stderr, "Couldn't get frame from flushed resampler: %s\n", get_str_err(err));
  119.             return err;
  120.         }
  121.         int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, encoded->nb_samples, codec_ctx->sample_fmt, 1);
  122.         fwrite(encoded->data[0], 1, data_size, stdout);
  123.         total_samples += encoded->nb_samples;
  124.     }
  125.     fprintf(stderr, "Samples: %i\n", total_samples*2); //times 2 because nb_samples is per channel, and we have 2
  126.  
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement