1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2012 Stefano Sabatini 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 5cabdff1aSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 6cabdff1aSopenharmony_ci * in the Software without restriction, including without limitation the rights 7cabdff1aSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8cabdff1aSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 9cabdff1aSopenharmony_ci * furnished to do so, subject to the following conditions: 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * The above copyright notice and this permission notice shall be included in 12cabdff1aSopenharmony_ci * all copies or substantial portions of the Software. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15cabdff1aSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16cabdff1aSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17cabdff1aSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18cabdff1aSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19cabdff1aSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20cabdff1aSopenharmony_ci * THE SOFTWARE. 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * libswscale API use example. 26cabdff1aSopenharmony_ci * @example scaling_video.c 27cabdff1aSopenharmony_ci */ 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include <libavutil/imgutils.h> 30cabdff1aSopenharmony_ci#include <libavutil/parseutils.h> 31cabdff1aSopenharmony_ci#include <libswscale/swscale.h> 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_cistatic void fill_yuv_image(uint8_t *data[4], int linesize[4], 34cabdff1aSopenharmony_ci int width, int height, int frame_index) 35cabdff1aSopenharmony_ci{ 36cabdff1aSopenharmony_ci int x, y; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci /* Y */ 39cabdff1aSopenharmony_ci for (y = 0; y < height; y++) 40cabdff1aSopenharmony_ci for (x = 0; x < width; x++) 41cabdff1aSopenharmony_ci data[0][y * linesize[0] + x] = x + y + frame_index * 3; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci /* Cb and Cr */ 44cabdff1aSopenharmony_ci for (y = 0; y < height / 2; y++) { 45cabdff1aSopenharmony_ci for (x = 0; x < width / 2; x++) { 46cabdff1aSopenharmony_ci data[1][y * linesize[1] + x] = 128 + y + frame_index * 2; 47cabdff1aSopenharmony_ci data[2][y * linesize[2] + x] = 64 + x + frame_index * 5; 48cabdff1aSopenharmony_ci } 49cabdff1aSopenharmony_ci } 50cabdff1aSopenharmony_ci} 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ciint main(int argc, char **argv) 53cabdff1aSopenharmony_ci{ 54cabdff1aSopenharmony_ci uint8_t *src_data[4], *dst_data[4]; 55cabdff1aSopenharmony_ci int src_linesize[4], dst_linesize[4]; 56cabdff1aSopenharmony_ci int src_w = 320, src_h = 240, dst_w, dst_h; 57cabdff1aSopenharmony_ci enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24; 58cabdff1aSopenharmony_ci const char *dst_size = NULL; 59cabdff1aSopenharmony_ci const char *dst_filename = NULL; 60cabdff1aSopenharmony_ci FILE *dst_file; 61cabdff1aSopenharmony_ci int dst_bufsize; 62cabdff1aSopenharmony_ci struct SwsContext *sws_ctx; 63cabdff1aSopenharmony_ci int i, ret; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci if (argc != 3) { 66cabdff1aSopenharmony_ci fprintf(stderr, "Usage: %s output_file output_size\n" 67cabdff1aSopenharmony_ci "API example program to show how to scale an image with libswscale.\n" 68cabdff1aSopenharmony_ci "This program generates a series of pictures, rescales them to the given " 69cabdff1aSopenharmony_ci "output_size and saves them to an output file named output_file\n." 70cabdff1aSopenharmony_ci "\n", argv[0]); 71cabdff1aSopenharmony_ci exit(1); 72cabdff1aSopenharmony_ci } 73cabdff1aSopenharmony_ci dst_filename = argv[1]; 74cabdff1aSopenharmony_ci dst_size = argv[2]; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) { 77cabdff1aSopenharmony_ci fprintf(stderr, 78cabdff1aSopenharmony_ci "Invalid size '%s', must be in the form WxH or a valid size abbreviation\n", 79cabdff1aSopenharmony_ci dst_size); 80cabdff1aSopenharmony_ci exit(1); 81cabdff1aSopenharmony_ci } 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci dst_file = fopen(dst_filename, "wb"); 84cabdff1aSopenharmony_ci if (!dst_file) { 85cabdff1aSopenharmony_ci fprintf(stderr, "Could not open destination file %s\n", dst_filename); 86cabdff1aSopenharmony_ci exit(1); 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci /* create scaling context */ 90cabdff1aSopenharmony_ci sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt, 91cabdff1aSopenharmony_ci dst_w, dst_h, dst_pix_fmt, 92cabdff1aSopenharmony_ci SWS_BILINEAR, NULL, NULL, NULL); 93cabdff1aSopenharmony_ci if (!sws_ctx) { 94cabdff1aSopenharmony_ci fprintf(stderr, 95cabdff1aSopenharmony_ci "Impossible to create scale context for the conversion " 96cabdff1aSopenharmony_ci "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", 97cabdff1aSopenharmony_ci av_get_pix_fmt_name(src_pix_fmt), src_w, src_h, 98cabdff1aSopenharmony_ci av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h); 99cabdff1aSopenharmony_ci ret = AVERROR(EINVAL); 100cabdff1aSopenharmony_ci goto end; 101cabdff1aSopenharmony_ci } 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci /* allocate source and destination image buffers */ 104cabdff1aSopenharmony_ci if ((ret = av_image_alloc(src_data, src_linesize, 105cabdff1aSopenharmony_ci src_w, src_h, src_pix_fmt, 16)) < 0) { 106cabdff1aSopenharmony_ci fprintf(stderr, "Could not allocate source image\n"); 107cabdff1aSopenharmony_ci goto end; 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_ci /* buffer is going to be written to rawvideo file, no alignment */ 111cabdff1aSopenharmony_ci if ((ret = av_image_alloc(dst_data, dst_linesize, 112cabdff1aSopenharmony_ci dst_w, dst_h, dst_pix_fmt, 1)) < 0) { 113cabdff1aSopenharmony_ci fprintf(stderr, "Could not allocate destination image\n"); 114cabdff1aSopenharmony_ci goto end; 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci dst_bufsize = ret; 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci for (i = 0; i < 100; i++) { 119cabdff1aSopenharmony_ci /* generate synthetic video */ 120cabdff1aSopenharmony_ci fill_yuv_image(src_data, src_linesize, src_w, src_h, i); 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci /* convert to destination format */ 123cabdff1aSopenharmony_ci sws_scale(sws_ctx, (const uint8_t * const*)src_data, 124cabdff1aSopenharmony_ci src_linesize, 0, src_h, dst_data, dst_linesize); 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci /* write scaled image to file */ 127cabdff1aSopenharmony_ci fwrite(dst_data[0], 1, dst_bufsize, dst_file); 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n" 131cabdff1aSopenharmony_ci "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n", 132cabdff1aSopenharmony_ci av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename); 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ciend: 135cabdff1aSopenharmony_ci fclose(dst_file); 136cabdff1aSopenharmony_ci av_freep(&src_data[0]); 137cabdff1aSopenharmony_ci av_freep(&dst_data[0]); 138cabdff1aSopenharmony_ci sws_freeContext(sws_ctx); 139cabdff1aSopenharmony_ci return ret < 0; 140cabdff1aSopenharmony_ci} 141