void FFmpegDecoder::videoParseRunnable()
{
    CHANNEL_LOG(ffmpeg_threads) << "Video thread started";
    m_videoStartClock = VIDEO_START_CLOCK_NOT_INITIALIZED;
    double videoClock = 0; // pts of last decoded frame / predicted pts of next decoded frame

    VideoParseContext context{};

    for (;;)
    {
        if (m_isPaused && !m_isVideoSeekingWhilePaused)
        {
            boost::unique_lock<boost::mutex> locker(m_isPausedMutex);
            while (m_isPaused && !m_isVideoSeekingWhilePaused)
            {
                m_isPausedCV.wait(locker);
            }
        }

        for (;;)
        {
            AVPacket packet;
            if (!m_videoPacketsQueue.pop(packet,
                [this] { return m_isPaused && !m_isVideoSeekingWhilePaused; }))
            {
                break;
            }

            auto packetGuard = MakeGuard(&packet, av_packet_unref);

            if (!handleVideoPacket(packet, videoClock, context)
                || m_isPaused && !m_isVideoSeekingWhilePaused)
            {
                break;
            }
        }
    }
}
Exemple #2
0
void D2V::index() {
    AVPacket packet;
    av_init_packet(&packet);

    while (av_read_frame(f->fctx, &packet) == 0) {
        if (stop_processing) {
            stop_processing = false;
            result = ProcessingCancelled;
            fclose(d2v_file);
            closeAudioFiles(audio_files, f->fctx);
            return;
        }

        // Apparently we might receive packets from streams with AVDISCARD_ALL set,
        // and also from streams discovered late, probably.
        if (packet.stream_index != video_stream->index &&
            !audio_files.count(packet.stream_index)) {
            av_free_packet(&packet);
            continue;
        }

        bool okay = true;

        if (packet.stream_index == video_stream->index)
            okay = handleVideoPacket(&packet);
        else
            okay = handleAudioPacket(&packet);

        if (!okay) {
            av_free_packet(&packet);
            result = ProcessingError;
            fclose(d2v_file);
            closeAudioFiles(audio_files, f->fctx);
            return;
        }

        av_free_packet(&packet);
    }

    if (!isDataLineNull()) {
        reorderDataLineFlags();
        lines.push_back(line);
        clearDataLine();
    }


    if (!lines.size()) {
        result = ProcessingFinished;
        fclose(d2v_file);
        closeAudioFiles(audio_files, f->fctx);
        return;
    }


    if (!printHeader()) {
        result = ProcessingError;
        fclose(d2v_file);
        closeAudioFiles(audio_files, f->fctx);
        return;
    }

    if (!printSettings()) {
        result = ProcessingError;
        fclose(d2v_file);
        closeAudioFiles(audio_files, f->fctx);
        return;
    }

    for (size_t i = 0; i < lines.size(); i++) {
        if (stop_processing) {
            stop_processing = false;
            result = ProcessingCancelled;
            fclose(d2v_file);
            closeAudioFiles(audio_files, f->fctx);
            return;
        }

        if (!printDataLine(lines[i])) {
            result = ProcessingError;
            fclose(d2v_file);
            closeAudioFiles(audio_files, f->fctx);
            return;
        }
    }

    if (!printStreamEnd()) {
        result = ProcessingError;
        fclose(d2v_file);
        closeAudioFiles(audio_files, f->fctx);
        return;
    }

    result = ProcessingFinished;
    fclose(d2v_file);
    closeAudioFiles(audio_files, f->fctx);
}