Esempio n. 1
0
bool Player::Init(int videomode, int connection, int camera)
{
    // Initialize the DeckLink API
    IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance();
    HRESULT result;
    int i = 0;

    if (!deckLinkIterator) {
        fprintf(stderr,
                "This application requires the DeckLink drivers installed.\n");
        goto bail;
    }

    m_audioSampleDepth =
        av_get_exact_bits_per_sample(audio_st->codec->codec_id);

    switch (audio_st->codec->channels) {
        case  2:
        case  8:
        case 16:
            break;
        default:
            fprintf(stderr,
                    "%d channels not supported, please use 2, 8 or 16\n",
                    audio_st->codec->channels);
            goto bail;
    }

    switch (m_audioSampleDepth) {
        case 16:
        case 32:
            break;
        default:
            fprintf(stderr, "%dbit audio not supported use 16bit or 32bit\n",
                    m_audioSampleDepth);
    }

    do
        result = deckLinkIterator->Next(&m_deckLink);
    while (i++ < camera);

    if (result != S_OK) {
        fprintf(stderr, "No DeckLink PCI cards found\n");
        goto bail;
    }

    // Obtain the audio/video output interface (IDeckLinkOutput)
    if (m_deckLink->QueryInterface(IID_IDeckLinkOutput,
                                   (void **)&m_deckLinkOutput) != S_OK)
        goto bail;

    result = m_deckLink->QueryInterface(IID_IDeckLinkConfiguration,
                                        (void **)&deckLinkConfiguration);
    if (result != S_OK) {
        fprintf(
            stderr,
            "Could not obtain the IDeckLinkConfiguration interface - result = %08x\n",
            result);
        goto bail;
    }
    //XXX make it generic
    switch (connection) {
    case 1:
        DECKLINK_SET_VIDEO_CONNECTION(bmdVideoConnectionComposite);
        DECKLINK_SET_AUDIO_CONNECTION(bmdAudioConnectionAnalog);
        break;
    case 2:
        DECKLINK_SET_VIDEO_CONNECTION(bmdVideoConnectionComponent);
        DECKLINK_SET_AUDIO_CONNECTION(bmdAudioConnectionAnalog);
        break;
    case 3:
        DECKLINK_SET_VIDEO_CONNECTION(bmdVideoConnectionHDMI);
        DECKLINK_SET_AUDIO_CONNECTION(bmdAudioConnectionEmbedded);
        break;
    case 4:
        DECKLINK_SET_VIDEO_CONNECTION(bmdVideoConnectionSDI);
        DECKLINK_SET_AUDIO_CONNECTION(bmdAudioConnectionEmbedded);
        break;
    default:
        // do not change it
        break;
    }

    // Provide this class as a delegate to the audio and video output interfaces
    m_deckLinkOutput->SetScheduledFrameCompletionCallback(this);
    m_deckLinkOutput->SetAudioCallback(this);

    avframe = avcodec_alloc_frame();

    packet_queue_init(&audioqueue);
    packet_queue_init(&videoqueue);
    packet_queue_init(&dataqueue);
    pthread_t th;
    pthread_create(&th, NULL, fill_queues, NULL);

    usleep(buffer); // You can add the microseconds you need for pre-buffering before start playing
    // Start playing
    StartRunning(videomode);

    pthread_mutex_lock(&sleepMutex);
    pthread_cond_wait(&sleepCond, &sleepMutex);
    pthread_mutex_unlock(&sleepMutex);
    fill_me = 0;
    fprintf(stderr, "Exiting, cleaning up\n");
    packet_queue_end(&audioqueue);
    packet_queue_end(&videoqueue);

bail:
    if (m_running == true) {
        StopRunning();
    } else {
        // Release any resources that were partially allocated
        if (m_deckLinkOutput != NULL) {
            m_deckLinkOutput->Release();
            m_deckLinkOutput = NULL;
        }
        //
        if (m_deckLink != NULL) {
            m_deckLink->Release();
            m_deckLink = NULL;
        }
    }

    if (deckLinkIterator != NULL)
        deckLinkIterator->Release();

    return true;
}
Esempio n. 2
0
/* wav input */
static int wav_read_header(AVFormatContext *s)
{
    int64_t size, av_uninit(data_size);
    int64_t sample_count = 0;
    int rf64;
    uint32_t tag;
    AVIOContext *pb      = s->pb;
    AVStream *st         = NULL;
    WAVDemuxContext *wav = s->priv_data;
    int ret, got_fmt = 0;
    int64_t next_tag_ofs, data_ofs = -1;

    wav->unaligned = avio_tell(s->pb) & 1;

    wav->smv_data_ofs = -1;

    /* check RIFF header */
    tag = avio_rl32(pb);

    rf64 = tag == MKTAG('R', 'F', '6', '4');
    if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
        return AVERROR_INVALIDDATA;
    avio_rl32(pb); /* file size */
    tag = avio_rl32(pb);
    if (tag != MKTAG('W', 'A', 'V', 'E'))
        return AVERROR_INVALIDDATA;

    if (rf64) {
        if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
            return AVERROR_INVALIDDATA;
        size = avio_rl32(pb);
        if (size < 24)
            return AVERROR_INVALIDDATA;
        avio_rl64(pb); /* RIFF size */

        data_size    = avio_rl64(pb);
        sample_count = avio_rl64(pb);

        if (data_size < 0 || sample_count < 0) {
            av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
                   "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
                   data_size, sample_count);
            return AVERROR_INVALIDDATA;
        }
        avio_skip(pb, size - 24); /* skip rest of ds64 chunk */

    }

    for (;;) {
        AVStream *vst;
        size         = next_tag(pb, &tag);
        next_tag_ofs = avio_tell(pb) + size;

        if (avio_feof(pb))
            break;

        switch (tag) {
        case MKTAG('f', 'm', 't', ' '):
            /* only parse the first 'fmt ' tag found */
            if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
                return ret;
            } else if (got_fmt)
                av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");

            got_fmt = 1;
            break;
        case MKTAG('d', 'a', 't', 'a'):
            if (!got_fmt) {
                av_log(s, AV_LOG_ERROR,
                       "found no 'fmt ' tag before the 'data' tag\n");
                return AVERROR_INVALIDDATA;
            }

            if (rf64) {
                next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
            } else {
                data_size    = size;
                next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
            }

            data_ofs = avio_tell(pb);

            /* don't look for footer metadata if we can't seek or if we don't
             * know where the data tag ends
             */
            if (!pb->seekable || (!rf64 && !size))
                goto break_loop;
            break;
        case MKTAG('f', 'a', 'c', 't'):
            if (!sample_count)
                sample_count = avio_rl32(pb);
            break;
        case MKTAG('b', 'e', 'x', 't'):
            if ((ret = wav_parse_bext_tag(s, size)) < 0)
                return ret;
            break;
        case MKTAG('S','M','V','0'):
            if (!got_fmt) {
                av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
                return AVERROR_INVALIDDATA;
            }
            // SMV file, a wav file with video appended.
            if (size != MKTAG('0','2','0','0')) {
                av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
                goto break_loop;
            }
            av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
            wav->smv_given_first = 0;
            vst = avformat_new_stream(s, NULL);
            if (!vst)
                return AVERROR(ENOMEM);
            avio_r8(pb);
            vst->id = 1;
            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
            vst->codec->width  = avio_rl24(pb);
            vst->codec->height = avio_rl24(pb);
            if (ff_alloc_extradata(vst->codec, 4)) {
                av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
                return AVERROR(ENOMEM);
            }
            size = avio_rl24(pb);
            wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
            avio_rl24(pb);
            wav->smv_block_size = avio_rl24(pb);
            avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
            vst->duration = avio_rl24(pb);
            avio_rl24(pb);
            avio_rl24(pb);
            wav->smv_frames_per_jpeg = avio_rl24(pb);
            if (wav->smv_frames_per_jpeg > 65536) {
                av_log(s, AV_LOG_ERROR, "too many frames per jpeg\n");
                return AVERROR_INVALIDDATA;
            }
            AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
            wav->smv_cur_pt = 0;
            goto break_loop;
        case MKTAG('L', 'I', 'S', 'T'):
            if (size < 4) {
                av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
                return AVERROR_INVALIDDATA;
            }
            switch (avio_rl32(pb)) {
            case MKTAG('I', 'N', 'F', 'O'):
                ff_read_riff_info(s, size - 4);
            }
            break;
        }

        /* seek to next tag unless we know that we'll run into EOF */
        if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
            wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) {
            break;
        }
    }

break_loop:
    if (data_ofs < 0) {
        av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
        return AVERROR_INVALIDDATA;
    }

    avio_seek(pb, data_ofs, SEEK_SET);

    if (data_size > 0 && sample_count && data_size / sample_count / st->codec->channels > 8) {
        av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
        sample_count = 0;
    }

    if (!sample_count || av_get_exact_bits_per_sample(st->codec->codec_id) > 0)
        if (   st->codec->channels
            && data_size
            && av_get_bits_per_sample(st->codec->codec_id)
            && wav->data_end <= avio_size(pb))
            sample_count = (data_size << 3)
                                  /
                (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));

    if (sample_count)
        st->duration = sample_count;

    ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);

    return 0;
}