Advertisement
Guest User

Untitled

a guest
Nov 20th, 2016
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.86 KB | None | 0 0
  1.     int initialize_encoding_audio(const char *filename)
  2.     {
  3.         int ret;
  4.         AVCodecID aud_codec_id = AV_CODEC_ID_AAC;
  5.         AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
  6.  
  7.         avcodec_register_all();
  8.         av_register_all();
  9.  
  10.         aud_codec = avcodec_find_encoder(aud_codec_id);
  11.         avcodec_register(aud_codec);
  12.  
  13.         if (!aud_codec)
  14.             return COULD_NOT_FIND_AUD_CODEC;
  15.  
  16.         aud_codec_context = avcodec_alloc_context3(aud_codec);
  17.         if (!aud_codec_context)
  18.             return CONTEXT_CREATION_ERROR;
  19.  
  20.         aud_codec_context->bit_rate = 192000;
  21.         aud_codec_context->sample_rate = select_sample_rate(aud_codec);
  22.         aud_codec_context->sample_fmt = sample_fmt;
  23.         aud_codec_context->channel_layout = AV_CH_LAYOUT_STEREO;
  24.         aud_codec_context->channels = av_get_channel_layout_nb_channels(aud_codec_context->channel_layout);
  25.  
  26.         aud_codec_context->codec = aud_codec;
  27.         aud_codec_context->codec_id = aud_codec_id;
  28.  
  29.         ret = avcodec_open2(aud_codec_context, aud_codec, NULL);
  30.  
  31.         if (ret < 0)
  32.             return COULD_NOT_OPEN_AUD_CODEC;
  33.  
  34.         outctx = avformat_alloc_context();
  35.         ret = avformat_alloc_output_context2(&outctx, NULL, "mp4", filename);
  36.  
  37.         outctx->audio_codec = aud_codec;
  38.         outctx->audio_codec_id = aud_codec_id;
  39.  
  40.         audio_st = avformat_new_stream(outctx, aud_codec);
  41.  
  42.         audio_st->codecpar->bit_rate = aud_codec_context->bit_rate;
  43.         audio_st->codecpar->sample_rate = aud_codec_context->sample_rate;
  44.         audio_st->codecpar->channels = aud_codec_context->channels;
  45.         audio_st->codecpar->channel_layout = aud_codec_context->channel_layout;
  46.         audio_st->codecpar->codec_id = aud_codec_id;
  47.         audio_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
  48.         audio_st->codecpar->format = sample_fmt;
  49.         audio_st->codecpar->frame_size = aud_codec_context->frame_size;
  50.         audio_st->codecpar->block_align = aud_codec_context->block_align;
  51.         audio_st->codecpar->initial_padding = aud_codec_context->initial_padding;
  52.  
  53.         outctx->streams = new AVStream*[1];
  54.         outctx->streams[0] = audio_st;
  55.  
  56.         av_dump_format(outctx, 0, filename, 1);
  57.  
  58.         if (!(outctx->oformat->flags & AVFMT_NOFILE))
  59.         {
  60.             if (avio_open(&outctx->pb, filename, AVIO_FLAG_WRITE) < 0)
  61.                 return COULD_NOT_OPEN_FILE;
  62.         }
  63.  
  64.         ret = avformat_write_header(outctx, NULL);
  65.  
  66.         aud_frame = av_frame_alloc();
  67.         aud_frame->nb_samples = aud_codec_context->frame_size;
  68.         aud_frame->format = aud_codec_context->sample_fmt;
  69.         aud_frame->channel_layout = aud_codec_context->channel_layout;
  70.  
  71.         int buffer_size = av_samples_get_buffer_size(NULL, aud_codec_context->channels, aud_codec_context->frame_size,
  72.             aud_codec_context->sample_fmt, 0);
  73.  
  74.         av_frame_get_buffer(aud_frame, buffer_size / 2);
  75.  
  76.         if (!aud_frame)
  77.             return COULD_NOT_ALLOCATE_FRAME;
  78.  
  79.         aud_frame_counter = 0;
  80.  
  81.         return 0;
  82.     }
  83.  
  84.     float t, tincr, tincr2;
  85.     void get_audio_frame(float_t *samples, int frame_size)
  86.     {
  87.         int j, i;
  88.         float v;
  89.         for (j = 0; j < frame_size; j++)
  90.         {
  91.             v = sin(t);
  92.  
  93.             *samples = v;
  94.             samples++;
  95.  
  96.             t += tincr;
  97.             tincr += tincr2;
  98.         }
  99.     }
  100.     int encode_audio_samples(uint8_t **aud_samples)
  101.     {
  102.         int ret;
  103.  
  104.         int buffer_size = av_samples_get_buffer_size(NULL, aud_codec_context->channels, aud_codec_context->frame_size,
  105.             aud_codec_context->sample_fmt, 0);
  106.  
  107.         //This looks bad to me, but it's been so long since I've coded in c++ (work with c#) so I'm just trying
  108.         for (size_t i = 0; i < buffer_size / 2; i++)
  109.         {
  110.             aud_frame->data[0][i] = aud_samples[0][i];
  111.             aud_frame->data[1][i] = aud_samples[1][i];
  112.         }
  113.  
  114.         aud_frame->pts = aud_frame_counter++;
  115.  
  116.         ret = avcodec_send_frame(aud_codec_context, aud_frame);
  117.         if (ret < 0)
  118.             return ERROR_ENCODING_SAMPLES_SEND;
  119.  
  120.         AVPacket pkt;
  121.         av_init_packet(&pkt);
  122.         pkt.data = NULL;
  123.         pkt.size = 0;
  124.  
  125.         while (true)
  126.         {
  127.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  128.             if (!ret)
  129.             {
  130.                 av_packet_rescale_ts(&pkt, aud_codec_context->time_base, audio_st->time_base);
  131.  
  132.                 pkt.stream_index = audio_st->index;
  133.                 av_write_frame(outctx, &pkt);
  134.                 av_packet_unref(&pkt);
  135.             }
  136.             if (ret == AVERROR(EAGAIN))
  137.                 break;
  138.             else if (ret < 0)
  139.                 return ERROR_ENCODING_SAMPLES_RECEIVE;
  140.             else
  141.                 break;
  142.         }
  143.  
  144.         return 0;
  145.     }
  146.  
  147.  
  148.     int finish_audio_encoding()
  149.     {
  150.         AVPacket pkt;
  151.         av_init_packet(&pkt);
  152.         pkt.data = NULL;
  153.         pkt.size = 0;
  154.  
  155.         fflush(stdout);
  156.  
  157.         int ret = avcodec_send_frame(aud_codec_context, NULL);
  158.         if (ret < 0)
  159.             return ERROR_ENCODING_FRAME_SEND;
  160.  
  161.         while (true)
  162.         {
  163.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  164.             if (!ret)
  165.             {
  166.                 if (pkt.pts != AV_NOPTS_VALUE)
  167.                     pkt.pts = av_rescale_q(pkt.pts, aud_codec_context->time_base, audio_st->time_base);
  168.                 if (pkt.dts != AV_NOPTS_VALUE)
  169.                     pkt.dts = av_rescale_q(pkt.dts, aud_codec_context->time_base, audio_st->time_base);
  170.  
  171.                 av_write_frame(outctx, &pkt);
  172.                 av_packet_unref(&pkt);
  173.             }
  174.             if (ret == -AVERROR(AVERROR_EOF))
  175.                 break;
  176.             else if (ret < 0)
  177.                 return ERROR_ENCODING_FRAME_RECEIVE;
  178.         }
  179.  
  180.         av_write_trailer(outctx);
  181.     }
  182.  
  183. void get_audio_frame(float_t *samples, int frame_size, float* t, float* tincr, float* tincr2)
  184. {
  185.     int j, i;
  186.     float v;
  187.     for (j = 0; j < frame_size; j++)
  188.     {
  189.         v = sin(*t);
  190.  
  191.         *samples = v;
  192.         samples++;
  193.  
  194.         *t += *tincr;
  195.         *tincr += *tincr2;
  196.     }
  197. }
  198.  
  199. int main()
  200. {
  201.     int frame_rate = 30; // this should be like 96000 / 1024 or somthing i guess?
  202.     float t, tincr, tincr2;
  203.  
  204.     initialize_encoding_audio("audio.mp4");
  205.  
  206.     int sec = 10;
  207.  
  208.     float_t** aud_samples;
  209.     int src_nb_samples = 1024;
  210.     int src_channels = 2;
  211.  
  212.     int ret = av_samples_alloc_array_and_samples((uint8_t***)&aud_samples, &src_samples_linesize, src_channels,
  213.         src_nb_samples, AV_SAMPLE_FMT_FLTP, 0);
  214.  
  215.     for (size_t i = 0; i < frame_rate * sec; i++)
  216.     {
  217.         get_audio_frame(aud_samples[0], src_nb_samples, &t, &tincr, &tincr2);
  218.         get_audio_frame(aud_samples[1], src_nb_samples, &t, &tincr, &tincr2);
  219.  
  220.         encode_audio_samples((uint8_t **)aud_samples);
  221.  
  222.     }
  223.  
  224.     finish_audio_encoding();
  225.     cleanup();
  226.  
  227.     return 0;
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement