813 lines · 27.0 KB · C++
RawDownload
                            i = 317;                    }                }#endif                if (videoFrame->GetWidth() == 1920 && vanc_format == bmdFormat10BitYUV) {                    int first_active_line = ctx->bmd_field_dominance == bmdProgressiveFrame ? 42 : 584;                    for (i = 8; i < first_active_line; i++) {                        uint8_t *buf;                        if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK)                            txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines);                        if (ctx->bmd_field_dominance != bmdProgressiveFrame && i == 20)     // skip field1 active lines                            i = 569;                        if (txt_buf - txt_buf0 > 1611) {   // ensure we still have at least 1920 bytes free in the buffer                            av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n");                            break;                        }                    }                }                vanc->Release();                if (txt_buf - txt_buf0 > 1) {                    int stuffing_units = (4 - ((45 + txt_buf - txt_buf0) / 46) % 4) % 4;                    while (stuffing_units--) {                        memset(txt_buf, 0xff, 46);                        txt_buf[1] = 0x2c; // data_unit_length                        txt_buf += 46;                    }                    av_init_packet(&txt_pkt);                    txt_pkt.pts = pkt.pts;                    txt_pkt.dts = pkt.dts;                    txt_pkt.stream_index = ctx->teletext_st->index;                    txt_pkt.data = txt_buf0;                    txt_pkt.size = txt_buf - txt_buf0;                    if (avpacket_queue_put(&ctx->queue, &txt_pkt) < 0) {                        ++ctx->dropped;                    }                }            }        }         if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {            ++ctx->dropped;        }    }     // Handle Audio Frame    if (audioFrame) {        AVPacket pkt;        BMDTimeValue audio_pts;        av_init_packet(&pkt);         //hack among hacks        pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (16 / 8);        audioFrame->GetBytes(&audioFrameBytes);        audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);        pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts);        pkt.dts = pkt.pts;         //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);        pkt.flags       |= AV_PKT_FLAG_KEY;        pkt.stream_index = ctx->audio_st->index;        pkt.data         = (uint8_t *)audioFrameBytes;         if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {            ++ctx->dropped;        }    }     return S_OK;} HRESULT decklink_input_callback::VideoInputFormatChanged(    BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,    BMDDetectedVideoInputFormatFlags){    return S_OK;} static HRESULT decklink_start_input(AVFormatContext *avctx){    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;     ctx->input_callback = new decklink_input_callback(avctx);    ctx->dli->SetCallback(ctx->input_callback);    return ctx->dli->StartStreams();} extern "C" { av_cold int ff_decklink_read_close(AVFormatContext *avctx){    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;     if (ctx->capture_started) {        ctx->dli->StopStreams();        ctx->dli->DisableVideoInput();        ctx->dli->DisableAudioInput();    }     ff_decklink_cleanup(avctx);    avpacket_queue_end(&ctx->queue);     av_freep(&cctx->ctx);     return 0;} av_cold int ff_decklink_read_header(AVFormatContext *avctx){    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;    struct decklink_ctx *ctx;    AVStream *st;    HRESULT result;    char fname[1024];    char *tmp;    int mode_num = 0;    int ret;     ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));    if (!ctx)        return AVERROR(ENOMEM);    ctx->list_devices = cctx->list_devices;    ctx->list_formats = cctx->list_formats;    ctx->teletext_lines = cctx->teletext_lines;    ctx->preroll      = cctx->preroll;    ctx->duplex_mode  = cctx->duplex_mode;    if (cctx->video_input > 0 && (unsigned int)cctx->video_input < FF_ARRAY_ELEMS(decklink_video_connection_map))        ctx->video_input = decklink_video_connection_map[cctx->video_input];    if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input < FF_ARRAY_ELEMS(decklink_audio_connection_map))        ctx->audio_input = decklink_audio_connection_map[cctx->audio_input];    ctx->audio_pts_source = cctx->audio_pts_source;    ctx->video_pts_source = cctx->video_pts_source;    ctx->draw_bars = cctx->draw_bars;    cctx->ctx = ctx;     /* Check audio channel option for valid values: 2, 8 or 16 */    switch (cctx->audio_channels) {        case 2:        case 8:        case 16:            break;        default:            av_log(avctx, AV_LOG_ERROR, "Value of channels option must be one of 2, 8 or 16\n");            return AVERROR(EINVAL);    }     /* List available devices. */    if (ctx->list_devices) {        ff_decklink_list_devices(avctx);        return AVERROR_EXIT;    }     strcpy (fname, avctx->filename);    tmp=strchr (fname, '@');    if (tmp != NULL) {        av_log(avctx, AV_LOG_WARNING, "The @mode syntax is deprecated and will be removed. Please use the -format_code option.\n");        mode_num = atoi (tmp+1);        *tmp = 0;    }     ret = ff_decklink_init_device(avctx, fname);    if (ret < 0)        return ret;     /* Get input device. */    if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) {        av_log(avctx, AV_LOG_ERROR, "Could not open input device from '%s'\n",               avctx->filename);        ret = AVERROR(EIO);        goto error;    }     /* List supported formats. */    if (ctx->list_formats) {        ff_decklink_list_formats(avctx, DIRECTION_IN);        ret = AVERROR_EXIT;        goto error;    }     if (mode_num > 0 || cctx->format_code) {        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");        ret = AVERROR(ENOMEM);        goto error;    }    st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;    st->codecpar->codec_id    = 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");        ret = AVERROR(ENOMEM);        goto error;    }    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;    av_stream_set_r_frame_rate(st, av_make_q(st->time_base.den, st->time_base.num));     if (cctx->v210) {        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);    } else {        st->codecpar->codec_id    = AV_CODEC_ID_RAWVIDEO;        st->codecpar->format      = AV_PIX_FMT_UYVY422;        st->codecpar->codec_tag   = MKTAG('U', 'Y', 'V', 'Y');        st->codecpar->bit_rate    = av_rescale(ctx->bmd_width * ctx->bmd_height * 16, st->time_base.den, st->time_base.num);    }     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");            ret = AVERROR(ENOMEM);            goto error;        }        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, bmdAudioSampleType16bitInteger, ctx->audio_st->codecpar->channels);     if (result != S_OK) {        av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");        ret = AVERROR(EIO);        goto error;    }     result = ctx->dli->EnableVideoInput(ctx->bmd_mode,                                        cctx->v210 ? bmdFormat10BitYUV : bmdFormat8BitYUV,                                        bmdVideoInputFlagDefault);     if (result != S_OK) {        av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");        ret = AVERROR(EIO);        goto error;    }     avpacket_queue_init (avctx, &ctx->queue);     if (decklink_start_input (avctx) != S_OK) {        av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");        ret = AVERROR(EIO);        goto error;    }     return 0; error:    ff_decklink_cleanup(avctx);    return ret;} 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;} } /* extern "C" */

Lines 501–813 of 813. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t