void setup_video_track()

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;
  }