yading@10: /* yading@10: * Copyright (c) 2012 Stefano Sabatini yading@10: * yading@10: * Permission is hereby granted, free of charge, to any person obtaining a copy yading@10: * of this software and associated documentation files (the "Software"), to deal yading@10: * in the Software without restriction, including without limitation the rights yading@10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell yading@10: * copies of the Software, and to permit persons to whom the Software is yading@10: * furnished to do so, subject to the following conditions: yading@10: * yading@10: * The above copyright notice and this permission notice shall be included in yading@10: * all copies or substantial portions of the Software. yading@10: * yading@10: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR yading@10: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, yading@10: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL yading@10: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER yading@10: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, yading@10: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN yading@10: * THE SOFTWARE. yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * libswscale API use example. yading@10: * @example doc/examples/scaling_video.c yading@10: */ yading@10: yading@10: #include yading@10: #include yading@10: #include yading@10: yading@10: static void fill_yuv_image(uint8_t *data[4], int linesize[4], yading@10: int width, int height, int frame_index) yading@10: { yading@10: int x, y; yading@10: yading@10: /* Y */ yading@10: for (y = 0; y < height; y++) yading@10: for (x = 0; x < width; x++) yading@10: data[0][y * linesize[0] + x] = x + y + frame_index * 3; yading@10: yading@10: /* Cb and Cr */ yading@10: for (y = 0; y < height / 2; y++) { yading@10: for (x = 0; x < width / 2; x++) { yading@10: data[1][y * linesize[1] + x] = 128 + y + frame_index * 2; yading@10: data[2][y * linesize[2] + x] = 64 + x + frame_index * 5; yading@10: } yading@10: } yading@10: } yading@10: yading@10: int main(int argc, char **argv) yading@10: { yading@10: uint8_t *src_data[4], *dst_data[4]; yading@10: int src_linesize[4], dst_linesize[4]; yading@10: int src_w = 320, src_h = 240, dst_w, dst_h; yading@10: enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24; yading@10: const char *dst_size = NULL; yading@10: const char *dst_filename = NULL; yading@10: FILE *dst_file; yading@10: int dst_bufsize; yading@10: struct SwsContext *sws_ctx; yading@10: int i, ret; yading@10: yading@10: if (argc != 3) { yading@10: fprintf(stderr, "Usage: %s output_file output_size\n" yading@10: "API example program to show how to scale an image with libswscale.\n" yading@10: "This program generates a series of pictures, rescales them to the given " yading@10: "output_size and saves them to an output file named output_file\n." yading@10: "\n", argv[0]); yading@10: exit(1); yading@10: } yading@10: dst_filename = argv[1]; yading@10: dst_size = argv[2]; yading@10: yading@10: if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) { yading@10: fprintf(stderr, yading@10: "Invalid size '%s', must be in the form WxH or a valid size abbreviation\n", yading@10: dst_size); yading@10: exit(1); yading@10: } yading@10: yading@10: dst_file = fopen(dst_filename, "wb"); yading@10: if (!dst_file) { yading@10: fprintf(stderr, "Could not open destination file %s\n", dst_filename); yading@10: exit(1); yading@10: } yading@10: yading@10: /* create scaling context */ yading@10: sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt, yading@10: dst_w, dst_h, dst_pix_fmt, yading@10: SWS_BILINEAR, NULL, NULL, NULL); yading@10: if (!sws_ctx) { yading@10: fprintf(stderr, yading@10: "Impossible to create scale context for the conversion " yading@10: "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", yading@10: av_get_pix_fmt_name(src_pix_fmt), src_w, src_h, yading@10: av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h); yading@10: ret = AVERROR(EINVAL); yading@10: goto end; yading@10: } yading@10: yading@10: /* allocate source and destination image buffers */ yading@10: if ((ret = av_image_alloc(src_data, src_linesize, yading@10: src_w, src_h, src_pix_fmt, 16)) < 0) { yading@10: fprintf(stderr, "Could not allocate source image\n"); yading@10: goto end; yading@10: } yading@10: yading@10: /* buffer is going to be written to rawvideo file, no alignment */ yading@10: if ((ret = av_image_alloc(dst_data, dst_linesize, yading@10: dst_w, dst_h, dst_pix_fmt, 1)) < 0) { yading@10: fprintf(stderr, "Could not allocate destination image\n"); yading@10: goto end; yading@10: } yading@10: dst_bufsize = ret; yading@10: yading@10: for (i = 0; i < 100; i++) { yading@10: /* generate synthetic video */ yading@10: fill_yuv_image(src_data, src_linesize, src_w, src_h, i); yading@10: yading@10: /* convert to destination format */ yading@10: sws_scale(sws_ctx, (const uint8_t * const*)src_data, yading@10: src_linesize, 0, src_h, dst_data, dst_linesize); yading@10: yading@10: /* write scaled image to file */ yading@10: fwrite(dst_data[0], 1, dst_bufsize, dst_file); yading@10: } yading@10: yading@10: fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n" yading@10: "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n", yading@10: av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename); yading@10: yading@10: end: yading@10: if (dst_file) yading@10: fclose(dst_file); yading@10: av_freep(&src_data[0]); yading@10: av_freep(&dst_data[0]); yading@10: sws_freeContext(sws_ctx); yading@10: return ret < 0; yading@10: }