Exemplo n.º 1
0
static void ffmpeg_flush_audio(ffmpeg_t *handle, void *audio_buf,
      size_t audio_buf_size)
{
   size_t avail = fifo_read_avail(handle->audio_fifo);

   if (avail)
   {
      struct ffemu_audio_data aud = {0};

      fifo_read(handle->audio_fifo, audio_buf, avail);

      aud.frames = avail / (sizeof(int16_t) * handle->params.channels);
      aud.data = audio_buf;

      ffmpeg_push_audio_thread(handle, &aud, false);
   }

   for (;;)
   {
      AVPacket pkt;
      if (!encode_audio(handle, &pkt, true) || !pkt.size ||
            av_interleaved_write_frame(handle->muxer.ctx, &pkt) < 0)
         break;
   }
}
Exemplo n.º 2
0
static void ffmpeg_flush_buffers(ffmpeg_t *handle)
{
   bool did_work;
   void *video_buf = av_malloc(2 * handle->params.fb_width * 
         handle->params.fb_height * handle->video.pix_size);
   size_t audio_buf_size = handle->config.audio_enable ? 
      (handle->audio.codec->frame_size * 
       handle->params.channels * sizeof(int16_t)) : 0;
   void *audio_buf = NULL;

   if (audio_buf_size)
      audio_buf = av_malloc(audio_buf_size);
   /* Try pushing data in an interleaving pattern to 
    * ease the work of the muxer a bit. */

   do
   {
      struct ffemu_video_data attr_buf;

      did_work = false;

      if (handle->config.audio_enable)
      {
         if (fifo_read_avail(handle->audio_fifo) >= audio_buf_size)
         {
            struct ffemu_audio_data aud = {0};

            fifo_read(handle->audio_fifo, audio_buf, audio_buf_size);

            aud.frames = handle->audio.codec->frame_size;
            aud.data = audio_buf;

            ffmpeg_push_audio_thread(handle, &aud, true);
            did_work = true;
         }
      }

      if (fifo_read_avail(handle->attr_fifo) >= sizeof(attr_buf))
      {
         fifo_read(handle->attr_fifo, &attr_buf, sizeof(attr_buf));
         fifo_read(handle->video_fifo, video_buf, 
               attr_buf.height * attr_buf.pitch);
         attr_buf.data = video_buf;
         ffmpeg_push_video_thread(handle, &attr_buf);

         did_work = true;
      }
   } while (did_work);

   /* Flush out last audio. */
   if (handle->config.audio_enable)
      ffmpeg_flush_audio(handle, audio_buf, audio_buf_size);

   /* Flush out last video. */
   ffmpeg_flush_video(handle);

   av_free(video_buf);
   av_free(audio_buf);
}
Exemplo n.º 3
0
static void ffmpeg_thread(void *data)
{
   ffmpeg_t *ff = (ffmpeg_t*)data;

   // For some reason, FFmpeg has a tendency to crash if we don't overallocate a bit. :s
   void *video_buf = av_malloc(2 * ff->params.fb_width * ff->params.fb_height * ff->video.pix_size);
   assert(video_buf);

   size_t audio_buf_size = ff->config.audio_enable ? (ff->audio.codec->frame_size * ff->params.channels * sizeof(int16_t)) : 0;
   void *audio_buf = audio_buf_size ? av_malloc(audio_buf_size) : NULL;

   while (ff->alive)
   {
      struct ffemu_video_data attr_buf;

      bool avail_video = false;
      bool avail_audio = false;

      slock_lock(ff->lock);
      if (fifo_read_avail(ff->attr_fifo) >= sizeof(attr_buf))
         avail_video = true;

      if (ff->config.audio_enable)
         if (fifo_read_avail(ff->audio_fifo) >= audio_buf_size)
            avail_audio = true;
      slock_unlock(ff->lock);

      if (!avail_video && !avail_audio)
      {
         slock_lock(ff->cond_lock);
         if (ff->can_sleep)
         {
            ff->can_sleep = false;
            scond_wait(ff->cond, ff->cond_lock);
            ff->can_sleep = true;
         }
         else
            scond_signal(ff->cond);

         slock_unlock(ff->cond_lock);
      }

      if (avail_video)
      {
         slock_lock(ff->lock);
         fifo_read(ff->attr_fifo, &attr_buf, sizeof(attr_buf));
         fifo_read(ff->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
         slock_unlock(ff->lock);
         scond_signal(ff->cond);

         attr_buf.data = video_buf;
         ffmpeg_push_video_thread(ff, &attr_buf);
      }

      if (avail_audio)
      {
         slock_lock(ff->lock);
         fifo_read(ff->audio_fifo, audio_buf, audio_buf_size);
         slock_unlock(ff->lock);
         scond_signal(ff->cond);

         struct ffemu_audio_data aud = {0};
         aud.frames = ff->audio.codec->frame_size;
         aud.data = audio_buf;

         ffmpeg_push_audio_thread(ff, &aud, true);
      }
   }

   av_free(video_buf);
   av_free(audio_buf);
}