} // namespace
#include "audio_encoder.h"
-#include "context.h"
+#include "shared/context.h"
#include "defs.h"
-#include "disk_space_estimator.h"
+#include "shared/disk_space_estimator.h"
#include "shared/ffmpeg_raii.h"
#include "flags.h"
#include "shared/mux.h"
#define CHECK_VASTATUS(va_status, func) \
if (va_status != VA_STATUS_SUCCESS) { \
fprintf(stderr, "%s:%d (%s) failed with %d\n", __func__, __LINE__, func, va_status); \
- exit(1); \
+ abort(); \
}
#undef BUFFER_OFFSET
va_dpy = try_open_va(va_display, &h264_profile, &error);
if (va_dpy == nullptr) {
fprintf(stderr, "error: %s\n", error.c_str());
- exit(1);
+ abort();
}
if (!va_dpy->can_use_zerocopy) {
use_zerocopy = false;
/* check the interested configattrib */
if ((attrib[VAConfigAttribRTFormat].value & VA_RT_FORMAT_YUV420) == 0) {
printf("Not find desired YUV420 RT format\n");
- exit(1);
+ abort();
} else {
config_attrib[config_attrib_num].type = VAConfigAttribRTFormat;
config_attrib[config_attrib_num].value = VA_RT_FORMAT_YUV420;
if (attrib[VAConfigAttribRateControl].value != VA_ATTRIB_NOT_SUPPORTED) {
if (!(attrib[VAConfigAttribRateControl].value & VA_RC_CQP)) {
fprintf(stderr, "ERROR: VA-API encoder does not support CQP mode.\n");
- exit(1);
+ abort();
}
config_attrib[config_attrib_num].type = VAConfigAttribRateControl;
pic_param.CurrPic.frame_idx = current_ref_frame_num;
CurrentCurrPic.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
// Insert the new frame at the start of the reference queue.
reference_frames.push_front(ReferenceFrame{ CurrentCurrPic, current_display_frame });
// this is weird. but it seems to put a new frame onto the queue
void QuickSyncEncoderImpl::storage_task_enqueue(storage_task task)
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
storage_task_queue.push(move(task));
storage_task_queue_changed.notify_all();
}
// Unlock the frame, and all its references.
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
release_gl_surface(display_order);
for (size_t frame_num : ref_display_frame_numbers) {
void QuickSyncEncoderImpl::release_encode()
{
for (unsigned i = 0; i < SURFACE_NUM; i++) {
- vaDestroyBuffer(va_dpy->va_dpy, gl_surfaces[i].coded_buf);
- vaDestroySurfaces(va_dpy->va_dpy, &gl_surfaces[i].src_surface, 1);
- vaDestroySurfaces(va_dpy->va_dpy, &gl_surfaces[i].ref_surface, 1);
+ VAStatus va_status = vaDestroyBuffer(va_dpy->va_dpy, gl_surfaces[i].coded_buf);
+ CHECK_VASTATUS(va_status, "vaDestroyBuffer");
+ va_status = vaDestroySurfaces(va_dpy->va_dpy, &gl_surfaces[i].src_surface, 1);
+ CHECK_VASTATUS(va_status, "vaDestroySurfaces");
+ va_status = vaDestroySurfaces(va_dpy->va_dpy, &gl_surfaces[i].ref_surface, 1);
+ CHECK_VASTATUS(va_status, "vaDestroySurfaces");
}
- vaDestroyContext(va_dpy->va_dpy, context_id);
- vaDestroyConfig(va_dpy->va_dpy, config_id);
+ VAStatus va_status = vaDestroyContext(va_dpy->va_dpy, context_id);
+ CHECK_VASTATUS(va_status, "vaDestroyContext");
+ va_status = vaDestroyConfig(va_dpy->va_dpy, config_id);
+ CHECK_VASTATUS(va_status, "vaDestroyConfig");
}
void QuickSyncEncoderImpl::release_gl_resources()
if (!make_current(context, this->surface)) {
printf("display=%p surface=%p context=%p curr=%p err=%d\n", eglGetCurrentDisplay(), this->surface, context, eglGetCurrentContext(),
eglGetError());
- exit(1);
+ abort();
}
encode_thread_func();
delete_context(context);
GLenum type = global_flags.x264_bit_depth > 8 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
GLSurface *surf;
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
surf = surface_for_frame[current_storage_frame];
assert(surf != nullptr);
}
check_error();
{
- unique_lock<mutex> lock(frame_queue_mutex);
+ lock_guard<mutex> lock(frame_queue_mutex);
current_video_frame.fence = fence;
pending_video_frames.push(move(current_video_frame));
++current_storage_frame;
}
{
- unique_lock<mutex> lock(frame_queue_mutex);
+ lock_guard<mutex> lock(frame_queue_mutex);
encode_thread_should_quit = true;
frame_queue_nonempty.notify_all();
}
encode_thread.join();
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
storage_thread_should_quit = true;
frame_queue_nonempty.notify_all();
storage_task_queue_changed.notify_all();
{
AVFormatContext *avctx = avformat_alloc_context();
avctx->oformat = av_guess_format(NULL, filename.c_str(), NULL);
- assert(filename.size() < sizeof(avctx->filename) - 1);
- strcpy(avctx->filename, filename.c_str());
+ avctx->url = strdup(filename.c_str());
string url = "file:" + filename;
int ret = avio_open2(&avctx->pb, url.c_str(), AVIO_FLAG_WRITE, &avctx->interrupt_callback, NULL);
if (ret < 0) {
char tmp[AV_ERROR_MAX_STRING_SIZE];
fprintf(stderr, "%s: avio_open2() failed: %s\n", filename.c_str(), av_make_error_string(tmp, sizeof(tmp), ret));
- exit(1);
+ abort();
}
string video_extradata; // FIXME: See other comment about global headers.
{
lock_guard<mutex> lock(file_audio_encoder_mutex);
AVCodecParametersWithDeleter audio_codecpar = file_audio_encoder->get_codec_parameters();
- file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, video_extradata, audio_codecpar.get(), get_color_space(global_flags.ycbcr_rec709_coefficients), Mux::WITH_AUDIO, TIMEBASE,
- std::bind(&DiskSpaceEstimator::report_write, disk_space_estimator, filename, _1),
+ file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, video_extradata, audio_codecpar.get(), get_color_space(global_flags.ycbcr_rec709_coefficients), TIMEBASE,
+ std::bind(&DiskSpaceEstimator::report_append, disk_space_estimator, filename, _1),
Mux::WRITE_BACKGROUND,
{ ¤t_file_mux_metrics, &total_mux_metrics }));
}
pass_frame(frame, display_frame_num, frame.pts, frame.duration);
if (global_flags.x264_video_to_disk) {
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
release_gl_surface(display_frame_num);
continue;
}
if (frame_type == FRAME_IDR) {
// Release any reference frames from the previous GOP.
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
for (const ReferenceFrame &frame : reference_frames) {
release_gl_surface(frame.display_number);
}
stream_mux->add_packet(pkt, pts, pts);
}
-namespace {
-
void memcpy_with_pitch(uint8_t *dst, const uint8_t *src, size_t src_width, size_t dst_pitch, size_t height)
{
if (src_width == dst_pitch) {
}
}
-} // namespace
-
void QuickSyncEncoderImpl::pass_frame(QuickSyncEncoderImpl::PendingFrame frame, int display_frame_num, int64_t pts, int64_t duration)
{
// Wait for the GPU to be done with the frame.
GLSurface *surf;
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
surf = surface_for_frame[display_frame_num];
assert(surf != nullptr);
}
GLSurface *surf;
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
surf = surface_for_frame[display_frame_num];
assert(surf != nullptr);
}
// Lock the references for this frame; otherwise, they could be
// rendered to before this frame is done encoding.
{
- unique_lock<mutex> lock(storage_task_queue_mutex);
+ lock_guard<mutex> lock(storage_task_queue_mutex);
for (const ReferenceFrame &frame : reference_frames) {
assert(surface_for_frame.count(frame.display_number));
++surface_for_frame[frame.display_number]->refcount;
fprintf(stderr, "to expose Quick Sync. Alternatively, you can use --record-x264-video\n");
fprintf(stderr, "to use software instead of hardware H.264 encoding, at the expense\n");
fprintf(stderr, "of increased CPU usage and possibly bit rate.\n");
- exit(1);
+ abort();
}