in vireo/mux/mp4.cpp [329:415]
void setup_video_track(const settings::Video& video_settings) {
lsmash_video_summary_t* video_summary = (lsmash_video_summary_t*)lsmash_create_summary(LSMASH_SUMMARY_TYPE_VIDEO);
CHECK(video_summary);
video_summary->sample_type = ISOM_CODEC_TYPE_AVC1_VIDEO;
video_summary->width = video_settings.coded_width;
video_summary->height = video_settings.coded_height;
// Video track
tracks(SampleType::Video).track_ID = lsmash_create_track(root.get(), ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK);
// Video track params
lsmash_track_parameters_t track_parameters;
lsmash_initialize_track_parameters(&track_parameters);
track_parameters.mode = (lsmash_track_mode)(ISOM_TRACK_ENABLED | ISOM_TRACK_IN_MOVIE | ISOM_TRACK_IN_PREVIEW);
track_parameters.display_width = video_settings.width << 16;
track_parameters.display_height = video_settings.height << 16;
THROW_IF(video_settings.par_width <= 0 || video_settings.par_width >= 0x8000, InvalidArguments, "Invalid pixel aspect ratio");
THROW_IF(video_settings.par_height <= 0 || video_settings.par_height >= 0x8000, InvalidArguments, "Invalid pixel aspect ratio");
// Set orientation
CHECK(video_settings.orientation != settings::Video::Orientation::UnknownOrientation);
switch (video_settings.orientation) {
case settings::Video::Orientation::LandscapeReverse:
track_parameters.matrix[0] = -0x10000 * video_settings.par_width;
track_parameters.matrix[1] = 0x00000;
track_parameters.matrix[3] = 0x00000;
track_parameters.matrix[4] = -0x10000 * video_settings.par_height;
track_parameters.matrix[6] = video_summary->width << 16;
track_parameters.matrix[7] = video_summary->height << 16;
break;
case settings::Video::Orientation::Portrait:
track_parameters.matrix[0] = 0x00000;
track_parameters.matrix[1] = 0x10000 * video_settings.par_width;
track_parameters.matrix[3] = -0x10000 * video_settings.par_height;
track_parameters.matrix[4] = 0x00000;
track_parameters.matrix[6] = video_summary->height << 16;
break;
case settings::Video::Orientation::PortraitReverse:
track_parameters.matrix[0] = 0x00000;
track_parameters.matrix[1] = -0x10000 * video_settings.par_width;
track_parameters.matrix[3] = 0x10000 * video_settings.par_height;
track_parameters.matrix[4] = 0x00000;
track_parameters.matrix[7] = video_summary->width << 16;
break;
case settings::Video::Orientation::Landscape:
track_parameters.matrix[0] = 0x10000 * video_settings.par_width;
track_parameters.matrix[1] = 0x00000;
track_parameters.matrix[3] = 0x00000;
track_parameters.matrix[4] = 0x10000 * video_settings.par_height;
default:
break;
}
THROW_IF(lsmash_set_track_parameters(root.get(), tracks(SampleType::Video).track_ID, &track_parameters) != 0, InvalidArguments);
// Media params
lsmash_media_parameters_t media_parameters;
lsmash_initialize_media_parameters(&media_parameters);
media_parameters.timescale = video_settings.timescale;
char vireo_version[64];
snprintf(vireo_version, 64, "Vireo Eyes v%s", VIREO_VERSION);
media_parameters.media_handler_name = vireo_version;
THROW_IF(lsmash_set_media_parameters(root.get(), tracks(SampleType::Video).track_ID, &media_parameters) != 0, InvalidArguments);
tracks(SampleType::Video).media_timescale = lsmash_get_media_timescale(root.get(), tracks(SampleType::Video).track_ID);
CHECK(tracks(SampleType::Video).media_timescale);
// SPS / PPS
auto cs = unique_ptr<lsmash_codec_specific_t, decltype(&lsmash_destroy_codec_specific_data)>(lsmash_create_codec_specific_data(LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_VIDEO_H264, LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED), lsmash_destroy_codec_specific_data);
CHECK(cs);
lsmash_h264_specific_parameters_t* parameters = (lsmash_h264_specific_parameters_t*)cs->data.structured;
parameters->lengthSizeMinusOne = video_settings.sps_pps.nalu_length_size - 1;
THROW_IF(lsmash_append_h264_parameter_set(parameters, H264_PARAMETER_SET_TYPE_SPS, (void*)video_settings.sps_pps.sps.data(), video_settings.sps_pps.sps.count()) != 0, InvalidArguments);
THROW_IF(lsmash_append_h264_parameter_set(parameters, H264_PARAMETER_SET_TYPE_PPS, (void*)video_settings.sps_pps.pps.data(), video_settings.sps_pps.pps.count()) != 0, InvalidArguments);
THROW_IF(lsmash_add_codec_specific_data((lsmash_summary_t*)video_summary, cs.get()) != 0, InvalidArguments);
auto csb = unique_ptr<lsmash_codec_specific_t, decltype(&lsmash_destroy_codec_specific_data)>(lsmash_create_codec_specific_data(LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_VIDEO_H264_BITRATE, LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED), lsmash_destroy_codec_specific_data);
CHECK(csb);
THROW_IF(lsmash_add_codec_specific_data((lsmash_summary_t*)video_summary, csb.get()) != 0, InvalidArguments);
// Sample entry
tracks(SampleType::Video).sample_entry = lsmash_add_sample_entry(root.get(), tracks(SampleType::Video).track_ID, video_summary);
CHECK(tracks(SampleType::Video).sample_entry);
lsmash_cleanup_summary((lsmash_summary_t*)video_summary);
tracks(SampleType::Video).timescale = video_settings.timescale;
}