Advertisement
Guest User

Untitled

a guest
Dec 21st, 2016
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.18 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iterator>
  3. #include <math.h>
  4.  
  5. extern "C"
  6. {
  7. #include "libavcodec/avcodec.h"
  8. #include "libavdevice/avdevice.h"
  9. #include "libavfilter/avfilter.h"
  10. #include "libavformat/avformat.h"
  11. #include "libavutil/avutil.h"
  12. #include "libavutil/imgutils.h"
  13. #include "libswscale/swscale.h"
  14. #include "libswresample/swresample.h"
  15.  
  16. #define RES_NOT_MUL_OF_TWO 1
  17. #define COULD_NOT_FIND_VID_CODEC 2
  18. #define CONTEXT_CREATION_ERROR 3
  19. #define COULD_NOT_OPEN_VID_CODEC 4
  20. #define COULD_NOT_OPEN_FILE 5
  21. #define COULD_NOT_ALLOCATE_FRAME 6
  22. #define COULD_NOT_ALLOCATE_PIC_BUF 7
  23. #define ERROR_ENCODING_FRAME_SEND 8
  24. #define ERROR_ENCODING_FRAME_RECEIVE 9
  25. #define COULD_NOT_FIND_AUD_CODEC 10
  26. #define COULD_NOT_OPEN_AUD_CODEC 11
  27. #define COULD_NOT_ALL_RESMPL_CONTEXT 12
  28. #define FAILED_TO_INIT_RESMPL_CONTEXT 13
  29. #define COULD_NOT_ALLOC_SAMPLES 14
  30. #define COULD_NOT_CONVERT_AUD 15
  31. #define ERROR_ENCODING_SAMPLES_SEND 16
  32. #define ERROR_ENCODING_SAMPLES_RECEIVE 17
  33. #define ENCODED_VIDEO 18
  34. #define ENCODED_AUDIO 19
  35. #define ENCODED_AUDIO_AND_VIDEO 20
  36.  
  37.     AVCodec *aud_codec;
  38.     AVCodecContext *aud_codec_context = NULL;
  39.     AVFormatContext *outctx;
  40.     AVStream *audio_st;
  41.     AVFrame *aud_frame;
  42.  
  43.     int aud_frame_counter;
  44.  
  45.     int initialize_encoding_audio(const char *filename)
  46.     {
  47.         int ret;
  48.         AVCodecID aud_codec_id = AV_CODEC_ID_AAC;
  49.         AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
  50.  
  51.         avcodec_register_all();
  52.         av_register_all();
  53.  
  54.         // Fixup audio codec
  55.         aud_codec = avcodec_find_encoder(aud_codec_id);
  56.         //avcodec_register(aud_codec);
  57.  
  58.         if (!aud_codec)
  59.             return COULD_NOT_FIND_AUD_CODEC;
  60.  
  61.         aud_codec_context = avcodec_alloc_context3(aud_codec);
  62.         if (!aud_codec_context)
  63.             return CONTEXT_CREATION_ERROR;
  64.  
  65.         /* select other audio parameters supported by the encoder */
  66.         aud_codec_context->bit_rate = 128000;
  67.         aud_codec_context->sample_rate = 48000;
  68.         aud_codec_context->sample_fmt = sample_fmt;
  69.         aud_codec_context->channel_layout = AV_CH_LAYOUT_STEREO;
  70.         aud_codec_context->channels = av_get_channel_layout_nb_channels(aud_codec_context->channel_layout);
  71.         //aud_codec_context->profile = FF_PROFILE_AAC_MAIN;
  72.  
  73.         aud_codec_context->codec = aud_codec;
  74.         aud_codec_context->codec_id = aud_codec_id;
  75.  
  76.         ret = avcodec_open2(aud_codec_context, aud_codec, NULL);
  77.  
  78.         if (ret < 0)
  79.             return COULD_NOT_OPEN_AUD_CODEC;
  80.  
  81.         outctx = avformat_alloc_context();
  82.         ret = avformat_alloc_output_context2(&outctx, NULL, "mp4", filename);
  83.  
  84.         outctx->audio_codec = aud_codec;
  85.         outctx->audio_codec_id = aud_codec_id;
  86.  
  87.         audio_st = avformat_new_stream(outctx, aud_codec);
  88.         outctx->streams = &audio_st;
  89.  
  90.         audio_st->codecpar->codec_id = aud_codec_id;
  91.         audio_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
  92.         audio_st->codecpar->codec_tag = aud_codec_context->codec_tag;
  93.         //audio_st->codecpar->bits_per_coded_sample = aud_codec_context->bits_per_raw_sample;
  94.         audio_st->codecpar->bits_per_raw_sample = aud_codec_context->bits_per_raw_sample;
  95.         audio_st->codecpar->bit_rate = aud_codec_context->bit_rate;
  96.         audio_st->codecpar->sample_rate = aud_codec_context->sample_rate;
  97.         audio_st->codecpar->channels = aud_codec_context->channels;
  98.         audio_st->codecpar->channel_layout = aud_codec_context->channel_layout;
  99.         audio_st->codecpar->format = sample_fmt;
  100.         audio_st->codecpar->frame_size = aud_codec_context->frame_size;
  101.         audio_st->codecpar->block_align = aud_codec_context->block_align;
  102.         audio_st->codecpar->initial_padding = aud_codec_context->initial_padding;
  103.  
  104.         av_dump_format(outctx, 0, filename, 1);
  105.  
  106.         if (!(outctx->oformat->flags & AVFMT_NOFILE))
  107.         {
  108.             if (avio_open(&outctx->pb, filename, AVIO_FLAG_WRITE) < 0)
  109.                 return COULD_NOT_OPEN_FILE;
  110.         }
  111.  
  112.         ret = avformat_write_header(outctx, NULL);
  113.  
  114.         aud_frame = av_frame_alloc();
  115.         aud_frame->nb_samples = aud_codec_context->frame_size;
  116.         //aud_frame->sample_rate = aud_codec_context->sample_rate;
  117.         aud_frame->format = aud_codec_context->sample_fmt;
  118.         aud_frame->channel_layout = aud_codec_context->channel_layout;
  119.  
  120.         int buffer_size = av_samples_get_buffer_size(NULL, aud_codec_context->channels, aud_codec_context->frame_size,
  121.             aud_codec_context->sample_fmt, 0);
  122.  
  123.         av_frame_get_buffer(aud_frame, buffer_size / 2);
  124.  
  125.         if (!aud_frame)
  126.             return COULD_NOT_ALLOCATE_FRAME;
  127.  
  128.         aud_frame_counter = 0;
  129.  
  130.         return 0;
  131.     }
  132.  
  133.     int encode_audio_samples(uint8_t **aud_samples)
  134.     {
  135.         int ret;
  136.  
  137.         double audio_time = audio_st ? av_stream_get_end_pts(audio_st) * av_q2d(audio_st->time_base) : 0.0;
  138.  
  139.         aud_frame->data[0] = aud_samples[0];
  140.         aud_frame->data[1] = aud_samples[1];
  141.  
  142.         aud_frame->extended_data = aud_frame->data;
  143.  
  144.         aud_frame->pts = aud_frame_counter++;
  145.  
  146.         ret = avcodec_send_frame(aud_codec_context, aud_frame);
  147.         if (ret < 0)
  148.             return ERROR_ENCODING_SAMPLES_SEND;
  149.  
  150.         AVPacket pkt;
  151.         av_init_packet(&pkt);
  152.         pkt.data = NULL;
  153.         pkt.size = 0;
  154.  
  155.         while (true)
  156.         {
  157.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  158.             if (!ret)
  159.             {
  160.                 av_packet_rescale_ts(&pkt, aud_codec_context->time_base, audio_st->time_base);
  161.  
  162.                 pkt.stream_index = audio_st->index;
  163.                 av_write_frame(outctx, &pkt);
  164.                 av_packet_unref(&pkt);
  165.             }
  166.             if (ret == AVERROR(EAGAIN))
  167.                 break;
  168.             else if (ret < 0)
  169.                 return ERROR_ENCODING_SAMPLES_RECEIVE;
  170.             else
  171.                 break;
  172.         }
  173.  
  174.         return 0;
  175.     }
  176.  
  177.     int finish_audio_encoding()
  178.     {
  179.         AVPacket pkt;
  180.         av_init_packet(&pkt);
  181.         pkt.data = NULL;
  182.         pkt.size = 0;
  183.  
  184.         fflush(stdout);
  185.  
  186.         int ret = avcodec_send_frame(aud_codec_context, NULL);
  187.         if (ret < 0)
  188.             return ERROR_ENCODING_FRAME_SEND;
  189.  
  190.         while (true)
  191.         {
  192.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  193.             if (!ret)
  194.             {
  195.                 av_packet_rescale_ts(&pkt, aud_codec_context->time_base, audio_st->time_base);
  196.  
  197.                 pkt.stream_index = audio_st->index;
  198.                 av_write_frame(outctx, &pkt);
  199.                 av_packet_unref(&pkt);
  200.             }
  201.             if (ret == -AVERROR(AVERROR_EOF))
  202.                 break;
  203.             else if (ret < 0)
  204.                 return ERROR_ENCODING_FRAME_RECEIVE;
  205.         }
  206.  
  207.         av_write_trailer(outctx);
  208.     }
  209.  
  210.     void cleanup()
  211.     {
  212.         if (aud_frame)
  213.         {
  214.             av_frame_free(&aud_frame);
  215.         }
  216.         if (outctx)
  217.         {
  218.             for (int i = 0; i < outctx->nb_streams; i++)
  219.                 av_freep(&outctx->streams[i]);
  220.  
  221.             avio_close(outctx->pb);
  222.             av_free(outctx);
  223.         }
  224.  
  225.         if (aud_codec_context)
  226.         {
  227.             avcodec_close(aud_codec_context);
  228.             av_free(aud_codec_context);
  229.         }
  230.     }
  231.  
  232.     void get_audio_frame(float_t *left_samples, float_t *right_samples, int frame_size, float* t)
  233.     {
  234.         int j, i;
  235.         float v;
  236.         for (j = 0; j < frame_size; j++)
  237.         {
  238.             v = sin(*t) * 0.5;
  239.             left_samples[j] = v;
  240.             right_samples[j] = v;
  241.  
  242.             *t += (M_PI_2 * 220) / frame_size;
  243.         }
  244.     }
  245.  
  246.     int main()
  247.     {
  248.         int frame_rate = 30;
  249.         float t = 0;
  250.  
  251.         initialize_encoding_audio("audio.m4a");
  252.  
  253.         int sec = 5;
  254.  
  255.         float_t** aud_samples;
  256.         int src_samples_linesize;
  257.         int src_nb_samples = 1024;
  258.         int src_channels = 2;
  259.  
  260.         int ret = av_samples_alloc_array_and_samples((uint8_t***)&aud_samples, &src_samples_linesize, src_channels,
  261.             src_nb_samples, AV_SAMPLE_FMT_FLTP, 0);
  262.  
  263.         for (size_t i = 0; i < frame_rate * sec; i++)
  264.         {
  265.             get_audio_frame(aud_samples[0], aud_samples[1], src_nb_samples, &t);
  266.  
  267.             encode_audio_samples((uint8_t **)aud_samples);
  268.         }
  269.  
  270.         finish_audio_encoding();
  271.         cleanup();
  272.  
  273.         return 0;
  274.     }
  275. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement