Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/lib/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 10 kB image not shown  

Quelle  media_track.c   Sprache: C

 

/*****************************************************************************
 * media_track.c: Libvlc API media track
 *****************************************************************************
 * Copyright (C) 2020 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <assert.h>
#include <errno.h>
#include <stdckdint.h>

#include <vlc/libvlc.h>
#include <vlc/libvlc_picture.h>
#include <vlc/libvlc_media.h>

#include "libvlc_internal.h"
#include "media_internal.h"

struct libvlc_media_tracklist_t
{
    size_t count;
    libvlc_media_trackpriv_t *tracks[];
};

void
libvlc_media_trackpriv_from_es( libvlc_media_trackpriv_t *trackpriv,
                                const es_format_t *es  )
{
    libvlc_media_track_t *track = &trackpriv->t;

    track->i_codec = es->i_codec;
    track->i_original_fourcc = es->i_original_fourcc;
    track->i_id = es->i_id;

    track->i_profile = es->i_profile;
    track->i_level = es->i_level;

    track->i_bitrate = es->i_bitrate;
    track->psz_language = es->psz_language != NULL ? strdup(es->psz_language) : NULL;
    track->psz_description = es->psz_description != NULL ? strdup(es->psz_description) : NULL;
    track->psz_id = NULL;
    track->id_stable = false;
    track->psz_name = NULL;
    track->selected = false;

    switch( es->i_cat )
    {
    case UNKNOWN_ES:
    default:
        track->i_type = libvlc_track_unknown;
        break;
    case VIDEO_ES:
        track->u.video = &trackpriv->video;
        track->i_type = libvlc_track_video;
        track->u.video->i_height = es->video.i_visible_height;
        track->u.video->i_width = es->video.i_visible_width;
        track->u.video->i_sar_num = es->video.i_sar_num;
        track->u.video->i_sar_den = es->video.i_sar_den;
        track->u.video->i_frame_rate_num = es->video.i_frame_rate;
        track->u.video->i_frame_rate_den = es->video.i_frame_rate_base;

        assert( es->video.orientation >= ORIENT_TOP_LEFT &&
                es->video.orientation <= ORIENT_RIGHT_BOTTOM );
        track->u.video->i_orientation = (int) es->video.orientation;

        assert( ( es->video.projection_mode >= PROJECTION_MODE_RECTANGULAR &&
                es->video.projection_mode <= PROJECTION_MODE_EQUIRECTANGULAR ) ||
                ( es->video.projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD ) );
        track->u.video->i_projection = (int) es->video.projection_mode;

        vlc_viewpoint_to_euler(&es->video.pose,
                               &track->u.video->pose.f_yaw,
                               &track->u.video->pose.f_pitch,
                               &track->u.video->pose.f_roll);
        track->u.video->pose.f_field_of_view = es->video.pose.fov;

        assert( es->video.multiview_mode >= MULTIVIEW_2D &&
                es->video.multiview_mode <= MULTIVIEW_STEREO_CHECKERBOARD );
        track->u.video->i_multiview = (int) es->video.multiview_mode;
        break;
    case AUDIO_ES:
        track->u.audio = &trackpriv->audio;
        track->i_type = libvlc_track_audio;
        track->u.audio->i_channels = es->audio.i_channels;
        track->u.audio->i_rate = es->audio.i_rate;
        break;
    case SPU_ES:
        track->u.subtitle = &trackpriv->subtitle;
        track->i_type = libvlc_track_text;
        track->u.subtitle->psz_encoding = es->subs.psz_encoding != NULL ?
                                        strdup(es->subs.psz_encoding) : NULL;
        break;
    }
}

static libvlc_media_trackpriv_t *
libvlc_media_trackpriv_new( void )
{
    libvlc_media_trackpriv_t *trackpriv =
        malloc( sizeof (libvlc_media_trackpriv_t ) );

    if( trackpriv == NULL )
        return NULL;

    trackpriv->es_id = NULL;
    trackpriv->item_str_id = NULL;
    vlc_atomic_rc_init( &trackpriv->rc );
    return trackpriv;
}

static void libvlc_media_track_clean( libvlc_media_track_t *track )
{
    free( track->psz_language );
    free( track->psz_description );
    free( track->psz_name );
    switch( track->i_type )
    {
    case libvlc_track_audio:
        break;
    case libvlc_track_video:
        break;
    case libvlc_track_text:
        free( track->u.subtitle->psz_encoding );
        break;
    case libvlc_track_unknown:
    default:
        break;
    }
}

libvlc_media_track_t *
libvlc_media_track_retain( libvlc_media_track_t *track )
{
    libvlc_media_trackpriv_t *trackpriv =
        container_of( track, libvlc_media_trackpriv_t, t );
    vlc_atomic_rc_inc( &trackpriv->rc );
    return track;
}

void
libvlc_media_track_release( libvlc_media_track_t *track )
{
    libvlc_media_trackpriv_t *trackpriv =
        container_of( track, libvlc_media_trackpriv_t, t );

    if( vlc_atomic_rc_dec( &trackpriv->rc ) )
    {
        libvlc_media_track_clean( track );
        if( trackpriv->es_id )
            vlc_es_id_Release( trackpriv->es_id );
        free( trackpriv->item_str_id );
        free( trackpriv );
    }
}

static libvlc_media_tracklist_t *
libvlc_media_tracklist_alloc( size_t count )
{
    size_t size;
    if (ckd_mul(&size, count, sizeof (libvlc_media_trackpriv_t *)) ||
        ckd_add(&size, size, sizeof (libvlc_media_tracklist_t)))
        return NULL;

    libvlc_media_tracklist_t *list = malloc( size );
    if( list == NULL )
        return NULL;

    list->count = 0;
    return list;
}

libvlc_media_tracklist_t *
libvlc_media_tracklist_from_item( input_item_t *item, libvlc_track_type_t type )
{
    size_t count = 0;
    const enum es_format_category_e cat = libvlc_track_type_to_escat( type );

    for( size_t i = 0; i < item->es_vec.size; ++i )
    {
        const es_format_t *es_fmt = &item->es_vec.data[i].es;
        if( es_fmt->i_cat == cat )
            count++;
    }

    libvlc_media_tracklist_t *list = libvlc_media_tracklist_alloc( count );

    if( count == 0 || list == NULL )
        return list;

    for( size_t i = 0; i < item->es_vec.size; ++i )
    {
        const struct input_item_es *item_es = &item->es_vec.data[i];
        const es_format_t *es_fmt = &item_es->es;
        if( es_fmt->i_cat == cat )
        {
            libvlc_media_trackpriv_t *trackpriv = libvlc_media_trackpriv_new();
            if( trackpriv == NULL )
            {
                libvlc_media_tracklist_delete( list );
                return NULL;
            }
            list->tracks[list->count++] = trackpriv;
            libvlc_media_trackpriv_from_es( trackpriv, es_fmt );

            trackpriv->item_str_id = strdup( item_es->id );
            if( trackpriv->item_str_id == NULL )
            {
                libvlc_media_tracklist_delete( list );
                return NULL;
            }
            trackpriv->t.psz_id = trackpriv->item_str_id;
            trackpriv->t.id_stable = item_es->id_stable;
        }
    }

    return list;
}

static void
libvlc_media_trackpriv_from_player_track( libvlc_media_trackpriv_t *trackpriv,
                                          const struct vlc_player_track *track )
{
    libvlc_media_trackpriv_from_es( trackpriv, &track->fmt );

    trackpriv->es_id = vlc_es_id_Hold( track->es_id );

    trackpriv->t.psz_id = vlc_es_id_GetStrId( track->es_id );
    trackpriv->t.id_stable = vlc_es_id_IsStrIdStable( track->es_id );
    trackpriv->t.psz_name = strdup( track->name );
    trackpriv->t.selected = track->selected;
}

libvlc_media_track_t *
libvlc_media_track_create_from_player_track( const struct vlc_player_track *track )
{
    libvlc_media_trackpriv_t *trackpriv = libvlc_media_trackpriv_new();
    if( trackpriv == NULL )
        return NULL;
    libvlc_media_trackpriv_from_player_track( trackpriv, track );
    return &trackpriv->t;
}

libvlc_media_tracklist_t *
libvlc_media_tracklist_from_player( vlc_player_t *player,
                                    libvlc_track_type_t type, bool selected )
{
    const enum es_format_category_e cat = libvlc_track_type_to_escat( type );

    const size_t total_count = vlc_player_GetTrackCount( player, cat );
    size_t count = 0;

    if( selected )
    {
        size_t selected_count = 0;
        for( size_t i = 0; i < total_count; ++i )
        {
            const struct vlc_player_track *track =
                vlc_player_GetTrackAt( player, cat, i );
            assert( track );
            if( track->selected )
                selected_count++;
        }
        count = selected_count;
    }
    else
        count = total_count;

    libvlc_media_tracklist_t *list = libvlc_media_tracklist_alloc( count );

    if( count == 0 || list == NULL )
        return list;

    for( size_t i = 0; i < total_count; ++i )
    {
        const struct vlc_player_track *track =
            vlc_player_GetTrackAt( player, cat, i );
        assert( track );

        if( selected && !track->selected )
            continue;

        libvlc_media_trackpriv_t *trackpriv = libvlc_media_trackpriv_new();
        if( trackpriv == NULL )
        {
            libvlc_media_tracklist_delete( list );
            return NULL;
        }
        list->tracks[list->count++] = trackpriv;
        libvlc_media_trackpriv_from_player_track( trackpriv, track );
    }

    return list;
}

size_t
libvlc_media_tracklist_count( const libvlc_media_tracklist_t *list )
{
    return list->count;
}

libvlc_media_track_t *
libvlc_media_tracklist_at( libvlc_media_tracklist_t *list, size_t idx )
{
    assert( idx < list->count );
    return &list->tracks[idx]->t;
}

void
libvlc_media_tracklist_delete( libvlc_media_tracklist_t *list )
{
    for( size_t i = 0; i < list->count; ++i )
    {
        libvlc_media_trackpriv_t *trackpriv = list->tracks[i];
        libvlc_media_track_release( &trackpriv->t );
    }
    free( list );
}

Messung
CHZG
839710093

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.