Advertisement
Guest User

Using std::vector as buffer revision 2

a guest
Aug 2nd, 2013
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.37 KB | None | 0 0
  1.  
  2. extern "C"
  3. {
  4. #include <libavcodec/avcodec.h>
  5. }
  6.  
  7. #include <fstream>
  8. #include <vector>
  9.  
  10. #include <iostream>
  11.  
  12. //This example will take in an MP2 file and decode it
  13. int main()
  14. {
  15.     std::cout << "Decode MP2 file " << "test.mp2" << " to WAV. \n"
  16.     << "The wav file name is decodedAudio.wav\n";
  17.    
  18.     //First we will register the codecs availible from FFMPEG
  19.     avcodec_register_all();
  20.    
  21.     //We will find the decoder for MP3
  22.     AVCodec *mp2Codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
  23.    
  24.     //If the codec was not found then fail.
  25.     if(!mp2Codec)
  26.     {
  27.         std::cout << "Unable to find the MP2 decoder.\n";
  28.         exit(-1);
  29.     }
  30.    
  31.     //Since the codec was succefully found we now will allocate the
  32.     //memory required to set different properties on the decoder
  33.     AVCodecContext *mp2DecoderProperties = avcodec_alloc_context3(mp2Codec);
  34.    
  35.     //Check that the AVCodecContext successfully was allocated
  36.     //Otherwise fail out of the example
  37.     if(!mp2DecoderProperties)
  38.     {
  39.         std::cout << "Unable to allocate enough memory for mp2DecoderProperties\n";
  40.     }
  41.    
  42.     //Now we know the codec is availible and that the mp3DecoderProperties
  43.     //is allocated, lets open the decoder if not fail out
  44.     if(avcodec_open2(mp2DecoderProperties, mp2Codec, NULL) < 0)
  45.     {
  46.         std::cout << "Unable to open the mp2Decoder\n";
  47.         exit(-2);
  48.     }
  49.    
  50.     //Lets open the file stream to the file we wish to decode
  51.     std::ifstream inputAudioFile;
  52.     inputAudioFile.open("test.mp2");
  53.     inputAudioFile.exceptions(std::ifstream::badbit | std::ifstream::failbit | std::ifstream::eofbit);
  54.    
  55.     //OPTION 1 Decode entire file in memory
  56.     //Create an input buffer for the decoder to read through
  57.     std::vector<uint8_t> rawMP3File;
  58.    
  59.     //Seek the entire file to find it's complete size
  60.     inputAudioFile.seekg(0, std::ios::end);
  61.     std::streampos rawInputFileLength(inputAudioFile.tellg());
  62.    
  63.     if (rawInputFileLength)
  64.     {
  65.         //Seek back to the beginning of the audio file
  66.         inputAudioFile.seekg(0, std::ios::beg);
  67.        
  68.         //Resize the vector to accomodate for the file
  69.         rawMP3File.resize(static_cast<std::size_t>(rawInputFileLength) + FF_INPUT_BUFFER_PADDING_SIZE);
  70.        
  71.         //Read in the file to the vector
  72.         inputAudioFile.read((char *)&rawMP3File.front(), static_cast<std::size_t>(rawInputFileLength));
  73.         inputAudioFile.close();
  74.     }
  75.     else
  76.     {
  77.         std::cout << "Unable to determine the size of the file.\n";
  78.         inputAudioFile.close();
  79.         exit(-3);
  80.     }
  81.  
  82.     //Lets create a AVPacket and set the whole file as the input buffer
  83.     AVPacket currentProcessingAudioPacket;
  84.    
  85.     //Initialize the AVPacket for use
  86.     av_init_packet(&currentProcessingAudioPacket);
  87.    
  88.     //Set the packet data pointer and size (in our case the whole file)
  89.     currentProcessingAudioPacket.data = &rawMP3File.front();
  90.     currentProcessingAudioPacket.size = rawMP3File.size();
  91.    
  92.     //The decoded frame is the remaining audio which will then be
  93.     //written to disk. (or otherwise reencoded to another format)
  94.     //Attempt to allocate a AVFrame
  95.     AVFrame *decodedFrame = avcodec_alloc_frame();
  96.    
  97.     //Ensure that that the frame was able to be allocated
  98.     if(!decodedFrame)
  99.     {
  100.         std::cout << "Could not allocate memory for the AVFrame\n";
  101.         exit(-5);
  102.     }
  103.    
  104.     //Used to tell the number of bytes that have been successfully processed
  105.     int bytesProcessed = 0;
  106.    
  107.     //Open the output file for writing
  108.     std::ofstream decodedAudioFile;
  109.     decodedAudioFile.open("decodedAudio");
  110.    
  111.     int loop = 0;
  112.     //Now we get to start processing the audio
  113.     while((currentProcessingAudioPacket.size - FF_INPUT_BUFFER_PADDING_SIZE) > 0)
  114.     {
  115.         std::cout << "Buffer Size is: " << av_samples_get_buffer_size(NULL, mp2DecoderProperties->channels,
  116.                                                                       decodedFrame->nb_samples, mp2DecoderProperties->sample_fmt, 1) << '\n';
  117.         //Flag to notify when a frame is completely decoded and
  118.         //ready to be written to disk.
  119.         int completedFrame = 0;
  120.        
  121.         //Set the AVFrame to it's default values
  122.         avcodec_get_frame_defaults(decodedFrame);
  123.  
  124.        
  125.         //Decode a frame's worth on audio
  126.         bytesProcessed = avcodec_decode_audio4(mp2DecoderProperties, decodedFrame, &completedFrame, &currentProcessingAudioPacket);
  127.        
  128.         //If there was an error, do error handling here or fatal fail out
  129.         if(bytesProcessed < 0)
  130.         {
  131.             std::cout << "An error occured while decoding the Audio packet\n";
  132.             exit(-6);
  133.         }
  134.        
  135.         //If we successfully got a complete decoded frame write it to disk
  136.         if(completedFrame)
  137.         {
  138.             //Write the result to disk
  139.             decodedAudioFile.write((char *) decodedFrame->data[0], av_samples_get_buffer_size(NULL, mp2DecoderProperties->channels,
  140.                                                                                             decodedFrame->nb_samples, mp2DecoderProperties->sample_fmt, 1));
  141.         }
  142.        
  143.         currentProcessingAudioPacket.size -= bytesProcessed;
  144.         currentProcessingAudioPacket.data += bytesProcessed;
  145.         currentProcessingAudioPacket.dts =
  146.         currentProcessingAudioPacket.pts = AV_NOPTS_VALUE;
  147.        
  148.         std::cout  << " on loop " << loop++ << '\n';
  149.     }
  150.    
  151.     decodedAudioFile.close();
  152.    
  153.     avcodec_close(mp2DecoderProperties);
  154.     av_free(mp2DecoderProperties);
  155.     avcodec_free_frame(&decodedFrame);
  156.    
  157.     return 0;
  158. }
  159.  
  160. /*
  161. #define INBUF_SIZE 4096
  162. #define AUDIO_INBUF_SIZE 20480
  163. #define AUDIO_REFILL_THRESH 4096
  164.  
  165.  
  166. int main()
  167. {
  168.     avcodec_register_all();
  169.     char *filename = "test.mp2";
  170.     char *outfilename = "old.wav";
  171.     AVCodec *codec;
  172.     AVCodecContext *c= NULL;
  173.     int len;
  174.     FILE *f, *outfile;
  175.     uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
  176.     AVPacket avpkt;
  177.     AVFrame *decoded_frame = NULL;
  178.    
  179.     av_init_packet(&avpkt);
  180.    
  181.     printf("Decode audio file %s to %s\n", filename, outfilename);
  182.    
  183.  
  184.     codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
  185.     if (!codec) {
  186.         fprintf(stderr, "Codec not found\n");
  187.         exit(1);
  188.     }
  189.    
  190.     c = avcodec_alloc_context3(codec);
  191.     if (!c) {
  192.         fprintf(stderr, "Could not allocate audio codec context\n");
  193.         exit(1);
  194.     }
  195.    
  196.  
  197.     if (avcodec_open2(c, codec, NULL) < 0) {
  198.         fprintf(stderr, "Could not open codec\n");
  199.         exit(1);
  200.     }
  201.    
  202.     f = fopen(filename, "rb");
  203.     if (!f) {
  204.         fprintf(stderr, "Could not open %s\n", filename);
  205.         exit(1);
  206.     }
  207.     outfile = fopen(outfilename, "wb");
  208.     if (!outfile) {
  209.         av_free(c);
  210.         exit(1);
  211.     }
  212.    
  213.  
  214.     avpkt.data = inbuf;
  215.     avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
  216.    
  217.     while (avpkt.size > 0) {
  218.         int got_frame = 0;
  219.        
  220.         if (!decoded_frame) {
  221.             if (!(decoded_frame = avcodec_alloc_frame())) {
  222.                 fprintf(stderr, "Could not allocate audio frame\n");
  223.                 exit(1);
  224.             }
  225.         } else
  226.             avcodec_get_frame_defaults(decoded_frame);
  227.        
  228.         len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
  229.         if (len < 0) {
  230.             fprintf(stderr, "Error while decoding\n");
  231.             exit(1);
  232.         }
  233.         if (got_frame) {
  234.  
  235.             int data_size = av_samples_get_buffer_size(NULL, c->channels,
  236.                                                        decoded_frame->nb_samples,
  237.                                                        c->sample_fmt, 1);
  238.             fwrite(decoded_frame->data[0], 1, data_size, outfile);
  239.         }
  240.         avpkt.size -= len;
  241.         avpkt.data += len;
  242.         avpkt.dts =
  243.         avpkt.pts = AV_NOPTS_VALUE;
  244.         if (avpkt.size < AUDIO_REFILL_THRESH) {
  245.  
  246.             memmove(inbuf, avpkt.data, avpkt.size);
  247.             avpkt.data = inbuf;
  248.             len = fread(avpkt.data + avpkt.size, 1,
  249.                         AUDIO_INBUF_SIZE - avpkt.size, f);
  250.             if (len > 0)
  251.                 avpkt.size += len;
  252.         }
  253.     }
  254.    
  255.     fclose(outfile);
  256.     fclose(f);
  257.    
  258.     avcodec_close(c);
  259.     av_free(c);
  260.     avcodec_free_frame(&decoded_frame);
  261. }*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement