Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.54 KB | None | 0 0
  1. //
  2. // Created by ranqingguo on 7/21/17.
  3. //
  4.  
  5. #include <cstdio>
  6.  
  7.  
  8. #include "ExportThread.h"
  9. #include "util/common.h"
  10. #include "Player.h"
  11.  
  12. #define TAG "ExportThread"
  13.  
  14. enum {
  15. kWhatDequeueFrame,
  16. kWhatStart,
  17. kWhatStop,
  18. kWhatSetExportParams,
  19. kWhatSignalEndOfStream,
  20. };
  21.  
  22. void ExportThread::handle(int what, void *data) {
  23.  
  24. switch (what) {
  25. case kWhatDequeueFrame:
  26. handleDequeueFrame();
  27. break;
  28. case kWhatStart:
  29. handleStart();
  30. break;
  31. case kWhatStop:
  32. handleStop();
  33. break;
  34. case kWhatSetExportParams:
  35. handleSetParams((ExportOpts *) data);
  36. case kWhatSignalEndOfStream: {
  37. AMediaCodec_signalEndOfInputStream(mEncoder);
  38. }
  39. break;
  40. default:
  41. break;
  42. }
  43.  
  44. }
  45.  
  46.  
  47. ExportThread::ExportThread(Painter *painter)
  48. : Looper("export"), mPainter(painter) {
  49. post(kWhatStart, nullptr);
  50. }
  51.  
  52. ExportThread::~ExportThread() {
  53. }
  54.  
  55. void ExportThread::handleStart() {
  56. }
  57.  
  58. void ExportThread::handleStop() {
  59. if (mEncoder != nullptr) {
  60. AMediaCodec_stop(mEncoder);
  61. AMediaCodec_delete(mEncoder);
  62. mEncoder = nullptr;
  63. }
  64.  
  65. if (mMuxer != nullptr) {
  66. AMediaMuxer_stop(mMuxer);
  67. AMediaMuxer_delete(mMuxer);
  68. mMuxer = nullptr;
  69. }
  70.  
  71. if (mOutFile != nullptr) {
  72. fflush(mOutFile);
  73. fclose(mOutFile);
  74. mOutFile = nullptr;
  75. }
  76.  
  77. mPainter->postExportFinished();
  78. }
  79.  
  80. void ExportThread::handleSetParams(ExportOpts *pOpts) {
  81. #define COLOR_FormatSurface 0x7F000789
  82.  
  83. FILE *file = fopen(pOpts->outPath.c_str(), "w");
  84. mOutFile = file;
  85. int fd = fileno(file);
  86. mMuxer = AMediaMuxer_new(fd, AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4);
  87. char mime[] = "video/avc";
  88. AMediaFormat *format = AMediaFormat_new();
  89. AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime);
  90. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, pOpts->width);
  91. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, pOpts->height);
  92. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, pOpts->bitrate);
  93. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, pOpts->frameRate);
  94. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, COLOR_FormatSurface);
  95. AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
  96.  
  97. mEncoder = AMediaCodec_createEncoderByType(mime);
  98. if (mEncoder == nullptr) {
  99. LOGE("AMediaCodec_createEncoderByType fail");
  100. }
  101. auto r = AMediaCodec_configure(mEncoder, format, nullptr, nullptr,
  102. AMEDIACODEC_CONFIGURE_FLAG_ENCODE);
  103. if (r != AMEDIA_OK) {
  104. LOGE("AMediaCodec_configure fail");
  105. }
  106. ANativeWindow *window;
  107. r = AMediaCodec_createInputSurface(mEncoder, &window);
  108. if (r != AMEDIA_OK) {
  109. LOGE("AMediaCodec_createInputSurface fail");
  110. }
  111. r = AMediaCodec_start(mEncoder);
  112.  
  113. if (r != AMEDIA_OK) {
  114. LOGE("AMediaCodec_start fail");
  115. }
  116.  
  117. mPainter->postCreateWindowSurface(window);
  118. }
  119.  
  120. #define DEQUEUE_WAIT_TIME_US 0
  121.  
  122. void ExportThread::handleDequeueFrame() {
  123. auto index = AMediaCodec_dequeueOutputBuffer(mEncoder, &mInfo, DEQUEUE_WAIT_TIME_US);
  124.  
  125. switch (index) {
  126. case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED: {
  127. auto format = AMediaCodec_getOutputFormat(mEncoder);
  128. mVideoTrack = (size_t) AMediaMuxer_addTrack(mMuxer, format);
  129. auto r = AMediaMuxer_start(mMuxer);
  130. if (r != AMEDIA_OK) {
  131. LOGE("AMediaMuxer_start fail");
  132. }
  133. break;
  134. }
  135. case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
  136. break;
  137. case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
  138. break;
  139.  
  140. default: {
  141. size_t size = 0;
  142. auto buf = AMediaCodec_getOutputBuffer(mEncoder, (size_t) index, &size);
  143. if (mInfo.size > 0) {
  144. auto r = AMediaMuxer_writeSampleData(mMuxer, mVideoTrack, buf, &mInfo);
  145. if (r != AMEDIA_OK) {
  146. LOGE("AMediaMuxer_writeSampleData fail");
  147. }
  148. }
  149.  
  150. AMediaCodec_releaseOutputBuffer(mEncoder, (size_t) index, false);
  151.  
  152. if ((mInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) != 0) {
  153. post(kWhatStop, nullptr);
  154. return;
  155. }
  156. break;
  157. }
  158. }
  159.  
  160. post(kWhatDequeueFrame, nullptr);
  161.  
  162. }
  163.  
  164. void ExportThread::postSetup(ExportOpts *pOpts) {
  165. post(kWhatSetExportParams, pOpts);
  166. }
  167.  
  168. void ExportThread::signalEndOfStream() {
  169. post(kWhatSignalEndOfStream, nullptr);
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement