25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

347 satır
9.3 KiB

  1. /*
  2. * libpipi Pathetic image processing interface library
  3. * Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * codec.c: image I/O functions
  16. */
  17. #include "config.h"
  18. #if defined _WIN32
  19. # undef _CRT_SECURE_NO_WARNINGS
  20. # define _CRT_SECURE_NO_WARNINGS /* I know how to use snprintf, thank you */
  21. # define snprintf _snprintf
  22. #endif
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #if defined USE_FFMPEG
  27. # include <libavformat/avformat.h>
  28. # include <libswscale/swscale.h>
  29. #endif
  30. #include "pipi.h"
  31. #include "pipi_internals.h"
  32. #if defined USE_FFMPEG
  33. typedef struct
  34. {
  35. uint8_t *buf;
  36. size_t buf_len;
  37. AVFormatContext *fmt_ctx;
  38. AVStream *stream;
  39. AVCodecContext *cod_ctx;
  40. AVCodec *codec;
  41. AVFrame *frame;
  42. struct SwsContext *sws_ctx;
  43. int src_width, src_height, src_fmt;
  44. }
  45. ffmpeg_codec_t;
  46. #endif
  47. pipi_sequence_t *pipi_open_sequence(char const *file,
  48. int width, int height, int rgb, int fps,
  49. int par_num, int par_den, int bitrate)
  50. {
  51. #if defined USE_FFMPEG
  52. static int initialised = 0;
  53. pipi_sequence_t *seq;
  54. ffmpeg_codec_t *ff;
  55. uint8_t *tmp;
  56. seq = malloc(sizeof(pipi_sequence_t));
  57. seq->w = width;
  58. seq->h = height;
  59. seq->fps = fps;
  60. seq->convert_buf = NULL;
  61. ff = malloc(sizeof(ffmpeg_codec_t));
  62. memset(ff, 0, sizeof(*ff));
  63. seq->codec_priv = ff;
  64. if (!initialised)
  65. {
  66. av_register_all();
  67. initialised = 1;
  68. }
  69. ff->fmt_ctx = avformat_alloc_context();
  70. if (!ff->fmt_ctx)
  71. goto error;
  72. /* Careful here: the Win32 snprintf doesn't seem to add a trailing
  73. * zero to the truncated output. */
  74. snprintf(ff->fmt_ctx->filename, sizeof(ff->fmt_ctx->filename),
  75. file);
  76. ff->fmt_ctx->filename[sizeof(ff->fmt_ctx->filename) - 1] = '\0';
  77. ff->fmt_ctx->oformat = av_guess_format(NULL, file, NULL);
  78. if (!ff->fmt_ctx->oformat)
  79. ff->fmt_ctx->oformat = av_guess_format("mpeg", NULL, NULL);
  80. if (!ff->fmt_ctx->oformat)
  81. goto error;
  82. ff->stream = av_new_stream(ff->fmt_ctx, 0);
  83. if (!ff->stream)
  84. goto error;
  85. ff->stream->sample_aspect_ratio.num = par_num;
  86. ff->stream->sample_aspect_ratio.den = par_den;
  87. ff->cod_ctx = ff->stream->codec;
  88. ff->cod_ctx->width = width;
  89. ff->cod_ctx->height = height;
  90. ff->cod_ctx->sample_aspect_ratio.num = par_num;
  91. ff->cod_ctx->sample_aspect_ratio.den = par_den;
  92. ff->cod_ctx->codec_id = ff->fmt_ctx->oformat->video_codec;
  93. ff->cod_ctx->codec_type = CODEC_TYPE_VIDEO;
  94. ff->cod_ctx->bit_rate = bitrate;
  95. ff->cod_ctx->time_base.num = 1;
  96. ff->cod_ctx->time_base.den = fps;
  97. ff->cod_ctx->pix_fmt = PIX_FMT_YUV420P; /* send YUV 420 */
  98. if (ff->cod_ctx->codec_id == CODEC_ID_MPEG2VIDEO)
  99. ff->cod_ctx->max_b_frames = 2;
  100. if (ff->cod_ctx->codec_id == CODEC_ID_MPEG1VIDEO)
  101. ff->cod_ctx->mb_decision = 2;
  102. if (ff->cod_ctx->codec_id == CODEC_ID_H264)
  103. {
  104. /* Import x264 slow presets */
  105. ff->cod_ctx->coder_type = 1;
  106. ff->cod_ctx->flags |= CODEC_FLAG_LOOP_FILTER;
  107. ff->cod_ctx->me_cmp |= FF_CMP_CHROMA;
  108. ff->cod_ctx->partitions |= X264_PART_I4X4 | X264_PART_I8X8
  109. | X264_PART_P4X4 | X264_PART_P8X8;
  110. ff->cod_ctx->me_method = ME_UMH;
  111. ff->cod_ctx->me_subpel_quality = 8;
  112. ff->cod_ctx->me_range = 16;
  113. ff->cod_ctx->gop_size = 250;
  114. ff->cod_ctx->keyint_min = 25;
  115. ff->cod_ctx->scenechange_threshold = 40;
  116. ff->cod_ctx->i_quant_factor = 0.71f;
  117. ff->cod_ctx->b_frame_strategy = 2;
  118. ff->cod_ctx->qcompress = 0.6f;
  119. ff->cod_ctx->qmin = 10;
  120. ff->cod_ctx->qmax = 51;
  121. ff->cod_ctx->max_qdiff = 4;
  122. ff->cod_ctx->max_b_frames = 3;
  123. ff->cod_ctx->refs = 5;
  124. ff->cod_ctx->directpred = 3;
  125. ff->cod_ctx->trellis = 1;
  126. ff->cod_ctx->flags2 |= CODEC_FLAG2_BPYRAMID | CODEC_FLAG2_MIXED_REFS
  127. | CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT
  128. | CODEC_FLAG2_FASTPSKIP;
  129. ff->cod_ctx->weighted_p_pred = 2;
  130. ff->cod_ctx->rc_lookahead = 50;
  131. }
  132. if (ff->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
  133. ff->cod_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
  134. if (av_set_parameters(ff->fmt_ctx, NULL) < 0)
  135. goto error;
  136. ff->codec = avcodec_find_encoder(ff->cod_ctx->codec_id);
  137. if (!ff->codec)
  138. goto error;
  139. if (avcodec_open(ff->cod_ctx, ff->codec) < 0)
  140. goto error;
  141. ff->frame = avcodec_alloc_frame();
  142. if (!ff->frame)
  143. goto error;
  144. tmp = (uint8_t *)av_malloc(avpicture_get_size(ff->cod_ctx->pix_fmt,
  145. ff->cod_ctx->width,
  146. ff->cod_ctx->height));
  147. if (!tmp)
  148. goto error;
  149. avpicture_fill((AVPicture *)ff->frame, tmp, ff->cod_ctx->pix_fmt,
  150. ff->cod_ctx->width, ff->cod_ctx->height);
  151. if (!(ff->fmt_ctx->flags & AVFMT_NOFILE))
  152. if (url_fopen(&ff->fmt_ctx->pb, file, URL_WRONLY) < 0)
  153. goto error;
  154. ff->buf_len = 64 * 1024 * 1024;
  155. ff->buf = (uint8_t *)av_malloc(ff->buf_len);
  156. ff->src_fmt = rgb ? PIX_FMT_RGB32 : PIX_FMT_YUV444P;
  157. av_write_header(ff->fmt_ctx);
  158. return seq;
  159. error:
  160. pipi_close_sequence(seq);
  161. return NULL;
  162. #else
  163. return NULL;
  164. #endif
  165. }
  166. int pipi_feed_sequence(pipi_sequence_t *seq, uint8_t const *buffer,
  167. int width, int height)
  168. {
  169. #if defined USE_FFMPEG
  170. AVPacket packet;
  171. uint8_t const *buflist[3];
  172. int pitchlist[3];
  173. size_t bytes;
  174. int n;
  175. ffmpeg_codec_t *ff = (ffmpeg_codec_t *)seq->codec_priv;
  176. if (ff->src_width != width || ff->src_height != height)
  177. {
  178. ff->src_width = width;
  179. ff->src_height = height;
  180. if (ff->sws_ctx)
  181. sws_freeContext(ff->sws_ctx);
  182. ff->sws_ctx = NULL;
  183. }
  184. if (!ff->sws_ctx)
  185. {
  186. ff->sws_ctx = sws_getContext(width, height, ff->src_fmt,
  187. ff->cod_ctx->width,
  188. ff->cod_ctx->height,
  189. ff->cod_ctx->pix_fmt, SWS_BICUBIC,
  190. NULL, NULL, NULL);
  191. if (seq->convert_buf)
  192. {
  193. free(seq->convert_buf);
  194. seq->convert_buf = NULL;
  195. }
  196. }
  197. if (!ff->sws_ctx)
  198. return -1;
  199. /* Convert interleaved YUV to planar YUV */
  200. if (ff->src_fmt == PIX_FMT_YUV444P)
  201. {
  202. if (!seq->convert_buf)
  203. seq->convert_buf = malloc(width * height * 3);
  204. for (n = 0; n < width * height; n++)
  205. {
  206. seq->convert_buf[n] = buffer[4 * n];
  207. seq->convert_buf[n + width * height] = buffer[4 * n + 1];
  208. seq->convert_buf[n + 2 * width * height] = buffer[4 * n + 2];
  209. }
  210. /* Feed the buffers to FFmpeg */
  211. buflist[0] = seq->convert_buf;
  212. buflist[1] = seq->convert_buf + 2 * width * height;
  213. buflist[2] = seq->convert_buf + width * height;
  214. pitchlist[0] = pitchlist[1] = pitchlist[2] = width;
  215. }
  216. else
  217. {
  218. buflist[0] = buffer;
  219. pitchlist[0] = 4 * width;
  220. }
  221. sws_scale(ff->sws_ctx, buflist, pitchlist, 0, height,
  222. ff->frame->data, ff->frame->linesize);
  223. bytes = avcodec_encode_video(ff->cod_ctx, ff->buf,
  224. ff->buf_len, ff->frame);
  225. if (bytes <= 0)
  226. return 0;
  227. av_init_packet(&packet);
  228. if (ff->cod_ctx->coded_frame->pts != 0x8000000000000000LL)
  229. packet.pts = av_rescale_q(ff->cod_ctx->coded_frame->pts,
  230. ff->cod_ctx->time_base, ff->stream->time_base);
  231. if (ff->cod_ctx->coded_frame->key_frame)
  232. packet.flags |= PKT_FLAG_KEY;
  233. packet.stream_index = 0;
  234. packet.data = ff->buf;
  235. packet.size = bytes;
  236. if (av_interleaved_write_frame(ff->fmt_ctx, &packet) < 0)
  237. return -1;
  238. #endif
  239. return 0;
  240. }
  241. int pipi_close_sequence(pipi_sequence_t *seq)
  242. {
  243. #if defined USE_FFMPEG
  244. ffmpeg_codec_t *ff = (ffmpeg_codec_t *)seq->codec_priv;
  245. /* Finish the sequence */
  246. if (ff->buf)
  247. {
  248. av_write_trailer(ff->fmt_ctx);
  249. }
  250. /* Close everything */
  251. if (ff->buf)
  252. {
  253. av_free(ff->buf);
  254. ff->buf = NULL;
  255. }
  256. if (ff->cod_ctx)
  257. {
  258. avcodec_close(ff->cod_ctx);
  259. ff->cod_ctx = NULL;
  260. }
  261. if (ff->frame)
  262. {
  263. av_free(ff->frame->data[0]);
  264. av_free(ff->frame);
  265. ff->frame = NULL;
  266. }
  267. if (ff->fmt_ctx)
  268. {
  269. av_freep(&ff->fmt_ctx->streams[0]->codec);
  270. ff->codec = NULL;
  271. av_freep(&ff->fmt_ctx->streams[0]);
  272. ff->stream = NULL;
  273. if (!(ff->fmt_ctx->flags & AVFMT_NOFILE) && ff->fmt_ctx->pb)
  274. url_fclose(ff->fmt_ctx->pb);
  275. av_free(ff->fmt_ctx);
  276. ff->fmt_ctx = NULL;
  277. }
  278. if (ff->sws_ctx)
  279. {
  280. sws_freeContext(ff->sws_ctx);
  281. ff->sws_ctx = NULL;
  282. ff->src_width = ff->src_height = 0;
  283. }
  284. free(ff);
  285. free(seq);
  286. #endif
  287. return 0;
  288. }