gsd_img_mpeg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*!
  2. \file gsd_img_mpeg.c
  3. \brief OGSF library - FFMPEG stuff
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008, 2012 by the GRASS Development Team
  6. This program is free software under the GNU General Public License
  7. (>=v2). Read the file COPYING that comes with GRASS for details.
  8. \author Bill Brown USACERL, GMSL/University of Illinois
  9. \author Doxygenized (May 2008) and update for FFMPEG >= 0.7
  10. (November 2012) by Martin Landa <landa.martin gmail.com>
  11. */
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <grass/gis.h>
  15. #include <grass/glocale.h>
  16. #include <grass/ogsf.h>
  17. /* FFMPEG stuff */
  18. #ifdef HAVE_FFMPEG
  19. #include <avformat.h>
  20. #include <avio.h>
  21. #if LIBAVUTIL_VERSION_MAJOR < 51
  22. #include <avutil.h>
  23. #else
  24. /* libavutil 51.22.1's avutil.h doesn't include libavutil/mathematics.h */
  25. #include <mathematics.h>
  26. #endif
  27. /* 5 seconds stream duration */
  28. #define STREAM_DURATION 5.0
  29. #define STREAM_FRAME_RATE 25 /* 25 images/s */
  30. #define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
  31. #define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
  32. AVFrame *picture, *tmp_picture;
  33. uint8_t *video_outbuf;
  34. int frame_count, video_outbuf_size;
  35. AVOutputFormat *fmt;
  36. AVFormatContext *oc;
  37. AVStream *video_st;
  38. /*!
  39. \brief Add a video output stream
  40. \param oc
  41. \param codec_id
  42. \param w
  43. \param h
  44. \return
  45. */
  46. static AVStream *add_video_stream(AVFormatContext * oc, int codec_id, int w,
  47. int h)
  48. {
  49. AVCodecContext *c;
  50. AVStream *st;
  51. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 112, 0)
  52. st = av_new_stream(oc, 0);
  53. #else
  54. st = avformat_new_stream(oc, NULL);
  55. #endif
  56. if (!st) {
  57. G_warning(_("Unable to allocate stream"));
  58. return NULL;
  59. }
  60. c = st->codec;
  61. c->codec_id = codec_id;
  62. #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 123, 0)
  63. c->codec_type = CODEC_TYPE_VIDEO;
  64. #else
  65. c->codec_type = AVMEDIA_TYPE_VIDEO;
  66. #endif
  67. /* put sample parameters */
  68. c->bit_rate = 400000;
  69. /* resolution must be a multiple of two */
  70. c->width = w;
  71. c->height = h;
  72. /* time base: this is the fundamental unit of time (in seconds) in terms
  73. of which frame timestamps are represented. for fixed-fps content,
  74. timebase should be 1/framerate and timestamp increments should be
  75. identically 1. */
  76. c->time_base.den = STREAM_FRAME_RATE;
  77. c->time_base.num = 1;
  78. c->gop_size = 12; /* emit one intra frame every twelve frames at most */
  79. c->pix_fmt = STREAM_PIX_FMT;
  80. if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
  81. /* just for testing, we also add B frames */
  82. c->max_b_frames = 2;
  83. }
  84. if (c->codec_id == CODEC_ID_MPEG1VIDEO) {
  85. /* Needed to avoid using macroblocks in which some coeffs overflow.
  86. This does not happen with normal video, it just happens here as
  87. the motion of the chroma plane does not match the luma plane. */
  88. c->mb_decision = 2;
  89. }
  90. /* some formats want stream headers to be separate */
  91. if (!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov")
  92. || !strcmp(oc->oformat->name, "3gp"))
  93. c->flags |= CODEC_FLAG_GLOBAL_HEADER;
  94. c->flags |= CODEC_FLAG_QSCALE;
  95. /* Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. */
  96. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  97. c->global_quality = st->quality = FF_QP2LAMBDA * 10;
  98. #else
  99. c->global_quality = FF_QP2LAMBDA * 10;
  100. #endif
  101. return st;
  102. }
  103. /*!
  104. \brief Allocate picture
  105. \param pix_fmt
  106. \param width picture width
  107. \param height picture height
  108. \return pointer to AVFrame struct
  109. \return NULL on failure
  110. */
  111. static AVFrame *alloc_picture(int pix_fmt, int width, int height)
  112. {
  113. AVFrame *picture;
  114. uint8_t *picture_buf;
  115. int size;
  116. picture = avcodec_alloc_frame();
  117. if (!picture)
  118. return NULL;
  119. size = avpicture_get_size(pix_fmt, width, height);
  120. picture_buf = av_malloc(size);
  121. if (!picture_buf) {
  122. av_free(picture);
  123. return NULL;
  124. }
  125. avpicture_fill((AVPicture *) picture, picture_buf,
  126. pix_fmt, width, height);
  127. return picture;
  128. }
  129. /*!
  130. \brief Open video
  131. \param oc
  132. \param st
  133. */
  134. static void open_video(AVFormatContext * oc, AVStream * st)
  135. {
  136. AVCodec *codec;
  137. AVCodecContext *c;
  138. c = st->codec;
  139. /* find the video encoder */
  140. codec = avcodec_find_encoder(c->codec_id);
  141. if (!codec) {
  142. G_warning(_("Video codec not found"));
  143. return;
  144. }
  145. /* open the codec */
  146. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  147. if (avcodec_open(c, codec) < 0) {
  148. #else
  149. if (avcodec_open2(c, codec, NULL) < 0) {
  150. #endif
  151. G_warning(_("Unable to open codec"));
  152. return;
  153. }
  154. video_outbuf = NULL;
  155. if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
  156. /* allocate output buffer */
  157. /* XXX: API change will be done */
  158. /* buffers passed into lav* can be allocated any way you prefer,
  159. as long as they're aligned enough for the architecture, and
  160. they're freed appropriately (such as using av_free for buffers
  161. allocated with av_malloc) */
  162. video_outbuf_size = 200000;
  163. video_outbuf = av_malloc(video_outbuf_size);
  164. }
  165. /* allocate the encoded raw picture */
  166. picture = alloc_picture(c->pix_fmt, c->width, c->height);
  167. if (!picture) {
  168. G_warning(_("Unable to allocate picture"));
  169. return;
  170. }
  171. /* if the output format is not YUV420P, then a temporary YUV420P
  172. picture is needed too. It is then converted to the required
  173. output format */
  174. tmp_picture = NULL;
  175. if (c->pix_fmt != PIX_FMT_YUV420P) {
  176. tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height);
  177. if (!tmp_picture) {
  178. G_warning(_("Unable to allocate temporary picture"));
  179. return;
  180. }
  181. }
  182. }
  183. /*!
  184. \brief Write video frame
  185. \param oc
  186. \param st
  187. */
  188. static void write_video_frame(AVFormatContext * oc, AVStream * st)
  189. {
  190. int out_size, ret;
  191. AVCodecContext *c;
  192. c = st->codec;
  193. if (oc->oformat->flags & AVFMT_RAWPICTURE) {
  194. /* raw video case. The API will change slightly in the near
  195. future for that */
  196. AVPacket pkt;
  197. av_init_packet(&pkt);
  198. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
  199. pkt.flags |= PKT_FLAG_KEY;
  200. #else
  201. pkt.flags |= AV_PKT_FLAG_KEY;
  202. #endif
  203. pkt.stream_index = st->index;
  204. pkt.data = (uint8_t *) picture;
  205. pkt.size = sizeof(AVPicture);
  206. ret = av_write_frame(oc, &pkt);
  207. }
  208. else {
  209. /* encode the image */
  210. out_size =
  211. avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
  212. /* if zero size, it means the image was buffered */
  213. if (out_size > 0) {
  214. AVPacket pkt;
  215. av_init_packet(&pkt);
  216. pkt.pts =
  217. av_rescale_q(c->coded_frame->pts, c->time_base,
  218. st->time_base);
  219. if (c->coded_frame->key_frame)
  220. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
  221. pkt.flags |= PKT_FLAG_KEY;
  222. #else
  223. pkt.flags |= AV_PKT_FLAG_KEY;
  224. #endif
  225. pkt.stream_index = st->index;
  226. pkt.data = video_outbuf;
  227. pkt.size = out_size;
  228. /* write the compressed frame in the media file */
  229. ret = av_write_frame(oc, &pkt);
  230. }
  231. else {
  232. ret = 0;
  233. }
  234. }
  235. if (ret != 0) {
  236. G_warning(_("Error while writing video frame"));
  237. return;
  238. }
  239. frame_count++;
  240. }
  241. /*!
  242. \brief Close video
  243. \param oc [unused]
  244. \param st
  245. */
  246. static void close_video(AVStream * st)
  247. {
  248. avcodec_close(st->codec);
  249. av_free(picture->data[0]);
  250. av_free(picture);
  251. if (tmp_picture) {
  252. av_free(tmp_picture->data[0]);
  253. av_free(tmp_picture);
  254. }
  255. av_free(video_outbuf);
  256. }
  257. #endif
  258. /*!
  259. \brief Initialize FAME setup mpeg defaults and open file for writing
  260. \param filename file name
  261. \return -1 on failure
  262. \return 0 on success
  263. */
  264. int gsd_init_mpeg(const char *filename)
  265. {
  266. #ifdef HAVE_FFMPEG
  267. GLuint l, r, b, t;
  268. GLint tmp[4];
  269. glGetIntegerv(GL_VIEWPORT, tmp);
  270. l = tmp[0];
  271. r = tmp[0] + tmp[2] - 1;
  272. b = tmp[1];
  273. t = tmp[1] + tmp[3] - 1;
  274. G_verbose_message(_("Opening MPEG stream <%s>..."), filename);
  275. /* initialize libavcodec, and register all codecs and formats */
  276. av_register_all();
  277. /* auto detect the output format from the name. default is mpeg. */
  278. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
  279. fmt = guess_format(NULL, filename, NULL);
  280. #else
  281. fmt = av_guess_format(NULL, filename, NULL);
  282. #endif
  283. if (!fmt) {
  284. G_warning(_("Unable to deduce output format from file extension: using MPEG"));
  285. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
  286. fmt = guess_format("mpeg", NULL, NULL);
  287. #else
  288. fmt = av_guess_format("mpeg", NULL, NULL);
  289. #endif
  290. }
  291. if (!fmt) {
  292. G_warning(_("Unable to find suitable output format"));
  293. return (-1);
  294. }
  295. /* allocate the output media context */
  296. oc = avformat_alloc_context();
  297. if (!oc) {
  298. G_warning(_("Out of memory"));
  299. return (-1);
  300. }
  301. oc->oformat = fmt;
  302. snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
  303. /* if you want to hardcode the codec (eg #ifdef USE_XVID)
  304. this may be the place to do it (?????) */
  305. #ifdef USE_XVID
  306. fmt->video_codec = CODEC_ID_XVID;
  307. #endif
  308. video_st = NULL;
  309. if (fmt->video_codec != CODEC_ID_NONE) {
  310. video_st =
  311. add_video_stream(oc, fmt->video_codec, (r - l + 1), (t - b + 1));
  312. }
  313. /* set the output parameters (must be done even if no parameters). */
  314. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  315. if (av_set_parameters(oc, NULL) < 0) {
  316. #else
  317. if (avformat_write_header(oc, NULL) < 0) {
  318. #endif
  319. G_warning(_("Invalid output format parameters"));
  320. return -1;
  321. }
  322. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  323. dump_format(oc, 0, filename, 1);
  324. #else
  325. av_dump_format(oc, 0, filename, 1);
  326. #endif
  327. /* now that all the parameters are set, we can open the audio and
  328. video codecs and allocate the necessary encode buffers */
  329. if (video_st)
  330. open_video(oc, video_st);
  331. /* open the output file, if needed */
  332. if (!(fmt->flags & AVFMT_NOFILE)) {
  333. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 112, 0)
  334. if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
  335. #else
  336. if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
  337. #endif
  338. G_warning(_("Unable to open <%s>"), filename);
  339. return (-1);
  340. }
  341. }
  342. /* write the stream header, if any */
  343. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  344. av_write_header(oc);
  345. #else
  346. avformat_write_header(oc, NULL);
  347. #endif
  348. #else
  349. G_warning(_("OGSF library has not been built with MPEG output support"));
  350. return -1;
  351. #endif
  352. return 0;
  353. }
  354. /*!
  355. \brief Get RGB pixbuf and convert to YUV 4:2:0
  356. Image and write to mpeg stream
  357. \return 0
  358. */
  359. int gsd_write_mpegframe(void)
  360. {
  361. #ifdef HAVE_FFMPEG
  362. unsigned int xsize, ysize, x;
  363. int y, xy, xy_uv;
  364. int yy, uu, vv;
  365. unsigned char *pixbuf;
  366. gsd_getimage(&pixbuf, &xsize, &ysize);
  367. xy = xy_uv = 0;
  368. for (y = ysize - 1; y >= 0; y--) {
  369. for (x = 0; x < xsize; x++) {
  370. unsigned char r = pixbuf[(y * xsize + x) * 4 + 0];
  371. unsigned char g = pixbuf[(y * xsize + x) * 4 + 1];
  372. unsigned char b = pixbuf[(y * xsize + x) * 4 + 2];
  373. yy = (0.257 * r) + (0.504 * g) + (0.098 * b) + 16;;
  374. vv = (0.439 * r) - (0.368 * g) - (0.071 * b) + 128;
  375. uu = -(0.148 * r) - (0.291 * g) + (0.439 * b) + 128;
  376. fflush(stdout);
  377. picture->data[0][xy] = yy;
  378. if ((x % 2) && (y % 2)) {
  379. picture->data[1][xy_uv] = uu;
  380. picture->data[2][xy_uv] = vv;
  381. xy_uv++;
  382. }
  383. xy++;
  384. }
  385. }
  386. G_free(pixbuf);
  387. write_video_frame(oc, video_st);
  388. #endif
  389. return (0);
  390. }
  391. /*!
  392. \brief Close the mpeg, free buffer, and close file
  393. \return 0
  394. */
  395. int gsd_close_mpeg(void)
  396. {
  397. #ifdef HAVE_FFMPEG
  398. unsigned int i;
  399. close_video(video_st);
  400. /* write the trailer, if any */
  401. av_write_trailer(oc);
  402. /* free the streams */
  403. for (i = 0; i < oc->nb_streams; i++) {
  404. av_freep(&oc->streams[i]->codec);
  405. av_freep(&oc->streams[i]);
  406. }
  407. if (!(fmt->flags & AVFMT_NOFILE)) {
  408. /* close the output file */
  409. #if (LIBAVFORMAT_VERSION_INT>>16) < 52
  410. url_fclose(&oc->pb);
  411. #elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
  412. url_fclose(oc->pb);
  413. #else
  414. avio_close(oc->pb);
  415. #endif
  416. }
  417. /* free the stream */
  418. av_free(oc);
  419. G_debug(3, "Closed MPEG stream");
  420. #endif
  421. return 0;
  422. }