Beispiel #1
0
void
parse_playlistpointer(FILE * file, uint32_t start, uint32_t pbegin,
		      uint32_t pend)
{
    uint16_t count = 0;
    fseek(file, start, SEEK_SET);
    fread(&count, sizeof(count), 1, file);

    printf("\t\t\tPlaylistpointer (0x%X, %d)\n", start, count);
    int i = 0;
    int playerror = 0;
    for (i = 0; i < count; i++) {
	uint32_t pointer;
	fseek(file, start + 2 + i * 4, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	if ((pointer < pbegin) || (pointer > pend)) {
	    printf("\t\t\t\tPlaylist (0x%X) = PlayError!\n ", pointer);
	    playerror = 1;
	} else {
	    parse_playlist(file, pointer);
	}
    }
    if (playerror == 1) {
	parse_playlist(file, start);
    }


}
Beispiel #2
0
static int applehttp_open(URLContext *h, const char *uri, int flags)
{
    AppleHTTPContext *s;
    int ret, i;
    const char *nested_url;

    if (flags & AVIO_FLAG_WRITE)
        return AVERROR(ENOSYS);

    s = av_mallocz(sizeof(AppleHTTPContext));
    if (!s)
        return AVERROR(ENOMEM);
    h->priv_data = s;
    h->is_streamed = 1;

    if (av_strstart(uri, "applehttp+", &nested_url)) {
        av_strlcpy(s->playlisturl, nested_url, sizeof(s->playlisturl));
    } else if (av_strstart(uri, "applehttp://", &nested_url)) {
        av_strlcpy(s->playlisturl, "http://", sizeof(s->playlisturl));
        av_strlcat(s->playlisturl, nested_url, sizeof(s->playlisturl));
    } else {
        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
        ret = AVERROR(EINVAL);
        goto fail;
    }

    if ((ret = parse_playlist(h, s->playlisturl)) < 0)
        goto fail;

    if (s->n_segments == 0 && s->n_variants > 0) {
        int max_bandwidth = 0, maxvar = -1;
        for (i = 0; i < s->n_variants; i++) {
            if (s->variants[i]->bandwidth > max_bandwidth || i == 0) {
                max_bandwidth = s->variants[i]->bandwidth;
                maxvar = i;
            }
        }
        av_strlcpy(s->playlisturl, s->variants[maxvar]->url,
                   sizeof(s->playlisturl));
        if ((ret = parse_playlist(h, s->playlisturl)) < 0)
            goto fail;
    }

    if (s->n_segments == 0) {
        av_log(h, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR(EIO);
        goto fail;
    }
    s->cur_seq_no = s->start_seq_no;
    if (!s->finished && s->n_segments >= 3)
        s->cur_seq_no = s->start_seq_no + s->n_segments - 3;

    return 0;

fail:
    av_free(s);
    return ret;
}
static int applehttp_read(URLContext *h, uint8_t *buf, int size)
{
    AppleHTTPContext *s = h->priv_data;
    const char *url;
    int ret;

start:
    if (s->seg_hd) {
        ret = ffurl_read(s->seg_hd, buf, size);
        if (ret > 0)
            return ret;
    }
    if (s->seg_hd) {
        ffurl_close(s->seg_hd);
        s->seg_hd = NULL;
        s->cur_seq_no++;
    }
retry:
    if (!s->finished) {
        int64_t now = av_gettime();
        if (now - s->last_load_time >= s->target_duration*1000000)
            if ((ret = parse_playlist(h, s->playlisturl)) < 0)
                return ret;
    }
    if (s->cur_seq_no < s->start_seq_no) {
        av_log(h, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlist\n",
               s->start_seq_no - s->cur_seq_no);
        s->cur_seq_no = s->start_seq_no;
    }
    if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
        if (s->finished)
            return AVERROR_EOF;
        while (av_gettime() - s->last_load_time < s->target_duration*1000000) {
            if (ff_check_interrupt(&h->interrupt_callback))
                return AVERROR_EXIT;
            usleep(100*1000);
        }
        goto retry;
    }
    url = s->segments[s->cur_seq_no - s->start_seq_no]->url,
    av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
    ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ,
                     &h->interrupt_callback, NULL);
    if (ret < 0) {
        if (ff_check_interrupt(&h->interrupt_callback))
            return AVERROR_EXIT;
        av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
        s->cur_seq_no++;
        goto retry;
    }
    goto start;
}
Beispiel #4
0
int expand(struct playlist * list) {
	struct hash p = { 0, NULL };
	char * response;

	assert(list != NULL);

	set(& p, "discovery", (!!enabled(DISCOVERY)) ? "true" : "false");
	response = rest("radio.getPlaylist", & p);

	if(response != NULL) {
		int result = parse_playlist(list, response);
		free(response);
		return result;
	}
	else {
		return 0;
	}
}
Beispiel #5
0
bool
parser_c::parse(mm_io_c *file) {
  try {
    file->setFilePointer(0);
    int64_t file_size = file->get_size();

    if ((4 * 5 > file_size) || (10 * 1024 * 1024 < file_size))
      throw mtx::mpls::exception(boost::format("File too small or too big: %1%") % file_size);

    auto content = file->read(4 * 5);
    m_bc         = std::make_shared<bit_reader_c>(content->get_buffer(), 4 * 5);
    parse_header();

    file->setFilePointer(0);

    content = file->read(file_size);
    m_bc    = std::make_shared<bit_reader_c>(content->get_buffer(), file_size);

    parse_playlist();
    parse_chapters();

    m_bc.reset();

    m_ok = true;

  } catch (mtx::mpls::exception &ex) {
    mxdebug_if(m_debug, boost::format("MPLS exception: %1%\n") % ex.what());
  } catch (mtx::mm_io::exception &ex) {
    mxdebug_if(m_debug, boost::format("I/O exception: %1%\n") % ex.what());
  }

  if (m_debug)
    dump();

  file->setFilePointer(0);

  return m_ok;
}
Beispiel #6
0
static int hls_read_header(AVFormatContext *s)
{
    HLSContext *c = s->priv_data;
    int ret = 0, i, j, stream_offset = 0;

    c->interrupt_callback = &s->interrupt_callback;

    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
        goto fail;

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained variants, parse each individual
     * variant playlist. */
    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
        for (i = 0; i < c->n_variants; i++) {
            struct variant *v = c->variants[i];
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
    if (c->variants[0]->finished) {
        int64_t duration = 0;
        for (i = 0; i < c->variants[0]->n_segments; i++)
            duration += c->variants[0]->segments[i]->duration;
        s->duration = duration * AV_TIME_BASE;
    }

    /* Open the demuxer for each variant */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
        AVInputFormat *in_fmt = NULL;
        char bitrate_str[20];
        AVProgram * program = NULL;
        if (v->n_segments == 0)
            continue;

        if (!(v->ctx = avformat_alloc_context())) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        v->index  = i;
        v->needed = 1;
        v->parent = s;

        /* If this is a live stream with more than 3 segments, start at the
         * third last segment. */
        v->cur_seq_no = v->start_seq_no;
        if (!v->finished && v->n_segments > 3)
            v->cur_seq_no = v->start_seq_no + v->n_segments - 3;

        v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
        ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
                          read_data, NULL, NULL);
        v->pb.seekable = 0;
        ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
                                    NULL, 0, 0);
        if (ret < 0) {
            /* Free the ctx - it isn't initialized properly at this point,
             * so avformat_close_input shouldn't be called. If
             * avformat_open_input fails below, it frees and zeros the
             * context, so it doesn't need any special treatment like this. */
            av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", v->segments[0]->url);
            avformat_free_context(v->ctx);
            v->ctx = NULL;
            goto fail;
        }
        v->ctx->pb       = &v->pb;
        ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
        if (ret < 0)
            goto fail;

        v->stream_offset = stream_offset;
        v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
        ret = avformat_find_stream_info(v->ctx, NULL);
        if (ret < 0)
            goto fail;
        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);

        /* Create new AVprogram for variant i */
        program = av_new_program(s, i);
        if ( !program )
            goto fail;
        av_dict_set(&program->metadata, "variant_bitrate", bitrate_str, 0);
        program->bitrate = v->bandwidth;

        /* Create new AVStreams for each stream in this variant */
        for (j = 0; j < v->ctx->nb_streams; j++) {
            AVStream *st = avformat_new_stream(s, NULL);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            ff_program_add_stream_index(s, i, st->index);
            st->id = i;
            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
            if (v->bandwidth)
                av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
                                 0);
        }
        stream_offset += v->ctx->nb_streams;
    }

    c->first_packet = 1;
    c->first_timestamp = AV_NOPTS_VALUE;
    c->seek_timestamp  = AV_NOPTS_VALUE;

    return 0;
fail:
    free_variant_list(c);
    return ret;
}
Beispiel #7
0
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
    struct variant *v = opaque;
    HLSContext *c = v->parent->priv_data;
    int ret, i;

restart:
    if (!v->input) {
        /* If this is a live stream and the reload interval has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        int64_t reload_interval = v->n_segments > 0 ?
                                  v->segments[v->n_segments - 1]->duration :
                                  v->target_duration;
        reload_interval *= 1000000;

reload:
        if (!v->finished &&
            av_gettime() - v->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                return ret;
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = v->target_duration * 500000LL;
        }
        if (v->cur_seq_no < v->start_seq_no) {
            av_log(NULL, AV_LOG_WARNING,
                   "skipping %d segments ahead, expired from playlists\n",
                   v->start_seq_no - v->cur_seq_no);
            v->cur_seq_no = v->start_seq_no;
        }
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
            if (v->finished)
                return AVERROR_EOF;
            while (av_gettime() - v->last_load_time < reload_interval) {
                if (ff_check_interrupt(c->interrupt_callback))
                    return AVERROR_EXIT;
                av_usleep(100*1000);
            }
            /* Enough time has elapsed since the last reload */
            goto reload;
        }

        ret = open_input(v);
        if (ret < 0)
            return ret;
    }
    ret = ffurl_read(v->input, buf, buf_size);
    if (ret > 0)
        return ret;
    ffurl_close(v->input);
    v->input = NULL;
    v->cur_seq_no++;

    c->end_of_segment = 1;
    c->cur_seq_no = v->cur_seq_no;

    if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
        v->needed = 0;
        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
             i++) {
            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
                v->needed = 1;
        }
    }
    if (!v->needed) {
        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
               v->index);
        return AVERROR_EOF;
    }
    goto restart;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    struct stat buf = { 0 };
    struct mntent *mnt = NULL;
    FILE *fp = NULL;
    gchar *uri;
    gint fileindex = 1;
    GError *error = NULL;
    GOptionContext *context;
    gint i;
    gdouble volume = 100.0;
    gchar *accelerator_keys;
    gchar **parse;
#ifdef GTK3_ENABLED
    GtkSettings *gtk_settings;
#endif
    int stat_result;

#ifndef OS_WIN32
    struct sigaction sa;
#endif
    gboolean playiter = FALSE;

#ifdef GIO_ENABLED
    GFile *file;
#endif

#ifdef ENABLE_NLS
    bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
    textdomain(GETTEXT_PACKAGE);
#endif

    playlist = 0;
    embed_window = 0;
    control_id = 0;
    window_x = 0;
    window_y = 0;
    last_window_width = 0;
    last_window_height = 0;
    showcontrols = 1;
    showsubtitles = TRUE;
    autostart = 1;
    videopresent = 0;
    disable_context_menu = FALSE;
    dontplaynext = FALSE;
    idledata = (IdleData *) g_new0(IdleData, 1);
    idledata->videopresent = FALSE;
    idledata->length = 0.0;
    idledata->device = NULL;
    idledata->cachepercent = -1.0;
    selection = NULL;
    path = NULL;
    js_state = STATE_UNDEFINED;
    control_instance = TRUE;
    playlistname = NULL;
    rpconsole = NULL;
    subtitle = NULL;
    tv_device = NULL;
    tv_driver = NULL;
    tv_width = 0;
    tv_height = 0;
    tv_fps = 0;
    ok_to_play = TRUE;
    alang = NULL;
    slang = NULL;
    metadata_codepage = NULL;
    playlistname = NULL;
    window_width = -1;
    window_height = -1;
    stored_window_width = -1;
    stored_window_height = -1;
    cache_size = 0;
    forcecache = FALSE;
    use_volume_option = FALSE;
    vertical_layout = FALSE;
    playlist_visible = FALSE;
    disable_fullscreen = FALSE;
    disable_framedrop = FALSE;
    softvol = FALSE;
    remember_softvol = FALSE;
    volume_softvol = -1;
    volume_gain = 0;
    subtitlefont = NULL;
    subtitle_codepage = NULL;
    subtitle_color = NULL;
    subtitle_outline = FALSE;
    subtitle_shadow = FALSE;
    subtitle_fuzziness = 0;
    disable_embeddedfonts = FALSE;
    quit_on_complete = FALSE;
    verbose = 0;
    reallyverbose = 0;
    embedding_disabled = FALSE;
    disable_pause_on_click = FALSE;
    disable_animation = FALSE;
    auto_hide_timeout = 3;
    mouse_over_controls = FALSE;
    use_mediakeys = TRUE;
    use_defaultpl = FALSE;
    mplayer_bin = NULL;
    mplayer_dvd_device = NULL;
    single_instance = FALSE;
    disable_deinterlace = TRUE;
    details_visible = FALSE;
    replace_and_play = FALSE;
    bring_to_front = FALSE;
    keep_on_top = FALSE;
    resize_on_new_media = FALSE;
    use_pausing_keep_force = FALSE;
    show_notification = TRUE;
    show_status_icon = TRUE;
    lang_group = NULL;
    audio_group = NULL;
    gpod_mount_point = NULL;
    load_tracks_from_gpod = FALSE;
    disable_cover_art_fetch = FALSE;
    fullscreen = 0;
    vo = NULL;
    data = NULL;
    max_data = NULL;
    details_table = NULL;
    large_buttons = FALSE;
    button_size = GTK_ICON_SIZE_BUTTON;
    lastguistate = -1;
    non_fs_height = 0;
    non_fs_width = 0;
    use_hw_audio = FALSE;
    start_second = 0;
    play_length = 0;
    save_loc = TRUE;
    use_xscrnsaver = FALSE;
    screensaver_disabled = FALSE;
    update_control_flag = FALSE;
    gchar *filename;
    skip_fixed_allocation_on_show = FALSE;
    skip_fixed_allocation_on_hide = FALSE;
    pref_volume = -1;
    use_mplayer2 = FALSE;
    enable_global_menu = FALSE;

#ifndef OS_WIN32
    sa.sa_handler = hup_handler;
    sigemptyset(&sa.sa_mask);
#ifdef SA_RESTART
    sa.sa_flags = SA_RESTART;   /* Restart functions if
                                   interrupted by handler */
#endif
#ifdef SIGINT
    if (sigaction(SIGINT, &sa, NULL) == -1)
        printf("SIGINT signal handler not installed\n");
#endif
#ifdef SIGHUP
    if (sigaction(SIGHUP, &sa, NULL) == -1)
        printf("SIGHUP signal handler not installed\n");
#endif
#ifdef SIGTERM
    if (sigaction(SIGTERM, &sa, NULL) == -1)
        printf("SIGTERM signal handler not installed\n");
#endif
#endif

    // call g_type_init or otherwise we can crash
    gtk_init(&argc, &argv);
    if (!g_thread_supported())
        g_thread_init(NULL);

    uri = g_strdup_printf("%s/gnome-mplayer/cover_art", g_get_user_config_dir());
    if (!g_file_test(uri, G_FILE_TEST_IS_DIR)) {
        g_mkdir_with_parents(uri, 0775);
    }
    g_free(uri);

    uri = g_strdup_printf("%s/gnome-mplayer/plugin", g_get_user_config_dir());
    if (!g_file_test(uri, G_FILE_TEST_IS_DIR)) {
        g_mkdir_with_parents(uri, 0775);
    }
    g_free(uri);
    uri = NULL;

    default_playlist = g_strdup_printf("file://%s/gnome-mplayer/default.pls", g_get_user_config_dir());
    safe_to_save_default_playlist = TRUE;

    gm_store = gm_pref_store_new("gnome-mplayer");
    gmp_store = gm_pref_store_new("gecko-mediaplayer");
    vo = gm_pref_store_get_string(gm_store, VO);
    audio_device.alsa_mixer = gm_pref_store_get_string(gm_store, ALSA_MIXER);
    use_hardware_codecs = gm_pref_store_get_boolean(gm_store, USE_HARDWARE_CODECS);
    use_crystalhd_codecs = gm_pref_store_get_boolean(gm_store, USE_CRYSTALHD_CODECS);
    osdlevel = gm_pref_store_get_int(gm_store, OSDLEVEL);
    pplevel = gm_pref_store_get_int(gm_store, PPLEVEL);
#ifndef HAVE_ASOUNDLIB
    volume = gm_pref_store_get_int(gm_store, VOLUME);
#endif
    audio_channels = gm_pref_store_get_int(gm_store, AUDIO_CHANNELS);
    use_hw_audio = gm_pref_store_get_boolean(gm_store, USE_HW_AUDIO);
    fullscreen = gm_pref_store_get_boolean(gm_store, FULLSCREEN);
    softvol = gm_pref_store_get_boolean(gm_store, SOFTVOL);
    remember_softvol = gm_pref_store_get_boolean(gm_store, REMEMBER_SOFTVOL);
    volume_softvol = gm_pref_store_get_float(gm_store, VOLUME_SOFTVOL);
    volume_gain = gm_pref_store_get_int(gm_store, VOLUME_GAIN);
    forcecache = gm_pref_store_get_boolean(gm_store, FORCECACHE);
    vertical_layout = gm_pref_store_get_boolean(gm_store, VERTICAL);
    playlist_visible = gm_pref_store_get_boolean(gm_store, SHOWPLAYLIST);
    details_visible = gm_pref_store_get_boolean(gm_store, SHOWDETAILS);
    show_notification = gm_pref_store_get_boolean(gm_store, SHOW_NOTIFICATION);
    show_status_icon = gm_pref_store_get_boolean(gm_store, SHOW_STATUS_ICON);
    showcontrols = gm_pref_store_get_boolean_with_default(gm_store, SHOW_CONTROLS, showcontrols);
    restore_controls = showcontrols;
    disable_deinterlace = gm_pref_store_get_boolean(gm_store, DISABLEDEINTERLACE);
    disable_framedrop = gm_pref_store_get_boolean(gm_store, DISABLEFRAMEDROP);
    disable_fullscreen = gm_pref_store_get_boolean(gm_store, DISABLEFULLSCREEN);
    disable_context_menu = gm_pref_store_get_boolean(gm_store, DISABLECONTEXTMENU);
    disable_ass = gm_pref_store_get_boolean(gm_store, DISABLEASS);
    disable_embeddedfonts = gm_pref_store_get_boolean(gm_store, DISABLEEMBEDDEDFONTS);
    disable_pause_on_click = gm_pref_store_get_boolean(gm_store, DISABLEPAUSEONCLICK);
    disable_animation = gm_pref_store_get_boolean(gm_store, DISABLEANIMATION);
    auto_hide_timeout = gm_pref_store_get_int_with_default(gm_store, AUTOHIDETIMEOUT, auto_hide_timeout);
    disable_cover_art_fetch = gm_pref_store_get_boolean(gm_store, DISABLE_COVER_ART_FETCH);
    use_mediakeys = gm_pref_store_get_boolean_with_default(gm_store, USE_MEDIAKEYS, use_mediakeys);
    use_defaultpl = gm_pref_store_get_boolean_with_default(gm_store, USE_DEFAULTPL, use_defaultpl);
    metadata_codepage = gm_pref_store_get_string(gm_store, METADATACODEPAGE);

    alang = gm_pref_store_get_string(gm_store, AUDIO_LANG);
    slang = gm_pref_store_get_string(gm_store, SUBTITLE_LANG);

    subtitlefont = gm_pref_store_get_string(gm_store, SUBTITLEFONT);
    subtitle_scale = gm_pref_store_get_float(gm_store, SUBTITLESCALE);
    if (subtitle_scale < 0.25) {
        subtitle_scale = 1.0;
    }
    subtitle_codepage = gm_pref_store_get_string(gm_store, SUBTITLECODEPAGE);
    subtitle_color = gm_pref_store_get_string(gm_store, SUBTITLECOLOR);
    subtitle_outline = gm_pref_store_get_boolean(gm_store, SUBTITLEOUTLINE);
    subtitle_shadow = gm_pref_store_get_boolean(gm_store, SUBTITLESHADOW);
    subtitle_margin = gm_pref_store_get_int(gm_store, SUBTITLE_MARGIN);
    subtitle_fuzziness = gm_pref_store_get_int(gm_store, SUBTITLE_FUZZINESS);
    showsubtitles = gm_pref_store_get_boolean_with_default(gm_store, SHOW_SUBTITLES, TRUE);

    qt_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_QT);
    real_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_REAL);
    wmp_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_WMP);
    dvx_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_DVX);
    midi_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_MIDI);
    embedding_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_EMBEDDING);
    disable_embedded_scaling = gm_pref_store_get_boolean(gmp_store, DISABLE_EMBEDDED_SCALING);
    if (embed_window == 0) {
        single_instance = gm_pref_store_get_boolean(gm_store, SINGLE_INSTANCE);
        if (single_instance) {
            replace_and_play = gm_pref_store_get_boolean(gm_store, REPLACE_AND_PLAY);
            bring_to_front = gm_pref_store_get_boolean(gm_store, BRING_TO_FRONT);
        }
    }
    enable_global_menu = gm_pref_store_get_boolean(gm_store, ENABLE_GLOBAL_MENU);
    if (!enable_global_menu) {
        enable_global_menu = (g_getenv("UBUNTU_MENUPROXY") == NULL ? FALSE : TRUE);
    }

    enable_nautilus_plugin = gm_pref_store_get_boolean_with_default(gm_store, ENABLE_NAUTILUS_PLUGIN, TRUE);

    mplayer_bin = gm_pref_store_get_string(gm_store, MPLAYER_BIN);
    if (mplayer_bin != NULL && !g_file_test(mplayer_bin, G_FILE_TEST_EXISTS)) {
        g_free(mplayer_bin);
        mplayer_bin = NULL;
    }
    mplayer_dvd_device = gm_pref_store_get_string(gm_store, MPLAYER_DVD_DEVICE);
    extraopts = gm_pref_store_get_string(gm_store, EXTRAOPTS);
    use_xscrnsaver = gm_pref_store_get_boolean_with_default(gm_store, USE_XSCRNSAVER, use_xscrnsaver);

    accelerator_keys = gm_pref_store_get_string(gm_store, ACCELERATOR_KEYS);
    accel_keys = g_strv_new(KEY_COUNT);
    accel_keys_description = g_strv_new(KEY_COUNT);
    if (accelerator_keys != NULL) {
        parse = g_strsplit(accelerator_keys, " ", KEY_COUNT);
        for (i = 0; i < g_strv_length(parse); i++) {
            accel_keys[i] = g_strdup(parse[i]);
        }
        g_free(accelerator_keys);
        g_strfreev(parse);
    }
    assign_default_keys();
    accel_keys_description[FILE_OPEN_LOCATION] = g_strdup(_("Open Location"));
    accel_keys_description[EDIT_SCREENSHOT] = g_strdup(_("Take Screenshot"));
    accel_keys_description[EDIT_PREFERENCES] = g_strdup(_("Preferences"));
    accel_keys_description[VIEW_PLAYLIST] = g_strdup(_("Playlist"));
    accel_keys_description[VIEW_INFO] = g_strdup(_("Media Info"));
    accel_keys_description[VIEW_DETAILS] = g_strdup(_("Details"));
    accel_keys_description[VIEW_METER] = g_strdup(_("Audio Meter"));
    accel_keys_description[VIEW_FULLSCREEN] = g_strdup(_("Full Screen"));
    accel_keys_description[VIEW_ASPECT] = g_strdup(_("Aspect"));
    accel_keys_description[VIEW_SUBTITLES] = g_strdup(_("Subtitles"));
    accel_keys_description[VIEW_DECREASE_SIZE] = g_strdup(_("Decrease Subtitle Size"));
    accel_keys_description[VIEW_INCREASE_SIZE] = g_strdup(_("Increase Subtitle Size"));
    accel_keys_description[VIEW_ANGLE] = g_strdup(_("Switch Angle"));
    accel_keys_description[VIEW_CONTROLS] = g_strdup(_("Controls"));

    remember_loc = gm_pref_store_get_boolean(gm_store, REMEMBER_LOC);
    loc_window_x = gm_pref_store_get_int(gm_store, WINDOW_X);
    loc_window_y = gm_pref_store_get_int(gm_store, WINDOW_Y);
    loc_window_height = gm_pref_store_get_int(gm_store, WINDOW_HEIGHT);
    loc_window_width = gm_pref_store_get_int(gm_store, WINDOW_WIDTH);
    loc_panel_position = gm_pref_store_get_int(gm_store, PANEL_POSITION);

    keep_on_top = gm_pref_store_get_boolean(gm_store, KEEP_ON_TOP);
    resize_on_new_media = gm_pref_store_get_boolean(gm_store, RESIZE_ON_NEW_MEDIA);
    mouse_wheel_changes_volume = gm_pref_store_get_boolean_with_default(gm_store, MOUSE_WHEEL_CHANGES_VOLUME, FALSE);

    audio_device_name = gm_pref_store_get_string(gm_store, AUDIO_DEVICE_NAME);
    audio_device.description = g_strdup(audio_device_name);

    context = g_option_context_new(_("[FILES...] - GNOME Media player based on MPlayer"));
#ifdef GTK2_12_ENABLED
    g_option_context_set_translation_domain(context, "UTF-8");
    g_option_context_set_translate_func(context, (GTranslateFunc) gettext, NULL, NULL);
#endif
    g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
    g_option_context_add_group(context, gtk_get_option_group(TRUE));
    g_option_context_parse(context, &argc, &argv, &error);
    g_option_context_free(context);

    if (new_instance)
        single_instance = FALSE;

    if (verbose == 0)
        verbose = gm_pref_store_get_int(gm_store, VERBOSE);

    if (reallyverbose)
        verbose = 2;

    if (verbose) {
        printf(_("GNOME MPlayer v%s\n"), VERSION);
        printf(_("gmtk v%s\n"), gmtk_version());
    }

    if (cache_size == 0)
        cache_size = gm_pref_store_get_int(gm_store, CACHE_SIZE);
    if (cache_size == 0)
        cache_size = 2000;

    plugin_audio_cache_size = gm_pref_store_get_int(gm_store, PLUGIN_AUDIO_CACHE_SIZE);
    if (plugin_audio_cache_size == 0)
        plugin_audio_cache_size = 2000;

    plugin_video_cache_size = gm_pref_store_get_int(gm_store, PLUGIN_VIDEO_CACHE_SIZE);
    if (plugin_video_cache_size == 0)
        plugin_video_cache_size = 2000;

    if (control_id != 0)
        cache_size = plugin_video_cache_size;

    gm_pref_store_free(gm_store);
    gm_pref_store_free(gmp_store);

    if (verbose && embed_window) {
        printf("embedded in window id 0x%x\n", embed_window);
    }

    if (verbose && single_instance) {
        printf("Running in single instance mode\n");
    }
#ifdef GIO_ENABLED
    if (verbose) {
        printf("Running with GIO support\n");
    }
#endif
#ifdef ENABLE_PANSCAN
    if (verbose) {
        printf("Running with panscan enabled (mplayer svn r29565 or higher required)\n");
    }
#endif
    if (verbose) {
        printf("Using audio device: %s\n", audio_device_name);
    }

    if (softvol) {
        if (verbose)
            printf("Using MPlayer Software Volume control\n");
        if (remember_softvol && volume_softvol != -1) {
            if (verbose)
                printf("Using last volume of %f%%\n", volume_softvol * 100.0);
            volume = (gdouble) volume_softvol *100.0;
        } else {
            volume = 100.0;
        }
    }

    if (large_buttons)
        button_size = GTK_ICON_SIZE_DIALOG;

    if (playlist_visible && control_id != 0)
        playlist_visible = FALSE;

    if (error != NULL) {
        printf("%s\n", error->message);
        printf(_("Run 'gnome-mplayer --help' to see a full list of available command line options.\n"));
        return 1;
    }
    // if (verbose)
    //      printf("Threading support enabled = %i\n",g_thread_supported());

    if (rpconsole == NULL)
        rpconsole = g_strdup("NONE");

    // setup playliststore
    playliststore =
        gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
                           G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING,
                           G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING,
                           G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
                           G_TYPE_FLOAT, G_TYPE_FLOAT, G_TYPE_BOOLEAN);

    // only use dark theme if not embedded, otherwise use the default theme  
#ifdef GTK3_ENABLED
    if (embed_window <= 0) {
        gtk_settings = gtk_settings_get_default();
        g_object_set(G_OBJECT(gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL);
    }
#endif

    create_window(embed_window);

    autopause = FALSE;
#ifdef GIO_ENABLED
    idledata->caching = g_mutex_new();
    idledata->caching_complete = g_cond_new();
#endif

    retrieve_metadata_pool = g_thread_pool_new(retrieve_metadata, NULL, 10, TRUE, NULL);

    if (argv[fileindex] != NULL) {
#ifdef GIO_ENABLED
        file = g_file_new_for_commandline_arg(argv[fileindex]);
        stat_result = -1;
        if (file != NULL) {
            GError *error = NULL;
            GFileInfo *file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_UNIX_MODE, 0, NULL, &error);
            if (file_info != NULL) {
                buf.st_mode = g_file_info_get_attribute_uint32(file_info, G_FILE_ATTRIBUTE_UNIX_MODE);
                stat_result = 0;
                g_object_unref(file_info);
            }
            if (error != NULL) {
                if (verbose)
                    printf("failed to get mode: %s\n", error->message);
                g_error_free(error);
            }
            g_object_unref(file);
        }
#else
        stat_result = g_stat(argv[fileindex], &buf);
#endif

        if (verbose) {
            printf("opening %s\n", argv[fileindex]);
            printf("stat_result = %i\n", stat_result);
            printf("is block %i\n", S_ISBLK(buf.st_mode));
            printf("is character %i\n", S_ISCHR(buf.st_mode));
            printf("is reg %i\n", S_ISREG(buf.st_mode));
            printf("is dir %i\n", S_ISDIR(buf.st_mode));
            printf("playlist %i\n", playlist);
            printf("embedded in window id 0x%x\n", embed_window);
        }
        if (stat_result == 0 && S_ISBLK(buf.st_mode)) {
            // might have a block device, so could be a DVD

#ifdef HAVE_SYS_MOUNT_H
            fp = setmntent("/etc/mtab", "r");
            do {
                mnt = getmntent(fp);
                if (mnt)
                    printf("%s is at %s\n", mnt->mnt_fsname, mnt->mnt_dir);
                if (argv[fileindex] != NULL && mnt && mnt->mnt_fsname != NULL) {
                    if (strcmp(argv[fileindex], mnt->mnt_fsname) == 0)
                        break;
                }
            }
            while (mnt);
            endmntent(fp);
#endif
            if (mnt && mnt->mnt_dir) {
                printf("%s is mounted on %s\n", argv[fileindex], mnt->mnt_dir);
                uri = g_strdup_printf("%s/VIDEO_TS", mnt->mnt_dir);
                stat(uri, &buf);
                g_free(uri);
                if (S_ISDIR(buf.st_mode)) {
                    add_item_to_playlist("dvdnav://", 0);
                    gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                    gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVD);
                    //play_iter(&iter, 0);
                    playiter = TRUE;
                } else {
                    uri = g_strdup_printf("file://%s", mnt->mnt_dir);
                    create_folder_progress_window();
                    add_folder_to_playlist_callback(uri, NULL);
                    g_free(uri);
                    destroy_folder_progress_window();
                    if (random_order) {
                        gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                        randomize_playlist(playliststore);
                    }
                    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter)) {
                        // play_iter(&iter, 0);
                        playiter = TRUE;
                    }
                }
            } else {
                parse_cdda("cdda://");
                if (random_order) {
                    gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                    randomize_playlist(playliststore);
                }
                //play_file("cdda://", playlist);
                if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter)) {
                    // play_iter(&iter, 0);
                    playiter = TRUE;
                }
            }
        } else if (stat_result == 0 && S_ISDIR(buf.st_mode)) {
            uri = g_strdup_printf("%s/VIDEO_TS", argv[fileindex]);
            stat_result = g_stat(uri, &buf);
            g_free(uri);
            if (stat_result == 0 && S_ISDIR(buf.st_mode)) {
                add_item_to_playlist("dvdnav://", 0);
                gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVD);
                //play_iter(&iter, 0);
                playiter = TRUE;
            } else {
                create_folder_progress_window();
                uri = NULL;
#ifdef GIO_ENABLED
                file = g_file_new_for_commandline_arg(argv[fileindex]);
                if (file != NULL) {
                    uri = g_file_get_uri(file);
                    g_object_unref(file);
                }
#else
                uri = g_filename_to_uri(argv[fileindex], NULL, NULL);
#endif
                add_folder_to_playlist_callback(uri, NULL);
                g_free(uri);
                destroy_folder_progress_window();
                if (random_order) {
                    gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                    randomize_playlist(playliststore);
                }
                if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter)) {
                    //play_iter(&iter, 0);
                    playiter = TRUE;
                }
            }
        } else {
            // local file
            // detect if playlist here, so even if not specified it can be picked up
            i = fileindex;

            while (argv[i] != NULL) {
                if (verbose > 1)
                    printf("Argument %i is %s\n", i, argv[i]);
#ifdef GIO_ENABLED
                if (!device_name(argv[i])) {
                    file = g_file_new_for_commandline_arg(argv[i]);
                    if (file != NULL) {
                        uri = g_file_get_uri(file);
                        g_object_unref(file);
                    } else {
                        uri = g_strdup(argv[i]);
                    }
                } else {
                    uri = g_strdup(argv[i]);
                }
#else
                uri = g_filename_to_uri(argv[i], NULL, NULL);
#endif

                if (uri != NULL) {
                    if (playlist == 0)
                        playlist = detect_playlist(uri);
                    if (!playlist) {
                        add_item_to_playlist(uri, playlist);
                    } else {
                        if (!parse_playlist(uri)) {
                            add_item_to_playlist(uri, playlist);
                        }
                    }
                    g_free(uri);
                }
                i++;
            }

            if (random_order) {
                gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
                randomize_playlist(playliststore);
            }
            if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter)) {
                // play_iter(&iter, 0);
                playiter = TRUE;
            }
        }

    }
#ifdef HAVE_GPOD
    if (load_tracks_from_gpod) {
        gpod_mount_point = find_gpod_mount_point();
        printf("mount point is %s\n", gpod_mount_point);
        if (gpod_mount_point != NULL) {
            gpod_load_tracks(gpod_mount_point);
        } else {
            printf("Unable to find gpod mount point\n");
        }
    }
#endif

    gm_audio_update_device(&audio_device);
    gm_audio_get_volume(&audio_device);
    gm_audio_set_server_volume_update_callback(&audio_device, set_volume);
    set_media_player_attributes(media);

    if (!softvol) {
        if (pref_volume != -1) {
            audio_device.volume = (gdouble) pref_volume / 100.0;
        }
        if (verbose)
            printf("The volume on '%s' is %f\n", audio_device.description, audio_device.volume);
        volume = audio_device.volume * 100;
    } else {
        audio_device.volume = volume / 100.0;
    }
#ifdef GTK2_12_ENABLED
    gtk_scale_button_set_value(GTK_SCALE_BUTTON(vol_slider), audio_device.volume);
#else
    gtk_range_set_value(GTK_RANGE(vol_slider), audio_device.volume);
#endif
    use_volume_option = detect_volume_option();

    dbus_hookup(embed_window, control_id);
    show_window(embed_window);

    if (playiter)
        play_iter(&iter, 0);

    if (argv[fileindex] == NULL && embed_window == 0) {
        // When running as apple.com external player, don't load the default playlist
        if (control_id == 0) {
            use_remember_loc = remember_loc;
            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_playlist), playlist_visible);
        } else {
            remember_loc = FALSE;
            use_remember_loc = FALSE;
            // prevents saving of a playlist with one item on it
            use_defaultpl = FALSE;
            // don't save the loc when launched with a single file
            save_loc = FALSE;
        }
    } else {
        // prevents saving of a playlist with one item on it
        use_defaultpl = FALSE;
        // don't save the loc when launched with a single file
        save_loc = FALSE;
    }

    if (single_instance && embed_window == 0) {
        if (control_id == 0) {
            use_remember_loc = remember_loc;
            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_playlist), playlist_visible);
        }
    }

    if (embed_window == 0) {
        if (remember_loc) {
            gtk_window_move(GTK_WINDOW(window), loc_window_x, loc_window_y);
            g_idle_add(set_pane_position, NULL);

        }
    }

    safe_to_save_default_playlist = FALSE;
    if (use_defaultpl) {
        create_folder_progress_window();
        parse_playlist(default_playlist);
        destroy_folder_progress_window();
    }
    safe_to_save_default_playlist = TRUE;

    gtk_main();

    return 0;
}
Beispiel #9
0
static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    AppleHTTPContext *c = s->priv_data;
    int ret = 0, i, j, stream_offset = 0;

    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
        goto fail;

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained variants, parse each individual
     * variant playlist. */
    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
        for (i = 0; i < c->n_variants; i++) {
            struct variant *v = c->variants[i];
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
    if (c->variants[0]->finished) {
        int64_t duration = 0;
        for (i = 0; i < c->variants[0]->n_segments; i++)
            duration += c->variants[0]->segments[i]->duration;
        s->duration = duration * AV_TIME_BASE;
    }

    /* Open the demuxer for each variant */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
        AVInputFormat *in_fmt = NULL;
        char bitrate_str[20];
        if (v->n_segments == 0)
            continue;

        v->index  = i;
        v->needed = 1;
        v->parent = s;

        /* If this is a live stream with more than 3 segments, start at the
         * third last segment. */
        v->cur_seq_no = v->start_seq_no;
        if (!v->finished && v->n_segments > 3)
            v->cur_seq_no = v->start_seq_no + v->n_segments - 3;

        v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
        ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
                          read_data, NULL, NULL);
        v->pb.seekable = 0;
        ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
                                    NULL, 0, 0);
        if (ret < 0)
            goto fail;
        ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
                                   in_fmt, NULL);
        if (ret < 0)
            goto fail;
        v->stream_offset = stream_offset;
        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
        /* Create new AVStreams for each stream in this variant */
        for (j = 0; j < v->ctx->nb_streams; j++) {
            AVStream *st = av_new_stream(s, i);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
            av_metadata_set2(&st->metadata, "variant_bitrate", bitrate_str, 0);
        }
        stream_offset += v->ctx->nb_streams;
    }

    c->first_packet = 1;

    return 0;
fail:
    free_variant_list(c);
    return ret;
}
Beispiel #10
0
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
    struct variant *v = opaque;
    AppleHTTPContext *c = v->parent->priv_data;
    int ret, i;

restart:
    if (!v->input) {
reload:
        /* If this is a live stream and target_duration has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        if (!v->finished &&
            av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
            (ret = parse_playlist(c, v->url, v, NULL)) < 0)
                return ret;
        if (v->cur_seq_no < v->start_seq_no) {
            av_log(NULL, AV_LOG_WARNING,
                   "skipping %d segments ahead, expired from playlists\n",
                   v->start_seq_no - v->cur_seq_no);
            v->cur_seq_no = v->start_seq_no;
        }
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
            if (v->finished)
                return AVERROR_EOF;
            while (av_gettime() - v->last_load_time <
                   v->target_duration*1000000) {
                if (url_interrupt_cb())
                    return AVERROR_EXIT;
                usleep(100*1000);
            }
            /* Enough time has elapsed since the last reload */
            goto reload;
        }

        ret = open_input(v);
        if (ret < 0)
            return ret;
    }
    ret = ffurl_read(v->input, buf, buf_size);
    if (ret > 0)
        return ret;
    if (ret < 0 && ret != AVERROR_EOF)
        return ret;
    ffurl_close(v->input);
    v->input = NULL;
    v->cur_seq_no++;

    c->end_of_segment = 1;
    c->cur_seq_no = v->cur_seq_no;

    if (v->ctx) {
        v->needed = 0;
        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
             i++) {
            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
                v->needed = 1;
        }
    }
    if (!v->needed) {
        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
               v->index);
        return AVERROR_EOF;
    }
    goto restart;
}
Beispiel #11
0
static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AppleHTTPContext *c = s->priv_data;
    int ret, i, minvariant = -1, first = 1, needed = 0, changed = 0,
        variants = 0;

    /* Recheck the discard flags - which streams are desired at the moment */
    for (i = 0; i < c->n_variants; i++)
        c->variants[i]->needed = 0;
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        struct variant *var = c->variants[s->streams[i]->id];
        if (st->discard < AVDISCARD_ALL) {
            var->needed = 1;
            needed++;
        }
        /* Copy the discard flag to the chained demuxer, to indicate which
         * streams are desired. */
        var->ctx->streams[i - var->stream_offset]->discard = st->discard;
    }
    if (!needed)
        return AVERROR_EOF;
start:
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Close unneeded streams, open newly requested streams */
        if (var->pb && !var->needed) {
            av_log(s, AV_LOG_DEBUG,
                   "Closing variant stream %d, no longer needed\n", i);
            av_free_packet(&var->pkt);
            reset_packet(&var->pkt);
            url_fclose(var->pb);
            var->pb = NULL;
            changed = 1;
        } else if (!var->pb && var->needed) {
            if (first)
                av_log(s, AV_LOG_DEBUG, "Opening variant stream %d\n", i);
            if (first && !c->finished)
                if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
                    return ret;
            ret = open_variant(c, var, first);
            if (ret < 0)
                return ret;
            changed = 1;
        }
        /* Count the number of open variants */
        if (var->pb)
            variants++;
        /* Make sure we've got one buffered packet from each open variant
         * stream */
        if (var->pb && !var->pkt.data) {
            ret = av_read_frame(var->ctx, &var->pkt);
            if (ret < 0) {
                if (!url_feof(var->pb))
                    return ret;
                reset_packet(&var->pkt);
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if (minvariant < 0 ||
                var->pkt.dts < c->variants[minvariant]->pkt.dts)
                minvariant = i;
        }
    }
    if (first && changed)
        av_log(s, AV_LOG_INFO, "Receiving %d variant streams\n", variants);
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        c->last_packet_dts = pkt->dts;
        return 0;
    }
    /* No more packets - eof reached in all variant streams, close the
     * current segments. */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        if (var->pb) {
            url_fclose(var->pb);
            var->pb = NULL;
        }
    }
    /* Indicate that we're opening the next segment, not opening a new
     * variant stream in parallel, so we shouldn't try to skip ahead. */
    first = 0;
    c->cur_seq_no++;
reload:
    if (!c->finished) {
        /* If this is a live stream and target_duration has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        int64_t now = av_gettime();
        if (now - c->last_load_time >= c->target_duration*1000000) {
            c->max_start_seq = 0;
            c->min_end_seq   = INT_MAX;
            for (i = 0; i < c->n_variants; i++) {
                struct variant *var = c->variants[i];
                if (var->needed) {
                    if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
                        return ret;
                    c->max_start_seq = FFMAX(c->max_start_seq,
                                             var->start_seq_no);
                    c->min_end_seq   = FFMIN(c->min_end_seq,
                                             var->start_seq_no + var->n_segments);
                }
            }
        }
    }
    if (c->cur_seq_no < c->max_start_seq) {
        av_log(NULL, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlists\n",
               c->max_start_seq - c->cur_seq_no);
        c->cur_seq_no = c->max_start_seq;
    }
    /* If more segments exit, open the next one */
    if (c->cur_seq_no < c->min_end_seq)
        goto start;
    /* We've reached the end of the playlists - return eof if this is a
     * non-live stream, wait until the next playlist reload if it is live. */
    if (c->finished)
        return AVERROR_EOF;
    while (av_gettime() - c->last_load_time < c->target_duration*1000000) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        usleep(100*1000);
    }
    /* Enough time has elapsed since the last reload */
    goto reload;
}
Beispiel #12
0
static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    AppleHTTPContext *c = s->priv_data;
    int ret = 0, i, j, stream_offset = 0;

    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
        goto fail;

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained variants, parse each individual
     * variant playlist. */
    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
        for (i = 0; i < c->n_variants; i++) {
            struct variant *v = c->variants[i];
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
    if (c->finished) {
        int64_t duration = 0;
        for (i = 0; i < c->variants[0]->n_segments; i++)
            duration += c->variants[0]->segments[i]->duration;
        s->duration = duration * AV_TIME_BASE;
    }

    c->min_end_seq = INT_MAX;
    /* Open the demuxer for each variant */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
        if (v->n_segments == 0)
            continue;
        c->max_start_seq = FFMAX(c->max_start_seq, v->start_seq_no);
        c->min_end_seq   = FFMIN(c->min_end_seq,   v->start_seq_no +
                                                   v->n_segments);
        ret = av_open_input_file(&v->ctx, v->segments[0]->url, NULL, 0, NULL);
        if (ret < 0)
            goto fail;
        url_fclose(v->ctx->pb);
        v->ctx->pb = NULL;
        v->stream_offset = stream_offset;
        /* Create new AVStreams for each stream in this variant */
        for (j = 0; j < v->ctx->nb_streams; j++) {
            AVStream *st = av_new_stream(s, i);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
        }
        stream_offset += v->ctx->nb_streams;
    }
    c->last_packet_dts = AV_NOPTS_VALUE;

    c->cur_seq_no = c->max_start_seq;
    /* If this is a live stream with more than 3 segments, start at the
     * third last segment. */
    if (!c->finished && c->min_end_seq - c->max_start_seq > 3)
        c->cur_seq_no = c->min_end_seq - 2;

    return 0;
fail:
    free_variant_list(c);
    return ret;
}
Beispiel #13
0
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
    struct variant *v = opaque;
    HLSContext *c = v->parent->priv_data;
#if 1 // added by yen for get duration	
    AVFormatContext *s = v->parent;
#endif	
    int ret, i;

restart:
//__android_log_print(ANDROID_LOG_VERBOSE, TAG, "read_data restart");
    if (!v->input) {
        /* If this is a live stream and the reload interval has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        double reload_interval = v->n_segments > 0 ?
                                  v->segments[v->n_segments - 1]->duration :
                                  v->target_duration;
        reload_interval *= 1000000;

reload:
       /*
        * add By Yen calculate the total duration for support TSTV
        */
        if(v->finished != 1) {
#if _SUPPORT_HLS_LIVE_SEEK_ // get current duration for seek
			{
				double duration = 0;
				c->first_timestamp = AV_NOPTS_VALUE;
				for (i = 0; i < c->variants[0]->n_segments - 3; i++)
					duration += c->variants[0]->segments[i]->duration;
				s->duration = duration * AV_TIME_BASE;
				//__android_log_print(ANDROID_LOG_VERBOSE, TAG, "read_data,duration:%f,segments:%d",(double)s->duration/AV_TIME_BASE,c->variants[0]->n_segments);
			}
#endif
        }
        if (!v->finished &&
            av_gettime() - v->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                return ret;
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = v->target_duration * 500000;
        }
        if (v->cur_seq_no < v->start_seq_no) {
            av_log(NULL, AV_LOG_WARNING,
                   "skipping %d segments ahead, expired from playlists\n",
                   v->start_seq_no - v->cur_seq_no);
            v->cur_seq_no = v->start_seq_no;
        }
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
            if (v->finished) {
//                FILE *fp = fopen( "/mnt/sdcard/Die_Hls.txt", "wta+");
//                     fprintf(fp, "Line = %d, recive EXT-X-ENDLIST", __LINE__);
//                     fclose(fp);
                return AVERROR_EOF;
            }
            while (av_gettime() - v->last_load_time < reload_interval) {
                if (ff_check_interrupt(c->interrupt_callback))
                    return AVERROR_EXIT;
                usleep(100*1000);
            }
            /* Enough time has elapsed since the last reload */
            goto reload;
        }

        ret = open_input(v);
        if (ret < 0)
            return ret;
    }
    ret = ffurl_read(v->input, buf, buf_size);
    if (ret > 0)
        return ret;
    if (ret < 0 && ret != AVERROR_EOF)
        return ret;
    ffurl_close(v->input);
    v->input = NULL;
    v->cur_seq_no++;

    c->end_of_segment = 1;
    c->cur_seq_no = v->cur_seq_no;

    if (v->ctx && v->ctx->nb_streams) {
        v->needed = 0;
        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
             i++) {
            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
                v->needed = 1;
        }
    }
    if (!v->needed) {
        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
               v->index);
        return AVERROR_EOF;
    }
    goto restart;
}
Beispiel #14
0
static int hls_read(URLContext *h, uint8_t *buf, int size)
{
    HLSContext *s = h->priv_data;
    const char *url;
    int ret;
    int64_t reload_interval;

start:
    if (s->seg_hd) {
        ret = ffurl_read(s->seg_hd, buf, size);
        if (ret > 0)
            return ret;
    }
    if (s->seg_hd) {
        ffurl_close(s->seg_hd);
        s->seg_hd = NULL;
        s->cur_seq_no++;
    }
    reload_interval = s->n_segments > 0 ?
                      s->segments[s->n_segments - 1]->duration :
                      s->target_duration;
retry:
    if (!s->finished) {
        int64_t now = av_gettime_relative();
        if (now - s->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(h, s->playlisturl)) < 0)
                return ret;
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = s->target_duration / 2;
        }
    }
    if (s->cur_seq_no < s->start_seq_no) {
        av_log(h, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlist\n",
               s->start_seq_no - s->cur_seq_no);
        s->cur_seq_no = s->start_seq_no;
    }
    if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
        if (s->finished)
            return AVERROR_EOF;
        while (av_gettime_relative() - s->last_load_time < reload_interval) {
            if (ff_check_interrupt(&h->interrupt_callback))
                return AVERROR_EXIT;
            av_usleep(100*1000);
        }
        goto retry;
    }
    url = s->segments[s->cur_seq_no - s->start_seq_no]->url;
    av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
    ret = ffurl_open_whitelist(&s->seg_hd, url, AVIO_FLAG_READ,
                               &h->interrupt_callback, NULL,
                               h->protocol_whitelist, h->protocol_blacklist, h);
    if (ret < 0) {
        if (ff_check_interrupt(&h->interrupt_callback))
            return AVERROR_EXIT;
        av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
        s->cur_seq_no++;
        goto retry;
    }
    goto start;
}
Beispiel #15
0
static int hls_open(URLContext *h, const char *uri, int flags)
{
    HLSContext *s = h->priv_data;
    int ret, i;
    const char *nested_url;

    if (flags & AVIO_FLAG_WRITE)
        return AVERROR(ENOSYS);

    h->is_streamed = 1;

    if (av_strstart(uri, "hls+", &nested_url)) {
        av_strlcpy(s->playlisturl, nested_url, sizeof(s->playlisturl));
    } else if (av_strstart(uri, "hls://", &nested_url)) {
        av_log(h, AV_LOG_ERROR,
               "No nested protocol specified. Specify e.g. hls+http://%s\n",
               nested_url);
        ret = AVERROR(EINVAL);
        goto fail;
    } else {
        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
        ret = AVERROR(EINVAL);
        goto fail;
    }
    av_log(h, AV_LOG_WARNING,
           "Using the hls protocol is discouraged, please try using the "
           "hls demuxer instead. The hls demuxer should be more complete "
           "and work as well as the protocol implementation. (If not, "
           "please report it.) To use the demuxer, simply use %s as url.\n",
           s->playlisturl);

    if ((ret = parse_playlist(h, s->playlisturl)) < 0)
        goto fail;

    if (s->n_segments == 0 && s->n_variants > 0) {
        int max_bandwidth = 0, maxvar = -1;
        for (i = 0; i < s->n_variants; i++) {
            if (s->variants[i]->bandwidth > max_bandwidth || i == 0) {
                max_bandwidth = s->variants[i]->bandwidth;
                maxvar = i;
            }
        }
        av_strlcpy(s->playlisturl, s->variants[maxvar]->url,
                   sizeof(s->playlisturl));
        if ((ret = parse_playlist(h, s->playlisturl)) < 0)
            goto fail;
    }

    if (s->n_segments == 0) {
        av_log(h, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR(EIO);
        goto fail;
    }
    s->cur_seq_no = s->start_seq_no;
    if (!s->finished && s->n_segments >= 3)
        s->cur_seq_no = s->start_seq_no + s->n_segments - 3;

    return 0;

fail:
    hls_close(h);
    return ret;
}
static int hls_read_header(AVFormatContext *s)
{
    HLSContext *c = s->priv_data;
    int ret = 0, i, j, stream_offset = 0;

    int only_parser_one_variants=1;
    int parser_start,parser_end;
    //c->interrupt_callback = &s->interrupt_callback;
   c->total_brate=500*1024;
   c->latest_3file_brate=c->total_brate;
   c->latest_1file_brate=c->total_brate;	
    s->bit_rate=0;
    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0){
	av_log(NULL, AV_LOG_WARNING, "parse_playlist failed ret=%d\n",ret);
        goto fail;
    }

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist 1\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained variants, parse each individual
     * variant playlist. */
    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
        for (i = 0; i < c->n_variants; i++) {
            struct variant *v = c->variants[i];
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist 2\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
    if (c->variants[0]->finished) {
        int64_t duration = 0;
        for (i = 0; i < c->variants[0]->n_segments; i++)
            duration += c->variants[0]->segments[i]->duration;
        s->duration = duration * AV_TIME_BASE;
    }
 
   if(only_parser_one_variants){	
   		parser_start=select_best_variant(c,c->total_brate);
		parser_end=parser_start+1;
   }else{
   		parser_start=0;
		parser_end=c->n_variants;
   }
    /* Open the demuxer for each variant */
    for (i = parser_start; i < parser_end; i++) {
        struct variant *v = c->variants[i];
        AVInputFormat *in_fmt = NULL;
        char bitrate_str[20];
        if (v->n_segments == 0)
            continue;

        if (!(v->ctx = avformat_alloc_context())) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        v->index  = i;
        v->needed = 1;
        v->parent = s;

        /* If this is a live stream with more than 3 segments, start at the
         * third last segment. */
        v->cur_seq_no = v->start_seq_no;
        if (!v->finished && v->n_segments > 3)
            v->cur_seq_no = v->start_seq_no + v->n_segments - 3;
#ifdef  USED_LP_BUF
	v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
       memset(&v->urllpbuf,0,sizeof(&v->urllpbuf));
	if(url_lpopen_ex(&v->urllpbuf,0,AVIO_FLAG_READ,read_data,read_data_exseek)==0){
		ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, &v->urllpbuf,
                          url_lpread, NULL, NULL);
	}else{
		
        	ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, &v->urllpbuf,
                          read_data, NULL, NULL);
	}
	v->urllpbuf.is_streamed=1;
	v->urllpbuf.is_slowmedia=1;
	v->urllpbuf.priv_data=v;
#else
        v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
        ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
                          read_data, NULL, NULL);
#endif		
        v->pb.seekable = 0;
        ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
                                    NULL, 0, 0);
        if (ret < 0) {
            /* Free the ctx - it isn't initialized properly at this point,
             * so avformat_close_input shouldn't be called. If
             * avformat_open_input fails below, it frees and zeros the
             * context, so it doesn't need any special treatment like this. */
            avformat_free_context(v->ctx);
            v->ctx = NULL;
            goto fail;
        }
        v->ctx->pb       = &v->pb;
        ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
        if (ret < 0)
            goto fail;
	 if(v->bandwidth<=0 && v->segments[0]->seg_filesize>0 && v->segments[0]->duration>0){
	 	v->bandwidth=v->segments[0]->seg_filesize/v->segments[0]->duration;
	 }
        v->stream_offset = stream_offset;
        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
        /* Create new AVStreams for each stream in this variant */
        for (j = 0; j < v->ctx->nb_streams; j++) {
            AVStream *st = av_new_stream(s, 0);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            st->id = i;
            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
            if (v->bandwidth)
                av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
                                 0);
		if(st->codec->bit_rate<=0)
			st->codec->bit_rate=v->bandwidth/v->ctx->nb_streams;
        }
	 v->ctx->bit_rate=v->bandwidth;
        stream_offset += v->ctx->nb_streams;
	 s->bit_rate+=v->bandwidth;
    }

    c->first_packet = 1;
    c->first_timestamp = AV_NOPTS_VALUE;
    c->seek_timestamp  = AV_NOPTS_VALUE;
    c->discontinue_pts_interval_ms=2000;	
    s->flags|=AVFMT_FLAG_FILESIZE_NOT_VALID;
   if(s->pb){
	 	/*reset read and free lp buf.*/
		/*del lp buf,to free memory*/
		ffio_fdopen_resetlpbuf(s->pb,0);
		s->pb->flags|=AVIO_FLAG_SIZE_NOTVALID;
		s->file_size=-1;
     }
    return 0;
fail:
    free_variant_list(c);
    
     return ret;
}
Beispiel #17
0
static int hls_read_header(AVFormatContext *s)
{
    URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
    HLSContext *c = s->priv_data;
    int ret = 0, i, j, stream_offset = 0;

    c->interrupt_callback = &s->interrupt_callback;

    // if the URL context is good, read important options we must broker later
    if (u && u->prot->priv_data_class) {
        // get the previous user agent & set back to null if string size is zero
        av_freep(&c->user_agent);
        av_opt_get(u->priv_data, "user-agent", 0, (uint8_t**)&(c->user_agent));
        if (c->user_agent && !strlen(c->user_agent))
            av_freep(&c->user_agent);

        // get the previous cookies & set back to null if string size is zero
        av_freep(&c->cookies);
        av_opt_get(u->priv_data, "cookies", 0, (uint8_t**)&(c->cookies));
        if (c->cookies && !strlen(c->cookies))
            av_freep(&c->cookies);

        // get the previous headers & set back to null if string size is zero
        av_freep(&c->headers);
        av_opt_get(u->priv_data, "headers", 0, (uint8_t**)&(c->headers));
        if (c->headers && !strlen(c->headers))
            av_freep(&c->headers);
    }

    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
        goto fail;

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained playlists (Master Playlist),
     * parse each individual playlist. */
    if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
        for (i = 0; i < c->n_playlists; i++) {
            struct playlist *pls = c->playlists[i];
            if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->playlists[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
    if (c->variants[0]->playlists[0]->finished) {
        int64_t duration = 0;
        for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
            duration += c->variants[0]->playlists[0]->segments[i]->duration;
        s->duration = duration;
    }

    /* Open the demuxer for each playlist */
    for (i = 0; i < c->n_playlists; i++) {
        struct playlist *pls = c->playlists[i];
        AVInputFormat *in_fmt = NULL;

        if (pls->n_segments == 0)
            continue;

        if (!(pls->ctx = avformat_alloc_context())) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        pls->index  = i;
        pls->needed = 1;
        pls->parent = s;

        /* If this is a live stream with more than 3 segments, start at the
         * third last segment. */
        pls->cur_seq_no = pls->start_seq_no;
        if (!pls->finished && pls->n_segments > 3)
            pls->cur_seq_no = pls->start_seq_no + pls->n_segments - 3;

        pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
        ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
                          read_data, NULL, NULL);
        pls->pb.seekable = 0;
        ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url,
                                    NULL, 0, 0);
        if (ret < 0) {
            /* Free the ctx - it isn't initialized properly at this point,
             * so avformat_close_input shouldn't be called. If
             * avformat_open_input fails below, it frees and zeros the
             * context, so it doesn't need any special treatment like this. */
            av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
            avformat_free_context(pls->ctx);
            pls->ctx = NULL;
            goto fail;
        }
        pls->ctx->pb       = &pls->pb;
        pls->stream_offset = stream_offset;
        ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
        if (ret < 0)
            goto fail;

        pls->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
        ret = avformat_find_stream_info(pls->ctx, NULL);
        if (ret < 0)
            goto fail;

        /* Create new AVStreams for each stream in this playlist */
        for (j = 0; j < pls->ctx->nb_streams; j++) {
            AVStream *st = avformat_new_stream(s, NULL);
            AVStream *ist = pls->ctx->streams[j];
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            st->id = i;
            avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
            avcodec_copy_context(st->codec, pls->ctx->streams[j]->codec);
        }

        stream_offset += pls->ctx->nb_streams;
    }

    /* Create a program for each variant */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
        char bitrate_str[20];
        AVProgram *program;

        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);

        program = av_new_program(s, i);
        if (!program)
            goto fail;
        av_dict_set(&program->metadata, "variant_bitrate", bitrate_str, 0);

        for (j = 0; j < v->n_playlists; j++) {
            struct playlist *pls = v->playlists[j];
            int is_shared = playlist_in_multiple_variants(c, pls);
            int k;

            for (k = 0; k < pls->ctx->nb_streams; k++) {
                struct AVStream *st = s->streams[pls->stream_offset + k];

                ff_program_add_stream_index(s, i, pls->stream_offset + k);

                /* Set variant_bitrate for streams unique to this variant */
                if (!is_shared && v->bandwidth)
                    av_dict_set(&st->metadata, "variant_bitrate", bitrate_str, 0);
            }
        }
    }

    c->first_packet = 1;
    c->first_timestamp = AV_NOPTS_VALUE;
    c->seek_timestamp  = AV_NOPTS_VALUE;

    return 0;
fail:
    free_playlist_list(c);
    free_variant_list(c);
    return ret;
}
Beispiel #18
0
void parse_game(FILE * file, int id, uint32_t start, uint32_t end)
{

    fseek(file, start, SEEK_SET);

    uint32_t index = 0;
    uint16_t type = 0;
    fread(&type, sizeof(type), 1, file);
    printf("\tType:\t%d\n", type);
    if (type == 253) {
	print_block(file, start, end, start, end);
	uint16_t count;
	fseek(file, start + 2, SEEK_SET);
	fread(&count, sizeof(count), 1, file);
	index = 4;

	int i;
	for (i = 0; i < count; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    parse_list_16(file, pointer);
	}

	printf("Typ%03d (%d)PLY ", type, count);
	for (i = 0; i < count; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_media(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}

	printf("\n");
	index = 4;

	printf("Typ%03d (%d)OID ", type, count);

	for (i = 0; i < count; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_oid(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}

	printf("\n");
	index = 4;

	printf("Typ%03d (%d)GID ", type, count);

	for (i = 0; i < count; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_gid(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}
	printf("\n");
	return;
    }

    uint16_t aa;
    fread(&aa, sizeof(aa), 1, file);

    uint16_t ignore1;
    fread(&ignore1, sizeof(ignore1), 1, file);

    uint16_t bb;
    fread(&bb, sizeof(bb), 1, file);

    int playscripts = 5;
    int ps2 = 10;
    if ((type == 7) || (type == 10) || (type == 6)) {
	ps2 = 11;
    }
    if ((type == 8) || (type == 16)) {
	ps2 = 14;
    }
    if (type == 9) {
	ps2 = 85;
    }
    printf("HT%02d C%03d I%02d C%03d\n", type, aa, ignore1, bb);
    if (type == 6) {
	index = 26;
	fseek(file, start + 26, SEEK_SET);
	playscripts = 7;
    } else {
	index = 18;
	fseek(file, start + 18 + playscripts * 4, SEEK_SET);
	uint32_t pointer;
	fread(&pointer, sizeof(pointer), 1, file);
	if (bb != 0) {
	    printf("Error4\n");
	}
    }
    int i = 0;
    for (i = 0; i < playscripts; i++) {
	uint32_t pointer;
	fseek(file, start + index + i * 4, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	if (test_list_32(file, pointer, start, end) > 0) {
	    printf("No Playlist pointer (%08X)\n", pointer);
	} else {
	    parse_playlistpointer(file, pointer, start, end);
	}
    }

    index += 4 * playscripts;

//  if (type != 6)
//    {
    int subgamestart = index;

    if (aa != 0) {
	printf("\n\tSubgames:\t[");
	for (i = 0; i < aa; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    printf("0x%X,", pointer);
	}
	printf("]\n\n");
    }
    index += aa * 4;
    if (type == 6) {
	if (bb != 0) {
	    printf("\n\tSubgames2:\t[");
	    for (i = 0; i < bb; i++) {
		uint32_t pointer;
		fseek(file, start + index + i * 4, SEEK_SET);
		fread(&pointer, sizeof(pointer), 1, file);
		printf("0x%X,", pointer);
	    }
	    printf("]\n\n");
	}
	index += bb * 4;
    }
    index += 20;

    for (i = 0; i < 10; i++) {
	uint32_t pointer;
	fseek(file, start + index + i * 4, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	if (test_list_32(file, pointer, start, end) > 0) {
	    printf("No Playlist pointer (%08X)\n", pointer);
	} else {
	    parse_playlistpointer(file, pointer, start, end);
	}
    }
    index += 10 * 4;

    if (type == 6) {
	uint32_t pointer;
	fseek(file, start + index, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	parse_playlist(file, pointer);
	index += 4;
    } else if (type == 7 || type == 10) {
	uint32_t pointer;
	fseek(file, start + index, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	parse_playlistpointer(file, pointer, start, end);
	index += 4;
    } else if (type == 8) {
	uint32_t pointer;
	fseek(file, start + index, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	parse_oidlist(file, pointer);

	index += 4;
	fseek(file, start + index, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	parse_gameidlist(file, pointer);

	index += 4;
	int i;
	for (i = 0; i < 2; i++) {
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    parse_playlistpointer(file, pointer, start, end);
	}
	index += 2 * 4;
    } else if (type == 9) {
	int i;
	for (i = 0; i < 75; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    parse_playlistpointer(file, pointer, start, end);
	}
	index += 75 * 4;
    } else if (type == 16) {
	uint32_t pointer;
	fseek(file, start + index, SEEK_SET);
	fread(&pointer, sizeof(pointer), 1, file);
	parse_oidlist(file, pointer);

	index += 4;
	int i;
	for (i = 0; i < 3; i++) {
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    parse_playlistpointer(file, pointer, start, end);
	}
	index += 3 * 4;
    }
    if (0) {
	printf("Typ%02d PLP ", type);

	for (i = 0; i < ps2; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_32(file, pointer, start, end);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }

	    if (test_list_32(file, pointer, start, end)) {
//          printf("No Playlist pointer (%08X)\n", pointer);
//          parse_playlistpointer(file, pointer, start, end);
	    } else {
//          parse_playlistpointer(file, pointer, start, end);
	    }
	}
	printf("\n");

	printf("Typ%02d PLY ", type);
	for (i = 0; i < ps2; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_media(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}
	printf("\n");

	printf("Typ%02d OID ", type);
	for (i = 0; i < ps2; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_oid(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}
	printf("\n");

	printf("Typ%02d GID ", type);
	for (i = 0; i < ps2; i++) {
	    uint32_t pointer;
	    fseek(file, start + index + i * 4, SEEK_SET);
	    fread(&pointer, sizeof(pointer), 1, file);
	    int tmp = test_list_gid(file, pointer);
	    if (tmp == 0) {
		printf("+");
	    }
	    if (tmp > 0) {
		printf("-");
	    }
	    if (tmp < 0) {
		printf("0");
	    }
	}
	printf("\n");
    }

    uint32_t firstsub;
    if (type == 6) {
	fseek(file, start + subgamestart + 4, SEEK_SET);
    } else {
	if (aa != 0) {
	    fseek(file, start + subgamestart, SEEK_SET);
	} else {
	    fseek(file, start + 18, SEEK_SET);
	}
    }
    fread(&firstsub, sizeof(firstsub), 1, file);
    if (start + index != firstsub) {
	printf
	    ("start(0x%X) + index(%d) + ps2(%d) * 4 = 0x%X != firstsub(0x%X)\n",
	     start, index, ps2, start + index + ps2 * 4, firstsub);
	printf("Error7!\n");
    }


    for (i = 0; i < aa - 1; i++) {
	uint32_t pointer1, pointer2;
	fseek(file, start + subgamestart + i * 4, SEEK_SET);
	fread(&pointer1, sizeof(pointer1), 1, file);
	fread(&pointer2, sizeof(pointer2), 1, file);
	printf("SubGame(%2d, 0x%X)\n--------------------------\n", i,
	       pointer1);
	parse_subgame(file, pointer1, pointer2, type);
//          print_block(file, pointer1, pointer2, start, end);
    }
    if (type == 6) {
	int sbs2 = subgamestart + 4 * aa;
	for (i = 0; i < bb - 1; i++) {
	    uint32_t pointer1, pointer2;
	    fseek(file, start + sbs2 + i * 4, SEEK_SET);
	    fread(&pointer1, sizeof(pointer1), 1, file);
	    fread(&pointer2, sizeof(pointer2), 1, file);
	    printf("SubGame2(%2d, 0x%X)\n--------------------------\n", i,
		   pointer1);
	    parse_subgame(file, pointer1, pointer2, type);
//          print_block(file, pointer1, pointer2, start, end);
	}
    }
//    }

//    printf("\tType? = %d\n\n", type);

//    fread(&bb, sizeof(bb),1,file);

    if (DUMP_BLOCKS) {

//  if (type == 6)
//    {
	uint32_t test = 0;

	i = 0;
	int b = 0;
	do {
	    i++;
	    fseek(file, start + i, SEEK_SET);
	    b = 0;
	    int j = 0;
	    for (j = 0; j < aa + 5; j++) {
		fread(&test, sizeof(test), 1, file);
		if ((test < start) || (test > end)) {
		    b = 1;
		}
	    }
//      printf("\t%X = %X\n", i, test);

	}
	while ((b == 1) && (i < (end - start - ((aa + 5) * 4))));

	printf("\tType? = %d\t%d\n\n", type, i);

//      fseek(file, start + 18 , SEEK_SET);
//      fread(&test, sizeof(test),1,file);
/*    if ((test < start) || (test > end )) {
//
	printf("%s_game%02d", gme, id);
	printf("\tType? = %d\t%d\n\n", type,i);
    }
*/
/*    if ((aa == 0) || (bb == 0 )) {
//
	printf("%s_game%02d", gme, id);
	printf("\taa = %d\tbb = %d\n\n", aa,bb);
	printf("\tType? = %d\t%d\n\n", type,i);
    }
*/

	uint32_t blocks[5001];
	blocks[0] = start;
	int bi = 1;
	i = 16;
	do {
	    i++;
	    fseek(file, start + i, SEEK_SET);
	    uint32_t testp;
	    fread(&testp, sizeof(testp), 1, file);
	    if ((testp >= start) && (testp < end)) {
		blocks[bi++] = testp;
	    }
	}
	while ((bi < 5000) && (i < (end - start - 3)));
	if (bi < 5000) {
	    blocks[bi++] = end;
	    // sortieren
	    int z = 0;
	    for (i = 0; i < bi; i++) {
		int j;
		for (j = i + 1; j < bi; j++) {
		    if (blocks[i] > blocks[j]) {
			uint32_t tmp = blocks[i];
			blocks[i] = blocks[j];
			blocks[j] = tmp;
		    }
		    if (blocks[i] == blocks[j]
			&& (blocks[i] != 0xffffffff)) {
			blocks[j] = 0xffffffff;
			z++;
		    }
		}
	    }
	    bi -= z;
	    // ausgeben
	    for (i = 0; i < (bi - 1); i++) {
		printf("0x%X B%02d %06d\n\t", blocks[i], i,
		       blocks[i + 1] - blocks[i]);
		uint32_t j;
		int p = 0;
		for (j = blocks[i]; j < blocks[i + 1]; j++) {
		    fseek(file, j, SEEK_SET);
		    uint8_t val;
		    fread(&val, sizeof(val), 1, file);
		    printf("%02X ", val);
		    if (p == 7) {
			printf(" ");
		    }
		    if (p++ == 15) {
			p = 0;
			printf("\n\t");
		    }
		}
		printf("\n\t\t");
		int coun = 0;
		uint32_t last = 0;
		int k = 0;
		for (j = blocks[i]; j < blocks[i + 1]; j++) {
		    fseek(file, j, SEEK_SET);
		    uint32_t point;
		    fread(&point, sizeof(point), 1, file);
		    if ((point >= start) && (point < end)) {
			j += 3;
			if (last < point) {
			    coun++;
			    last = point;
			} else {
			    printf("B%02d TP%02d I%02d L%02d \n\t\t", i,
				   type, k++, coun);
			    if ((i == 0) && (k == 2) && (coun != aa)
				&& (aa != 0))
				printf("Error!\n");
			    coun = 1;
			    last = 0;
			}
		    } else {
			if (coun > 0) {
			    if ((coun > 1) || (k > 0)) {
				printf("B%02d TP%02d I%02d L%02d \n\t\t",
				       i, type, k++, coun);
				if ((i == 0) && (k == 2) && (coun != aa)
				    && (aa != 0))
				    printf("Error!\n");
			    }
			    coun = 0;
			    last = 0;
			}
		    }
		}
		if (coun > 0) {
		    printf("B%02d TP%02d I%02d L%02d \n\t\t", i, type, k++,
			   coun);
		    if ((i == 0) && (k == 2) && (coun != aa) && (aa != 0))
			printf("Error!\n");
		    coun = 0;
		    last = 0;
		}
		printf("\n");
	    }
	}
    }
}