diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 610065bab6..a9dcd3c640 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -103,6 +103,7 @@ if [ $HAVE_THREADS != no ]; then if [ $HAVE_FFMPEG = yes ]; then check_lib FFMPEG_ALLOC_CONTEXT3 "$AVCODEC_LIBS" avcodec_alloc_context3 check_lib FFMPEG_AVCODEC_OPEN2 "$AVCODEC_LIBS" avcodec_open2 + check_lib FFMPEG_AVCODEC_ENCODE_AUDIO2 "$AVCODEC_LIBS" avcodec_encode_audio2 check_lib FFMPEG_AVIO_OPEN "$AVFORMAT_LIBS" avio_open check_lib FFMPEG_AVFORMAT_WRITE_HEADER "$AVFORMAT_LIBS" avformat_write_header check_lib FFMPEG_AVFORMAT_NEW_STREAM "$AVFORMAT_LIBS" avformat_new_stream @@ -135,7 +136,7 @@ check_pkgconf PYTHON python3 add_define_make OS $OS # Creates config.mk and config.h. -VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM X264RGB" +VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 X264RGB" create_config_make config.mk $VARS create_config_header config.h $VARS diff --git a/record/ffemu.c b/record/ffemu.c index 6bdb2f5dfb..1c56674845 100644 --- a/record/ffemu.c +++ b/record/ffemu.c @@ -547,7 +547,7 @@ static bool ffemu_push_video_thread(ffemu_t *handle, const struct ffemu_video_da if (handle->video.codec->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; - if (pkt.size > 0) + if (pkt.size) { if (av_interleaved_write_frame(handle->muxer.ctx, &pkt) < 0) return false; @@ -573,34 +573,72 @@ static bool ffemu_push_audio_thread(ffemu_t *handle, const struct ffemu_audio_da written_frames += write_frames; handle->audio.frames_in_buffer += write_frames; - if (handle->audio.frames_in_buffer == (size_t)handle->audio.codec->frame_size) - { - AVPacket pkt; - av_init_packet(&pkt); - pkt.data = (uint8_t*)handle->audio.outbuf; - pkt.stream_index = handle->muxer.astream->index; + if (handle->audio.frames_in_buffer < (size_t)handle->audio.codec->frame_size) + continue; - int out_size = avcodec_encode_audio(handle->audio.codec, - handle->audio.outbuf, handle->audio.outbuf_size, (const int16_t*)handle->audio.buffer); - if (out_size < 0) - return false; + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = handle->audio.outbuf; + pkt.stream_index = handle->muxer.astream->index; - pkt.size = out_size; + bool has_packet = true; - pkt.pts = av_rescale_q(handle->audio.codec->coded_frame->pts, - handle->audio.codec->time_base, handle->muxer.astream->time_base); +#if defined(HAVE_FFMPEG_AVCODEC_ENCODE_AUDIO2) && 0 // <-- Currently broken. + pkt.size = handle->audio.outbuf_size; + AVFrame frame; + avcodec_get_frame_defaults(&frame); + + frame.nb_samples = handle->audio.codec->frame_size; + + AVRational rat = { 1, handle->audio.codec->sample_rate }; + frame.pts = av_rescale_q(handle->audio.frame_cnt, + rat, handle->audio.codec->time_base); + + int samples_size = av_samples_get_buffer_size(NULL, + handle->audio.codec->channels, + frame.nb_samples, + handle->audio.codec->sample_fmt, 1); + + avcodec_fill_audio_frame(&frame, handle->audio.codec->channels, + handle->audio.codec->sample_fmt, (const uint8_t*)handle->audio.buffer, + samples_size, 1); + + int got_packet = 0; + int ret = avcodec_encode_audio2(handle->audio.codec, + &pkt, &frame, &got_packet); + + if (ret < 0) + return false; + + has_packet = got_packet; +#else + int out_size = avcodec_encode_audio(handle->audio.codec, + handle->audio.outbuf, handle->audio.outbuf_size, handle->audio.buffer); + if (out_size < 0) + return false; + + pkt.size = out_size; + has_packet = pkt.size; +#endif + + pkt.pts = av_rescale_q(handle->audio.codec->coded_frame->pts, + handle->audio.codec->time_base, + handle->muxer.astream->time_base); + + if (handle->audio.codec->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; - handle->audio.frames_in_buffer = 0; - handle->audio.frame_cnt += handle->audio.codec->frame_size; - if (pkt.size > 0) - { - if (av_interleaved_write_frame(handle->muxer.ctx, &pkt) < 0) - return false; - } + handle->audio.frames_in_buffer = 0; + handle->audio.frame_cnt += handle->audio.codec->frame_size; + + if (has_packet) + { + if (av_interleaved_write_frame(handle->muxer.ctx, &pkt) < 0) + return false; } } + return true; }