Skip to content
Snippets Groups Projects
decklink_dec.cpp 39.7 KiB
Newer Older
  • Learn to ignore specific revisions
  •     }
    
        /* List supported formats. */
        if (ctx->list_formats) {
            ff_decklink_list_formats(avctx, DIRECTION_IN);
    
        if (ff_decklink_set_configs(avctx, DIRECTION_IN) < 0) {
            av_log(avctx, AV_LOG_ERROR, "Could not set input configuration\n");
            ret = AVERROR(EIO);
            goto error;
        }
    
    
        ctx->input_callback = new decklink_input_callback(avctx);
        ctx->dli->SetCallback(ctx->input_callback);
    
        if (mode_num == 0 && !cctx->format_code) {
            if (decklink_autodetect(cctx) < 0) {
                av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No signal\n");
    
            av_log(avctx, AV_LOG_INFO, "Autodetected the input mode\n");
        }
        if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
            av_log(avctx, AV_LOG_ERROR, "Could not set mode number %d or format code %s for %s\n",
                mode_num, (cctx->format_code) ? cctx->format_code : "(unset)", fname);
            ret = AVERROR(EIO);
            goto error;
    
    #if !CONFIG_LIBZVBI
        if (ctx->teletext_lines && ctx->bmd_mode == bmdModePAL) {
            av_log(avctx, AV_LOG_ERROR, "Libzvbi support is needed for capturing SD PAL teletext, please recompile FFmpeg.\n");
            ret = AVERROR(ENOSYS);
            goto error;
        }
    #endif
    
    
        /* Setup streams. */
        st = avformat_new_stream(avctx, NULL);
        if (!st) {
            av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
    
        st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
    
        st->codecpar->codec_id    = cctx->audio_depth == 32 ? AV_CODEC_ID_PCM_S32LE : AV_CODEC_ID_PCM_S16LE;
    
        st->codecpar->sample_rate = bmdAudioSampleRate48kHz;
        st->codecpar->channels    = cctx->audio_channels;
    
        avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
        ctx->audio_st=st;
    
        st = avformat_new_stream(avctx, NULL);
        if (!st) {
            av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
    
        st->codecpar->codec_type  = AVMEDIA_TYPE_VIDEO;
        st->codecpar->width       = ctx->bmd_width;
        st->codecpar->height      = ctx->bmd_height;
    
        st->time_base.den      = ctx->bmd_tb_den;
        st->time_base.num      = ctx->bmd_tb_num;
    
        st->r_frame_rate       = av_make_q(st->time_base.den, st->time_base.num);
    
        switch((BMDPixelFormat)cctx->raw_format) {
        case bmdFormat8BitYUV:
    
            st->codecpar->codec_id    = AV_CODEC_ID_RAWVIDEO;
            st->codecpar->codec_tag   = MKTAG('U', 'Y', 'V', 'Y');
    
            st->codecpar->format      = AV_PIX_FMT_UYVY422;
    
            st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 16, st->time_base.den, st->time_base.num);
    
            break;
        case bmdFormat10BitYUV:
            st->codecpar->codec_id    = AV_CODEC_ID_V210;
            st->codecpar->codec_tag   = MKTAG('V','2','1','0');
            st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 64, st->time_base.den, st->time_base.num * 3);
            st->codecpar->bits_per_coded_sample = 10;
            break;
        case bmdFormat8BitARGB:
            st->codecpar->codec_id    = AV_CODEC_ID_RAWVIDEO;
    
            st->codecpar->codec_tag   = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format);
    
            st->codecpar->format      = AV_PIX_FMT_0RGB;
    
            st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num);
            break;
        case bmdFormat8BitBGRA:
            st->codecpar->codec_id    = AV_CODEC_ID_RAWVIDEO;
            st->codecpar->codec_tag   = avcodec_pix_fmt_to_codec_tag((enum AVPixelFormat)st->codecpar->format);
    
            st->codecpar->format      = AV_PIX_FMT_BGR0;
    
            st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 32, st->time_base.den, st->time_base.num);
            break;
        case bmdFormat10BitRGB:
            st->codecpar->codec_id    = AV_CODEC_ID_R210;
            st->codecpar->codec_tag   = MKTAG('R','2','1','0');
            st->codecpar->format      = AV_PIX_FMT_RGB48LE;
            st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 30, st->time_base.den, st->time_base.num);
            st->codecpar->bits_per_coded_sample = 10;
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Raw Format %.4s not supported\n", (char*) &cctx->raw_format);
            ret = AVERROR(EINVAL);
            goto error;
    
        switch (ctx->bmd_field_dominance) {
        case bmdUpperFieldFirst:
            st->codecpar->field_order = AV_FIELD_TT;
            break;
        case bmdLowerFieldFirst:
            st->codecpar->field_order = AV_FIELD_BB;
            break;
        case bmdProgressiveFrame:
        case bmdProgressiveSegmentedFrame:
            st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
            break;
        }
    
    
        avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
    
        ctx->video_st=st;
    
    
        if (ctx->teletext_lines) {
            st = avformat_new_stream(avctx, NULL);
            if (!st) {
                av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
    
            st->codecpar->codec_type  = AVMEDIA_TYPE_SUBTITLE;
            st->time_base.den         = ctx->bmd_tb_den;
            st->time_base.num         = ctx->bmd_tb_num;
            st->codecpar->codec_id    = AV_CODEC_ID_DVB_TELETEXT;
    
            avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
            ctx->teletext_st = st;
        }
    
    
        av_log(avctx, AV_LOG_VERBOSE, "Using %d input audio channels\n", ctx->audio_st->codecpar->channels);
    
        result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, cctx->audio_depth == 32 ? bmdAudioSampleType32bitInteger : bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);
    
    
        if (result != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
    
        result = ctx->dli->EnableVideoInput(ctx->bmd_mode,
    
                                            (BMDPixelFormat) cctx->raw_format,
    
    
        if (result != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");
    
            goto error;
        }
    
        avpacket_queue_init (avctx, &ctx->queue);
    
    
        if (ctx->dli->StartStreams() != S_OK) {
    
            av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
    
    }
    
    int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt)
    {
    
        struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
        struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
    
    
        avpacket_queue_get(&ctx->queue, pkt, 1);
    
        return 0;
    }
    
    
    int ff_decklink_list_input_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list)
    {
        return ff_decklink_list_devices(avctx, device_list, 1, 0);
    }
    
    
    } /* extern "C" */