| 572 | } |
| 573 | |
| 574 | static int create_stream(AVFormatContext *s) |
| 575 | { |
| 576 | XCBGrabContext *c = s->priv_data; |
| 577 | AVStream *st = avformat_new_stream(s, NULL); |
| 578 | xcb_get_geometry_cookie_t gc; |
| 579 | xcb_get_geometry_reply_t *geo; |
| 580 | int64_t frame_size_bits; |
| 581 | int ret; |
| 582 | |
| 583 | if (!st) |
| 584 | return AVERROR(ENOMEM); |
| 585 | |
| 586 | ret = av_parse_video_rate(&st->avg_frame_rate, c->framerate); |
| 587 | if (ret < 0) |
| 588 | return ret; |
| 589 | |
| 590 | avpriv_set_pts_info(st, 64, 1, 1000000); |
| 591 | |
| 592 | gc = xcb_get_geometry(c->conn, c->window_id); |
| 593 | geo = xcb_get_geometry_reply(c->conn, gc, NULL); |
| 594 | if (!geo) { |
| 595 | av_log(s, AV_LOG_ERROR, "Can't find window '0x%x', aborting.\n", c->window_id); |
| 596 | return AVERROR_EXTERNAL; |
| 597 | } |
| 598 | |
| 599 | if (!c->width || !c->height) { |
| 600 | c->width = geo->width; |
| 601 | c->height = geo->height; |
| 602 | } |
| 603 | |
| 604 | if (c->x + c->width > geo->width || |
| 605 | c->y + c->height > geo->height) { |
| 606 | av_log(s, AV_LOG_ERROR, |
| 607 | "Capture area %dx%d at position %d.%d " |
| 608 | "outside the screen size %dx%d\n", |
| 609 | c->width, c->height, |
| 610 | c->x, c->y, |
| 611 | geo->width, geo->height); |
| 612 | free(geo); |
| 613 | return AVERROR(EINVAL); |
| 614 | } |
| 615 | |
| 616 | c->time_base = (AVRational){ st->avg_frame_rate.den, |
| 617 | st->avg_frame_rate.num }; |
| 618 | c->frame_duration = av_rescale_q(1, c->time_base, AV_TIME_BASE_Q); |
| 619 | c->time_frame = av_gettime_relative(); |
| 620 | |
| 621 | ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codecpar->format, &c->bpp); |
| 622 | free(geo); |
| 623 | if (ret < 0) |
| 624 | return ret; |
| 625 | |
| 626 | frame_size_bits = (int64_t)c->width * c->height * c->bpp; |
| 627 | if (frame_size_bits / 8 + AV_INPUT_BUFFER_PADDING_SIZE > INT_MAX) { |
| 628 | av_log(s, AV_LOG_ERROR, "Captured area is too large\n"); |
| 629 | return AVERROR_PATCHWELCOME; |
| 630 | } |
| 631 | c->frame_size = frame_size_bits / 8; |
no test coverage detected