示例#1
0
bool media_input::stereo_layout_is_supported(parameters::stereo_layout_t layout, bool) const
{
    if (video_streams() < 1)
    {
        return false;
    }
    assert(_active_video_stream >= 0);
    assert(_active_video_stream < video_streams());
    int o, s;
    get_video_stream(_active_video_stream, o, s);
    const video_frame &t = _media_objects[o].video_frame_template(s);
    bool supported = true;
    if (((layout == parameters::layout_left_right || layout == parameters::layout_left_right_half) && t.raw_width % 2 != 0)
            || ((layout == parameters::layout_top_bottom || layout == parameters::layout_top_bottom_half) && t.raw_height % 2 != 0)
            || (layout == parameters::layout_even_odd_rows && t.raw_height % 2 != 0)
            || (layout == parameters::layout_separate && !_supports_stereo_layout_separate))
    {
        supported = false;
    }
    return supported;
}
示例#2
0
void media_input::get_video_stream(int stream, int &media_object, int &media_object_video_stream) const
{
    assert(stream < video_streams());

    size_t i = 0;
    while (_media_objects[i].video_streams() < stream + 1)
    {
        stream -= _media_objects[i].video_streams();
        i++;
    }
    media_object = i;
    media_object_video_stream = stream;
}
示例#3
0
void media_input::select_video_stream(int video_stream)
{
    if (_have_active_video_read)
    {
        (void)finish_video_frame_read();
    }
    if (_have_active_audio_read)
    {
        (void)finish_audio_blob_read();
    }
    if (_have_active_subtitle_read)
    {
        (void)finish_subtitle_box_read();
    }
    assert(video_stream >= 0);
    assert(video_stream < video_streams());
    if (_video_frame.stereo_layout == parameters::layout_separate)
    {
        _active_video_stream = 0;
        for (size_t i = 0; i < _media_objects.size(); i++)
        {
            for (int j = 0; j < _media_objects[i].video_streams(); j++)
            {
                _media_objects[i].video_stream_set_active(j, true);
            }
        }
    }
    else
    {
        _active_video_stream = video_stream;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        for (size_t i = 0; i < _media_objects.size(); i++)
        {
            for (int j = 0; j < _media_objects[i].video_streams(); j++)
            {
                _media_objects[i].video_stream_set_active(j, (i == static_cast<size_t>(o) && j == s));
            }
        }
    }
    // Re-set video frame template
    parameters::stereo_layout_t stereo_layout_bak = _video_frame.stereo_layout;
    bool stereo_layout_swap_bak = _video_frame.stereo_layout_swap;
    int o, s;
    get_video_stream(_active_video_stream, o, s);
    _video_frame = _media_objects[o].video_frame_template(s);
    _video_frame.stereo_layout = stereo_layout_bak;
    _video_frame.stereo_layout_swap = stereo_layout_swap_bak;
    _video_frame.set_view_dimensions();
}
示例#4
0
void media_input::get_video_stream(int stream, int &media_object, int &media_object_video_stream) const
{
    assert(stream < video_streams());

    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        if (_media_objects[i].video_streams() < stream + 1)
        {
            stream -= _media_objects[i].video_streams();
            continue;
        }
        media_object = i;
        media_object_video_stream = stream;
        break;
    }
}
示例#5
0
void media_input::select_video_stream(int video_stream)
{
    if (_have_active_video_read)
    {
        (void)finish_video_frame_read();
    }
    if (_have_active_audio_read)
    {
        (void)finish_audio_blob_read();
    }
    if (_have_active_subtitle_read)
    {
        (void)finish_subtitle_box_read();
    }
    assert(video_stream >= 0);
    assert(video_stream < video_streams());
    if (_video_frame.stereo_layout == video_frame::separate)
    {
        _active_video_stream = 0;
        for (size_t i = 0; i < _media_objects.size(); i++)
        {
            for (int j = 0; j < _media_objects[i].video_streams(); j++)
            {
                _media_objects[i].video_stream_set_active(j, true);
            }
        }
    }
    else
    {
        _active_video_stream = video_stream;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        for (size_t i = 0; i < _media_objects.size(); i++)
        {
            for (int j = 0; j < _media_objects[i].video_streams(); j++)
            {
                _media_objects[i].video_stream_set_active(j, (i == static_cast<size_t>(o) && j == s));
            }
        }
    }
}
示例#6
0
void media_input::open(const std::vector<std::string> &urls, const device_request &dev_request)
{
    assert(urls.size() > 0);

    // Open media objects
    _is_device = dev_request.is_device();
    _media_objects.resize(urls.size());
    for (size_t i = 0; i < urls.size(); i++)
    {
        _media_objects[i].open(urls[i], dev_request);
    }

    // Construct id for this input
    _id = basename(_media_objects[0].url());
    for (size_t i = 1; i < _media_objects.size(); i++)
    {
        _id += '/';
        _id += basename(_media_objects[i].url());
    }

    // Gather metadata
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        // Note that we may have multiple identical tag names in our metadata
        for (size_t j = 0; j < _media_objects[i].tags(); j++)
        {
            _tag_names.push_back(_media_objects[i].tag_name(j));
            _tag_values.push_back(_media_objects[i].tag_value(j));
        }
    }

    // Gather streams and stream names
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        for (int j = 0; j < _media_objects[i].video_streams(); j++)
        {
            _video_stream_names.push_back(_media_objects[i].video_frame_template(j).format_info());
        }
    }
    if (_video_stream_names.size() > 1)
    {
        for (size_t i = 0; i < _video_stream_names.size(); i++)
        {
            _video_stream_names[i].insert(0,
                    std::string(1, '#') + str::from(i + 1) + '/'
                    + str::from(_video_stream_names.size()) + ": ");
        }
    }
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        for (int j = 0; j < _media_objects[i].audio_streams(); j++)
        {
            _audio_stream_names.push_back(_media_objects[i].audio_blob_template(j).format_info());
        }
    }
    if (_audio_stream_names.size() > 1)
    {
        for (size_t i = 0; i < _audio_stream_names.size(); i++)
        {
            _audio_stream_names[i].insert(0,
                    std::string(1, '#') + str::from(i + 1) + '/'
                    + str::from(_audio_stream_names.size()) + ": ");
        }
    }
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        for (int j = 0; j < _media_objects[i].subtitle_streams(); j++)
        {
            _subtitle_stream_names.push_back(_media_objects[i].subtitle_box_template(j).format_info());
        }
    }
    if (_subtitle_stream_names.size() > 1)
    {
        for (size_t i = 0; i < _subtitle_stream_names.size(); i++)
        {
            _subtitle_stream_names[i].insert(0,
                    std::string(1, '#') + str::from(i + 1) + '/'
                    + str::from(_subtitle_stream_names.size()) + ": ");
        }
    }

    // Set duration information
    _duration = std::numeric_limits<int64_t>::max();
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        for (int j = 0; j < _media_objects[i].video_streams(); j++)
        {
            int64_t d = _media_objects[i].video_duration(j);
            if (d < _duration)
            {
                _duration = d;
            }
        }
        for (int j = 0; j < _media_objects[i].audio_streams(); j++)
        {
            int64_t d = _media_objects[i].audio_duration(j);
            if (d < _duration)
            {
                _duration = d;
            }
        }
        // Ignore subtitle stream duration; it seems unreliable and is not important anyway.
    }

    // Skip advertisement in 3dtv.at movies. Only works for single media objects.
    try { _initial_skip = str::to<int64_t>(tag_value("StereoscopicSkip")); } catch (...) { }

    // Find stereo layout and set active video stream(s)
    _supports_stereo_layout_separate = false;
    if (video_streams() == 2)
    {
        int o0, o1, v0, v1;
        get_video_stream(0, o0, v0);
        get_video_stream(1, o1, v1);
        video_frame t0 = _media_objects[o0].video_frame_template(v0);
        video_frame t1 = _media_objects[o1].video_frame_template(v1);
        if (t0.width == t1.width
                && t0.height == t1.height
                && (t0.aspect_ratio <= t1.aspect_ratio && t0.aspect_ratio >= t1.aspect_ratio)
                && t0.layout == t1.layout
                && t0.color_space == t1.color_space
                && t0.value_range == t1.value_range
                && t0.chroma_location == t1.chroma_location)
        {
            _supports_stereo_layout_separate = true;
        }
    }
    if (_supports_stereo_layout_separate)
    {
        _active_video_stream = 0;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        _video_frame = _media_objects[o].video_frame_template(s);
        _video_frame.stereo_layout = parameters::layout_separate;
    }
    else if (video_streams() > 0)
    {
        _active_video_stream = 0;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        _video_frame = _media_objects[o].video_frame_template(s);
    }
    else
    {
        _active_video_stream = -1;
    }
    if (_active_video_stream >= 0)
    {
        select_video_stream(_active_video_stream);
    }

    // Set active audio stream
    _active_audio_stream = (audio_streams() > 0 ? 0 : -1);
    if (_active_audio_stream >= 0)
    {
        int o, s;
        get_audio_stream(_active_audio_stream, o, s);
        _audio_blob = _media_objects[o].audio_blob_template(s);
        select_audio_stream(_active_audio_stream);
    }

    // Set active subtitle stream
    _active_subtitle_stream = -1;       // no subtitles by default

    // Print summary
    msg::inf(_("Input:"));
    for (int i = 0; i < video_streams(); i++)
    {
        int o, s;
        get_video_stream(i, o, s);
        msg::inf(4, _("Video %s: %s"), video_stream_name(i).c_str(),
                _media_objects[o].video_frame_template(s).format_name().c_str());
    }
    if (video_streams() == 0)
    {
        msg::inf(4, _("No video."));
    }
    for (int i = 0; i < audio_streams(); i++)
    {
        int o, s;
        get_audio_stream(i, o, s);
        msg::inf(4, _("Audio %s: %s"), audio_stream_name(i).c_str(),
                _media_objects[o].audio_blob_template(s).format_name().c_str());
    }
    if (audio_streams() == 0)
    {
        msg::inf(4, _("No audio."));
    }
    for (int i = 0; i < subtitle_streams(); i++)
    {
        int o, s;
        get_subtitle_stream(i, o, s);
        msg::inf(4, _("Subtitle %s: %s"), subtitle_stream_name(i).c_str(),
                _media_objects[o].subtitle_box_template(s).format_name().c_str());
    }
    if (subtitle_streams() == 0)
    {
        msg::inf(4, _("No subtitle."));
    }
    msg::inf(4, _("Duration: %g seconds"), duration() / 1e6f);
    if (video_streams() > 0)
    {
        msg::inf(4, _("Stereo layout: %s"), parameters::stereo_layout_to_string(
                    video_frame_template().stereo_layout, video_frame_template().stereo_layout_swap).c_str());
    }
}
示例#7
0
void media_input::open(const std::vector<std::string> &urls)
{
    assert(urls.size() > 0);

    // Open media objects
    _media_objects.resize(urls.size());
    for (size_t i = 0; i < urls.size(); i++)
    {
        _media_objects[i].open(urls[i]);
    }

    // Construct id for this input
    _id = basename(_media_objects[0].url());
    for (size_t i = 1; i < _media_objects.size(); i++)
    {
        _id += '/';
        _id += basename(_media_objects[i].url());
    }

    // Gather metadata
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        std::string pfx = (_media_objects.size() == 1 ? "" : str::from(i + 1) + " - ");
        for (size_t j = 0; j < _media_objects[i].tags(); j++)
        {
            _tag_names.push_back(pfx + _media_objects[i].tag_name(j));
            _tag_values.push_back(pfx + _media_objects[i].tag_value(j));
        }
    }

    // Gather streams and stream names
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        std::string pfx = (_media_objects.size() == 1 ? "" : str::from(i + 1) + " - ");
        for (int j = 0; j < _media_objects[i].video_streams(); j++)
        {
            std::string pfx2 = (_media_objects[i].video_streams() == 1 ? "" : str::from(j + 1) + " - ");
            _video_stream_names.push_back(pfx + pfx2
                    + _media_objects[i].video_frame_template(j).format_info());
        }
    }
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        std::string pfx = (_media_objects.size() == 1 ? "" : str::from(i + 1) + " - ");
        for (int j = 0; j < _media_objects[i].audio_streams(); j++)
        {
            std::string pfx2 = (_media_objects[i].audio_streams() == 1 ? "" : str::from(j + 1) + " - ");
            _audio_stream_names.push_back(pfx + pfx2
                    + _media_objects[i].audio_blob_template(j).format_info());
        }
    }
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        std::string pfx = (_media_objects.size() == 1 ? "" : str::from(i + 1) + " - ");
        for (int j = 0; j < _media_objects[i].subtitle_streams(); j++)
        {
            std::string pfx2 = (_media_objects[i].subtitle_streams() == 1 ? "" : str::from(j + 1) + " - ");
            _subtitle_stream_names.push_back(pfx + pfx2
                    + _media_objects[i].subtitle_box_template(j).format_info());
        }
    }

    // Set duration information
    _duration = std::numeric_limits<int64_t>::max();
    for (size_t i = 0; i < _media_objects.size(); i++)
    {
        for (int j = 0; j < _media_objects[i].video_streams(); j++)
        {
            int64_t d = _media_objects[i].video_duration(j);
            if (d < _duration)
            {
                _duration = d;
            }
        }
        for (int j = 0; j < _media_objects[i].audio_streams(); j++)
        {
            int64_t d = _media_objects[i].audio_duration(j);
            if (d < _duration)
            {
                _duration = d;
            }
        }
        for (int j = 0; j < _media_objects[i].subtitle_streams(); j++)
        {
//             int64_t d = _media_objects[i].subtitle_duration(j);
//             if (d < _duration)
//             {
//                 _duration = d;
//             }
        }
    }
 
    // Skip advertisement in 3dtv.at movies. Only works for single media objects.
    try { _initial_skip = str::to<int64_t>(tag_value("StereoscopicSkip")); } catch (...) { }

    // Find stereo layout and set active video stream(s)
    _supports_stereo_layout_separate = false;
    if (video_streams() == 2)
    {
        int o0, o1, v0, v1;
        get_video_stream(0, o0, v0);
        get_video_stream(1, o1, v1);
        video_frame t0 = _media_objects[o0].video_frame_template(v0);
        video_frame t1 = _media_objects[o1].video_frame_template(v1);
        if (t0.width == t1.width
                && t0.height == t1.height
                && (t0.aspect_ratio <= t1.aspect_ratio && t0.aspect_ratio >= t1.aspect_ratio)
                && t0.layout == t1.layout
                && t0.color_space == t1.color_space
                && t0.value_range == t1.value_range
                && t0.chroma_location == t1.chroma_location)
        {
            _supports_stereo_layout_separate = true;
        }
    }
    if (_supports_stereo_layout_separate)
    {
        _active_video_stream = 0;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        _video_frame = _media_objects[o].video_frame_template(s);
        _video_frame.stereo_layout = video_frame::separate;
    }
    else if (video_streams() > 0)
    {
        _active_video_stream = 0;
        int o, s;
        get_video_stream(_active_video_stream, o, s);
        _video_frame = _media_objects[o].video_frame_template(s);
    }
    else
    {
        _active_video_stream = -1;
    }
    if (_active_video_stream >= 0)
    {
        select_video_stream(_active_video_stream);
    }

    // Set active audio stream
    _active_audio_stream = (audio_streams() > 0 ? 0 : -1);
    if (_active_audio_stream >= 0)
    {
        int o, s;
        get_audio_stream(_active_audio_stream, o, s);
        _audio_blob = _media_objects[o].audio_blob_template(s);
        select_audio_stream(_active_audio_stream);
    }

    // Set active subtitle stream
    _active_subtitle_stream = -1;       // no subtitles by default

    // Print summary
    msg::inf("Input:");
    for (int i = 0; i < video_streams(); i++)
    {
        int o, s;
        get_video_stream(i, o, s);
        msg::inf("    Video %s: %s", video_stream_name(i).c_str(),
                _media_objects[o].video_frame_template(s).format_name().c_str());
    }
    if (video_streams() == 0)
    {
        msg::inf("    No video.");
    }
    for (int i = 0; i < audio_streams(); i++)
    {
        int o, s;
        get_audio_stream(i, o, s);
        msg::inf("    Audio %s: %s", audio_stream_name(i).c_str(), 
                _media_objects[o].audio_blob_template(s).format_name().c_str());
    }
    if (audio_streams() == 0)
    {
        msg::inf("    No audio.");
    }
    for (int i = 0; i < subtitle_streams(); i++)
    {
        int o, s;
        get_subtitle_stream(i, o, s);
        msg::inf("    Subtitle %s: %s", subtitle_stream_name(i).c_str(), 
                _media_objects[o].subtitle_box_template(s).format_name().c_str());
    }
    if (subtitle_streams() == 0)
    {
        msg::inf("    No subtitles.");
    }
    msg::inf("    Duration: %g seconds", duration() / 1e6f);
    if (video_streams() > 0)
    {
        msg::inf("    Stereo layout: %s", video_frame::stereo_layout_to_string(
                    video_frame_template().stereo_layout, video_frame_template().stereo_layout_swap).c_str());
    }
}