コード例 #1
0
ファイル: timecode.c プロジェクト: IAPark/vlc
static int Open (vlc_object_t *obj)
{
    demux_t *demux = (demux_t *)obj;
    demux_sys_t *sys = vlc_malloc(obj, sizeof (*sys));

    if (unlikely(sys == NULL))
        return VLC_ENOMEM;

    es_format_t fmt;
    es_format_Init (&fmt, SPU_ES, VLC_CODEC_ITU_T140);
    sys->es = es_out_Add (demux->out, &fmt);

    unsigned num, den;
    if (var_InheritURational (demux, &num, &den, "timecode-fps")
     || !num || !den)
    {
        msg_Err (demux, "invalid frame rate");
        return VLC_EGENERIC;
    }

    date_Init (&sys->date, num, den);
    date_Set (&sys->date, VLC_TS_0);
    sys->next_time = VLC_TS_INVALID;

    demux->p_sys = sys;
    demux->pf_demux   = Demux;
    demux->pf_control = Control;
    return VLC_SUCCESS;
}
コード例 #2
0
ファイル: decklink.cpp プロジェクト: chouquette/vlc
static es_format_t GetModeSettings(demux_t *demux, IDeckLinkDisplayMode *m)
{
    demux_sys_t *sys = demux->p_sys;
    uint32_t flags = 0;
    (void)GetFieldDominance(m->GetFieldDominance(), &flags);

    BMDTimeValue frame_duration, time_scale;
    if (m->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
        time_scale = 0;
        frame_duration = 1;
    }

    es_format_t video_fmt;
    vlc_fourcc_t chroma = sys->tenbits ? VLC_CODEC_I422_10L : VLC_CODEC_UYVY;
    es_format_Init(&video_fmt, VIDEO_ES, chroma);

    video_fmt.video.i_width = m->GetWidth();
    video_fmt.video.i_height = m->GetHeight();
    video_fmt.video.i_sar_num = 1;
    video_fmt.video.i_sar_den = 1;
    video_fmt.video.i_frame_rate = time_scale;
    video_fmt.video.i_frame_rate_base = frame_duration;
    video_fmt.i_bitrate = video_fmt.video.i_width * video_fmt.video.i_height * video_fmt.video.i_frame_rate * 2 * 8;

    unsigned aspect_num, aspect_den;
    if (!var_InheritURational(demux, &aspect_num, &aspect_den, "decklink-aspect-ratio") &&
         aspect_num > 0 && aspect_den > 0) {
        video_fmt.video.i_sar_num = aspect_num * video_fmt.video.i_height;
        video_fmt.video.i_sar_den = aspect_den * video_fmt.video.i_width;
    }

    sys->dominance_flags = flags;

    return video_fmt;
}
コード例 #3
0
ファイル: image.c プロジェクト: jomanmuk/vlc-2.2
static int Open(vlc_object_t *object)
{
    demux_t *demux = (demux_t*)object;

    /* Detect the image type */
    const image_format_t *img;

    const uint8_t *peek;
    int peek_size = 0;
    for (int i = 0; ; i++) {
        img = &formats[i];
        if (!img->codec)
            return VLC_EGENERIC;

        if (img->detect) {
            if (img->detect(demux->s))
                break;
        } else {
            if (peek_size < img->marker_size)
                peek_size = stream_Peek(demux->s, &peek, img->marker_size);
            if (peek_size >= img->marker_size &&
                !memcmp(peek, img->marker, img->marker_size))
                break;
        }
    }
    msg_Dbg(demux, "Detected image: %s",
            vlc_fourcc_GetDescription(VIDEO_ES, img->codec));

    if( img->codec == VLC_CODEC_MXPEG )
    {
        return VLC_EGENERIC; //let avformat demux this file
    }

    /* Load and if selected decode */
    es_format_t fmt;
    es_format_Init(&fmt, VIDEO_ES, img->codec);
    fmt.video.i_chroma = fmt.i_codec;

    block_t *data = Load(demux);
    if (data && var_InheritBool(demux, "image-decode")) {
        char *string = var_InheritString(demux, "image-chroma");
        vlc_fourcc_t chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, string);
        free(string);

        data = Decode(demux, &fmt.video, chroma, data);
        fmt.i_codec = fmt.video.i_chroma;
    }
    fmt.i_id    = var_InheritInteger(demux, "image-id");
    fmt.i_group = var_InheritInteger(demux, "image-group");
    if (var_InheritURational(demux,
                             &fmt.video.i_frame_rate,
                             &fmt.video.i_frame_rate_base,
                             "image-fps") ||
        fmt.video.i_frame_rate <= 0 || fmt.video.i_frame_rate_base <= 0) {
        msg_Err(demux, "Invalid frame rate, using 10/1 instead");
        fmt.video.i_frame_rate      = 10;
        fmt.video.i_frame_rate_base = 1;
    }

    /* If loadind failed, we still continue to avoid mis-detection
     * by other demuxers. */
    if (!data)
        msg_Err(demux, "Failed to load the image");

    /* */
    demux_sys_t *sys = malloc(sizeof(*sys));
    if (!sys) {
        if (data)
            block_Release(data);
        es_format_Clean(&fmt);
        return VLC_ENOMEM;
    }

    sys->data        = data;
    sys->es          = es_out_Add(demux->out, &fmt);
    sys->duration    = CLOCK_FREQ * var_InheritFloat(demux, "image-duration");
    sys->is_realtime = var_InheritBool(demux, "image-realtime");
    sys->pts_origin  = sys->is_realtime ? mdate() : 0;
    sys->pts_next    = VLC_TS_INVALID;
    date_Init(&sys->pts, fmt.video.i_frame_rate, fmt.video.i_frame_rate_base);
    date_Set(&sys->pts, 0);

    es_format_Clean(&fmt);

    demux->pf_demux   = Demux;
    demux->pf_control = Control;
    demux->p_sys      = sys;
    return VLC_SUCCESS;
}
コード例 #4
0
ファイル: rawvid.c プロジェクト: 0xheart0/vlc
/*****************************************************************************
 * Open: initializes raw DV demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    int i_width=-1, i_height=-1;
    unsigned u_fps_num, u_fps_den;
    vlc_fourcc_t i_chroma = 0;
    unsigned int i_sar_num;
    unsigned int i_sar_den;
    const struct preset_t *p_preset = NULL;
    const uint8_t *p_peek;
    bool b_y4m = false;

    if( stream_Peek( p_demux->s, &p_peek, 9 ) == 9 )
    {
        /* http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */
        if( !strncmp( (char *)p_peek, "YUV4MPEG2", 9 ) )
        {
            b_y4m = true;
            goto valid;
        }
    }

    if( !p_demux->b_force )
    {
        /* guess preset based on file extension */
        if( !p_demux->psz_file )
            return VLC_EGENERIC;

        const char *psz_ext = strrchr( p_demux->psz_file, '.' );
        if( !psz_ext )
            return VLC_EGENERIC;
        psz_ext++;

        for( unsigned i = 0; p_presets[i].psz_ext ; i++ )
        {
            if( !strcasecmp( psz_ext, p_presets[i].psz_ext ) )
            {
                p_preset = &p_presets[i];
                goto valid;
            }
        }
        return VLC_EGENERIC;
    }
valid:
    p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sys->b_y4m = b_y4m;

    /* guess the parameters based on the preset */
    if( p_preset )
    {
        i_width = p_preset->i_width;
        i_height = p_preset->i_height;
        u_fps_num = p_preset->u_fps_num;
        u_fps_den = p_preset->u_fps_den;
        i_sar_num = p_preset->u_ar_num * p_preset->i_height;
        i_sar_den = p_preset->u_ar_den * p_preset->i_width;
        i_chroma = p_preset->i_chroma;
    }

    /* override presets if yuv4mpeg2 */
    if( b_y4m )
    {
        /* The string should start with "YUV4MPEG2" */
        char *psz = stream_ReadLine( p_demux->s );
        char *psz_buf;
        int a = 1;
        int b = 1;

        if( unlikely(psz == NULL) )
            goto error;

        /* NB, it is not possible to handle interlaced here, since the
         * interlaced picture flags are in picture_t not block_t */

#define READ_FRAC( key, num, den ) do { \
        psz_buf = strstr( psz+9, key );\
        if( psz_buf )\
        {\
            char *end = strchr( psz_buf+1, ' ' );\
            char *sep;\
            if( end ) *end = '\0';\
            sep = strchr( psz_buf+1, ':' );\
            if( sep )\
            {\
                *sep = '\0';\
                den = atoi( sep+1 );\
            }\
            else\
            {\
                den = 1;\
            }\
            num = atoi( psz_buf+2 );\
            if( sep ) *sep = ':';\
            if( end ) *end = ' ';\
        } } while(0)
        READ_FRAC( " W", i_width, a );
        READ_FRAC( " H", i_height, a );
        READ_FRAC( " F", u_fps_num, u_fps_den );
        READ_FRAC( " A", a, b );
#undef READ_FRAC
        if( b != 0 )
        {
            i_sar_num = a;
            i_sar_den = b;
        }

        psz_buf = strstr( psz+9, " C" );
        if( psz_buf )
        {
            static const struct { const char *psz_name; vlc_fourcc_t i_fcc; } formats[] =
            {
                { "420jpeg",    VLC_CODEC_I420 },
                { "420paldv",   VLC_CODEC_I420 },
                { "420",        VLC_CODEC_I420 },
                { "422",        VLC_CODEC_I422 },
                { "444",        VLC_CODEC_I444 },
                { "mono",       VLC_CODEC_GREY },
                { NULL, 0 }
            };
            bool b_found = false;
            char *psz_end = strchr( psz_buf+1, ' ' );
            if( psz_end )
                *psz_end = '\0';
            psz_buf += 2;

            for( int i = 0; formats[i].psz_name != NULL; i++ )
            {
                if( !strncmp( psz_buf, formats[i].psz_name, strlen(formats[i].psz_name) ) )
                {
                    i_chroma = formats[i].i_fcc;
                    b_found = true;
                    break;
                }
            }
            if( !b_found )
                msg_Warn( p_demux, "Unknown YUV4MPEG2 chroma type \"%s\"", psz_buf );
            if( psz_end )
                *psz_end = ' ';
        }

        free( psz );
    }

    /* allow the user to override anything guessed from the input */
    int i_tmp;
    i_tmp = var_CreateGetInteger( p_demux, "rawvid-width" );
    if( i_tmp ) i_width = i_tmp;

    i_tmp = var_CreateGetInteger( p_demux, "rawvid-height" );
    if( i_tmp ) i_height = i_tmp;

    char *psz_tmp;
    psz_tmp = var_CreateGetNonEmptyString( p_demux, "rawvid-chroma" );
    if( psz_tmp )
    {
        if( strlen( psz_tmp ) != 4 )
        {
            msg_Err( p_demux, "Invalid fourcc format/chroma specification %s"
                     " expecting four characters eg, UYVY", psz_tmp );
            free( psz_tmp );
            goto error;
        }
        memcpy( &i_chroma, psz_tmp, 4 );
        msg_Dbg( p_demux, "Forcing chroma to 0x%.8x (%4.4s)", i_chroma, (char*)&i_chroma );
        free( psz_tmp );
    }

    if( var_InheritURational( p_demux, &u_fps_num, &u_fps_den, "rawvid-fps" ) )
    {
        u_fps_num = 0;
        u_fps_den = 1;
    }

    if( var_InheritURational( p_demux, &i_sar_num, &i_sar_den,
                              "rawvid-aspect-ratio" ) )
        i_sar_num = i_sar_den = 1;

    /* moan about anything wrong */
    if( i_width <= 0 || i_height <= 0 )
    {
        msg_Err( p_demux, "width and height must be strictly positive." );
        goto error;
    }

    if( !u_fps_num || !u_fps_den )
    {
        msg_Err( p_demux, "invalid or no framerate specified." );
        goto error;
    }

    if( i_chroma == 0 )
    {
        msg_Err( p_demux, "invalid or no chroma specified." );
        goto error;
    }

    /* fixup anything missing with sensible assumptions */
    if( i_sar_num <= 0 || i_sar_den <= 0 )
    {
        /* assume 1:1 sar */
        i_sar_num = 1;
        i_sar_den = 1;
    }

    es_format_Init( &p_sys->fmt_video, VIDEO_ES, i_chroma );
    video_format_Setup( &p_sys->fmt_video.video, i_chroma,
                        i_width, i_height, i_width, i_height,
                        i_sar_num, i_sar_den );

    vlc_ureduce( &p_sys->fmt_video.video.i_frame_rate,
                 &p_sys->fmt_video.video.i_frame_rate_base,
                 u_fps_num, u_fps_den, 0);
    date_Init( &p_sys->pcr, p_sys->fmt_video.video.i_frame_rate,
               p_sys->fmt_video.video.i_frame_rate_base );
    date_Set( &p_sys->pcr, 0 );

    if( !p_sys->fmt_video.video.i_bits_per_pixel )
    {
        msg_Err( p_demux, "Unsupported chroma 0x%.8x (%4.4s)", i_chroma,
                 (char*)&i_chroma );
        goto error;
    }
    p_sys->frame_size = i_width * i_height
                        * p_sys->fmt_video.video.i_bits_per_pixel / 8;
    p_sys->p_es_video = es_out_Add( p_demux->out, &p_sys->fmt_video );

    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    return VLC_SUCCESS;

error:
    stream_Seek( p_demux->s, 0 ); // Workaround, but y4m uses stream_ReadLines
    free( p_sys );
    return VLC_EGENERIC;
}
コード例 #5
0
ファイル: transcode.c プロジェクト: maniacs-m/vlc
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_stream_t     *p_stream = (sout_stream_t*)p_this;
    sout_stream_sys_t *p_sys;
    char              *psz_string;

    if( !p_stream->p_next )
    {
        msg_Err( p_stream, "cannot create chain" );
        return VLC_EGENERIC;
    }
    p_sys = calloc( 1, sizeof( *p_sys ) );
    p_sys->i_master_drift = 0;

    config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
                   p_stream->p_cfg );

    /* Audio transcoding parameters */
    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" );
    p_sys->psz_aenc = NULL;
    p_sys->p_audio_cfg = NULL;
    if( psz_string && *psz_string )
    {
        char *psz_next;
        psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg,
                                       psz_string );
        free( psz_next );
    }
    free( psz_string );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "acodec" );
    p_sys->i_acodec = 0;
    if( psz_string && *psz_string )
    {
        char fcc[5] = "    \0";
        memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) );
        p_sys->i_acodec = vlc_fourcc_GetCodecFromString( AUDIO_ES, fcc );
        msg_Dbg( p_stream, "Checking codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_acodec);
    }
    free( psz_string );

    p_sys->psz_alang = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "alang" );

    p_sys->i_abitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ab" );
    if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000;

    p_sys->i_sample_rate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "samplerate" );

    p_sys->i_channels = var_GetInteger( p_stream, SOUT_CFG_PREFIX "channels" );

    if( p_sys->i_acodec )
    {
        if( ( p_sys->i_acodec == VLC_CODEC_MP3 ||
              p_sys->i_acodec == VLC_CODEC_MP2 ||
              p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 )
        {
            msg_Warn( p_stream, "%d channels invalid for mp2/mp3, forcing to 2",
                      p_sys->i_channels );
            p_sys->i_channels = 2;
        }
        msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
                 (char *)&p_sys->i_acodec, p_sys->i_sample_rate,
                 p_sys->i_channels, p_sys->i_abitrate / 1000 );
    }

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "afilter" );
    if( psz_string && *psz_string )
        p_sys->psz_af = strdup( psz_string );
    else
        p_sys->psz_af = NULL;
    free( psz_string );

    /* Video transcoding parameters */
    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" );
    p_sys->psz_venc = NULL;
    p_sys->p_video_cfg = NULL;
    if( psz_string && *psz_string )
    {
        char *psz_next;
        psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg,
                                   psz_string );
        free( psz_next );
    }
    free( psz_string );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" );
    p_sys->i_vcodec = 0;
    if( psz_string && *psz_string )
    {
        char fcc[5] = "    \0";
        memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) );
        p_sys->i_vcodec = vlc_fourcc_GetCodecFromString( VIDEO_ES, fcc );
        msg_Dbg( p_stream, "Checking video codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_vcodec);
    }
    free( psz_string );

    p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" );
    if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000;

    p_sys->f_scale = var_GetFloat( p_stream, SOUT_CFG_PREFIX "scale" );

    p_sys->b_master_sync = var_InheritURational( p_stream, &p_sys->fps_num, &p_sys->fps_den, SOUT_CFG_PREFIX "fps" ) == VLC_SUCCESS;

    p_sys->i_width = var_GetInteger( p_stream, SOUT_CFG_PREFIX "width" );

    p_sys->i_height = var_GetInteger( p_stream, SOUT_CFG_PREFIX "height" );

    p_sys->i_maxwidth = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxwidth" );

    p_sys->i_maxheight = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxheight" );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vfilter" );
    if( psz_string && *psz_string )
        p_sys->psz_vf2 = strdup(psz_string );
    else
        p_sys->psz_vf2 = NULL;
    free( psz_string );

    p_sys->b_deinterlace = var_GetBool( p_stream, SOUT_CFG_PREFIX "deinterlace" );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "deinterlace-module" );
    p_sys->psz_deinterlace = NULL;
    p_sys->p_deinterlace_cfg = NULL;
    if( psz_string && *psz_string )
    {
        char *psz_next;
        psz_next = config_ChainCreate( &p_sys->psz_deinterlace,
                                   &p_sys->p_deinterlace_cfg,
                                   psz_string );
        free( psz_next );
    }
    free( psz_string );

    p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" );
    p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" );

    if( p_sys->i_vcodec )
    {
        msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s",
                 (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height,
                 p_sys->f_scale, p_sys->i_vbitrate / 1000 );
    }

    /* Disable hardware decoding by default (unlike normal playback) */
    psz_string = var_CreateGetString( p_stream, "avcodec-hw" );
    if( !strcasecmp( "any", psz_string ) )
        var_SetString( p_stream, "avcodec-hw", "none" );
    free( psz_string );

    /* Subpictures transcoding parameters */
    p_sys->p_spu = NULL;
    p_sys->p_spu_blend = NULL;
    p_sys->psz_senc = NULL;
    p_sys->p_spu_cfg = NULL;
    p_sys->i_scodec = 0;

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "senc" );
    if( psz_string && *psz_string )
    {
        char *psz_next;
        psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg,
                                   psz_string );
        free( psz_next );
    }
    free( psz_string );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "scodec" );
    if( psz_string && *psz_string )
    {
        char fcc[5] = "    \0";
        memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) );
        p_sys->i_scodec = vlc_fourcc_GetCodecFromString( SPU_ES, fcc );
        msg_Dbg( p_stream, "Checking spu codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_scodec);
    }
    free( psz_string );

    if( p_sys->i_scodec )
    {
        msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec );
    }

    p_sys->b_soverlay = var_GetBool( p_stream, SOUT_CFG_PREFIX "soverlay" );

    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" );
    if( psz_string && *psz_string )
    {
        p_sys->p_spu = spu_Create( p_stream );
        if( p_sys->p_spu )
            spu_ChangeSources( p_sys->p_spu, psz_string );
    }
    free( psz_string );

    /* OSD menu transcoding parameters */
    p_sys->psz_osdenc = NULL;
    p_sys->p_osd_cfg  = NULL;
    p_sys->i_osdcodec = 0;
    p_sys->b_osd   = var_GetBool( p_stream, SOUT_CFG_PREFIX "osd" );

    if( p_sys->b_osd )
    {
        char *psz_next;

        psz_next = config_ChainCreate( &p_sys->psz_osdenc,
                                   &p_sys->p_osd_cfg, "dvbsub" );
        free( psz_next );

        p_sys->i_osdcodec = VLC_CODEC_YUVP;

        msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );

        if( !p_sys->p_spu )
        {
            p_sys->p_spu = spu_Create( p_stream );
            if( p_sys->p_spu )
                spu_ChangeSources( p_sys->p_spu, "osdmenu" );
        }
        else
        {
            spu_ChangeSources( p_sys->p_spu, "osdmenu" );
        }
    }

    p_stream->pf_add    = Add;
    p_stream->pf_del    = Del;
    p_stream->pf_send   = Send;
    p_stream->p_sys     = p_sys;

    return VLC_SUCCESS;
}
コード例 #6
0
ファイル: imem.c プロジェクト: Italianmoose/Stereoscopic-VLC
/**
 * It opens an imem access_demux.
 */
static int OpenDemux(vlc_object_t *object)
{
    demux_t    *demux = (demux_t *)object;
    imem_sys_t *sys;

    if (OpenCommon(object, &sys, demux->psz_location))
        return VLC_EGENERIC;

    /* ES format */
    es_format_t fmt;
    es_format_Init(&fmt, UNKNOWN_ES, 0);

    fmt.i_id = var_InheritInteger(object, "imem-id");
    fmt.i_group = var_InheritInteger(object, "imem-group");

    char *tmp = var_InheritString(object, "imem-codec");
    if (tmp)
        fmt.i_codec = vlc_fourcc_GetCodecFromString(UNKNOWN_ES, tmp);
    free(tmp);

    const int cat = var_InheritInteger(object, "imem-cat");
    switch (cat) {
    case 1: {
        fmt.i_cat = AUDIO_ES;
        fmt.audio.i_channels = var_InheritInteger(object, "imem-channels");
        fmt.audio.i_rate = var_InheritInteger(object, "imem-samplerate");

        msg_Dbg(object, "Audio %4.4s %d channels %d Hz",
                (const char *)&fmt.i_codec,
                fmt.audio.i_channels, fmt.audio.i_rate);
        break;
    }
    case 2: {
        fmt.i_cat = VIDEO_ES;
        fmt.video.i_width  = var_InheritInteger(object, "imem-width");
        fmt.video.i_height = var_InheritInteger(object, "imem-height");
        unsigned num, den;
        if (!var_InheritURational(object, &num, &den, "imem-dar") && num > 0 && den > 0) {
            if (fmt.video.i_width > 0 && fmt.video.i_height > 0) {
                fmt.video.i_sar_num = num * fmt.video.i_height;
                fmt.video.i_sar_den = den * fmt.video.i_width;
            }
        }
        if (!var_InheritURational(object, &num, &den, "imem-fps") && num > 0 && den > 0) {
            fmt.video.i_frame_rate      = num;
            fmt.video.i_frame_rate_base = den;
        }

        msg_Dbg(object, "Video %4.4s %dx%d  SAR %d:%d frame rate %u/%u",
                (const char *)&fmt.i_codec,
                fmt.video.i_width, fmt.video.i_height,
                fmt.video.i_sar_num, fmt.video.i_sar_den,
                fmt.video.i_frame_rate, fmt.video.i_frame_rate_base);
        break;
    }
    case 3: {
        fmt.i_cat = SPU_ES;
        fmt.subs.spu.i_original_frame_width =
            var_InheritInteger(object, "imem-width");
        fmt.subs.spu.i_original_frame_height =
            var_InheritInteger(object, "imem-height");

        msg_Dbg(object, "Subtitle %4.4s",
                (const char *)&fmt.i_codec);
        break;
    }
    default:
        if (cat != 4)
            msg_Err(object, "Invalid ES category");
        es_format_Clean(&fmt);
        CloseCommon(sys);
        return VLC_EGENERIC;
    }

    fmt.psz_language = var_InheritString(object, "imem-language");

    sys->es = es_out_Add(demux->out, &fmt);
    es_format_Clean(&fmt);

    if (!sys->es) {
        CloseCommon(sys);
        return VLC_EGENERIC;
    }

    /* */
    demux->pf_control = ControlDemux;
    demux->pf_demux   = Demux;
    demux->p_sys      = (demux_sys_t*)sys;

    demux->info.i_update = 0;
    demux->info.i_title = 0;
    demux->info.i_seekpoint = 0;
    return VLC_SUCCESS;
}