Recherche avancée

Médias (0)

Mot : - Tags -/presse-papier

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (40)

  • Keeping control of your media in your hands

    13 avril 2011, par

    The vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
    While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
    MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
    MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

  • MediaSPIP v0.2

    21 juin 2013, par

    MediaSPIP 0.2 est la première version de MediaSPIP stable.
    Sa date de sortie officielle est le 21 juin 2013 et est annoncée ici.
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Comme pour la version précédente, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

Sur d’autres sites (6515)

  • how to extract audio from video using ffmpeg c++

    28 juin 2016, par daenerys

    I am trying to write c++ code on how to extract audio from mp4 format file. I have compiled the examples in ffmpeg library and tried to run the demuxing_decoding.c file. The problem is that on running the code, it starts to decode way more than the actual file size and decodes wrong codec format (the decoded files cant be run).

    here is the demuxing_decoding.c that I am trying to run :

    #include

    #include <libavutil></libavutil>opt.h>
    #include <libavcodec></libavcodec>avcodec.h>
    #include <libavutil></libavutil>channel_layout.h>
    #include <libavutil></libavutil>common.h>
    #include <libavutil></libavutil>imgutils.h>
    #include <libavutil></libavutil>mathematics.h>
    #include <libavutil></libavutil>samplefmt.h>

    #define INBUF_SIZE 4096
    #define AUDIO_INBUF_SIZE 20480
    #define AUDIO_REFILL_THRESH 4096

    /* check that a given sample format is supported by the encoder */
    static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
    {
       const enum AVSampleFormat *p = codec->sample_fmts;

       while (*p != AV_SAMPLE_FMT_NONE) {
           if (*p == sample_fmt)
               return 1;
           p++;
       }
       return 0;
    }

    /* just pick the highest supported samplerate */
    static int select_sample_rate(AVCodec *codec)
    {
       const int *p;
       int best_samplerate = 0;

       if (!codec->supported_samplerates)
           return 44100;

       p = codec->supported_samplerates;
       while (*p) {
           best_samplerate = FFMAX(*p, best_samplerate);
           p++;
       }
       return best_samplerate;
    }

    /* select layout with the highest channel count */
    static int select_channel_layout(AVCodec *codec)
    {
       const uint64_t *p;
       uint64_t best_ch_layout = 0;
       int best_nb_channels   = 0;

       if (!codec->channel_layouts)
           return AV_CH_LAYOUT_STEREO;

       p = codec->channel_layouts;
       while (*p) {
           int nb_channels = av_get_channel_layout_nb_channels(*p);

           if (nb_channels > best_nb_channels) {
               best_ch_layout    = *p;
               best_nb_channels = nb_channels;
           }
           p++;
       }
       return best_ch_layout;
    }

    /*
    * Audio encoding example
    */
    static void audio_encode_example(const char *filename)
    {
       AVCodec *codec;
       AVCodecContext *c= NULL;
       AVFrame *frame;
       AVPacket pkt;
       int i, j, k, ret, got_output;
       int buffer_size;
       FILE *f;
       uint16_t *samples;
       float t, tincr;

       printf("Encode audio file %s\n", filename);

       /* find the MP2 encoder */
       codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
       if (!codec) {
           fprintf(stderr, "Codec not found\n");
           exit(1);
       }

       c = avcodec_alloc_context3(codec);
       if (!c) {
           fprintf(stderr, "Could not allocate audio codec context\n");
           exit(1);
       }

       /* put sample parameters */
       c->bit_rate = 64000;

       /* check that the encoder supports s16 pcm input */
       c->sample_fmt = AV_SAMPLE_FMT_S16;
       if (!check_sample_fmt(codec, c->sample_fmt)) {
           fprintf(stderr, "Encoder does not support sample format %s",
                   av_get_sample_fmt_name(c->sample_fmt));
           exit(1);
       }

       /* select other audio parameters supported by the encoder */
       c->sample_rate    = select_sample_rate(codec);
       c->channel_layout = select_channel_layout(codec);
       c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);

       /* open it */
       if (avcodec_open2(c, codec, NULL) &lt; 0) {
           fprintf(stderr, "Could not open codec\n");
           exit(1);
       }

       f = fopen(filename, "wb");
       if (!f) {
           fprintf(stderr, "Could not open %s\n", filename);
           exit(1);
       }

       /* frame containing input raw audio */
       frame = av_frame_alloc();
       if (!frame) {
           fprintf(stderr, "Could not allocate audio frame\n");
           exit(1);
       }

       frame->nb_samples     = c->frame_size;
       frame->format         = c->sample_fmt;
       frame->channel_layout = c->channel_layout;

       /* the codec gives us the frame size, in samples,
        * we calculate the size of the samples buffer in bytes */
       buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
                                                c->sample_fmt, 0);
       if (buffer_size &lt; 0) {
           fprintf(stderr, "Could not get sample buffer size\n");
           exit(1);
       }
       samples = av_malloc(buffer_size);
       if (!samples) {
           fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
                   buffer_size);
           exit(1);
       }
       /* setup the data pointers in the AVFrame */
       ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
                                      (const uint8_t*)samples, buffer_size, 0);
       if (ret &lt; 0) {
           fprintf(stderr, "Could not setup audio frame\n");
           exit(1);
       }

       /* encode a single tone sound */
       t = 0;
       tincr = 2 * M_PI * 440.0 / c->sample_rate;
       for (i = 0; i &lt; 200; i++) {
           av_init_packet(&amp;pkt);
           pkt.data = NULL; // packet data will be allocated by the encoder
           pkt.size = 0;

           for (j = 0; j &lt; c->frame_size; j++) {
               samples[2*j] = (int)(sin(t) * 10000);

               for (k = 1; k &lt; c->channels; k++)
                   samples[2*j + k] = samples[2*j];
               t += tincr;
           }
           /* encode the samples */
           ret = avcodec_encode_audio2(c, &amp;pkt, frame, &amp;got_output);
           if (ret &lt; 0) {
               fprintf(stderr, "Error encoding audio frame\n");
               exit(1);
           }
           if (got_output) {
               fwrite(pkt.data, 1, pkt.size, f);
               av_free_packet(&amp;pkt);
           }
       }

       /* get the delayed frames */
       for (got_output = 1; got_output; i++) {
           ret = avcodec_encode_audio2(c, &amp;pkt, NULL, &amp;got_output);
           if (ret &lt; 0) {
               fprintf(stderr, "Error encoding frame\n");
               exit(1);
           }

           if (got_output) {
               fwrite(pkt.data, 1, pkt.size, f);
               av_free_packet(&amp;pkt);
           }
       }
       fclose(f);

       av_freep(&amp;samples);
       av_frame_free(&amp;frame);
       avcodec_close(c);
       av_free(c);
    }

    /*
    * Audio decoding.
    */
    static void audio_decode_example(const char *outfilename, const char *filename)
    {
       AVCodec *codec;
       AVCodecContext *c= NULL;
       int len;
       FILE *f, *outfile;
       uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
       AVPacket avpkt;
       AVFrame *decoded_frame = NULL;

       av_init_packet(&amp;avpkt);

       printf("Decode audio file %s to %s\n", filename, outfilename);

       /* find the mpeg audio decoder */
       codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
       if (!codec) {
           fprintf(stderr, "Codec not found\n");
           exit(1);
       }

       c = avcodec_alloc_context3(codec);
       if (!c) {
           fprintf(stderr, "Could not allocate audio codec context\n");
           exit(1);
       }

       /* open it */
       if (avcodec_open2(c, codec, NULL) &lt; 0) {
           fprintf(stderr, "Could not open codec\n");
           exit(1);
       }

       f = fopen(filename, "rb");
       if (!f) {
           fprintf(stderr, "Could not open %s\n", filename);
           exit(1);
       }
       outfile = fopen(outfilename, "wb");
       if (!outfile) {
           av_free(c);
           exit(1);
       }

       /* decode until eof */
       avpkt.data = inbuf;
       avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

       while (avpkt.size > 0) {
           int i, ch;
           int got_frame = 0;

           if (!decoded_frame) {
               if (!(decoded_frame = av_frame_alloc())) {
                   fprintf(stderr, "Could not allocate audio frame\n");
                   exit(1);
               }
           }

           len = avcodec_decode_audio4(c, decoded_frame, &amp;got_frame, &amp;avpkt);
           if (len &lt; 0) {
               fprintf(stderr, "Error while decoding\n");
               exit(1);
           }
           if (got_frame) {
               /* if a frame has been decoded, output it */
               int data_size = av_get_bytes_per_sample(c->sample_fmt);
               if (data_size &lt; 0) {
                   /* This should not occur, checking just for paranoia */
                   fprintf(stderr, "Failed to calculate data size\n");
                   exit(1);
               }
               for (i=0; inb_samples; i++)
                   for (ch=0; chchannels; ch++)
                       fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
           }
           avpkt.size -= len;
           avpkt.data += len;
           avpkt.dts =
           avpkt.pts = AV_NOPTS_VALUE;
           if (avpkt.size &lt; AUDIO_REFILL_THRESH) {
               /* Refill the input buffer, to avoid trying to decode
                * incomplete frames. Instead of this, one could also use
                * a parser, or use a proper container format through
                * libavformat. */
               memmove(inbuf, avpkt.data, avpkt.size);
               avpkt.data = inbuf;
               len = fread(avpkt.data + avpkt.size, 1,
                           AUDIO_INBUF_SIZE - avpkt.size, f);
               if (len > 0)
                   avpkt.size += len;
           }
       }

       fclose(outfile);
       fclose(f);

       avcodec_close(c);
       av_free(c);
       av_frame_free(&amp;decoded_frame);
    }

    /*
    * Video encoding example
    */
    static void video_encode_example(const char *filename, int codec_id)
    {
       AVCodec *codec;
       AVCodecContext *c= NULL;
       int i, ret, x, y, got_output;
       FILE *f;
       AVFrame *frame;
       AVPacket pkt;
       uint8_t endcode[] = { 0, 0, 1, 0xb7 };

       printf("Encode video file %s\n", filename);

       /* find the mpeg1 video encoder */
       codec = avcodec_find_encoder(codec_id);
       if (!codec) {
           fprintf(stderr, "Codec not found\n");
           exit(1);
       }

       c = avcodec_alloc_context3(codec);
       if (!c) {
           fprintf(stderr, "Could not allocate video codec context\n");
           exit(1);
       }

       /* put sample parameters */
       c->bit_rate = 400000;
       /* resolution must be a multiple of two */
       c->width = 352;
       c->height = 288;
       /* frames per second */
       c->time_base = (AVRational){1,25};
       /* emit one intra frame every ten frames
        * check frame pict_type before passing frame
        * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
        * then gop_size is ignored and the output of encoder
        * will always be I frame irrespective to gop_size
        */
       c->gop_size = 10;
       c->max_b_frames = 1;
       c->pix_fmt = AV_PIX_FMT_YUV420P;

       if (codec_id == AV_CODEC_ID_H264)
           av_opt_set(c->priv_data, "preset", "slow", 0);

       /* open it */
       if (avcodec_open2(c, codec, NULL) &lt; 0) {
           fprintf(stderr, "Could not open codec\n");
           exit(1);
       }

       f = fopen(filename, "wb");
       if (!f) {
           fprintf(stderr, "Could not open %s\n", filename);
           exit(1);
       }

       frame = av_frame_alloc();
       if (!frame) {
           fprintf(stderr, "Could not allocate video frame\n");
           exit(1);
       }
       frame->format = c->pix_fmt;
       frame->width  = c->width;
       frame->height = c->height;

       /* the image can be allocated by any means and av_image_alloc() is
        * just the most convenient way if av_malloc() is to be used */
       ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
                            c->pix_fmt, 32);
       if (ret &lt; 0) {
           fprintf(stderr, "Could not allocate raw picture buffer\n");
           exit(1);
       }

       /* encode 1 second of video */
       for (i = 0; i &lt; 25; i++) {
           av_init_packet(&amp;pkt);
           pkt.data = NULL;    // packet data will be allocated by the encoder
           pkt.size = 0;

           fflush(stdout);
           /* prepare a dummy image */
           /* Y */
           for (y = 0; y &lt; c->height; y++) {
               for (x = 0; x &lt; c->width; x++) {
                   frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
               }
           }

           /* Cb and Cr */
           for (y = 0; y &lt; c->height/2; y++) {
               for (x = 0; x &lt; c->width/2; x++) {
                   frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                   frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
               }
           }

           frame->pts = i;

           /* encode the image */
           ret = avcodec_encode_video2(c, &amp;pkt, frame, &amp;got_output);
           if (ret &lt; 0) {
               fprintf(stderr, "Error encoding frame\n");
               exit(1);
           }

           if (got_output) {
               printf("Write frame %3d (size=%5d)\n", i, pkt.size);
               fwrite(pkt.data, 1, pkt.size, f);
               av_free_packet(&amp;pkt);
           }
       }

       /* get the delayed frames */
       for (got_output = 1; got_output; i++) {
           fflush(stdout);

           ret = avcodec_encode_video2(c, &amp;pkt, NULL, &amp;got_output);
           if (ret &lt; 0) {
               fprintf(stderr, "Error encoding frame\n");
               exit(1);
           }

           if (got_output) {
               printf("Write frame %3d (size=%5d)\n", i, pkt.size);
               fwrite(pkt.data, 1, pkt.size, f);
               av_free_packet(&amp;pkt);
           }
       }

       /* add sequence end code to have a real mpeg file */
       fwrite(endcode, 1, sizeof(endcode), f);
       fclose(f);

       avcodec_close(c);
       av_free(c);
       av_freep(&amp;frame->data[0]);
       av_frame_free(&amp;frame);
       printf("\n");
    }

    /*
    * Video decoding example
    */

    static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
                        char *filename)
    {
       FILE *f;
       int i;

       f = fopen(filename,"w");
       fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
       for (i = 0; i &lt; ysize; i++)
           fwrite(buf + i * wrap, 1, xsize, f);
       fclose(f);
    }

    static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
                                 AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
    {
       int len, got_frame;
       char buf[1024];

       len = avcodec_decode_video2(avctx, frame, &amp;got_frame, pkt);
       if (len &lt; 0) {
           fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
           return len;
       }
       if (got_frame) {
           printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
           fflush(stdout);

           /* the picture is allocated by the decoder, no need to free it */
           snprintf(buf, sizeof(buf), outfilename, *frame_count);
           pgm_save(frame->data[0], frame->linesize[0],
                    frame->width, frame->height, buf);
           (*frame_count)++;
       }
       if (pkt->data) {
           pkt->size -= len;
           pkt->data += len;
       }
       return 0;
    }

    static void video_decode_example(const char *outfilename, const char *filename)
    {
       AVCodec *codec;
       AVCodecContext *c= NULL;
       int frame_count;
       FILE *f;
       AVFrame *frame;
       uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
       AVPacket avpkt;

       av_init_packet(&amp;avpkt);

       /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
       memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);

       printf("Decode video file %s to %s\n", filename, outfilename);

       /* find the mpeg1 video decoder */
       codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
       if (!codec) {
           fprintf(stderr, "Codec not found\n");
           exit(1);
       }

       c = avcodec_alloc_context3(codec);
       if (!c) {
           fprintf(stderr, "Could not allocate video codec context\n");
           exit(1);
       }

       if (codec->capabilities &amp; AV_CODEC_CAP_TRUNCATED)
           c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames

       /* For some codecs, such as msmpeg4 and mpeg4, width and height
          MUST be initialized there because this information is not
          available in the bitstream. */

       /* open it */
       if (avcodec_open2(c, codec, NULL) &lt; 0) {
           fprintf(stderr, "Could not open codec\n");
           exit(1);
       }

       f = fopen(filename, "rb");
       if (!f) {
           fprintf(stderr, "Could not open %s\n", filename);
           exit(1);
       }

       frame = av_frame_alloc();
       if (!frame) {
           fprintf(stderr, "Could not allocate video frame\n");
           exit(1);
       }

       frame_count = 0;
       for (;;) {
           avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
           if (avpkt.size == 0)
               break;

           /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
              and this is the only method to use them because you cannot
              know the compressed data size before analysing it.

              BUT some other codecs (msmpeg4, mpeg4) are inherently frame
              based, so you must call them with all the data for one
              frame exactly. You must also initialize 'width' and
              'height' before initializing them. */

           /* NOTE2: some codecs allow the raw parameters (frame size,
              sample rate) to be changed at any frame. We handle this, so
              you should also take care of it */

           /* here, we use a stream based decoder (mpeg1video), so we
              feed decoder and see if it could decode a frame */
           avpkt.data = inbuf;
           while (avpkt.size > 0)
               if (decode_write_frame(outfilename, c, frame, &amp;frame_count, &amp;avpkt, 0) &lt; 0)
                   exit(1);
       }

       /* some codecs, such as MPEG, transmit the I and P frame with a
          latency of one frame. You must do the following to have a
          chance to get the last frame of the video */
       avpkt.data = NULL;
       avpkt.size = 0;
       decode_write_frame(outfilename, c, frame, &amp;frame_count, &amp;avpkt, 1);

       fclose(f);

       avcodec_close(c);
       av_free(c);
       av_frame_free(&amp;frame);
       printf("\n");
    }

    int main(int argc, char **argv)
    {
       const char *output_type;

       /* register all the codecs */
       avcodec_register_all();

       if (argc &lt; 2) {
           printf("usage: %s output_type\n"
                  "API example program to decode/encode a media stream with libavcodec.\n"
                  "This program generates a synthetic stream and encodes it to a file\n"
                  "named test.h264, test.mp2 or test.mpg depending on output_type.\n"
                  "The encoded stream is then decoded and written to a raw data output.\n"
                  "output_type must be chosen between 'h264', 'mp2', 'mpg'.\n",
                  argv[0]);
           return 1;
       }
       output_type = argv[1];

       if (!strcmp(output_type, "h264")) {
           video_encode_example("test.h264", AV_CODEC_ID_H264);
       } else if (!strcmp(output_type, "mp2")) {
           audio_encode_example("test.mp2");
           audio_decode_example("test.pcm", "test.mp2");
       } else if (!strcmp(output_type, "mpg")) {
           video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
           video_decode_example("test%02d.pgm", "test.mpg");
       } else {
           fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
                   output_type);
           return 1;
       }

       return 0;
    }

    What could be wrong ?
    The command I used is :

    ./demuxing_decoding /home/cortana/Burn.mp4 /home/cortana/Desktop/Burn.mp4 /home/cortana/Desktop/Burn.aac
  • Decoding and playing audio with ffmpeg and XAudio2 - frequency raito wrong

    12 juillet 2016, par Brent de Carteret

    I’m using ffmpeg to decode audio and output it using the XAudio2 API, it works and plays synced with the video output using the pts. But it’s high pitched (i.e. sounds like chipmunks).

    Setting breakpoints I can see it has sets the correct sample rate from the audio codec in CreateSourceVoice. I’m stumped.

    Any help would be much appreciated.

    #include "DVDAudioDevice.h"

    HANDLE m_hBufferEndEvent;

    CDVDAudio::CDVDAudio()
    {
       m_pXAudio2 = NULL;
       m_pMasteringVoice = NULL;
       m_pSourceVoice = NULL;
       m_pWfx  = NULL;

       m_VoiceCallback = NULL;

       m_hBufferEndEvent = CreateEvent(NULL, false, false, "Buffer end event");
    }

    CDVDAudio::~CDVDAudio()
    {
       m_pXAudio2 = NULL;
       m_pMasteringVoice = NULL;
       m_pSourceVoice = NULL;
       m_pWfx  = NULL;

       m_VoiceCallback = NULL;

       CloseHandle(m_hBufferEndEvent);
       m_hBufferEndEvent = NULL;
    }

    bool CDVDAudio::Create(int iChannels, int iBitrate, int iBitsPerSample, bool bPasstrough)
    {
       CoInitializeEx(NULL, COINIT_MULTITHREADED);

       HRESULT hr = XAudio2Create( &amp;m_pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);

       if (SUCCEEDED(hr))
       {
           m_pXAudio2->CreateMasteringVoice( &amp;m_pMasteringVoice );
       }

       // Create source voice
       WAVEFORMATEXTENSIBLE wfx;
       memset(&amp;wfx, 0, sizeof(WAVEFORMATEXTENSIBLE));

       wfx.Format.wFormatTag           = WAVE_FORMAT_PCM;
       wfx.Format.nSamplesPerSec       = iBitrate;//pFFMpegData->pAudioCodecCtx->sample_rate;//48000 by default
       wfx.Format.nChannels            = iChannels;//pFFMpegData->pAudioCodecCtx->channels;
       wfx.Format.wBitsPerSample       = 16;
       wfx.Format.nBlockAlign          = wfx.Format.nChannels*16/8;
       wfx.Format.nAvgBytesPerSec      = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
       wfx.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
       wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;

       if(wfx.Format.nChannels == 1)
       {
           wfx.dwChannelMask = SPEAKER_MONO;
       }
       else if(wfx.Format.nChannels == 2)
       {
           wfx.dwChannelMask = SPEAKER_STEREO;
       }
       else if(wfx.Format.nChannels == 5)
       {
           wfx.dwChannelMask = SPEAKER_5POINT1;
       }

       wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

       unsigned int flags = 0;//XAUDIO2_VOICE_NOSRC;// | XAUDIO2_VOICE_NOPITCH;

       //Source voice

       m_VoiceCallback = new StreamingVoiceCallback(this);

       hr = m_pXAudio2->CreateSourceVoice(&amp;m_pSourceVoice,(WAVEFORMATEX*)&amp;wfx, 0 , 1.0f, m_VoiceCallback);

       if(!SUCCEEDED(hr))
           return false;

       // Start sound
       hr = m_pSourceVoice->Start(0);

       if(!SUCCEEDED(hr))
           return false;

       return true;
    }

    DWORD CDVDAudio::AddPackets(unsigned char* data, DWORD len)
    {  
           memset(&amp;m_SoundBuffer,0,sizeof(XAUDIO2_BUFFER));

           m_SoundBuffer.AudioBytes = len;
           m_SoundBuffer.pAudioData = data;
           m_SoundBuffer.pContext = NULL;//(VOID*)data;

           XAUDIO2_VOICE_STATE state;

           while(m_pSourceVoice->GetState( &amp;state ), state.BuffersQueued > 60)
           {
               WaitForSingleObject( m_hBufferEndEvent, INFINITE );
           }

           m_pSourceVoice->SubmitSourceBuffer( &amp;m_SoundBuffer );

       return 0;
    }

    void CDVDAudio::Destroy()
    {
       m_pMasteringVoice->DestroyVoice();
       m_pXAudio2->Release();

       m_pSourceVoice->DestroyVoice();

       delete m_VoiceCallback;
       m_VoiceCallback = NULL;
    }
    #include "DVDAudioCodecFFmpeg.h"
    #include "Log.h"

    CDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg() : CDVDAudioCodec()
    {
       m_iBufferSize = 0;
       m_pCodecContext = NULL;
       m_bOpenedCodec = false;
    }

    CDVDAudioCodecFFmpeg::~CDVDAudioCodecFFmpeg()
    {
       Dispose();
    }

    bool CDVDAudioCodecFFmpeg::Open(AVCodecID codecID, int iChannels, int iSampleRate)
    {
       AVCodec* pCodec;
       m_bOpenedCodec = false;

       av_register_all();

       pCodec = avcodec_find_decoder(codecID);

       m_pCodecContext = avcodec_alloc_context3(pCodec);//avcodec_alloc_context();
       avcodec_get_context_defaults3(m_pCodecContext, pCodec);

       if (!pCodec)
       {
           CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to find codec");
           return false;
       }

       m_pCodecContext->debug_mv = 0;
       m_pCodecContext->debug = 0;
       m_pCodecContext->workaround_bugs = 1;

       if (pCodec->capabilities &amp; CODEC_CAP_TRUNCATED)
           m_pCodecContext->flags |= CODEC_FLAG_TRUNCATED;

       m_pCodecContext->channels = iChannels;
       m_pCodecContext->sample_rate = iSampleRate;
       //m_pCodecContext->bits_per_sample = 24;

    /* //FIXME BRENT
     if( ExtraData &amp;&amp; ExtraSize > 0 )
     {
       m_pCodecContext->extradata_size = ExtraSize;
       m_pCodecContext->extradata = m_dllAvCodec.av_mallocz(ExtraSize + FF_INPUT_BUFFER_PADDING_SIZE);
       memcpy(m_pCodecContext->extradata, ExtraData, ExtraSize);
     }
    */
       // set acceleration
       //m_pCodecContext->dsp_mask = FF_MM_FORCE | FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE; //BRENT

       if (avcodec_open2(m_pCodecContext, pCodec, NULL) &lt; 0)
       {
           CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to open codec");
           Dispose();
           return false;
       }

       m_bOpenedCodec = true;
       return true;
    }

    void CDVDAudioCodecFFmpeg::Dispose()
    {
       if (m_pCodecContext)
       {
           if (m_bOpenedCodec) avcodec_close(m_pCodecContext);
           m_bOpenedCodec = false;
           av_free(m_pCodecContext);
           m_pCodecContext = NULL;
       }
       m_iBufferSize = 0;
    }

    int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize)
    {
       int iBytesUsed;
       if (!m_pCodecContext) return -1;

       //Copy into a FFMpeg AVPAcket again
       AVPacket packet;
       av_init_packet(&amp;packet);

       packet.data=pData;
       packet.size=iSize;

       int iOutputSize = AVCODEC_MAX_AUDIO_FRAME_SIZE; //BRENT

       iBytesUsed = avcodec_decode_audio3(m_pCodecContext, (int16_t *)m_buffer, &amp;iOutputSize/*m_iBufferSize*/, &amp;packet);

       m_iBufferSize = iOutputSize;//BRENT

       return iBytesUsed;
    }

    int CDVDAudioCodecFFmpeg::GetData(BYTE** dst)
    {
       *dst = m_buffer;
       return m_iBufferSize;
    }

    void CDVDAudioCodecFFmpeg::Reset()
    {
       if (m_pCodecContext) avcodec_flush_buffers(m_pCodecContext);
    }

    int CDVDAudioCodecFFmpeg::GetChannels()
    {
       if (m_pCodecContext) return m_pCodecContext->channels;
       return 0;
    }

    int CDVDAudioCodecFFmpeg::GetSampleRate()
    {
       if (m_pCodecContext) return m_pCodecContext->sample_rate;
       return 0;
    }

    int CDVDAudioCodecFFmpeg::GetBitsPerSample()
    {
       if (m_pCodecContext) return 16;
       return 0;
    }
    #include "DVDPlayerAudio.h"
    #include "DVDDemuxUtils.h"
    #include "Log.h"

    #include
    #include "DVDAudioCodecFFmpeg.h" //FIXME Move to a codec factory!!

    CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock) : CThread()
    {
       m_pClock = pClock;
       m_pAudioCodec = NULL;
       m_bInitializedOutputDevice = false;
       m_iSourceChannels = 0;
       m_audioClock = 0;

    //  m_currentPTSItem.pts = DVD_NOPTS_VALUE;
    //  m_currentPTSItem.timestamp = 0;

       SetSpeed(DVD_PLAYSPEED_NORMAL);

       InitializeCriticalSection(&amp;m_critCodecSection);
       m_messageQueue.SetMaxDataSize(10 * 16 * 1024);
    //  g_dvdPerformanceCounter.EnableAudioQueue(&amp;m_packetQueue);
    }

    CDVDPlayerAudio::~CDVDPlayerAudio()
    {
    //  g_dvdPerformanceCounter.DisableAudioQueue();

       // close the stream, and don't wait for the audio to be finished
       CloseStream(true);
       DeleteCriticalSection(&amp;m_critCodecSection);
    }

    bool CDVDPlayerAudio::OpenStream( CDemuxStreamAudio *pDemuxStream )                                
    {
       // should alway's be NULL!!!!, it will probably crash anyway when deleting m_pAudioCodec here.
       if (m_pAudioCodec)
       {
           CLog::Log(LOGFATAL, "CDVDPlayerAudio::OpenStream() m_pAudioCodec != NULL");
           return false;
       }

       AVCodecID codecID = pDemuxStream->codec;

       CLog::Log(LOGNOTICE, "Finding audio codec for: %i", codecID);
       //m_pAudioCodec = CDVDFactoryCodec::CreateAudioCodec( pDemuxStream );
       m_pAudioCodec = new CDVDAudioCodecFFmpeg; //FIXME BRENT Codec Factory needed!

       if (!m_pAudioCodec->Open(pDemuxStream->codec, pDemuxStream->iChannels, pDemuxStream->iSampleRate))
       {
           m_pAudioCodec->Dispose();
           delete m_pAudioCodec;
           m_pAudioCodec = NULL;
           return false;
       }

       if( !m_pAudioCodec )
       {
           CLog::Log(LOGERROR, "Unsupported audio codec");
           return false;
       }

       m_codec = pDemuxStream->codec;
       m_iSourceChannels = pDemuxStream->iChannels;

       m_messageQueue.Init();

       CLog::Log(LOGNOTICE, "Creating audio thread");
       Create();

       return true;
    }

    void CDVDPlayerAudio::CloseStream(bool bWaitForBuffers)
    {
       // wait until buffers are empty
       if (bWaitForBuffers) m_messageQueue.WaitUntilEmpty();

       // send abort message to the audio queue
       m_messageQueue.Abort();

       CLog::Log(LOGNOTICE, "waiting for audio thread to exit");

       // shut down the adio_decode thread and wait for it
       StopThread(); // will set this->m_bStop to true
       this->WaitForThreadExit(INFINITE);

       // uninit queue
       m_messageQueue.End();

       CLog::Log(LOGNOTICE, "Deleting audio codec");
       if (m_pAudioCodec)
       {
           m_pAudioCodec->Dispose();
           delete m_pAudioCodec;
           m_pAudioCodec = NULL;
       }

       // flush any remaining pts values
       //FlushPTSQueue(); //FIXME BRENT
    }

    void CDVDPlayerAudio::OnStartup()
    {
       CThread::SetName("CDVDPlayerAudio");
       pAudioPacket = NULL;
       m_audioClock = 0;
       audio_pkt_data = NULL;
       audio_pkt_size = 0;

    //  g_dvdPerformanceCounter.EnableAudioDecodePerformance(ThreadHandle());
    }

    void CDVDPlayerAudio::Process()
    {
       CLog::Log(LOGNOTICE, "running thread: CDVDPlayerAudio::Process()");

       int result;

       // silence data
       BYTE silence[1024];
       memset(silence, 0, 1024);

       DVDAudioFrame audioframe;

       __int64 iClockDiff=0;
       while (!m_bStop)
       {
           //Don't let anybody mess with our global variables
           EnterCriticalSection(&amp;m_critCodecSection);
           result = DecodeFrame(audioframe, m_speed != DVD_PLAYSPEED_NORMAL); // blocks if no audio is available, but leaves critical section before doing so
           LeaveCriticalSection(&amp;m_critCodecSection);

           if( result &amp; DECODE_FLAG_ERROR )
           {      
               CLog::Log(LOGERROR, "CDVDPlayerAudio::Process - Decode Error. Skipping audio frame");
               continue;
           }

           if( result &amp; DECODE_FLAG_ABORT )
           {
               CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Abort recieved, exiting thread");
               break;
           }

           if( result &amp; DECODE_FLAG_DROP ) //FIXME BRENT
           {
    /*          //frame should be dropped. Don't let audio move ahead of the current time thou
               //we need to be able to start playing at any time
               //when playing backwords, we try to keep as small buffers as possible

               // set the time at this delay
               AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay());
    */
               if (m_speed > 0)
               {
                   __int64 timestamp = m_pClock->GetAbsoluteClock() + (audioframe.duration * DVD_PLAYSPEED_NORMAL) / m_speed;
                   while( !m_bStop &amp;&amp; timestamp > m_pClock->GetAbsoluteClock() ) Sleep(1);
               }
               continue;
           }

           if( audioframe.size > 0 )
           {
               // we have succesfully decoded an audio frame, openup the audio device if not already done
               if (!m_bInitializedOutputDevice)
               {
                   m_bInitializedOutputDevice = InitializeOutputDevice();
               }

               //Add any packets play
               m_dvdAudio.AddPackets(audioframe.data, audioframe.size);

               // store the delay for this pts value so we can calculate the current playing
               //AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay() - audioframe.duration);//BRENT
           }

           // if we where asked to resync on this packet, do so here
           if( result &amp; DECODE_FLAG_RESYNC )
           {      
               CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Resync recieved.");
               //while (!m_bStop &amp;&amp; (unsigned int)m_dvdAudio.GetDelay() > audioframe.duration ) Sleep(5); //BRENT
               m_pClock->Discontinuity(CLOCK_DISC_NORMAL, audioframe.pts);
           }

    #ifdef USEOLDSYNC
           //Clock should be calculated after packets have been added as m_audioClock points to the
           //time after they have been played

           const __int64 iCurrDiff = (m_audioClock - m_dvdAudio.GetDelay()) - m_pClock->GetClock();
           const __int64 iAvDiff = (iClockDiff + iCurrDiff)/2;

           //Check for discontinuity in the stream, use a moving average to
           //eliminate highfreq fluctuations of large packet sizes
           if( ABS(iAvDiff) > 5000 ) // sync clock if average diff is bigger than 5 msec
           {
               //Wait untill only the new audio frame wich triggered the discontinuity is left
               //then set disc state
               while (!m_bStop &amp;&amp; (unsigned int)m_dvdAudio.GetBytesInBuffer() > audioframe.size ) Sleep(5);

               m_pClock->Discontinuity(CLOCK_DISC_NORMAL, m_audioClock - m_dvdAudio.GetDelay());
               CLog::("CDVDPlayer:: Detected Audio Discontinuity, syncing clock. diff was: %I64d, %I64d, av: %I64d", iClockDiff, iCurrDiff, iAvDiff);
               iClockDiff = 0;
           }
           else
           {      
               //Do gradual adjustments (not working yet)
               //m_pClock->AdjustSpeedToMatch(iClock + iAvDiff);
               iClockDiff = iCurrDiff;
           }
    #endif
       }
    }

    void CDVDPlayerAudio::OnExit()
    {
       //g_dvdPerformanceCounter.DisableAudioDecodePerformance();

       // destroy audio device
       CLog::Log(LOGNOTICE, "Closing audio device");
       m_dvdAudio.Destroy();
       m_bInitializedOutputDevice = false;

       CLog::Log(LOGNOTICE, "thread end: CDVDPlayerAudio::OnExit()");
    }

    // decode one audio frame and returns its uncompressed size
    int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &amp;audioframe, bool bDropPacket)
    {
       CDVDDemux::DemuxPacket* pPacket = pAudioPacket;
       int n=48000*2*16/8, len;

       //Store amount left at this point, and what last pts was
       unsigned __int64 first_pkt_pts = 0;
       int first_pkt_size = 0;
       int first_pkt_used = 0;
       int result = 0;

       // make sure the sent frame is clean
       memset(&amp;audioframe, 0, sizeof(DVDAudioFrame));

       if (pPacket)
       {
           first_pkt_pts = pPacket->pts;
           first_pkt_size = pPacket->iSize;
           first_pkt_used = first_pkt_size - audio_pkt_size;
       }

       for (;;)
       {
           /* NOTE: the audio packet can contain several frames */
           while (audio_pkt_size > 0)
           {
               len = m_pAudioCodec->Decode(audio_pkt_data, audio_pkt_size);
               if (len &lt; 0)
               {
                   /* if error, we skip the frame */
                   audio_pkt_size=0;
                   m_pAudioCodec->Reset();
                   break;
               }

               // fix for fucked up decoders //FIXME BRENT
               if( len > audio_pkt_size )
               {        
                   CLog::Log(LOGERROR, "CDVDPlayerAudio:DecodeFrame - Codec tried to consume more data than available. Potential memory corruption");        
                   audio_pkt_size=0;
                   m_pAudioCodec->Reset();
                   assert(0);
               }

               // get decoded data and the size of it
               audioframe.size = m_pAudioCodec->GetData(&amp;audioframe.data);

               audio_pkt_data += len;
               audio_pkt_size -= len;

               if (audioframe.size &lt;= 0) continue;

               audioframe.pts = m_audioClock;

               // compute duration.
               n = m_pAudioCodec->GetChannels() * m_pAudioCodec->GetBitsPerSample() / 8 * m_pAudioCodec->GetSampleRate();
               if (n > 0)
               {
                   // safety check, if channels == 0, n will result in 0, and that will result in a nice devide exception
                   audioframe.duration = (unsigned int)(((__int64)audioframe.size * DVD_TIME_BASE) / n);

                   // increase audioclock to after the packet
                   m_audioClock += audioframe.duration;
               }

               //If we are asked to drop this packet, return a size of zero. then it won't be played
               //we currently still decode the audio.. this is needed since we still need to know it's
               //duration to make sure clock is updated correctly.
               if( bDropPacket )
               {
                   result |= DECODE_FLAG_DROP;
               }
               return result;
           }

           // free the current packet
           if (pPacket)
           {
               CDVDDemuxUtils::FreeDemuxPacket(pPacket); //BRENT FIXME
               pPacket = NULL;
               pAudioPacket = NULL;
           }

           if (m_messageQueue.RecievedAbortRequest()) return DECODE_FLAG_ABORT;

           // read next packet and return -1 on error
           LeaveCriticalSection(&amp;m_critCodecSection); //Leave here as this might stall a while

           CDVDMsg* pMsg;
           MsgQueueReturnCode ret = m_messageQueue.Get(&amp;pMsg, INFINITE);

           EnterCriticalSection(&amp;m_critCodecSection);
           if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT) return DECODE_FLAG_ABORT;

           if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
           {
               CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg;
               pPacket = pMsgDemuxerPacket->GetPacket();
               pMsgDemuxerPacket->m_pPacket = NULL; // XXX, test
               pAudioPacket = pPacket;
               audio_pkt_data = pPacket->pData;
               audio_pkt_size = pPacket->iSize;
           }
           else
           {
               // other data is not used here, free if
               // msg itself will still be available
               pMsg->Release();
           }

           // if update the audio clock with the pts
           if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET) || pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
           {
               if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
               {
                   //player asked us to sync on this package
                   CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;
                   result |= DECODE_FLAG_RESYNC;
                   m_audioClock = pMsgGeneralResync->GetPts();
               }
               else if (pPacket->pts != DVD_NOPTS_VALUE) // CDVDMsg::DEMUXER_PACKET, pPacket is already set above
               {
                   if (first_pkt_size == 0)
                   {
                       //first package
                       m_audioClock = pPacket->pts;        
                   }
                   else if (first_pkt_pts > pPacket->pts)
                   {
                       //okey first packet in this continous stream, make sure we use the time here        
                       m_audioClock = pPacket->pts;        
                   }
                   else if((unsigned __int64)m_audioClock &lt; pPacket->pts || (unsigned __int64)m_audioClock > pPacket->pts)
                   {
                       //crap, moved outsided correct pts
                       //Use pts from current packet, untill we find a better value for it.
                       //Should be ok after a couple of frames, as soon as it starts clean on a packet
                       m_audioClock = pPacket->pts;
                   }
                   else if(first_pkt_size == first_pkt_used)
                   {
                       //Nice starting up freshly on the start of a packet, use pts from it
                       m_audioClock = pPacket->pts;
                   }
               }
           }
           pMsg->Release();
       }
    }

    void CDVDPlayerAudio::SetSpeed(int speed)
    {
       m_speed = speed;

       //if (m_speed == DVD_PLAYSPEED_PAUSE) m_dvdAudio.Pause(); //BRENT FIXME
       //else m_dvdAudio.Resume();
    }

    bool CDVDPlayerAudio::InitializeOutputDevice()
    {
       int iChannels = m_pAudioCodec->GetChannels();
       int iSampleRate = m_pAudioCodec->GetSampleRate();
       int iBitsPerSample = m_pAudioCodec->GetBitsPerSample();
       //bool bPasstrough = m_pAudioCodec->NeedPasstrough(); //BRENT

       if (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)
       {
           CLog::Log(LOGERROR, "Unable to create audio device, (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)");
           return false;
       }

       CLog::Log(LOGNOTICE, "Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
       if (m_dvdAudio.Create(iChannels, iSampleRate, iBitsPerSample, /*bPasstrough*/0)) // always 16 bit with ffmpeg ? //BRENT Passthrough needed?
       {
           return true;
       }

       CLog::Log(LOGERROR, "Failed Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
       return false;
    }
  • FFmpeg and bash, Transcode multiple files to another drive with save path

    18 juillet 2016, par Виктор Гусев

    I have folder that contain files in many different path, for example : folder1/subfolder1/file.mov
    folder1/subfolder2/file.mov

    i need to convert and copy all files to another format, and save all paths after folder 1, for example :
    folder2/subfolder1/file.mp4
    folder2/subfolder2/file.mp4

    I have this script, but it save transcoded files in original location.

    #!/bin/bash
    MOVIES=/Volumes/drive/
    find "$MOVIES" -name '*.MP4' -exec sh -c 'ffmpeg -i "$0" -map 0 -c copy "${0%%.MP4}.mov"' {} \; exit;

    Please help
    Thank you !