movie_writer_mjpeg.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /**************************************************************************/
  2. /* movie_writer_mjpeg.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "movie_writer_mjpeg.h"
  31. #include "core/config/project_settings.h"
  32. uint32_t MovieWriterMJPEG::get_audio_mix_rate() const {
  33. return mix_rate;
  34. }
  35. AudioServer::SpeakerMode MovieWriterMJPEG::get_audio_speaker_mode() const {
  36. return speaker_mode;
  37. }
  38. bool MovieWriterMJPEG::handles_file(const String &p_path) const {
  39. return p_path.get_extension().to_lower() == "avi";
  40. }
  41. void MovieWriterMJPEG::get_supported_extensions(List<String> *r_extensions) const {
  42. r_extensions->push_back("avi");
  43. }
  44. Error MovieWriterMJPEG::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
  45. // Quick & Dirty MJPEG Code based on - https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
  46. base_path = p_base_path.get_basename();
  47. if (base_path.is_relative_path()) {
  48. base_path = "res://" + base_path;
  49. }
  50. base_path += ".avi";
  51. f = FileAccess::open(base_path, FileAccess::WRITE_READ);
  52. fps = p_fps;
  53. ERR_FAIL_COND_V(f.is_null(), ERR_CANT_OPEN);
  54. f->store_buffer((const uint8_t *)"RIFF", 4);
  55. f->store_32(0); // Total length (update later)
  56. f->store_buffer((const uint8_t *)"AVI ", 4);
  57. f->store_buffer((const uint8_t *)"LIST", 4);
  58. f->store_32(300); // 4 + 4 + 4 + 56 + 4 + 4 + 132 + 4 + 4 + 84
  59. f->store_buffer((const uint8_t *)"hdrl", 4);
  60. f->store_buffer((const uint8_t *)"avih", 4);
  61. f->store_32(56);
  62. f->store_32(1000000 / p_fps); // Microsecs per frame.
  63. f->store_32(7000); // Max bytes per second
  64. f->store_32(0); // Padding Granularity
  65. f->store_32(16);
  66. total_frames_ofs = f->get_position();
  67. f->store_32(0); // Total frames (update later)
  68. f->store_32(0); // Initial frames
  69. f->store_32(1); // Streams
  70. f->store_32(0); // Suggested buffer size
  71. f->store_32(p_movie_size.width); // Movie Width
  72. f->store_32(p_movie_size.height); // Movie Height
  73. for (uint32_t i = 0; i < 4; i++) {
  74. f->store_32(0); // Reserved.
  75. }
  76. f->store_buffer((const uint8_t *)"LIST", 4);
  77. f->store_32(132); // 4 + 4 + 4 + 48 + 4 + 4 + 40 + 4 + 4 + 16
  78. f->store_buffer((const uint8_t *)"strl", 4);
  79. f->store_buffer((const uint8_t *)"strh", 4);
  80. f->store_32(48);
  81. f->store_buffer((const uint8_t *)"vids", 4);
  82. f->store_buffer((const uint8_t *)"MJPG", 4);
  83. f->store_32(0); // Flags
  84. f->store_16(0); // Priority
  85. f->store_16(0); // Language
  86. f->store_32(0); // Initial Frames
  87. f->store_32(1); // Scale
  88. f->store_32(p_fps); // FPS
  89. f->store_32(0); // Start
  90. total_frames_ofs2 = f->get_position();
  91. f->store_32(0); // Number of frames (to be updated later)
  92. f->store_32(0); // Suggested Buffer Size
  93. f->store_32(0); // Quality
  94. f->store_32(0); // Sample Size
  95. f->store_buffer((const uint8_t *)"strf", 4);
  96. f->store_32(40); // Size.
  97. f->store_32(40); // Size.
  98. f->store_32(p_movie_size.width); // Width
  99. f->store_32(p_movie_size.height); // Width
  100. f->store_16(1); // Planes
  101. f->store_16(24); // Bitcount
  102. f->store_buffer((const uint8_t *)"MJPG", 4); // Compression
  103. f->store_32(((p_movie_size.width * 24 / 8 + 3) & 0xFFFFFFFC) * p_movie_size.height); // SizeImage
  104. f->store_32(0); // XPelsXMeter
  105. f->store_32(0); // YPelsXMeter
  106. f->store_32(0); // ClrUsed
  107. f->store_32(0); // ClrImportant
  108. f->store_buffer((const uint8_t *)"LIST", 4);
  109. f->store_32(16);
  110. f->store_buffer((const uint8_t *)"odml", 4);
  111. f->store_buffer((const uint8_t *)"dmlh", 4);
  112. f->store_32(4); // sizes
  113. total_frames_ofs3 = f->get_position();
  114. f->store_32(0); // Number of frames (to be updated later)
  115. // Audio //
  116. const uint32_t bit_depth = 32;
  117. uint32_t channels = 2;
  118. switch (speaker_mode) {
  119. case AudioServer::SPEAKER_MODE_STEREO:
  120. channels = 2;
  121. break;
  122. case AudioServer::SPEAKER_SURROUND_31:
  123. channels = 4;
  124. break;
  125. case AudioServer::SPEAKER_SURROUND_51:
  126. channels = 6;
  127. break;
  128. case AudioServer::SPEAKER_SURROUND_71:
  129. channels = 8;
  130. break;
  131. }
  132. uint32_t blockalign = bit_depth / 8 * channels;
  133. f->store_buffer((const uint8_t *)"LIST", 4);
  134. f->store_32(84); // 4 + 4 + 4 + 48 + 4 + 4 + 16
  135. f->store_buffer((const uint8_t *)"strl", 4);
  136. f->store_buffer((const uint8_t *)"strh", 4);
  137. f->store_32(48);
  138. f->store_buffer((const uint8_t *)"auds", 4);
  139. f->store_32(0); // Handler
  140. f->store_32(0); // Flags
  141. f->store_16(0); // Priority
  142. f->store_16(0); // Language
  143. f->store_32(0); // Initial Frames
  144. f->store_32(blockalign); // Scale
  145. f->store_32(mix_rate * blockalign); // mix rate
  146. f->store_32(0); // Start
  147. total_audio_frames_ofs4 = f->get_position();
  148. f->store_32(0); // Number of frames (to be updated later)
  149. f->store_32(12288); // Suggested Buffer Size
  150. f->store_32(0xFFFFFFFF); // Quality
  151. f->store_32(blockalign); // Block Align to 32 bits
  152. audio_block_size = (mix_rate / fps) * blockalign;
  153. f->store_buffer((const uint8_t *)"strf", 4);
  154. f->store_32(16); // Standard format, no extra fields
  155. f->store_16(1); // Compression code, standard PCM
  156. f->store_16(channels);
  157. f->store_32(mix_rate); // Samples (frames) / Sec
  158. f->store_32(mix_rate * blockalign); // Bytes / sec
  159. f->store_16(blockalign); // Bytes / sec
  160. f->store_16(bit_depth); // Bytes / sec
  161. f->store_buffer((const uint8_t *)"LIST", 4);
  162. movi_data_ofs = f->get_position();
  163. f->store_32(0); // Number of frames (to be updated later)
  164. f->store_buffer((const uint8_t *)"movi", 4);
  165. return OK;
  166. }
  167. Error MovieWriterMJPEG::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
  168. ERR_FAIL_COND_V(!f.is_valid(), ERR_UNCONFIGURED);
  169. Vector<uint8_t> jpg_buffer = p_image->save_jpg_to_buffer(quality);
  170. uint32_t s = jpg_buffer.size();
  171. f->store_buffer((const uint8_t *)"00db", 4); // Stream 0, Video
  172. f->store_32(jpg_buffer.size()); // sizes
  173. f->store_buffer(jpg_buffer.ptr(), jpg_buffer.size());
  174. if (jpg_buffer.size() & 1) {
  175. f->store_8(0);
  176. s++;
  177. }
  178. jpg_frame_sizes.push_back(s);
  179. f->store_buffer((const uint8_t *)"01wb", 4); // Stream 1, Audio.
  180. f->store_32(audio_block_size);
  181. f->store_buffer((const uint8_t *)p_audio_data, audio_block_size);
  182. frame_count++;
  183. return OK;
  184. }
  185. void MovieWriterMJPEG::write_end() {
  186. if (f.is_valid()) {
  187. // Finalize the file (frame indices)
  188. f->store_buffer((const uint8_t *)"idx1", 4);
  189. f->store_32(8 * 4 * frame_count);
  190. uint32_t ofs = 4;
  191. uint32_t all_data_size = 0;
  192. for (uint32_t i = 0; i < frame_count; i++) {
  193. f->store_buffer((const uint8_t *)"00db", 4);
  194. f->store_32(16); // AVI_KEYFRAME
  195. f->store_32(ofs);
  196. f->store_32(jpg_frame_sizes[i]);
  197. ofs += jpg_frame_sizes[i] + 8;
  198. f->store_buffer((const uint8_t *)"01wb", 4);
  199. f->store_32(16); // AVI_KEYFRAME
  200. f->store_32(ofs);
  201. f->store_32(audio_block_size);
  202. ofs += audio_block_size + 8;
  203. all_data_size += jpg_frame_sizes[i] + audio_block_size;
  204. }
  205. uint32_t file_size = f->get_position();
  206. f->seek(4);
  207. f->store_32(file_size - 78);
  208. f->seek(total_frames_ofs);
  209. f->store_32(frame_count);
  210. f->seek(total_frames_ofs2);
  211. f->store_32(frame_count);
  212. f->seek(total_frames_ofs3);
  213. f->store_32(frame_count);
  214. f->seek(total_audio_frames_ofs4);
  215. f->store_32(frame_count * mix_rate / fps);
  216. f->seek(movi_data_ofs);
  217. f->store_32(all_data_size + 4 + 16 * frame_count);
  218. f.unref();
  219. }
  220. }
  221. MovieWriterMJPEG::MovieWriterMJPEG() {
  222. mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate");
  223. speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")));
  224. quality = GLOBAL_GET("editor/movie_writer/mjpeg_quality");
  225. }