Example #1
0
void DecoderHandler::start(Metadata *mdata)
{
    m_state = LOADING;

    m_playlist.clear();
    m_meta = mdata;
    m_playlist_pos = -1;
    m_redirects = 0;

    QUrl url;
    if (QFileInfo(mdata->Filename()).isAbsolute())
        url = QUrl::fromLocalFile(mdata->Filename());
    else
        url.setUrl(mdata->Filename());

    bool result = createPlaylist(url);
    if (m_state == LOADING && result)
    {
        for (int ii = 0; ii < m_playlist.size(); ii++)
            VERBOSE(VB_PLAYBACK, QString("Track %1 = %2")
                .arg(ii)
                .arg(m_playlist.get(ii)->File()));
        next();
    }
    else
    {
        if (m_state != STOPPED)
        {
            doFailed(url, "Could not get playlist");
        }
    }
}
	void FooPlaylistManager::removePlaylist(QString name, QUuid uuid)
	{
		int i = playlistIndex(name, uuid);

		if (i >= 0)
		{
			FooPlaylist* const p = playlists->at(i);

			if (currentPlayingPlaylist == p)
			{
				currentPlayingPlaylist = NULL;
			}

			delete p;

			playlists->removeAt(i);

			emit playlistRemoved(name, uuid);

			if (playlists->size() == 0)
			{
				createPlaylist();
			}
		}
	}
Example #3
0
void KNMusicPlaylistManager::onActionCreatePlaylist(const int &position)
{
    //Create the playlist.
    QModelIndex playlistIndex=createPlaylist(position);
    //Require rename the playlist index.
    emit requireShowAndRenamePlaylist(playlistIndex);
}
Example #4
0
bool QSpotifyUser::createPlaylistInFolder(const QString &name, QSpotifyPlaylist *folder)
{
    if (!folder || folder->type() != QSpotifyPlaylist::Folder)
        return createPlaylist(name);

    if (name.trimmed().isEmpty())
        return false;

    QString n = name;
    if (n.size() > 255)
        n.resize(255);
    sp_playlist *pl = sp_playlistcontainer_add_new_playlist(m_playlistContainer->m_container, n.toUtf8().constData());
    if (!pl)
        return false;

    int i = m_playlistContainer->m_playlists.indexOf(folder);
    if (i == -1)
        return true;

    sp_uint64 folderId = sp_playlistcontainer_playlist_folder_id(m_playlistContainer->m_container, i);
    int count = sp_playlistcontainer_num_playlists(m_playlistContainer->m_container);
    for (int j = i + 1; j < count; ++j) {
        if (folderId == sp_playlistcontainer_playlist_folder_id(m_playlistContainer->m_container, j))
            i = j;
    }
    sp_playlistcontainer_move_playlist(m_playlistContainer->m_container, count - 1, i, false);

    return true;
}
OMXPlayerPlaylist::OMXPlayerPlaylist ( string filename )
{
   current = 0;
   playlistPath = filename;
   createPlaylist ();
   if ( !isValidPlaylist () )
   {
      printf ( "Invalid Playlist \n" );
   }
}
	FooPlaylistManager::FooPlaylistManager(FooAudioEngine *engine, QObject *parent) : QObject(parent)
	{
		this->engine = engine;
		playlists = new QList<FooPlaylist*>();
		//	metaVersion = 1;

		setPlaylistColumnConfig("%pn;%ti;%al;%ar");

		if (playlists->size() < 1)
		{
			createPlaylist();
			currentPlayingPlaylist = NULL;
		}
	}
Example #7
0
void DecoderHandler::start(MusicMetadata *mdata)
{
    m_state = LOADING;

    m_playlist.clear();
    m_meta = *mdata;
    m_playlist_pos = -1;
    m_redirects = 0;

    if (QFileInfo(mdata->Filename()).isAbsolute())
        m_url = QUrl::fromLocalFile(mdata->Filename());
    else
        m_url.setUrl(mdata->Filename());

    createPlaylist(m_url);
}
Example #8
0
//----------------------------------------------------------------
// main_utf8
// 
int main_utf8(int argc, char **argv)
{
    const char *input = NULL;
    const char *output_prefix = "";
    double target_segment_duration = 0.0;
    char *segment_duration_check = NULL;
    const char *playlist_filename = NULL;
    const char *http_prefix = "";
    long max_tsfiles = 0;
    char *max_tsfiles_check = NULL;
    double prev_segment_time = 0.0;
    double segment_duration = 0.0;
    unsigned int output_index = 0;
    const AVClass *fc = avformat_get_class();
    AVDictionary *format_opts = NULL;
    AVOutputFormat *ofmt = NULL;
    AVFormatContext *ic = NULL;
    AVFormatContext *oc = NULL;
    AVStream *video_st = NULL;
    AVStream *audio_st = NULL;
    AVCodec *codec = NULL;
    char *output_filename = NULL;
    char *pid_filename = NULL;
    int video_index = -1;
    int audio_index = -1;
    int kill_file = 0;
    int decode_done = 0;
    int ret = 0;
    int i = 0;
    TSMStreamLace * streamLace = NULL;
    TSMPlaylist * playlist = NULL;
    const double segment_duration_error_tolerance = 0.05;
    double extra_duration_needed = 0;
    int strict_segment_duration = 0;
    
    av_log_set_level(AV_LOG_INFO);
    
    for (int i = 1; i < argc; i++)
    {
        if (strcmp(argv[i], "-i") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -i parameter");
            i++;
            input = argv[i];
        }
        else if (strcmp(argv[i], "-o") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -i parameter");
            i++;
            output_prefix = argv[i];
        }
        else if (strcmp(argv[i], "-d") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -d parameter");
            i++;
            
            target_segment_duration = strtod(argv[i], &segment_duration_check);
            if (segment_duration_check == argv[i] ||
                target_segment_duration == HUGE_VAL ||
                target_segment_duration == -HUGE_VAL)
            {
                usage3(argv, "invalid segment duration: ", argv[i]);
            }
        }
        else if (strcmp(argv[i], "-x") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -x parameter");
            i++;
            playlist_filename = argv[i];
        }
        else if (strcmp(argv[i], "-p") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -p parameter");
            i++;
            http_prefix = argv[i];
        }
        else if (strcmp(argv[i], "-w") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -w parameter");
            i++;

            max_tsfiles = strtol(argv[i], &max_tsfiles_check, 10);
            if (max_tsfiles_check == argv[i] ||
                max_tsfiles < 0 ||
                max_tsfiles >= INT_MAX)
            {
                usage3(argv, "invalid live stream max window size: ", argv[i]);
            }
        }
        else if (strcmp(argv[i], "-P") == 0)
        {
            if ((argc - i) <= 1) usage(argv, "could not parse -P parameter");
            i++;
            pid_filename = argv[i];
        }
        else if (strcmp(argv[i], "--watch-for-kill-file") == 0)
        {
            // end program when it finds a file with name 'kill':
            kill_file = 1;
        }
        else if (strcmp(argv[i], "--strict-segment-duration") == 0)
        {
            // force segment creation on non-keyframe boundaries:
            strict_segment_duration = 1;
        }
        else if (strcmp(argv[i], "--avformat-option") == 0)
        {
            const AVOption *of;
            const char *opt;
            const char *arg;
            if ((argc - i) <= 1) usage(argv, "could not parse --avformat-option parameter");
            i++;
            opt = argv[i];
            if ((argc - i) <= 1) usage(argv, "could not parse --avformat-option parameter");
            i++;
            arg = argv[i];

            if ((of = av_opt_find(&fc, opt, NULL, 0,
                                  AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
                av_dict_set(&format_opts, opt, arg, (of->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0);
            else
                usage3(argv, "unknown --avformat-option parameter: ", opt);
        }
        else if (strcmp(argv[i], "--loglevel") == 0)
        {
            const char *arg;
            if ((argc - i) <= 1) usage(argv, "could not parse --loglevel parameter");
            i++;
            arg = argv[i];

            if (loglevel(arg))
                usage3(argv, "unknown --loglevel parameter: ", arg);
        }
    }
    
    if (!input)
    {
        usage(argv, "-i input file parameter must be specified");
    }
    
    if (!playlist_filename)
    {
        usage(argv, "-x m3u8 playlist file parameter must be specified");
    }
    
    if (target_segment_duration == 0.0)
    {
        usage(argv, "-d segment duration parameter must be specified");
    }
    
    // Create PID file
    if (pid_filename)
    {
        FILE* pid_file = fopen_utf8(pid_filename, "wb");
        if (pid_file)
        {
            fprintf(pid_file, "%d", getpid());
            fclose(pid_file);
        }
    }

    av_register_all();
    avformat_network_init();

    if (!strcmp(input, "-")) {
        input = "pipe:";
    }
    
    output_filename = malloc(sizeof(char) * (strlen(output_prefix) + 15));
    if (!output_filename) {
        fprintf(stderr, "Could not allocate space for output filenames\n");
        goto error;
    }

    playlist = createPlaylist(max_tsfiles,
                              target_segment_duration,
                              http_prefix);
    if (!playlist)
    {
        fprintf(stderr, "Could not allocate space for m3u8 playlist structure\n");
        goto error;
    }

    ret = avformat_open_input(&ic, input, NULL, (format_opts) ? &format_opts : NULL);
    if (ret != 0) {
        fprintf(stderr, "Could not open input file, make sure it is an mpegts or mp4 file: %d\n", ret);
        goto error;
    }
    av_dict_free(&format_opts);

    if (avformat_find_stream_info(ic, NULL) < 0) {
        fprintf(stderr, "Could not read stream information\n");
        goto error;
    }

#if LIBAVFORMAT_VERSION_MAJOR > 52 || (LIBAVFORMAT_VERSION_MAJOR == 52 && \
                                       LIBAVFORMAT_VERSION_MINOR >= 45)
    ofmt = av_guess_format("mpegts", NULL, NULL);
#else
    ofmt = guess_format("mpegts", NULL, NULL);
#endif
    
    if (!ofmt) {
        fprintf(stderr, "Could not find MPEG-TS muxer\n");
        goto error;
    }

    oc = avformat_alloc_context();
    if (!oc) {
        fprintf(stderr, "Could not allocated output context\n");
        goto error;
    }
    oc->oformat = ofmt;

    video_index = -1;
    audio_index = -1;

    for (i = 0; i < ic->nb_streams && (video_index < 0 || audio_index < 0); i++) {
        switch (ic->streams[i]->codec->codec_type) {
            case AVMEDIA_TYPE_VIDEO:
                video_index = i;
                ic->streams[i]->discard = AVDISCARD_NONE;
                video_st = add_output_stream(oc, ic->streams[i]);
                break;
            case AVMEDIA_TYPE_AUDIO:
                audio_index = i;
                ic->streams[i]->discard = AVDISCARD_NONE;
                audio_st = add_output_stream(oc, ic->streams[i]);
                break;
            default:
                ic->streams[i]->discard = AVDISCARD_ALL;
                break;
        }
    }

    av_dump_format(oc, 0, output_prefix, 1);
    
    if (video_index >=0) {
      codec = avcodec_find_decoder(video_st->codec->codec_id);
      if (!codec) {
        fprintf(stderr, "Could not find video decoder, key frames will not be honored\n");
      }

      if (avcodec_open2(video_st->codec, codec, NULL) < 0) {
        fprintf(stderr, "Could not open video decoder, key frames will not be honored\n");
      }
    }

    snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts", output_prefix, ++output_index);
    if (avio_open(&oc->pb, output_filename, AVIO_FLAG_WRITE) < 0) {
        fprintf(stderr, "Could not open '%s'\n", output_filename);
        goto error;
    }

    if (avformat_write_header(oc, NULL)) {
        fprintf(stderr, "Could not write mpegts header to first output file\n");
        goto error;
    }

    prev_segment_time = (double)(ic->start_time) / (double)(AV_TIME_BASE);

    streamLace = createStreamLace(ic->nb_streams);
    
    do {
        double segment_time = 0.0;
        AVPacket packet;
        double packetStartTime = 0.0;
        double packetDuration = 0.0;
        
        if (!decode_done)
        {
            decode_done = av_read_frame(ic, &packet);
            if (!decode_done)
            {
                if (packet.stream_index != video_index &&
                    packet.stream_index != audio_index)
                {
                    av_free_packet(&packet);
                    continue;
                }
                
                double timeStamp = 
                    (double)(packet.pts) * 
                    (double)(ic->streams[packet.stream_index]->time_base.num) /
                    (double)(ic->streams[packet.stream_index]->time_base.den);
                
                if (av_dup_packet(&packet) < 0)
                {
                    fprintf(stderr, "Could not duplicate packet\n");
                    av_free_packet(&packet);
                    break;
                }
                
                insertPacket(streamLace, &packet, timeStamp);
            }
        }
        
        if (countPackets(streamLace) < 50 && !decode_done)
        {
            /* allow the queue to fill up so that the packets can be sorted properly */
            continue;
        }
        
        if (!removePacket(streamLace, &packet))
        {
            if (decode_done)
            {
                /* the queue is empty, we are done */
                break;
            }
            
            assert(decode_done);
            continue;
        }
        
        packetStartTime = 
            (double)(packet.pts) * 
            (double)(ic->streams[packet.stream_index]->time_base.num) /
            (double)(ic->streams[packet.stream_index]->time_base.den);
        
        packetDuration =
            (double)(packet.duration) *
            (double)(ic->streams[packet.stream_index]->time_base.num) /
            (double)(ic->streams[packet.stream_index]->time_base.den);
        
#if !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG))
        if (av_log_get_level() >= AV_LOG_VERBOSE)
            fprintf(stderr,
                    "stream %i, packet [%f, %f)\n",
                    packet.stream_index,
                    packetStartTime,
                    packetStartTime + packetDuration);
#endif

        segment_duration = packetStartTime + packetDuration - prev_segment_time;

        // NOTE: segments are supposed to start on a keyframe.
        // If the keyframe interval and segment duration do not match
        // forcing the segment creation for "better seeking behavior"
        // will result in decoding artifacts after seeking or stream switching.
        if (packet.stream_index == video_index && (packet.flags & AV_PKT_FLAG_KEY || strict_segment_duration)) {
            segment_time = packetStartTime;
        }
        else if (video_index < 0) {
            segment_time = packetStartTime;
        }
        else {
            segment_time = prev_segment_time;
        }

        if (segment_time - prev_segment_time + segment_duration_error_tolerance >
            target_segment_duration + extra_duration_needed) 
        {
            avio_flush(oc->pb);
            avio_close(oc->pb);

            // Keep track of accumulated rounding error to account for it in later chunks.
            double segment_duration = segment_time - prev_segment_time;
            int rounded_segment_duration = (int)(segment_duration + 0.5);
            extra_duration_needed += (double)rounded_segment_duration - segment_duration;

            updatePlaylist(playlist,
                           playlist_filename,
                           output_filename,
                           output_index,
                           rounded_segment_duration);
            
            snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts", output_prefix, ++output_index);
            if (avio_open(&oc->pb, output_filename, AVIO_FLAG_WRITE) < 0) {
                fprintf(stderr, "Could not open '%s'\n", output_filename);
                break;
            }

            // close when we find the 'kill' file
            if (kill_file) {
                FILE* fp = fopen("kill", "rb");
                if (fp) {
                    fprintf(stderr, "user abort: found kill file\n");
                    fclose(fp);
                    remove("kill");
                    decode_done = 1;
                    removeAllPackets(streamLace);
                }
            }
            prev_segment_time = segment_time;
        }

        ret = av_interleaved_write_frame(oc, &packet);
        if (ret < 0) {
            fprintf(stderr, "Warning: Could not write frame of stream\n");
        }
        else if (ret > 0) {
            fprintf(stderr, "End of stream requested\n");
            av_free_packet(&packet);
            break;
        }

        av_free_packet(&packet);
    } while (!decode_done || countPackets(streamLace) > 0);

    av_write_trailer(oc);

    if (video_index >= 0) {
      avcodec_close(video_st->codec);
    }

    for(i = 0; i < oc->nb_streams; i++) {
        av_freep(&oc->streams[i]->codec);
        av_freep(&oc->streams[i]);
    }

    avio_close(oc->pb);
    av_free(oc);

    updatePlaylist(playlist,
                   playlist_filename,
                   output_filename,
                   output_index,
                   segment_duration);
    closePlaylist(playlist);
    releasePlaylist(&playlist);
    
    if (pid_filename)
    {
        remove(pid_filename);
    }

    return 0;

error:
    if (pid_filename)
    {
        remove(pid_filename);
    }

    return 1;

}
Example #9
0
void WMainMenuBar::initialize() {
    // FILE MENU
    QMenu* pFileMenu = new QMenu(tr("&File"));

    QString loadTrackText = tr("Load Track to Deck &%1");
    QString loadTrackStatusText = tr("Loads a track in deck %1");
    QString openText = tr("Open");
    for (unsigned int deck = 0; deck < kMaxLoadToDeckActions; ++deck) {
        QString playerLoadStatusText = loadTrackStatusText.arg(QString::number(deck + 1));
        QAction* pFileLoadSongToPlayer = new QAction(
            loadTrackText.arg(QString::number(deck + 1)), this);

        QString binding = m_pKbdConfig->getValueString(
                ConfigKey("[KeyboardShortcuts]", QString("FileMenu_LoadDeck%1").arg(deck + 1)),
                loadToDeckDefaultKeyBinding(deck));
        if (!binding.isEmpty()) {
            pFileLoadSongToPlayer->setShortcut(QKeySequence(binding));
            pFileLoadSongToPlayer->setShortcutContext(Qt::ApplicationShortcut);
        }
        pFileLoadSongToPlayer->setStatusTip(playerLoadStatusText);
        pFileLoadSongToPlayer->setWhatsThis(
            buildWhatsThis(openText, playerLoadStatusText));
        // Visibility of load to deck actions is set in
        // WMainMenuBar::onNumberOfDecksChanged.
        pFileLoadSongToPlayer->setVisible(false);
        connect(pFileLoadSongToPlayer, SIGNAL(triggered()),
                &m_loadToDeckMapper, SLOT(map()));
        m_loadToDeckMapper.setMapping(pFileLoadSongToPlayer, deck + 1);
        pFileMenu->addAction(pFileLoadSongToPlayer);
        m_loadToDeckActions.push_back(pFileLoadSongToPlayer);
    }

    pFileMenu->addSeparator();

    QString quitTitle = tr("&Exit");
    QString quitText = tr("Quits Mixxx");
    QAction* pFileQuit = new QAction(quitTitle, this);
    pFileQuit->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]", "FileMenu_Quit"),
                                                  tr("Ctrl+q"))));
    pFileQuit->setShortcutContext(Qt::ApplicationShortcut);
    pFileQuit->setStatusTip(quitText);
    pFileQuit->setWhatsThis(buildWhatsThis(quitTitle, quitText));
    pFileQuit->setMenuRole(QAction::QuitRole);
    connect(pFileQuit, SIGNAL(triggered()), this, SIGNAL(quit()));
    pFileMenu->addAction(pFileQuit);

    addMenu(pFileMenu);

    // LIBRARY MENU
    QMenu* pLibraryMenu = new QMenu(tr("&Library"));

    QString rescanTitle = tr("&Rescan Library");
    QString rescanText = tr("Rescans library folders for changes to tracks.");
    QAction* pLibraryRescan = new QAction(rescanTitle, this);
    pLibraryRescan->setStatusTip(rescanText);
    pLibraryRescan->setWhatsThis(buildWhatsThis(rescanTitle, rescanText));
    pLibraryRescan->setCheckable(false);
    connect(pLibraryRescan, SIGNAL(triggered()),
            this, SIGNAL(rescanLibrary()));
    // Disable the action when a scan is active.
    connect(this, SIGNAL(internalLibraryScanActive(bool)),
            pLibraryRescan, SLOT(setDisabled(bool)));
    pLibraryMenu->addAction(pLibraryRescan);

    pLibraryMenu->addSeparator();

    QString createPlaylistTitle = tr("Create &New Playlist");
    QString createPlaylistText = tr("Create a new playlist");
    QAction* pLibraryCreatePlaylist = new QAction(createPlaylistTitle, this);
    pLibraryCreatePlaylist->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "LibraryMenu_NewPlaylist"),
                                                  tr("Ctrl+n"))));
    pLibraryCreatePlaylist->setShortcutContext(Qt::ApplicationShortcut);
    pLibraryCreatePlaylist->setStatusTip(createPlaylistText);
    pLibraryCreatePlaylist->setWhatsThis(buildWhatsThis(createPlaylistTitle, createPlaylistText));
    connect(pLibraryCreatePlaylist, SIGNAL(triggered()),
            this, SIGNAL(createPlaylist()));
    pLibraryMenu->addAction(pLibraryCreatePlaylist);

    QString createCrateTitle = tr("Create New &Crate");
    QString createCrateText = tr("Create a new crate");
    QAction* pLibraryCreateCrate = new QAction(createCrateTitle, this);
    pLibraryCreateCrate->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "LibraryMenu_NewCrate"),
                                                  tr("Ctrl+Shift+N"))));
    pLibraryCreateCrate->setShortcutContext(Qt::ApplicationShortcut);
    pLibraryCreateCrate->setStatusTip(createCrateText);
    pLibraryCreateCrate->setWhatsThis(buildWhatsThis(createCrateTitle, createCrateText));
    connect(pLibraryCreateCrate, SIGNAL(triggered()),
            this, SIGNAL(createCrate()));
    pLibraryMenu->addAction(pLibraryCreateCrate);

    addMenu(pLibraryMenu);

    // VIEW MENU
    QMenu* pViewMenu = new QMenu(tr("&View"));

    QString mayNotBeSupported = tr("May not be supported on all skins.");
    QString showSamplersTitle = tr("Show Samplers");
    QString showSamplersText = tr("Show the sample deck section of the Mixxx interface.") +
            " " + mayNotBeSupported;
    QAction* pViewShowSamplers = new QAction(showSamplersTitle, this);
    pViewShowSamplers->setCheckable(true);
    pViewShowSamplers->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_ShowSamplers"),
                                                  tr("Ctrl+1", "Menubar|View|Show Samplers"))));
    pViewShowSamplers->setStatusTip(showSamplersText);
    pViewShowSamplers->setWhatsThis(buildWhatsThis(showSamplersTitle, showSamplersText));
    createVisibilityControl(pViewShowSamplers, ConfigKey("[Samplers]", "show_samplers"));
    pViewMenu->addAction(pViewShowSamplers);

    QString showMicrophoneTitle = tr("Show Microphone Section");
    QString showMicrophoneText = tr("Show the microphone section of the Mixxx interface.") +
            " " + mayNotBeSupported;
    QAction* pViewShowMicrophone = new QAction(showMicrophoneTitle, this);
    pViewShowMicrophone->setCheckable(true);
    pViewShowMicrophone->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(
            ConfigKey("[KeyboardShortcuts]", "ViewMenu_ShowMicrophone"),
            tr("Ctrl+2", "Menubar|View|Show Microphone Section"))));
    pViewShowMicrophone->setStatusTip(showMicrophoneText);
    pViewShowMicrophone->setWhatsThis(buildWhatsThis(showMicrophoneTitle, showMicrophoneText));
    createVisibilityControl(pViewShowMicrophone, ConfigKey("[Microphone]", "show_microphone"));
    pViewMenu->addAction(pViewShowMicrophone);

#ifdef __VINYLCONTROL__
    QString showVinylControlTitle = tr("Show Vinyl Control Section");
    QString showVinylControlText = tr("Show the vinyl control section of the Mixxx interface.") +
            " " + mayNotBeSupported;
    QAction* pViewVinylControl = new QAction(showVinylControlTitle, this);
    pViewVinylControl->setCheckable(true);
    pViewVinylControl->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(
            ConfigKey("[KeyboardShortcuts]", "ViewMenu_ShowVinylControl"),
            tr("Ctrl+3", "Menubar|View|Show Vinyl Control Section"))));
    pViewVinylControl->setStatusTip(showVinylControlText);
    pViewVinylControl->setWhatsThis(buildWhatsThis(showVinylControlTitle, showVinylControlText));
    createVisibilityControl(pViewVinylControl, ConfigKey(VINYL_PREF_KEY, "show_vinylcontrol"));
    pViewMenu->addAction(pViewVinylControl);
#endif

    QString showPreviewDeckTitle = tr("Show Preview Deck");
    QString showPreviewDeckText = tr("Show the preview deck in the Mixxx interface.") +
            " " + mayNotBeSupported;
    QAction* pViewShowPreviewDeck = new QAction(showPreviewDeckTitle, this);
    pViewShowPreviewDeck->setCheckable(true);
    pViewShowPreviewDeck->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_ShowPreviewDeck"),
                                                  tr("Ctrl+4", "Menubar|View|Show Preview Deck"))));
    pViewShowPreviewDeck->setStatusTip(showPreviewDeckText);
    pViewShowPreviewDeck->setWhatsThis(buildWhatsThis(showPreviewDeckTitle, showPreviewDeckText));
    createVisibilityControl(pViewShowPreviewDeck, ConfigKey("[PreviewDeck]", "show_previewdeck"));
    pViewMenu->addAction(pViewShowPreviewDeck);

    QString showEffectsTitle = tr("Show Effect Rack");
    QString showEffectsText = tr("Show the effect rack in the Mixxx interface.") +
    " " + mayNotBeSupported;
    QAction* pViewShowEffects = new QAction(showEffectsTitle, this);
    pViewShowEffects->setCheckable(true);
    pViewShowEffects->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_ShowEffects"),
                                                  tr("Ctrl+5", "Menubar|View|Show Effect Rack"))));
    pViewShowEffects->setStatusTip(showEffectsText);
    pViewShowEffects->setWhatsThis(buildWhatsThis(showEffectsTitle, showEffectsText));
    createVisibilityControl(pViewShowEffects, ConfigKey("[EffectRack1]", "show"));
    pViewMenu->addAction(pViewShowEffects);


    QString showCoverArtTitle = tr("Show Cover Art");
    QString showCoverArtText = tr("Show cover art in the Mixxx interface.") +
            " " + mayNotBeSupported;
    QAction* pViewShowCoverArt = new QAction(showCoverArtTitle, this);
    pViewShowCoverArt->setCheckable(true);
    pViewShowCoverArt->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_ShowCoverArt"),
                                                  tr("Ctrl+6", "Menubar|View|Show Cover Art"))));
    pViewShowCoverArt->setStatusTip(showCoverArtText);
    pViewShowCoverArt->setWhatsThis(buildWhatsThis(showCoverArtTitle, showCoverArtText));
    createVisibilityControl(pViewShowCoverArt, ConfigKey("[Library]", "show_coverart"));
    pViewMenu->addAction(pViewShowCoverArt);


    QString maximizeLibraryTitle = tr("Maximize Library");
    QString maximizeLibraryText = tr("Maximize the track library to take up all the available screen space.") +
            " " + mayNotBeSupported;
    QAction* pViewMaximizeLibrary = new QAction(maximizeLibraryTitle, this);
    pViewMaximizeLibrary->setCheckable(true);
    pViewMaximizeLibrary->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_MaximizeLibrary"),
                                                  tr("Space", "Menubar|View|Maximize Library"))));
    pViewMaximizeLibrary->setStatusTip(maximizeLibraryText);
    pViewMaximizeLibrary->setWhatsThis(buildWhatsThis(maximizeLibraryTitle, maximizeLibraryText));
    createVisibilityControl(pViewMaximizeLibrary, ConfigKey("[Master]", "maximize_library"));
    pViewMenu->addAction(pViewMaximizeLibrary);


    pViewMenu->addSeparator();


    QString fullScreenTitle = tr("&Full Screen");
    QString fullScreenText = tr("Display Mixxx using the full screen");
    QAction* pViewFullScreen = new QAction(fullScreenTitle, this);
    pViewFullScreen->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "ViewMenu_Fullscreen"),
                                                  fullScreenDefaultKeyBinding())));
    pViewFullScreen->setShortcutContext(Qt::ApplicationShortcut);
    pViewFullScreen->setCheckable(true);
    pViewFullScreen->setChecked(false);
    pViewFullScreen->setStatusTip(fullScreenText);
    pViewFullScreen->setWhatsThis(buildWhatsThis(fullScreenTitle, fullScreenText));
    connect(pViewFullScreen, SIGNAL(triggered(bool)),
            this, SIGNAL(toggleFullScreen(bool)));
    connect(this, SIGNAL(internalFullScreenStateChange(bool)),
            pViewFullScreen, SLOT(setChecked(bool)));
    pViewMenu->addAction(pViewFullScreen);

    addMenu(pViewMenu);

    // OPTIONS MENU
    QMenu* pOptionsMenu = new QMenu(tr("&Options"));

#ifdef __VINYLCONTROL__
    QMenu* pVinylControlMenu = new QMenu(tr("&Vinyl Control"));
    QString vinylControlText = tr(
            "Use timecoded vinyls on external turntables to control Mixxx");

    for (int i = 0; i < kMaximumVinylControlInputs; ++i) {
        QString vinylControlTitle = tr("Enable Vinyl Control &%1").arg(i + 1);
        QAction* vc_checkbox = new QAction(vinylControlTitle, this);
        m_vinylControlEnabledActions.push_back(vc_checkbox);

        QString binding = m_pKbdConfig->getValueString(
            ConfigKey("[KeyboardShortcuts]",
                      QString("OptionsMenu_EnableVinyl%1").arg(i + 1)),
            vinylControlDefaultKeyBinding(i));
        if (!binding.isEmpty()) {
            vc_checkbox->setShortcut(QKeySequence(binding));
            vc_checkbox->setShortcutContext(Qt::ApplicationShortcut);
        }

        // Either check or uncheck the vinyl control menu item depending on what
        // it was saved as.
        vc_checkbox->setCheckable(true);
        vc_checkbox->setChecked(false);
        // The visibility of these actions is set in
        // WMainMenuBar::onNumberOfDecksChanged.
        vc_checkbox->setVisible(false);
        vc_checkbox->setStatusTip(vinylControlText);
        vc_checkbox->setWhatsThis(buildWhatsThis(vinylControlTitle,
                                                 vinylControlText));

        m_vinylControlEnabledMapper.setMapping(vc_checkbox, i);
        connect(vc_checkbox, SIGNAL(triggered(bool)),
                &m_vinylControlEnabledMapper, SLOT(map()));
        pVinylControlMenu->addAction(vc_checkbox);
    }
    pOptionsMenu->addMenu(pVinylControlMenu);
    pOptionsMenu->addSeparator();
#endif

    QString recordTitle = tr("&Record Mix");
    QString recordText = tr("Record your mix to a file");
    QAction* pOptionsRecord = new QAction(recordTitle, this);
    pOptionsRecord->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "OptionsMenu_RecordMix"),
                                                  tr("Ctrl+R"))));
    pOptionsRecord->setShortcutContext(Qt::ApplicationShortcut);
    pOptionsRecord->setCheckable(true);
    pOptionsRecord->setStatusTip(recordText);
    pOptionsRecord->setWhatsThis(buildWhatsThis(recordTitle, recordText));
    connect(pOptionsRecord, SIGNAL(triggered(bool)),
            this, SIGNAL(toggleRecording(bool)));
    connect(this, SIGNAL(internalRecordingStateChange(bool)),
            pOptionsRecord, SLOT(setChecked(bool)));
    pOptionsMenu->addAction(pOptionsRecord);

#ifdef __SHOUTCAST__
    QString broadcastingTitle = tr("Enable Live &Broadcasting");
    QString broadcastingText = tr("Stream your mixes to a shoutcast or icecast server");
    QAction* pOptionsBroadcasting = new QAction(broadcastingTitle, this);
    pOptionsBroadcasting->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(
                    ConfigKey("[KeyboardShortcuts]",
                              "OptionsMenu_EnableLiveBroadcasting"),
                    tr("Ctrl+L"))));
    pOptionsBroadcasting->setShortcutContext(Qt::ApplicationShortcut);
    pOptionsBroadcasting->setCheckable(true);
    pOptionsBroadcasting->setStatusTip(broadcastingText);
    pOptionsBroadcasting->setWhatsThis(buildWhatsThis(broadcastingTitle, broadcastingText));

    connect(pOptionsBroadcasting, SIGNAL(triggered(bool)),
            this, SIGNAL(toggleBroadcasting(bool)));
    connect(this, SIGNAL(internalBroadcastingStateChange(bool)),
            pOptionsBroadcasting, SLOT(setChecked(bool)));
    pOptionsMenu->addAction(pOptionsBroadcasting);
#endif

    pOptionsMenu->addSeparator();

    QString keyboardShortcutTitle = tr("Enable &Keyboard Shortcuts");
    QString keyboardShortcutText = tr("Toggles keyboard shortcuts on or off");
    bool keyboardShortcutsEnabled = m_pConfig->getValueString(
        ConfigKey("[Keyboard]", "Enabled")) == "1";
    QAction* pOptionsKeyboard = new QAction(keyboardShortcutTitle, this);
    pOptionsKeyboard->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "OptionsMenu_EnableShortcuts"),
                                                  tr("Ctrl+`"))));
    pOptionsKeyboard->setShortcutContext(Qt::ApplicationShortcut);
    pOptionsKeyboard->setCheckable(true);
    pOptionsKeyboard->setChecked(keyboardShortcutsEnabled);
    pOptionsKeyboard->setStatusTip(keyboardShortcutText);
    pOptionsKeyboard->setWhatsThis(buildWhatsThis(keyboardShortcutTitle, keyboardShortcutText));
    connect(pOptionsKeyboard, SIGNAL(triggered(bool)),
            this, SIGNAL(toggleKeyboardShortcuts(bool)));

    pOptionsMenu->addAction(pOptionsKeyboard);

    pOptionsMenu->addSeparator();

    QString preferencesTitle = tr("&Preferences");
    QString preferencesText = tr("Change Mixxx settings (e.g. playback, MIDI, controls)");
    QAction* pOptionsPreferences = new QAction(preferencesTitle, this);
    pOptionsPreferences->setShortcut(
        QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                  "OptionsMenu_Preferences"),
                                                  showPreferencesKeyBinding())));
    pOptionsPreferences->setShortcutContext(Qt::ApplicationShortcut);
    pOptionsPreferences->setStatusTip(preferencesText);
    pOptionsPreferences->setWhatsThis(buildWhatsThis(preferencesTitle, preferencesText));
    pOptionsPreferences->setMenuRole(QAction::PreferencesRole);
    connect(pOptionsPreferences, SIGNAL(triggered()),
            this, SIGNAL(showPreferences()));
    pOptionsMenu->addAction(pOptionsPreferences);

    addMenu(pOptionsMenu);

    // DEVELOPER MENU
    if (CmdlineArgs::Instance().getDeveloper()) {
        QMenu* pDeveloperMenu = new QMenu(tr("&Developer"));

        QString reloadSkinTitle = tr("&Reload Skin");
        QString reloadSkinText = tr("Reload the skin");
        QAction* pDeveloperReloadSkin = new QAction(reloadSkinTitle, this);
        pDeveloperReloadSkin->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                                "OptionsMenu_ReloadSkin"),
                                                      tr("Ctrl+Shift+R"))));
        pDeveloperReloadSkin->setShortcutContext(Qt::ApplicationShortcut);
        pDeveloperReloadSkin->setStatusTip(reloadSkinText);
        pDeveloperReloadSkin->setWhatsThis(buildWhatsThis(reloadSkinTitle, reloadSkinText));
        connect(pDeveloperReloadSkin, SIGNAL(triggered()),
                this, SIGNAL(reloadSkin()));
        pDeveloperMenu->addAction(pDeveloperReloadSkin);

        QString developerToolsTitle = tr("Developer &Tools");
        QString developerToolsText = tr("Opens the developer tools dialog");
        QAction* pDeveloperTools = new QAction(developerToolsTitle, this);
        pDeveloperTools->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                                "OptionsMenu_DeveloperTools"),
                                                      tr("Ctrl+Shift+T"))));
        pDeveloperTools->setShortcutContext(Qt::ApplicationShortcut);
        pDeveloperTools->setCheckable(true);
        pDeveloperTools->setChecked(false);
        pDeveloperTools->setStatusTip(developerToolsText);
        pDeveloperTools->setWhatsThis(buildWhatsThis(developerToolsTitle, developerToolsText));
        connect(pDeveloperTools, SIGNAL(triggered(bool)),
                this, SIGNAL(toggleDeveloperTools(bool)));
        connect(this, SIGNAL(internalDeveloperToolsStateChange(bool)),
                pDeveloperTools, SLOT(setChecked(bool)));
        pDeveloperMenu->addAction(pDeveloperTools);

        QString enableExperimentTitle = tr("Stats: &Experiment Bucket");
        QString enableExperimentToolsText = tr(
            "Enables experiment mode. Collects stats in the EXPERIMENT tracking bucket.");
        QAction* pDeveloperStatsExperiment = new QAction(enableExperimentTitle, this);
        pDeveloperStatsExperiment->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                                "OptionsMenu_DeveloperStatsExperiment"),
                                                      tr("Ctrl+Shift+E"))));
        pDeveloperStatsExperiment->setShortcutContext(Qt::ApplicationShortcut);
        pDeveloperStatsExperiment->setStatusTip(enableExperimentToolsText);
        pDeveloperStatsExperiment->setWhatsThis(buildWhatsThis(
            enableExperimentTitle, enableExperimentToolsText));
        pDeveloperStatsExperiment->setCheckable(true);
        pDeveloperStatsExperiment->setChecked(Experiment::isExperiment());
        connect(pDeveloperStatsExperiment, SIGNAL(triggered(bool)),
                this, SLOT(slotDeveloperStatsExperiment(bool)));
        pDeveloperMenu->addAction(pDeveloperStatsExperiment);

        QString enableBaseTitle = tr("Stats: &Base Bucket");
        QString enableBaseToolsText = tr(
            "Enables base mode. Collects stats in the BASE tracking bucket.");
        QAction* pDeveloperStatsBase = new QAction(enableBaseTitle, this);
        pDeveloperStatsBase->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                                "OptionsMenu_DeveloperStatsBase"),
                                                      tr("Ctrl+Shift+B"))));
        pDeveloperStatsBase->setShortcutContext(Qt::ApplicationShortcut);
        pDeveloperStatsBase->setStatusTip(enableBaseToolsText);
        pDeveloperStatsBase->setWhatsThis(buildWhatsThis(
            enableBaseTitle, enableBaseToolsText));
        pDeveloperStatsBase->setCheckable(true);
        pDeveloperStatsBase->setChecked(Experiment::isBase());
        connect(pDeveloperStatsBase, SIGNAL(triggered(bool)),
                this, SLOT(slotDeveloperStatsBase(bool)));
        pDeveloperMenu->addAction(pDeveloperStatsBase);

        // "D" cannont be used with Alt here as it is already by the Developer menu
        QString scriptDebuggerTitle = tr("Deb&ugger Enabled");
        QString scriptDebuggerText = tr("Enables the debugger during skin parsing");
        bool scriptDebuggerEnabled = m_pConfig->getValueString(
            ConfigKey("[ScriptDebugger]", "Enabled")) == "1";
        QAction* pDeveloperDebugger = new QAction(scriptDebuggerTitle, this);
        pDeveloperDebugger->setShortcut(
            QKeySequence(m_pKbdConfig->getValueString(ConfigKey("[KeyboardShortcuts]",
                                                                "DeveloperMenu_EnableDebugger"),
                                                      tr("Ctrl+Shift+D"))));
        pDeveloperDebugger->setShortcutContext(Qt::ApplicationShortcut);
        pDeveloperDebugger->setWhatsThis(buildWhatsThis(keyboardShortcutTitle, keyboardShortcutText));
        pDeveloperDebugger->setCheckable(true);
        pDeveloperDebugger->setStatusTip(scriptDebuggerText);
        pDeveloperDebugger->setChecked(scriptDebuggerEnabled);
        connect(pDeveloperDebugger, SIGNAL(triggered(bool)),
                this, SLOT(slotDeveloperDebugger(bool)));
        pDeveloperMenu->addAction(pDeveloperDebugger);

        addMenu(pDeveloperMenu);
    }
Example #10
0
void Request::http(const String &prefix, Http::Request &request)
{
	try {
		std::unique_lock<std::mutex> lock(mMutex);	// Request::http() is synced !

		// Cancel autodeletion
		mAutoDeleter.cancel();

		int next = 0;
		if(request.get.contains("next"))
			request.get["next"].extract(next);

		duration timeout = milliseconds(Config::Get("request_timeout").toDouble());
		if(request.get.contains("timeout"))
			timeout = milliseconds(request.get["timeout"].toDouble());

		mCondition.wait_for(lock, timeout, [this, next]() {
			return int(mResults.size()) > next || mFinished;
		});

		// Playlist
		if(request.get.contains("playlist"))
		{
			int start = -1;
			int stop  = -1;

			String startParam;
			if(request.get.get("start", startParam) || request.get.get("t", startParam))
				start = timeParamToSeconds(startParam);

			String stopParam;
			if(request.get.get("stop", stopParam))
				stop = timeParamToSeconds(stopParam);

			Http::Response response(request, 200);
			response.headers["Content-Disposition"] = "attachment; filename=\"playlist.m3u\"";
			response.headers["Content-Type"] = "audio/x-mpegurl";
			response.send();

			String host;
			request.headers.get("Host", host);
			createPlaylist(response.stream, host, start, stop);
		}
		else {
			// JSON
			Http::Response response(request, 200);
			response.headers["Content-Type"] = "application/json";
			response.send();

			std::list<Resource::DirectoryRecord*> tmp;
			if(int(mResults.size()) > next)
				for(int i = next; i < int(mResults.size()); ++i)
					tmp.push_back(&mResults[i]);

			JsonSerializer(response.stream) << tmp;
		}
	}
	catch(...)
	{
		// Reset autodeletion
		autoDelete(mAutoDeleteTimeout);
		throw;
	}

	// Reset autodeletion
	autoDelete(mAutoDeleteTimeout);
}
Example #11
-2
//----------------------------------------------------------------
// main_utf8
// 
int main_utf8(int argc, char **argv)
{
	const char *input = NULL;
	const char *output_prefix = "";
	double target_segment_duration = 0.0;
	char *segment_duration_check = NULL;
	const char *playlist_filename = NULL;
	const char *http_prefix = "";
	long max_tsfiles = 0;
	char *max_tsfiles_check = NULL;
	double prev_segment_time = 0.0;
	double segment_duration = 0.0;
	unsigned int output_index = 1;
	const AVClass *fc = avformat_get_class();
	AVDictionary *format_opts = NULL;
	AVOutputFormat *ofmt = NULL;
	AVFormatContext *ic = NULL;
	AVFormatContext *oc = NULL;
	AVStream *video_st = NULL;
	AVStream *audio_st = NULL;
	AVCodec *codec = NULL;
	char *output_filename = NULL; 	
	int if_save_keyframe = 0;			//add by wanggm
	char *keyframeinfo_filename = NULL;	//add by wanggm
	json_object *obj = NULL;			//add by wanggm
	json_object *info_arr_obj = NULL;	//add by wanggm

	int if_monitor_related_process = 0;	//add by wanggm
	pid_t relatedProcessPid = 1; 		//add by wanggm
	char *pid_filename = NULL;
	int video_index = -1;
	int audio_index = -1;
	int kill_file = 0;
	int decode_done = 0;
	int ret = 0;
	int i = 0;
	TSMStreamLace * streamLace = NULL;
	TSMPlaylist * playlist = NULL;
	const double segment_duration_error_tolerance = 0.05;
	double extra_duration_needed = 0;
	int strict_segment_duration = 0;

	av_log_set_level(AV_LOG_INFO);


	for (i = 1; i < argc; i++)
	{
		if (strcmp(argv[i], "-i") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -i parameter");
			i++;
			input = argv[i];
		}
		else if (strcmp(argv[i], "-o") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -o parameter");
			i++;
			output_prefix = argv[i];
		}
		else if (strcmp(argv[i], "-d") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -d parameter");
			i++;

			target_segment_duration = strtod(argv[i], &segment_duration_check);
			if (segment_duration_check
					== argv[i] || target_segment_duration == HUGE_VAL
					|| target_segment_duration == -HUGE_VAL){
				usage3(argv, "invalid segment duration: ", argv[i]);
			}
		}
		else if (strcmp(argv[i], "-x") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -x parameter");
			i++;
			playlist_filename = argv[i];
		}
		else if (strcmp(argv[i], "-p") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -p parameter");
			i++;
			http_prefix = argv[i];
		}
		else if (strcmp(argv[i], "-w") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -w parameter");
			i++;

			max_tsfiles = strtol(argv[i], &max_tsfiles_check, 10);
			if (max_tsfiles_check == argv[i] || max_tsfiles < 0
					|| max_tsfiles >= INT_MAX)
			{
				usage3(argv, "invalid live stream max window size: ", argv[i]);
			}
		}
		else if (strcmp(argv[i], "-P") == 0)
		{
			if ((argc - i) <= 1)
				usage(argv, "could not parse -P parameter");
			i++;
			pid_filename = argv[i];
		}
		else if (strcmp(argv[i], "--watch-for-kill-file") == 0)
		{
			// end program when it finds a file with name 'kill':
			kill_file = 1;
		}
		else if (strcmp(argv[i], "--strict-segment-duration") == 0)
		{
			// force segment creation on non-keyframe boundaries:
			strict_segment_duration = 1;
		}
		else if (strcmp(argv[i], "--avformat-option") == 0)
		{
			const AVOption *of;
			const char *opt;
			const char *arg;
			if ((argc - i) <= 1)
				usage(argv, "could not parse --avformat-option parameter");
			i++;
			opt = argv[i];
			if ((argc - i) <= 1)
				usage(argv, "could not parse --avformat-option parameter");
			i++;
			arg = argv[i];

			if ((of = av_opt_find(&fc, opt, NULL, 0,
					AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
				av_dict_set(&format_opts, opt, arg,
						(of->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0);
			else
				usage3(argv, "unknown --avformat-option parameter: ", opt);
		}
		else if (strcmp(argv[i], "--loglevel") == 0)
		{
			const char *arg;
			if ((argc - i) <= 1)
				usage(argv, "could not parse --loglevel parameter");
			i++;
			arg = argv[i];

			if (loglevel(arg))
				usage3(argv, "unknown --loglevel parameter: ", arg);
		}
		else if (strcmp(argv[i], "-k") == 0)
		{ //add by wanggm for save key frame information into json file.
			if ((argc - i) <= 1)
				usage(argv, "could not parse -k parameter");
			i++;
			if_save_keyframe = atoi(argv[i]);
		}
		else if( strcmp(argv[i], "-s") == 0)
		{//add by wanggm for set the start index of ts file.
			if ( (argc -i ) <= 1)
				usage(argv, "could not parse -s parmeter");
			i++;
			
			char *output_index_check = NULL;
			output_index  = strtol(argv[i], &output_index_check, 10);
			if ( output_index_check== argv[i] || output_index < 0
					|| output_index >= INT_MAX)
			{
				usage3(argv, "invalid start index of ts file: ", argv[i]);
			}
			
		}
		else if( strcmp(argv[i], "-m") == 0)
		{ // add by wanggm for exit by monitor the process of which pid is given. 
			if ((argc - i) <= 1)
				usage(argv, "could not parse -m parmeter");
			i++;

			if_monitor_related_process = 1;
			unsigned int tmpPid= atoi(argv[i]);
			if( tmpPid > 0)
			{  
				relatedProcessPid = (pid_t) tmpPid;
				fprintf(stdout, "%s I will exit when the process PID= %d exit.\n", getSystemTime(timeChar), relatedProcessPid);
			}
		}
	}

	
	if (!input)
	{
		usage(argv, "-i input file parameter must be specified");
	}

	if (!playlist_filename)
	{
		usage(argv, "-x m3u8 playlist file parameter must be specified");
	}

	if (target_segment_duration == 0.0)
	{
		usage(argv, "-d segment duration parameter must be specified");
	}

	if( output_index <= 0 )
	{
		output_index = 1;	
	}

	if( 1 == if_monitor_related_process)
	{
		pthread_t id;
		pthread_create(&id, NULL, (void*)monitor_process, relatedProcessPid);
	}


	// Create PID file
	if (pid_filename)
	{
		FILE* pid_file = fopen_utf8(pid_filename, "wb");
		if (pid_file)
		{
			fprintf(pid_file, "%d", getpid());
			fclose(pid_file);
		}
	}


	av_register_all();
	avformat_network_init();

	if (!strcmp(input, "-"))
	{
		input = "pipe:";
	}

	output_filename = (char*) malloc(
			sizeof(char) * (strlen(output_prefix) + 15));
	//add by wanggm
	if(  if_save_keyframe == 1)
	{ 
		keyframeinfo_filename = (char*) malloc(
			sizeof(char)* (strlen(output_prefix) + 15));
	}
	if (!output_filename || (1 == if_save_keyframe && !keyframeinfo_filename))
	{
		fprintf(stderr, "%s Could not allocate space for output filenames\n", getSystemTime( timeChar));
		goto error;
	}

	playlist = createPlaylist(max_tsfiles, target_segment_duration,
			http_prefix);
	if (!playlist)
	{
		fprintf(stderr,
				"%s Could not allocate space for m3u8 playlist structure\n", getSystemTime( timeChar));
		goto error;
	}

	ret = avformat_open_input(&ic, input, NULL, (format_opts) ? &format_opts : NULL);

	if (ret != 0)
	{
		fprintf(stderr,
				"%sCould not open input file, make sure it is an mpegts or mp4 file: %d\n", getSystemTime(timeChar), ret);
		goto error;
	}
	av_dict_free(&format_opts);

	if (avformat_find_stream_info(ic, NULL) < 0)
	{
		fprintf(stderr, "%s Could not read stream information\n", getSystemTime( timeChar));
		goto error;
	}

#if LIBAVFORMAT_VERSION_MAJOR > 52 || (LIBAVFORMAT_VERSION_MAJOR == 52 && \
                                       LIBAVFORMAT_VERSION_MINOR >= 45)
	ofmt = av_guess_format("mpegts", NULL, NULL);
#else
	ofmt = guess_format("mpegts", NULL, NULL);
#endif

	if (!ofmt)
	{
		fprintf(stderr, "%s Could not find MPEG-TS muxer\n", getSystemTime( timeChar));
		goto error;
	}

	oc = avformat_alloc_context();
	if (!oc)
	{
		fprintf(stderr, "%s Could not allocated output context\n", getSystemTime( timeChar));
		goto error;
	}
	oc->oformat = ofmt;

	video_index = -1;
	audio_index = -1;

	for (i = 0; i < ic->nb_streams && (video_index < 0 || audio_index < 0); i++)
	{
		switch (ic->streams[i]->codec->codec_type)
		{
		case AVMEDIA_TYPE_VIDEO:
			video_index = i;
			ic->streams[i]->discard = AVDISCARD_NONE;
			video_st = add_output_stream(oc, ic->streams[i]);
			break;
		case AVMEDIA_TYPE_AUDIO:
			audio_index = i;
			ic->streams[i]->discard = AVDISCARD_NONE;
			audio_st = add_output_stream(oc, ic->streams[i]);
			break;
		default:
			ic->streams[i]->discard = AVDISCARD_ALL;
			break;
		}
	}

	av_dump_format(oc, 0, output_prefix, 1);

	if (video_index >= 0)
	{
		codec = avcodec_find_decoder(video_st->codec->codec_id);
		if (!codec)
		{
			fprintf(stderr,
					"%s Could not find video decoder, key frames will not be honored\n", getSystemTime( timeChar));
		}

		if (avcodec_open2(video_st->codec, codec, NULL) < 0)
		{
			fprintf(stderr,
					"%s Could not open video decoder, key frames will not be honored\n", getSystemTime( timeChar));
		}
	}

	snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts",
			output_prefix, output_index);

	if( 1 == if_save_keyframe)
	{ 
		snprintf(keyframeinfo_filename, strlen(output_prefix) + 15,
			"%s-%u.idx", output_prefix, output_index);
		obj = json_object_new_object();
		info_arr_obj = create_json_header(obj);
	}

	if (avio_open(&oc->pb, output_filename, AVIO_FLAG_WRITE) < 0)
	{
		fprintf(stderr, "%s Could not open '%s'\n", getSystemTime( timeChar),output_filename);
		goto error;
	}

	if (avformat_write_header(oc, NULL))
	{
		fprintf(stderr, "%s Could not write mpegts header to first output file\n", getSystemTime( timeChar));
		goto error;
	}

	prev_segment_time = (double) (ic->start_time) / (double) (AV_TIME_BASE);

	streamLace = createStreamLace(ic->nb_streams);

	// add by houmr
	int continue_error_cnt = 0;
	//int pushcnt = 0;
	//int popcnt = 0;
	int tscnt = 0;
	int audiopktcnt = 0;
	int videopktcnt = 0;
	int kfcnt = 0;
	int errpktcnt = 0;
	/////////////////////////
	do
	{
		double segment_time = 0.0;
		AVPacket packet;
		double packetStartTime = 0.0;
		double packetDuration = 0.0;

		if (!decode_done)
		{
			//fprintf(stdout, "%s av_read_frame() begin.\n", getSystemTime( timeChar));
			decode_done = av_read_frame(ic, &packet);
			//fprintf(stdout, "%s av_read_frame() end. packet.size=%d stream_index=%d duration=%d\n", getSystemTime( timeChar), packet.size, packet.stream_index, packet.duration);
			//fprintf(stdout, "%s decode_done=%d\n", getSystemTime( timeChar),decode_done);
			if (!decode_done)
			{
				if (packet.stream_index != video_index
						&& packet.stream_index != audio_index)
				{
					if( ++errpktcnt >= 10)
					{
						decode_done = 1;	
					}
					fprintf(stderr, "%s packet is not video or audio, packet.stream_index=%d\n", getSystemTime( timeChar), packet.stream_index);
					av_free_packet(&packet);
					continue;
				}
				errpktcnt = 0;

				/*printf("orgin : index - %d\t pts = %s\t duration=%d\n", packet.stream_index,
				 av_ts2str(packet.pts), packet.duration);*/
				// add by houmr
				/*if (adjust_pts(&packet, video_index, audio_index) < 0)
				{
					av_free_packet(&packet);
					continue;
				}
				*/
				/////////////////////////////////////
				double timeStamp =
						(double) (packet.pts)
								* (double) (ic->streams[packet.stream_index]->time_base.num)
								/ (double) (ic->streams[packet.stream_index]->time_base.den);

				if (av_dup_packet(&packet) < 0)
				{
					fprintf(stderr, "%s Could not duplicate packet\n" ,getSystemTime( timeChar));
					av_free_packet(&packet);
					break;
				}
				
				/*
				for(int i = 0; i < streamLace->numStreams; ++i)
				{ 
						fprintf(stdout, "streamLace[%d].size=%d\t", i, streamLace->streams[i]->size);
				}
				fprintf(stdout, "\n");
				*/
				insertPacket(streamLace, &packet, timeStamp);
			}
		}

		if (countPackets(streamLace) < 50 && !decode_done)
		{
			/* allow the queue to fill up so that the packets can be sorted properly */
			continue;
		}

		if (!removePacket(streamLace, &packet))
		{
			fprintf(stdout, "%s get packet failed!!\n", getSystemTime( timeChar));
			if (decode_done)
			{
				/* the queue is empty, we are done */
				break;
			}

			assert(decode_done);
			continue;
		}

		//fprintf(stdout, "%s get 1 packet success. packet info: pts=%ld, dts=%ld\n", getSystemTime( timeChar), packet.pts, packet.dts);
		packetStartTime = (double) (packet.pts)
				* (double) (ic->streams[packet.stream_index]->time_base.num)
				/ (double) (ic->streams[packet.stream_index]->time_base.den);

		packetDuration = (double) (packet.duration)
				* (double) (ic->streams[packet.stream_index]->time_base.num)
				/ (double) (ic->streams[packet.stream_index]->time_base.den);

#if !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG))
		if (av_log_get_level() >= AV_LOG_VERBOSE)
		fprintf(stderr,
				"%s stream %i, packet [%f, %f)\n",
				getSystemTime( timeChar),
				packet.stream_index,
				packetStartTime,
				packetStartTime + packetDuration);
#endif

		segment_duration = packetStartTime + packetDuration - prev_segment_time;

		// NOTE: segments are supposed to start on a keyframe.
		// If the keyframe interval and segment duration do not match
		// forcing the segment creation for "better seeking behavior"
		// will result in decoding artifacts after seeking or stream switching.
		if (packet.stream_index == video_index
				&& (packet.flags & AV_PKT_FLAG_KEY || strict_segment_duration))
		{
			//This is video packet and ( packet is key frame or strict time is needed )
			segment_time = packetStartTime;
		}
		else if (video_index < 0)
		{
			//This stream doesn't contain video stream
			segment_time = packetStartTime;
		}
		else
		{
			//This is a video packet or a video packet but not key frame 
			segment_time = prev_segment_time;
		}

		//fprintf(stdout, "%s extra_duration_needed=%f\n", getSystemTime( timeChar), extra_duration_needed);
		if (segment_time - prev_segment_time + segment_duration_error_tolerance
				> target_segment_duration + extra_duration_needed)
		{
			fprintf(stdout, "%s segment_time=%lf prev_segment_time=%lf  > target_segment_duration=%lf  extra_duration_needed=%lf\n", getSystemTime( timeChar), segment_time, prev_segment_time,  target_segment_duration, extra_duration_needed);
			fprintf(stdout, "%s File %s contains %d PES packet, of which %d are audio packet, %d are video packet within %d key frame.\n", getSystemTime( timeChar), output_filename, tscnt, audiopktcnt, videopktcnt, kfcnt);
			fflush(stdout);
			/*
			for(int i = 0; i < streamLace->numStreams; ++i)
			{
					fprintf(stdout, "%s streamLace[%d].size=%d\t", getSystemTime( timeChar), i, streamLace->streams[i]->size);
			}
			*/
			tscnt = audiopktcnt = videopktcnt = kfcnt = 0;
			avio_flush(oc->pb);
			avio_close(oc->pb);

			// Keep track of accumulated rounding error to account for it in later chunks.
		/*
			double segment_duration = segment_time - prev_segment_time;
			int rounded_segment_duration = (int) (segment_duration + 0.5);
			extra_duration_needed += (double) rounded_segment_duration
					- segment_duration;
		*/
			double seg_dur = segment_time - prev_segment_time;
			int rounded_segment_duration = (int) (seg_dur + 0.5);
			extra_duration_needed += (target_segment_duration - seg_dur - segment_duration_error_tolerance);
			//fprintf(stdout, "%s ________extra_duration_needed = %lf\n", getSystemTime( timeChar), extra_duration_needed);
			

			updatePlaylist(playlist, playlist_filename, output_filename,
					output_index, rounded_segment_duration);

			
			snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts",
					output_prefix, ++output_index);
			//add by wanggm
			//Save the all the keyframe information into json file
			if( 1 == if_save_keyframe && NULL != obj)
			{ 
				save_json_to_file(keyframeinfo_filename, obj);
				obj = info_arr_obj = NULL;

				snprintf(keyframeinfo_filename, strlen(output_prefix) + 15,
					"%s-%u.idx", output_prefix, output_index);
			}


			if (avio_open(&oc->pb, output_filename, AVIO_FLAG_WRITE) < 0)
			{
				fprintf(stderr, "%s Could not open '%s'\n", getSystemTime( timeChar), output_filename);
				break;
			}

			// close when we find the 'kill' file
			if (kill_file)
			{
				FILE* fp = fopen("kill", "rb");
				if (fp)
				{
					fprintf(stderr, "%s user abort: found kill file\n", getSystemTime( timeChar));
					fclose(fp);
					remove("kill");
					decode_done = 1;
					removeAllPackets(streamLace);
				}
			}
			prev_segment_time = segment_time;
		}

		//add by wanggm.
		++tscnt;
		if( video_index == packet.stream_index)
		{
			++videopktcnt;	
			if(1 == packet.flags)
			{ 
				++kfcnt;	
				if( 1 == if_save_keyframe)
				{
					//If it is key frame, it's information should be saved.
					//fprintf(stdout, "%s packet is keyframe, packet.pts=%ld\n", getSystemTime( timeChar), packet.pts);
					snprintf(keyframeinfo_filename, strlen(output_prefix) + 15,
					"%s-%u.idx", output_prefix, output_index);
					if (NULL == obj && NULL == info_arr_obj)
					{ 
						obj = json_object_new_object();
						info_arr_obj = create_json_header(obj);
					}
					avio_flush(oc->pb);		//flush the previous data into ts file.
					int64_t offset = avio_tell(oc->pb);	//Get the offset of this key frame in the file.
					save_keyframe_info(info_arr_obj, offset, packet.pts);
					//fprintf(stdout, "%s Keyframe.pos=%ld \tkeyframe.pts=%ld\n", getSystemTime( timeChar), offset, (long)packet.pts);
				}
			}
		}else if( audio_index == packet.stream_index)
		{
			++audiopktcnt;	
		}
		//fprintf(stdout, "%s packet is not keyframe.\n", getSystemTime( timeChar));

		ret = av_interleaved_write_frame(oc, &packet);

		if (ret < 0)
		{
			fprintf(stderr, "%s Warning: Could not write frame of stream\n", getSystemTime( timeChar));
			// add by houmr
			continue_error_cnt++;
			if (continue_error_cnt > 10)
			{
				av_free_packet(&packet);
				break;
			}
		}
		else if (ret > 0)
		{
			fprintf(stderr, "%s End of stream requested\n", getSystemTime( timeChar));
			av_free_packet(&packet);
			break;
		}
		else
		{
			// add by houmr error
			continue_error_cnt = 0;
			////////////////////////
		}
		av_free_packet(&packet);
	} while (!decode_done || countPackets(streamLace) > 0);

	av_write_trailer(oc);

	if (video_index >= 0)
	{
		avcodec_close(video_st->codec);
	}

	for (i = 0; i < oc->nb_streams; i++)
	{
		av_freep(&oc->streams[i]->codec);
		av_freep(&oc->streams[i]);
	}

	avio_close(oc->pb);
	av_free(oc);

	updatePlaylist(playlist, playlist_filename, output_filename, output_index,
			segment_duration);
	closePlaylist(playlist);
	releasePlaylist(&playlist);

	//add by wanggm
	if( 1 == if_save_keyframe && obj != NULL)
	{ 
		save_json_to_file(keyframeinfo_filename, obj);
	}

	if (pid_filename)
	{
		remove(pid_filename);
	}
	
	fflush(stdout);
	fflush(stderr);

	return 0;

	error: if (pid_filename)
	{
		remove(pid_filename);
	}

	return 1;

}