video.c 20.9 KB
Newer Older
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
1 2 3 4 5
/*****************************************************************************
 * video.c: libvlc new API video functions
 *****************************************************************************
 * Copyright (C) 2005 the VideoLAN team
 *
6
 * $Id$
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * Authors: Cl�ent Stenac <zorglub@videolan.org>
 *          Filippo Carone <littlejohn@videolan.org>
 *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
 *          Damien Fouilleul <damienf a_t videolan dot org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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.
 *****************************************************************************/

28 29
#include "libvlc_internal.h"

Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
30 31 32 33 34
#include <vlc/libvlc.h>
#include <vlc_input.h>
#include <vlc_vout.h>

/*
35
 * Remember to release the returned vout_thread_t.
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
36
 */
37
static vout_thread_t *GetVout( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
38 39 40 41 42 43 44
                               libvlc_exception_t *p_exception )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_exception );
    vout_thread_t *p_vout = NULL;

    if( p_input_thread )
    {
45
        p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
46 47 48 49 50 51 52 53 54 55 56 57 58
        if( !p_vout )
        {
            libvlc_exception_raise( p_exception, "No active video output" );
        }
        vlc_object_release( p_input_thread );
    }
    return p_vout;
}

/**********************************************************************
 * Exported functions
 **********************************************************************/

59
void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
60 61 62
                            libvlc_exception_t *p_e )
{
    /* We only work on the first vout */
63
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
64 65

    /* GetVout will raise the exception for us */
66
    if( !p_vout ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
67

68
    var_SetBool( p_vout, "fullscreen", b_fullscreen );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
69

70
    vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
71 72
}

73
int libvlc_get_fullscreen( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
74 75 76
                            libvlc_exception_t *p_e )
{
    /* We only work on the first vout */
77 78
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    int i_ret;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
79 80

    /* GetVout will raise the exception for us */
81
    if( !p_vout ) return 0;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
82

83
    i_ret = var_GetBool( p_vout, "fullscreen" );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
84

85
    vlc_object_release( p_vout );
86

87
    return i_ret;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
88 89
}

90
void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
91 92 93
                               libvlc_exception_t *p_e )
{
    /* We only work on the first vout */
94 95
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    bool ret;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
96 97

    /* GetVout will raise the exception for us */
98
    if( !p_vout ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
99

100 101
    ret = var_GetBool( p_vout, "fullscreen" );
    var_SetBool( p_vout, "fullscreen", !ret );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
102

103
    vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
104 105 106
}

void
107
libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, char *psz_filepath,
108
        unsigned int i_width, unsigned int i_height, libvlc_exception_t *p_e )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
109 110 111 112 113
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    input_thread_t *p_input_thread;

    /* GetVout will raise the exception for us */
114
    if( !p_vout ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
115 116 117 118 119 120 121

    if( !psz_filepath )
    {
        libvlc_exception_raise( p_e, "filepath is null" );
        return;
    }

122 123
    var_SetInteger( p_vout, "snapshot-width", i_width );
    var_SetInteger( p_vout, "snapshot-height", i_height );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
124

125 126
    p_input_thread = p_mi->p_input_thread;
    if( !p_mi->p_input_thread )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
127 128 129 130 131 132 133 134 135 136 137 138
    {
        libvlc_exception_raise( p_e, "Input does not exist" );
        return;
    }

    var_SetString( p_vout, "snapshot-path", psz_filepath );
    var_SetString( p_vout, "snapshot-format", "png" );

    vout_Control( p_vout, VOUT_SNAPSHOT );
    vlc_object_release( p_vout );
}

139
int libvlc_video_get_height( libvlc_media_player_t *p_mi,
140
                             libvlc_exception_t *p_e )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
141
{
142 143
    int height;

144
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
145 146 147
    if( !p_vout ) return 0;

    height = p_vout->i_window_height;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
148

149
    vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
150

151
    return height;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
152 153
}

154
int libvlc_video_get_width( libvlc_media_player_t *p_mi,
155
                            libvlc_exception_t *p_e )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
156
{
157 158
    int width;

159
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
160 161 162
    if( !p_vout ) return 0;

    width = p_vout->i_window_width;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
163

164
    vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
165

166
    return width;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
167 168
}

169
int libvlc_media_player_has_vout( libvlc_media_player_t *p_mi,
170
                                     libvlc_exception_t *p_e )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
171 172
{
    input_thread_t *p_input_thread = libvlc_get_input_thread(p_mi, p_e);
173
    bool has_vout = false;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
174 175 176 177 178 179 180 181

    if( p_input_thread )
    {
        vout_thread_t *p_vout;

        p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
        if( p_vout )
        {
182
            has_vout = true;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
183 184 185 186 187 188 189
            vlc_object_release( p_vout );
        }
        vlc_object_release( p_input_thread );
    }
    return has_vout;
}

190
int libvlc_video_reparent( libvlc_media_player_t *p_mi, libvlc_drawable_t d,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
191 192 193 194 195 196 197 198 199 200 201 202
                           libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );

    if( p_vout )
    {
        vout_Control( p_vout , VOUT_REPARENT, d);
        vlc_object_release( p_vout );
    }
    return 0;
}

203
void libvlc_video_resize( libvlc_media_player_t *p_mi, int width, int height, libvlc_exception_t *p_e )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
204 205 206 207 208 209 210 211 212
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    if( p_vout )
    {
        vout_Control( p_vout, VOUT_SET_SIZE, width, height );
        vlc_object_release( p_vout );
    }
}

213
void libvlc_video_redraw_rectangle( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
                           const libvlc_rectangle_t *area,
                           libvlc_exception_t *p_e )
{
    if( (NULL != area)
     && ((area->bottom - area->top) > 0)
     && ((area->right - area->left) > 0) )
    {
        vout_thread_t *p_vout = GetVout( p_mi, p_e );
        if( p_vout )
        {
            /* tell running vout to redraw area */
            vout_Control( p_vout , VOUT_REDRAW_RECT,
                               area->top, area->left, area->bottom, area->right );
            vlc_object_release( p_vout );
        }
    }
}

/* global video settings */

234
/* Deprecated use libvlc_media_player_set_drawable() */
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
235 236 237 238 239 240
void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d,
                              libvlc_exception_t *p_e )
{
    /* set as default for future vout instances */
    var_SetInteger(p_instance->p_libvlc_int, "drawable", (int)d);

241 242
    libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
    if( p_mi )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
243
    {
244
        libvlc_media_player_set_drawable( p_mi, d, p_e );
245
        libvlc_media_player_release(p_mi);
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
246 247 248
    }
}

249
/* Deprecated use libvlc_media_player_get_drawable() */
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
250 251
libvlc_drawable_t libvlc_video_get_parent( libvlc_instance_t *p_instance, libvlc_exception_t *p_e )
{
252 253
    VLC_UNUSED(p_e);

Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
254
    libvlc_drawable_t result;
255

Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
256
    result = var_GetInteger( p_instance->p_libvlc_int, "drawable" );
257

Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
258 259 260 261 262 263 264 265 266 267 268
    return result;
}


void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height,
                           libvlc_exception_t *p_e )
{
    /* set as default for future vout instances */
    config_PutInt(p_instance->p_libvlc_int, "width", width);
    config_PutInt(p_instance->p_libvlc_int, "height", height);

269 270
    libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
    if( p_mi )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
271
    {
272 273
        vout_thread_t *p_vout = GetVout( p_mi, p_e );
        if( p_vout )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
274
        {
275 276 277
            /* tell running vout to re-size */
            vout_Control( p_vout , VOUT_SET_SIZE, width, height);
            vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
278
        }
279
        libvlc_media_player_release(p_mi);
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
280 281 282 283 284 285 286
    }
}

void libvlc_video_set_viewport( libvlc_instance_t *p_instance,
                            const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip,
                           libvlc_exception_t *p_e )
{
287
    if( !view )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
288 289
    {
        libvlc_exception_raise( p_e, "viewport is NULL" );
290
        return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
291 292 293
    }

    /* if clip is NULL, then use view rectangle as clip */
294
    if( !clip )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
295 296 297 298 299 300 301 302 303 304 305 306
        clip = view;

    /* set as default for future vout instances */
    var_SetInteger( p_instance->p_libvlc_int, "drawable-view-top", view->top );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-view-left", view->left );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-view-bottom", view->bottom );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-view-right", view->right );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-top", clip->top );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-left", clip->left );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-bottom", clip->bottom );
    var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-right", clip->right );

307 308
    libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
    if( p_mi )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
309
    {
310 311
        vout_thread_t *p_vout = GetVout( p_mi, p_e );
        if( p_vout )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
312
        {
313 314 315 316 317
            /* change viewport for running vout */
            vout_Control( p_vout , VOUT_SET_VIEWPORT,
                               view->top, view->left, view->bottom, view->right,
                               clip->top, clip->left, clip->bottom, clip->right );
            vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
318
        }
319
        libvlc_media_player_release(p_mi);
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
320 321 322
    }
}

323
char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
324 325 326 327 328
                                     libvlc_exception_t *p_e )
{
    char *psz_aspect = 0;
    vout_thread_t *p_vout = GetVout( p_mi, p_e );

329
    if( !p_vout ) return 0;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
330

331
    psz_aspect = var_GetNonEmptyString( p_vout, "aspect-ratio" );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
332
    vlc_object_release( p_vout );
333
    return psz_aspect ? psz_aspect : strdup("");
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
334 335
}

336
void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
337 338 339 340 341
                                    char *psz_aspect, libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    int i_ret = -1;

342
    if( !p_vout ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
343 344 345 346 347 348 349 350 351

    i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
    if( i_ret )
        libvlc_exception_raise( p_e,
                        "Unexpected error while setting aspect-ratio value" );

    vlc_object_release( p_vout );
}

352
int libvlc_video_get_spu( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
353 354 355 356 357 358 359 360 361
                          libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;
    vlc_value_t val;
    int i_spu = -1;
    int i_ret = -1;
    int i;

362
    if( !p_input_thread ) return -1;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385

    i_ret = var_Get( p_input_thread, "spu-es", &val );
    if( i_ret < 0 )
    {
        libvlc_exception_raise( p_e, "Getting subtitle information failed" );
        vlc_object_release( p_input_thread );
        return i_ret;
    }

    var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
    for( i = 0; i < val_list.p_list->i_count; i++ )
    {
        vlc_value_t spu_val = val_list.p_list->p_values[i];
        if( val.i_int == spu_val.i_int )
        {
            i_spu = i;
            break;
        }
    }
    vlc_object_release( p_input_thread );
    return i_spu;
}

386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
int libvlc_video_get_spu_count( libvlc_media_player_t *p_mi,
                                libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;

    if( !p_input_thread )
        return -1;

    var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
    vlc_object_release( p_input_thread );
    return val_list.p_list->i_count;
}

libvlc_track_description_t *
        libvlc_video_get_spu_description( libvlc_media_player_t *p_mi,
                                          libvlc_exception_t *p_e )
{
    return libvlc_get_track_description( p_mi, "spu-es", p_e);
}

407
void libvlc_video_set_spu( libvlc_media_player_t *p_mi, int i_spu,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
408 409 410 411
                           libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;
412
    vlc_value_t newval;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
413 414
    int i_ret = -1;

415
    if( !p_input_thread ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
416 417

    var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
418
    if( (i_spu < 0) && (i_spu > val_list.p_list->i_count) )
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
419
    {
420 421 422 423 424 425 426 427 428 429
        libvlc_exception_raise( p_e, "Subtitle value out of range" );
        vlc_object_release( p_input_thread );
        return;
    }

    newval = val_list.p_list->p_values[i_spu];
    i_ret = var_Set( p_input_thread, "spu-es", newval );
    if( i_ret < 0 )
    {
        libvlc_exception_raise( p_e, "Setting subtitle value failed" );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
430 431 432 433
    }
    vlc_object_release( p_input_thread );
}

434 435 436 437 438 439 440 441 442
int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
                                    char *psz_subtitle,
                                    libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
    bool b_ret = false;

    if( p_input_thread )
    {
443
        if( !input_AddSubtitle( p_input_thread, psz_subtitle, true ) )
444 445 446 447 448 449
            b_ret = true;
        vlc_object_release( p_input_thread );
    }
    return b_ret;
}

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
libvlc_track_description_t *
        libvlc_video_get_title_description( libvlc_media_player_t *p_mi,
                                            libvlc_exception_t * p_e )
{
    return libvlc_get_track_description( p_mi, "title", p_e);
}

libvlc_track_description_t *
        libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
                                              int i_title,
                                              libvlc_exception_t *p_e )
{
    char psz_title[12];
    sprintf( psz_title,  "title %2i", i_title );
    return libvlc_get_track_description( p_mi, psz_title, p_e);
}

467
char *libvlc_video_get_crop_geometry( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
468 469 470 471 472
                                   libvlc_exception_t *p_e )
{
    char *psz_geometry = 0;
    vout_thread_t *p_vout = GetVout( p_mi, p_e );

473
    if( !p_vout ) return 0;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
474

475
    psz_geometry = var_GetNonEmptyString( p_vout, "crop" );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
476
    vlc_object_release( p_vout );
477
    return psz_geometry ? psz_geometry : strdup("");
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
478 479
}

480
void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
481 482 483 484 485
                                    char *psz_geometry, libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
    int i_ret = -1;

486
    if( !p_vout ) return;
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
487 488 489 490 491 492 493 494 495

    i_ret = var_SetString( p_vout, "crop", psz_geometry );
    if( i_ret )
        libvlc_exception_raise( p_e,
                        "Unexpected error while setting crop geometry" );

    vlc_object_release( p_vout );
}

496
int libvlc_video_get_teletext( libvlc_media_player_t *p_mi,
497 498 499
                               libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
500
    vlc_object_t *p_vbi;
501 502
    int i_ret = -1;

503
    if( !p_vout ) return i_ret;
504

505 506 507 508
    p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
                                                   FIND_ANYWHERE );
    if( p_vbi )
    {
509
        i_ret = var_GetInteger( p_vbi, "vbi-page" );
510 511 512
        vlc_object_release( p_vbi );
    }

513 514 515 516
    vlc_object_release( p_vout );
    return i_ret;
}

517
void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page,
518 519 520
                                libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
521
    vlc_object_t *p_vbi;
522
    int i_ret = -1;
523

524
    if( !p_vout ) return;
525

526 527 528 529 530 531
    p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
                                                   FIND_ANYWHERE );
    if( p_vbi )
    {
        i_ret = var_SetInteger( p_vbi, "vbi-page", i_page );
        vlc_object_release( p_vbi );
532 533 534
        if( i_ret )
            libvlc_exception_raise( p_e,
                            "Unexpected error while setting teletext page" );
535
    }
536 537 538
    vlc_object_release( p_vout );
}

539
void libvlc_toggle_teletext( libvlc_media_player_t *p_mi,
540 541
                             libvlc_exception_t *p_e )
{
542 543 544
    input_thread_t *p_input_thread;
    vlc_object_t *p_vbi;
    int i_ret;
545

546 547
    p_input_thread = libvlc_get_input_thread(p_mi, p_e);
    if( !p_input_thread ) return;
548

549 550 551 552 553 554
    p_vbi = (vlc_object_t *) vlc_object_find_name( p_input_thread, "zvbi",
                                                   FIND_ANYWHERE );
    if( p_vbi )
    {
        const int i_teletext_es = var_GetInteger( p_input_thread, "teletext-es" );
        const int i_spu_es = var_GetInteger( p_input_thread, "spu-es" );
555

556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
        if( (i_teletext_es >= 0) && (i_teletext_es == i_spu_es) )
        {
            int i_page = 100;

            i_page = var_GetInteger( p_vbi, "vbi-page" );
            i_page = (i_teletext_es >= 0) ? i_page : 0;

            i_ret = var_SetInteger( p_vbi, "vbi-page", i_page );
            if( i_ret )
                libvlc_exception_raise( p_e,
                                "Unexpected error while setting teletext page" );
        }
        else if( i_teletext_es >= 0 )
        {
            bool opaque = true;

            opaque = var_GetBool( p_vbi, "vbi-opaque" );
            i_ret = var_SetBool( p_vbi, "vbi-opaque", !opaque );
            if( i_ret )
                libvlc_exception_raise( p_e,
                                "Unexpected error while setting teletext transparency" );
        }
        vlc_object_release( p_vbi );
    }
    else
    {
        /* Teletext is not enabled yet, so enable it.
         * Only after it is enable it is possible to view teletext pages
         */
        const int i_teletext_es = var_GetInteger( p_input_thread, "teletext-es" );

        if( i_teletext_es >= 0 )
        {
            const int i_spu_es = var_GetInteger( p_input_thread, "spu-es" );

            if( i_teletext_es == i_spu_es )
                var_SetInteger( p_input_thread, "spu-es", -1 );
            else
                var_SetInteger( p_input_thread, "spu-es", i_teletext_es );
        }
    }
    vlc_object_release( p_input_thread );
598 599
}

600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
int libvlc_video_get_track_count( libvlc_media_player_t *p_mi,
                                  libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;

    if( !p_input_thread )
        return -1;

    var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
    vlc_object_release( p_input_thread );
    return val_list.p_list->i_count;
}

libvlc_track_description_t *
        libvlc_video_get_track_description( libvlc_media_player_t *p_mi,
                                            libvlc_exception_t *p_e )
{
    return libvlc_get_track_description( p_mi, "video-es", p_e);
}

int libvlc_video_get_track( libvlc_media_player_t *p_mi,
                            libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;
    vlc_value_t val;
    int i_track = -1;
    int i_ret = -1;
    int i;

    if( !p_input_thread )
        return -1;

    i_ret = var_Get( p_input_thread, "video-es", &val );
    if( i_ret < 0 )
    {
        libvlc_exception_raise( p_e, "Getting Video track information failed" );
        vlc_object_release( p_input_thread );
        return i_ret;
    }

    var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
    for( i = 0; i < val_list.p_list->i_count; i++ )
    {
        vlc_value_t track_val = val_list.p_list->p_values[i];
        if( track_val.i_int == val.i_int )
        {
            i_track = i;
            break;
       }
    }
    vlc_object_release( p_input_thread );
    return i_track;
}

void libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track,
                             libvlc_exception_t *p_e )
{
    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
    vlc_value_t val_list;
    int i_ret = -1;
    int i;

    if( !p_input_thread )
        return;

    var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
    for( i = 0; i < val_list.p_list->i_count; i++ )
    {
        vlc_value_t val = val_list.p_list->p_values[i];
        if( i_track == val.i_int )
        {
            i_ret = var_Set( p_input_thread, "audio-es", val );
            if( i_ret < 0 )
                libvlc_exception_raise( p_e, "Setting video track failed" );
            vlc_object_release( p_input_thread );
            return;
        }
    }
    libvlc_exception_raise( p_e, "Video track out of range" );
    vlc_object_release( p_input_thread );
}

684
int libvlc_video_destroy( libvlc_media_player_t *p_mi,
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
685 686 687
                          libvlc_exception_t *p_e )
{
    vout_thread_t *p_vout = GetVout( p_mi, p_e );
688
    vlc_object_detach( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
689
    vlc_object_release( p_vout );
690
    vlc_object_release( p_vout );
Pierre d'Herbemont's avatar
Pierre d'Herbemont committed
691 692 693

    return 0;
}