We will be needing this for HDMI/SDI output.
OPTION_DISABLE_ALSA_OUTPUT,
OPTION_NO_FLUSH_PBOS,
OPTION_PRINT_VIDEO_LATENCY,
- OPTION_AUDIO_QUEUE_LENGTH_MS
+ OPTION_AUDIO_QUEUE_LENGTH_MS,
+ OPTION_OUTPUT_YCBCR_COEFFICIENTS
};
void usage()
fprintf(stderr, " possible to run with apitrace in real time)\n");
fprintf(stderr, " --print-video-latency print out measurements of video latency on stdout\n");
fprintf(stderr, " --audio-queue-length-ms length of audio resampling queue (default 100.0)\n");
+ fprintf(stderr, " --output-ycbcr-coefficients={rec601,rec709}\n");
+ fprintf(stderr, " Y'CbCr coefficient standard of output (default rec601)\n");
}
void parse_flags(int argc, char * const argv[])
{ "no-flush-pbos", no_argument, 0, OPTION_NO_FLUSH_PBOS },
{ "print-video-latency", no_argument, 0, OPTION_PRINT_VIDEO_LATENCY },
{ "audio-queue-length-ms", required_argument, 0, OPTION_AUDIO_QUEUE_LENGTH_MS },
+ { "output-ycbcr-coefficients", required_argument, 0, OPTION_OUTPUT_YCBCR_COEFFICIENTS },
{ 0, 0, 0, 0 }
};
vector<string> theme_dirs;
+ string output_ycbcr_coefficients = "rec601";
for ( ;; ) {
int option_index = 0;
int c = getopt_long(argc, argv, "c:t:I:v:m:M:w:h:", long_options, &option_index);
case OPTION_AUDIO_QUEUE_LENGTH_MS:
global_flags.audio_queue_length_ms = atof(optarg);
break;
+ case OPTION_OUTPUT_YCBCR_COEFFICIENTS:
+ output_ycbcr_coefficients = optarg;
+ break;
case OPTION_HELP:
usage();
exit(0);
exit(1);
}
}
+
+ if (output_ycbcr_coefficients == "rec709") {
+ global_flags.ycbcr_rec709_coefficients = true;
+ } else if (output_ycbcr_coefficients == "rec601") {
+ global_flags.ycbcr_rec709_coefficients = false;
+ } else {
+ fprintf(stderr, "ERROR: --output-ycbcr-coefficients must be “rec601” or “rec709”\n");
+ exit(1);
+ }
}
std::string midi_mapping_filename; // Empty for none.
bool print_video_latency = false;
double audio_queue_length_ms = 100.0;
+ bool ycbcr_rec709_coefficients = false;
};
extern Flags global_flags;
if ( false ) {
bitstream_put_ui(bs, 0, 1); /* vui_parameters_present_flag */
} else {
+ // See H.264 annex E for the definition of this header.
bitstream_put_ui(bs, 1, 1); /* vui_parameters_present_flag */
bitstream_put_ui(bs, 0, 1); /* aspect_ratio_info_present_flag */
bitstream_put_ui(bs, 0, 1); /* overscan_info_present_flag */
{
bitstream_put_ui(bs, 1, 8); /* colour_primaries (1 = BT.709) */
bitstream_put_ui(bs, 2, 8); /* transfer_characteristics (2 = unspecified, since we use sRGB) */
- bitstream_put_ui(bs, 6, 8); /* matrix_coefficients (6 = BT.601/SMPTE 170M) */
+ if (global_flags.ycbcr_rec709_coefficients) {
+ bitstream_put_ui(bs, 1, 8); /* matrix_coefficients (1 = BT.709) */
+ } else {
+ bitstream_put_ui(bs, 6, 8); /* matrix_coefficients (6 = BT.601/SMPTE 170M) */
+ }
}
}
bitstream_put_ui(bs, 0, 1); /* chroma_loc_info_present_flag */
// happens in a pass not run by Movit (see ChromaSubsampler::subsample_chroma()).
output_ycbcr_format.chroma_subsampling_x = 1;
output_ycbcr_format.chroma_subsampling_y = 1;
-
- // Rec. 709 would be the sane thing to do, but it seems many players
- // (e.g. MPlayer and VLC) just default to BT.601 coefficients no matter
- // what (see discussions in e.g. https://trac.ffmpeg.org/ticket/4978).
- // We _do_ set the right flags, though, so that a player that works
- // properly doesn't have to guess.
- output_ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ if (global_flags.ycbcr_rec709_coefficients) {
+ output_ycbcr_format.luma_coefficients = YCBCR_REC_709;
+ } else {
+ output_ycbcr_format.luma_coefficients = YCBCR_REC_601;
+ }
output_ycbcr_format.full_range = false;
output_ycbcr_format.num_levels = 256;
param.i_frame_reference = 16; // Because speedcontrol is never allowed to change this above what we set at start.
}
- // NOTE: These should be in sync with the ones in h264encode.cpp (sbs_rbsp()).
+ // NOTE: These should be in sync with the ones in quicksync_encoder.cpp (sps_rbsp()).
param.vui.i_vidformat = 5; // Unspecified.
param.vui.b_fullrange = 0;
param.vui.i_colorprim = 1; // BT.709.
param.vui.i_transfer = 2; // Unspecified (since we use sRGB).
- param.vui.i_colmatrix = 6; // BT.601/SMPTE 170M.
-
+ if (global_flags.ycbcr_rec709_coefficients) {
+ param.vui.i_colmatrix = 1; // BT.709.
+ } else {
+ param.vui.i_colmatrix = 6; // BT.601/SMPTE 170M.
+ }
param.rc.i_rc_method = X264_RC_ABR;
param.rc.i_bitrate = global_flags.x264_bitrate;