| 708 | #endif |
| 709 | |
| 710 | static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) |
| 711 | { |
| 712 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
| 713 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
| 714 | AVStream *st = avctx->streams[pkt->stream_index]; |
| 715 | AVFrame *avframe = NULL, *tmp = (AVFrame *)pkt->data; |
| 716 | AVPacket *avpacket = NULL; |
| 717 | decklink_frame *frame; |
| 718 | uint32_t buffered; |
| 719 | HRESULT hr; |
| 720 | |
| 721 | ctx->last_pts = FFMAX(ctx->last_pts, pkt->pts); |
| 722 | |
| 723 | if (st->codecpar->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { |
| 724 | if (tmp->format != AV_PIX_FMT_UYVY422 || |
| 725 | tmp->width != ctx->bmd_width || |
| 726 | tmp->height != ctx->bmd_height) { |
| 727 | av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format or dimension.\n"); |
| 728 | return AVERROR(EINVAL); |
| 729 | } |
| 730 | |
| 731 | avframe = av_frame_clone(tmp); |
| 732 | if (!avframe) { |
| 733 | av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); |
| 734 | return AVERROR(EIO); |
| 735 | } |
| 736 | |
| 737 | frame = new decklink_frame(ctx, avframe, st->codecpar->codec_id, avframe->height, avframe->width); |
| 738 | } else { |
| 739 | avpacket = av_packet_clone(pkt); |
| 740 | if (!avpacket) { |
| 741 | av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); |
| 742 | return AVERROR(EIO); |
| 743 | } |
| 744 | |
| 745 | frame = new decklink_frame(ctx, avpacket, st->codecpar->codec_id, ctx->bmd_height, ctx->bmd_width); |
| 746 | |
| 747 | #if CONFIG_LIBKLVANC |
| 748 | if (decklink_construct_vanc(avctx, ctx, pkt, frame, st)) |
| 749 | av_log(avctx, AV_LOG_ERROR, "Failed to construct VANC\n"); |
| 750 | #endif |
| 751 | } |
| 752 | |
| 753 | if (!frame) { |
| 754 | av_log(avctx, AV_LOG_ERROR, "Could not create new frame.\n"); |
| 755 | av_frame_free(&avframe); |
| 756 | av_packet_free(&avpacket); |
| 757 | return AVERROR(EIO); |
| 758 | } |
| 759 | |
| 760 | /* Always keep at most one second of frames buffered. */ |
| 761 | pthread_mutex_lock(&ctx->mutex); |
| 762 | while (ctx->frames_buffer_available_spots == 0) { |
| 763 | pthread_cond_wait(&ctx->cond, &ctx->mutex); |
| 764 | } |
| 765 | ctx->frames_buffer_available_spots--; |
| 766 | pthread_mutex_unlock(&ctx->mutex); |
| 767 |
no test coverage detected