Advertisement
Guest User

Untitled

a guest
Nov 24th, 2016
971
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.99 KB | None | 0 0
  1. #include "encoder.h"
  2. #include <algorithm>
  3. #include <iterator>
  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.  
  34.     AVCodec *vid_codec, *aud_codec;
  35.     AVCodecContext *vid_codec_context = NULL;
  36.     AVCodecContext *aud_codec_context = NULL;
  37.     AVFormatContext *outctx;
  38.     AVStream *video_st, *audio_st;
  39.     AVFrame *vid_frame, *aud_frame;
  40.     SwsContext *sws_ctx;
  41.     SwrContext *swr_ctx = NULL;
  42.  
  43.     int vid_frame_counter, aud_frame_counter;
  44.     int vid_width, vid_height;
  45.  
  46.     // Audio converting
  47.     //uint8_t **src_samples_data;
  48.     int src_samples_linesize;
  49.     //int src_nb_samples;
  50.     int max_dst_nb_samples;
  51.  
  52.     uint8_t **dst_samples_data;
  53.     int dst_samples_linesize;
  54.     int dst_samples_size;
  55.  
  56.     static int select_sample_rate(AVCodec *codec)
  57.     {
  58.         const int *p;
  59.         int best_samplerate = 0;
  60.  
  61.         if (!codec->supported_samplerates)
  62.             return 44100;
  63.  
  64.         p = codec->supported_samplerates;
  65.         while (*p) {
  66.             best_samplerate = FFMAX(*p, best_samplerate);
  67.             p++;
  68.  
  69.         }
  70.         return best_samplerate;
  71.     }
  72.  
  73.     int initialize_encoding_audio(const char *filename)
  74.     {
  75.         int ret;
  76.         AVCodecID aud_codec_id = AV_CODEC_ID_AAC;
  77.         AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
  78.  
  79.         avcodec_register_all();
  80.         av_register_all();
  81.  
  82.         aud_codec = avcodec_find_encoder(aud_codec_id);
  83.         avcodec_register(aud_codec);
  84.  
  85.         if (!aud_codec)
  86.             return COULD_NOT_FIND_AUD_CODEC;
  87.  
  88.         aud_codec_context = avcodec_alloc_context3(aud_codec);
  89.         if (!aud_codec_context)
  90.             return CONTEXT_CREATION_ERROR;
  91.  
  92.         aud_codec_context->bit_rate = 192000;
  93.         aud_codec_context->sample_rate = select_sample_rate(aud_codec);
  94.         aud_codec_context->sample_fmt = sample_fmt;
  95.         aud_codec_context->channel_layout = AV_CH_LAYOUT_STEREO;
  96.         aud_codec_context->channels = av_get_channel_layout_nb_channels(aud_codec_context->channel_layout);
  97.  
  98.         aud_codec_context->codec = aud_codec;
  99.         aud_codec_context->codec_id = aud_codec_id;
  100.  
  101.         ret = avcodec_open2(aud_codec_context, aud_codec, NULL);
  102.  
  103.         if (ret < 0)
  104.             return COULD_NOT_OPEN_AUD_CODEC;
  105.  
  106.         outctx = avformat_alloc_context();
  107.         ret = avformat_alloc_output_context2(&outctx, NULL, "mp4", filename);
  108.  
  109.         outctx->audio_codec = aud_codec;
  110.         outctx->audio_codec_id = aud_codec_id;
  111.  
  112.         audio_st = avformat_new_stream(outctx, aud_codec);
  113.  
  114.         audio_st->codecpar->bit_rate = aud_codec_context->bit_rate;
  115.         audio_st->codecpar->sample_rate = aud_codec_context->sample_rate;
  116.         audio_st->codecpar->channels = aud_codec_context->channels;
  117.         audio_st->codecpar->channel_layout = aud_codec_context->channel_layout;
  118.         audio_st->codecpar->codec_id = aud_codec_id;
  119.         audio_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
  120.         audio_st->codecpar->format = sample_fmt;
  121.         audio_st->codecpar->frame_size = aud_codec_context->frame_size;
  122.         audio_st->codecpar->block_align = aud_codec_context->block_align;
  123.         audio_st->codecpar->initial_padding = aud_codec_context->initial_padding;
  124.  
  125.         outctx->streams = new AVStream*[1];
  126.         outctx->streams[0] = audio_st;
  127.  
  128.         av_dump_format(outctx, 0, filename, 1);
  129.  
  130.         if (!(outctx->oformat->flags & AVFMT_NOFILE))
  131.         {
  132.             if (avio_open(&outctx->pb, filename, AVIO_FLAG_WRITE) < 0)
  133.                 return COULD_NOT_OPEN_FILE;
  134.         }
  135.  
  136.         ret = avformat_write_header(outctx, NULL);
  137.  
  138.         aud_frame = av_frame_alloc();
  139.         aud_frame->nb_samples = aud_codec_context->frame_size;
  140.         aud_frame->format = aud_codec_context->sample_fmt;
  141.         aud_frame->channel_layout = aud_codec_context->channel_layout;
  142.  
  143.         int buffer_size = av_samples_get_buffer_size(NULL, aud_codec_context->channels, aud_codec_context->frame_size,
  144.             aud_codec_context->sample_fmt, 0);
  145.  
  146.         av_frame_get_buffer(aud_frame, buffer_size / aud_codec_context->channels);
  147.  
  148.         if (!aud_frame)
  149.             return COULD_NOT_ALLOCATE_FRAME;
  150.  
  151.         aud_frame_counter = 0;
  152.  
  153.         return 0;
  154.     }
  155.  
  156.     int encode_audio_samples(uint8_t **aud_samples)
  157.     {
  158.         int ret;
  159.  
  160.         int buffer_size = av_samples_get_buffer_size(NULL, aud_codec_context->channels, aud_codec_context->frame_size,
  161.             aud_codec_context->sample_fmt, 0);
  162.  
  163.         for (size_t i = 0; i < buffer_size / aud_codec_context->channels; i++)
  164.         {
  165.             aud_frame->data[0][i] = aud_samples[0][i];
  166.             aud_frame->data[1][i] = aud_samples[1][i];
  167.         }
  168.  
  169.         aud_frame->pts = aud_frame_counter++;
  170.  
  171.         ret = avcodec_send_frame(aud_codec_context, aud_frame);
  172.         if (ret < 0)
  173.             return ERROR_ENCODING_SAMPLES_SEND;
  174.  
  175.         AVPacket pkt;
  176.         av_init_packet(&pkt);
  177.         pkt.data = NULL;
  178.         pkt.size = 0;
  179.  
  180.         fflush(stdout);
  181.  
  182.         while (true)
  183.         {
  184.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  185.             if (!ret)
  186.             {
  187.                 av_packet_rescale_ts(&pkt, aud_codec_context->time_base, audio_st->time_base);
  188.  
  189.                 pkt.stream_index = audio_st->index;
  190.                 av_write_frame(outctx, &pkt);
  191.                 av_packet_unref(&pkt);
  192.             }
  193.             if (ret == AVERROR(EAGAIN))
  194.                 break;
  195.             else if (ret < 0)
  196.                 return ERROR_ENCODING_SAMPLES_RECEIVE;
  197.             else
  198.                 break;
  199.         }
  200.  
  201.         return 0;
  202.     }
  203.     int finish_audio_encoding()
  204.     {
  205.         AVPacket pkt;
  206.         av_init_packet(&pkt);
  207.         pkt.data = NULL;
  208.         pkt.size = 0;
  209.  
  210.         fflush(stdout);
  211.  
  212.         int ret = avcodec_send_frame(aud_codec_context, NULL);
  213.         if (ret < 0)
  214.             return ERROR_ENCODING_FRAME_SEND;
  215.  
  216.         while (true)
  217.         {
  218.             ret = avcodec_receive_packet(aud_codec_context, &pkt);
  219.             if (!ret)
  220.             {
  221.                 if (pkt.pts != AV_NOPTS_VALUE)
  222.                     pkt.pts = av_rescale_q(pkt.pts, aud_codec_context->time_base, audio_st->time_base);
  223.                 if (pkt.dts != AV_NOPTS_VALUE)
  224.                     pkt.dts = av_rescale_q(pkt.dts, aud_codec_context->time_base, audio_st->time_base);
  225.  
  226.                 av_write_frame(outctx, &pkt);
  227.                 av_packet_unref(&pkt);
  228.             }
  229.             if (ret == -AVERROR(AVERROR_EOF))
  230.                 break;
  231.             else if (ret < 0)
  232.                 return ERROR_ENCODING_FRAME_RECEIVE;
  233.         }
  234.  
  235.         av_write_trailer(outctx);
  236.     }
  237.  
  238.     void cleanup()
  239.     {
  240.         if (vid_frame)
  241.         {
  242.             av_frame_free(&vid_frame);
  243.         }
  244.         if (aud_frame)
  245.         {
  246.             av_frame_free(&aud_frame);
  247.         }
  248.         if (outctx)
  249.         {
  250.             for (int i = 0; i < outctx->nb_streams; i++)
  251.                 av_freep(&outctx->streams[i]);
  252.  
  253.             avio_close(outctx->pb);
  254.             av_free(outctx);
  255.         }
  256.  
  257.         if (aud_codec_context)
  258.         {
  259.             avcodec_close(aud_codec_context);
  260.             av_free(aud_codec_context);
  261.         }
  262.  
  263.         if (vid_codec_context)
  264.         {
  265.             avcodec_close(vid_codec_context);
  266.             av_free(vid_codec_context);
  267.         }
  268.     }
  269.    
  270.     void get_audio_frame(float_t *left_samples, float_t *right_samples, int frame_size, float* t, float* tincr, float* tincr2)
  271.     {
  272.         int j, i;
  273.         float v;
  274.         for (j = 0; j < frame_size; j++)
  275.         {
  276.             v = sin(*t);
  277.             *left_samples = v;
  278.             *right_samples = v;
  279.  
  280.             left_samples++;
  281.             right_samples++;
  282.  
  283.             *t += *tincr;
  284.             *tincr += *tincr2;
  285.         }
  286.     }
  287.  
  288.     int main()
  289.     {
  290.         int frame_rate = 30;  // this should be like 96000 / 1024 or somthing i guess?
  291.         float t, tincr, tincr2;
  292.  
  293.         initialize_encoding_audio("audio.mp4");
  294.  
  295.         int sec = 50;
  296.  
  297.         float_t** aud_samples;
  298.         int src_samples_linesize;
  299.         int src_nb_samples = 1024;
  300.         int src_channels = 2;
  301.  
  302.         int ret = av_samples_alloc_array_and_samples((uint8_t***)&aud_samples, &src_samples_linesize, src_channels,
  303.             src_nb_samples, AV_SAMPLE_FMT_FLTP, 0);
  304.  
  305.         for (size_t i = 0; i < frame_rate * sec; i++)
  306.         {
  307.             get_audio_frame(aud_samples[0], aud_samples[1], src_nb_samples, &t, &tincr, &tincr2);
  308.  
  309.             encode_audio_samples((uint8_t **)aud_samples);
  310.  
  311.         }
  312.  
  313.         finish_audio_encoding();
  314.         cleanup();
  315.  
  316.         return 0;
  317.     }
  318. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement