decoder.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. #include <stdio.h>
  2. #include <sys/time.h>
  3. #include <sys/timeb.h>
  4. #include <unistd.h>
  5. typedef void(*VideoCallback)(unsigned char *buff, int size, double timestamp);
  6. typedef void(*AudioCallback)(unsigned char *buff, int size, double timestamp);
  7. typedef void(*RequestCallback)(int offset, int available);
  8. #ifdef __cplusplus
  9. extern "C" {
  10. #endif
  11. #include "libavcodec/avcodec.h"
  12. #include "libavformat/avformat.h"
  13. #include "libavutil/fifo.h"
  14. //#include "libswscale/swscale.h"
  15. #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
  16. const int kCustomIoBufferSize = 32 * 1024;
  17. const int kInitialPcmBufferSize = 128 * 1024;
  18. const int kDefaultFifoSize = 1 * 1024 * 1024;
  19. const int kMaxFifoSize = 16 * 1024 * 1024;
  20. typedef enum ErrorCode {
  21. kErrorCode_Success = 0,
  22. kErrorCode_Invalid_Param,
  23. kErrorCode_Invalid_State,
  24. kErrorCode_Invalid_Data,
  25. kErrorCode_Invalid_Format,
  26. kErrorCode_NULL_Pointer,
  27. kErrorCode_Open_File_Error,
  28. kErrorCode_Eof,
  29. kErrorCode_FFmpeg_Error,
  30. kErrorCode_Old_Frame
  31. } ErrorCode;
  32. typedef enum LogLevel {
  33. kLogLevel_None, //Not logging.
  34. kLogLevel_Core, //Only logging core module(without ffmpeg).
  35. kLogLevel_All //Logging all, with ffmpeg.
  36. } LogLevel;
  37. typedef struct WebDecoder {
  38. AVFormatContext *avformatContext;
  39. AVCodecContext *videoCodecContext;
  40. AVCodecContext *audioCodecContext;
  41. AVFrame *avFrame;
  42. int videoStreamIdx;
  43. int audioStreamIdx;
  44. VideoCallback videoCallback;
  45. AudioCallback audioCallback;
  46. RequestCallback requestCallback;
  47. unsigned char *yuvBuffer;
  48. //unsigned char *rgbBuffer;
  49. unsigned char *pcmBuffer;
  50. int currentPcmBufferSize;
  51. int videoBufferSize;
  52. int videoSize;
  53. //struct SwsContext* swsCtx;
  54. unsigned char *customIoBuffer;
  55. FILE *fp;
  56. char fileName[64];
  57. int64_t fileSize;
  58. int64_t fileReadPos;
  59. int64_t fileWritePos;
  60. int64_t lastRequestOffset;
  61. double beginTimeOffset;
  62. int accurateSeek;
  63. // For streaming.
  64. int isStream;
  65. AVFifoBuffer *fifo;
  66. int fifoSize;
  67. } WebDecoder;
  68. WebDecoder *decoder = NULL;
  69. LogLevel logLevel = kLogLevel_None;
  70. int getAailableDataSize();
  71. unsigned long getTickCount() {
  72. struct timespec ts;
  73. clock_gettime(CLOCK_MONOTONIC, &ts);
  74. return ts.tv_sec * (unsigned long)1000 + ts.tv_nsec / 1000000;
  75. }
  76. void simpleLog(const char* format, ...) {
  77. if (logLevel == kLogLevel_None) {
  78. return;
  79. }
  80. char szBuffer[1024] = { 0 };
  81. char szTime[32] = { 0 };
  82. char *p = NULL;
  83. int prefixLength = 0;
  84. const char *tag = "Core";
  85. struct tm tmTime;
  86. struct timeb tb;
  87. ftime(&tb);
  88. localtime_r(&tb.time, &tmTime);
  89. if (1) {
  90. int tmYear = tmTime.tm_year + 1900;
  91. int tmMon = tmTime.tm_mon + 1;
  92. int tmMday = tmTime.tm_mday;
  93. int tmHour = tmTime.tm_hour;
  94. int tmMin = tmTime.tm_min;
  95. int tmSec = tmTime.tm_sec;
  96. int tmMillisec = tb.millitm;
  97. sprintf(szTime, "%d-%d-%d %d:%d:%d.%d", tmYear, tmMon, tmMday, tmHour, tmMin, tmSec, tmMillisec);
  98. }
  99. prefixLength = sprintf(szBuffer, "[%s][%s][DT] ", szTime, tag);
  100. p = szBuffer + prefixLength;
  101. if (1) {
  102. va_list ap;
  103. va_start(ap, format);
  104. vsnprintf(p, 1024 - prefixLength, format, ap);
  105. va_end(ap);
  106. }
  107. printf("%s\n", szBuffer);
  108. }
  109. void ffmpegLogCallback(void* ptr, int level, const char* fmt, va_list vl) {
  110. static int printPrefix = 1;
  111. static int count = 0;
  112. static char prev[1024] = { 0 };
  113. char line[1024] = { 0 };
  114. static int is_atty;
  115. AVClass* avc = ptr ? *(AVClass**)ptr : NULL;
  116. if (level > AV_LOG_DEBUG) {
  117. return;
  118. }
  119. line[0] = 0;
  120. if (printPrefix && avc) {
  121. if (avc->parent_log_context_offset) {
  122. AVClass** parent = *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset);
  123. if (parent && *parent) {
  124. snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent);
  125. }
  126. }
  127. snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr);
  128. }
  129. vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl);
  130. line[strlen(line) + 1] = 0;
  131. simpleLog("%s", line);
  132. }
  133. int openCodecContext(AVFormatContext *fmtCtx, enum AVMediaType type, int *streamIdx, AVCodecContext **decCtx) {
  134. int ret = 0;
  135. do {
  136. int streamIndex = -1;
  137. AVStream *st = NULL;
  138. AVCodec *dec = NULL;
  139. AVDictionary *opts = NULL;
  140. ret = av_find_best_stream(fmtCtx, type, -1, -1, NULL, 0);
  141. if (ret < 0) {
  142. simpleLog("Could not find %s stream.", av_get_media_type_string(type));
  143. break;
  144. }
  145. streamIndex = ret;
  146. st = fmtCtx->streams[streamIndex];
  147. dec = avcodec_find_decoder(st->codecpar->codec_id);
  148. if (!dec) {
  149. simpleLog("Failed to find %s codec %d.", av_get_media_type_string(type), st->codecpar->codec_id);
  150. ret = AVERROR(EINVAL);
  151. break;
  152. }
  153. *decCtx = avcodec_alloc_context3(dec);
  154. if (!*decCtx) {
  155. simpleLog("Failed to allocate the %s codec context.", av_get_media_type_string(type));
  156. ret = AVERROR(ENOMEM);
  157. break;
  158. }
  159. if ((ret = avcodec_parameters_to_context(*decCtx, st->codecpar)) != 0) {
  160. simpleLog("Failed to copy %s codec parameters to decoder context.", av_get_media_type_string(type));
  161. break;
  162. }
  163. av_dict_set(&opts, "refcounted_frames", "0", 0);
  164. if ((ret = avcodec_open2(*decCtx, dec, NULL)) != 0) {
  165. simpleLog("Failed to open %s codec.", av_get_media_type_string(type));
  166. break;
  167. }
  168. *streamIdx = streamIndex;
  169. avcodec_flush_buffers(*decCtx);
  170. } while (0);
  171. return ret;
  172. }
  173. void closeCodecContext(AVFormatContext *fmtCtx, AVCodecContext *decCtx, int streamIdx) {
  174. do {
  175. if (fmtCtx == NULL || decCtx == NULL) {
  176. break;
  177. }
  178. if (streamIdx < 0 || streamIdx >= fmtCtx->nb_streams) {
  179. break;
  180. }
  181. fmtCtx->streams[streamIdx]->discard = AVDISCARD_ALL;
  182. avcodec_close(decCtx);
  183. } while (0);
  184. }
  185. ErrorCode copyYuvData(AVFrame *frame, unsigned char *buffer, int width, int height) {
  186. ErrorCode ret = kErrorCode_Success;
  187. unsigned char *src = NULL;
  188. unsigned char *dst = buffer;
  189. int i = 0;
  190. do {
  191. if (frame == NULL || buffer == NULL) {
  192. ret = kErrorCode_Invalid_Param;
  193. break;
  194. }
  195. if (!frame->data[0] || !frame->data[1] || !frame->data[2]) {
  196. ret = kErrorCode_Invalid_Param;
  197. break;
  198. }
  199. for (i = 0; i < height; i++) {
  200. src = frame->data[0] + i * frame->linesize[0];
  201. memcpy(dst, src, width);
  202. dst += width;
  203. }
  204. for (i = 0; i < height / 2; i++) {
  205. src = frame->data[1] + i * frame->linesize[1];
  206. memcpy(dst, src, width / 2);
  207. dst += width / 2;
  208. }
  209. for (i = 0; i < height / 2; i++) {
  210. src = frame->data[2] + i * frame->linesize[2];
  211. memcpy(dst, src, width / 2);
  212. dst += width / 2;
  213. }
  214. } while (0);
  215. return ret;
  216. }
  217. /*
  218. ErrorCode yuv420pToRgb32(unsigned char *yuvBuff, unsigned char *rgbBuff, int width, int height) {
  219. ErrorCode ret = kErrorCode_Success;
  220. AVPicture yuvPicture, rgbPicture;
  221. uint8_t *ptmp = NULL;
  222. do {
  223. if (yuvBuff == NULL || rgbBuff == NULL) {
  224. ret = kErrorCode_Invalid_Param
  225. break;
  226. }
  227. if (decoder == NULL || decoder->swsCtx == NULL) {
  228. ret = kErrorCode_Invalid_Param
  229. break;
  230. }
  231. avpicture_fill(&yuvPicture, yuvBuff, AV_PIX_FMT_YUV420P, width, height);
  232. avpicture_fill(&rgbPicture, rgbBuff, AV_PIX_FMT_RGB32, width, height);
  233. ptmp = yuvPicture.data[1];
  234. yuvPicture.data[1] = yuvPicture.data[2];
  235. yuvPicture.data[2] = ptmp;
  236. sws_scale(decoder->swsCtx, yuvPicture.data, yuvPicture.linesize, 0, height, rgbPicture.data, rgbPicture.linesize);
  237. } while (0);
  238. return ret;
  239. }
  240. */
  241. int roundUp(int numToRound, int multiple) {
  242. return (numToRound + multiple - 1) & -multiple;
  243. }
  244. ErrorCode processDecodedVideoFrame(AVFrame *frame) {
  245. ErrorCode ret = kErrorCode_Success;
  246. double timestamp = 0.0f;
  247. do {
  248. if (frame == NULL ||
  249. decoder->videoCallback == NULL ||
  250. decoder->yuvBuffer == NULL ||
  251. decoder->videoBufferSize <= 0) {
  252. ret = kErrorCode_Invalid_Param;
  253. break;
  254. }
  255. if (decoder->videoCodecContext->pix_fmt != AV_PIX_FMT_YUV420P) {
  256. simpleLog("Not YUV420P, but unsupported format %d.", decoder->videoCodecContext->pix_fmt);
  257. ret = kErrorCode_Invalid_Format;
  258. break;
  259. }
  260. ret = copyYuvData(frame, decoder->yuvBuffer, decoder->videoCodecContext->width, decoder->videoCodecContext->height);
  261. if (ret != kErrorCode_Success) {
  262. break;
  263. }
  264. /*
  265. ret = yuv420pToRgb32(decoder->yuvBuffer, decoder->rgbBuffer, decoder->videoCodecContext->width, decoder->videoCodecContext->height);
  266. if (ret != kErrorCode_Success) {
  267. break;
  268. }
  269. */
  270. timestamp = (double)frame->pts * av_q2d(decoder->avformatContext->streams[decoder->videoStreamIdx]->time_base);
  271. if (decoder->accurateSeek && timestamp < decoder->beginTimeOffset) {
  272. //simpleLog("video timestamp %lf < %lf", timestamp, decoder->beginTimeOffset);
  273. ret = kErrorCode_Old_Frame;
  274. break;
  275. }
  276. decoder->videoCallback(decoder->yuvBuffer, decoder->videoSize, timestamp);
  277. } while (0);
  278. return ret;
  279. }
  280. ErrorCode processDecodedAudioFrame(AVFrame *frame) {
  281. ErrorCode ret = kErrorCode_Success;
  282. int sampleSize = 0;
  283. int audioDataSize = 0;
  284. int targetSize = 0;
  285. int offset = 0;
  286. int i = 0;
  287. int ch = 0;
  288. double timestamp = 0.0f;
  289. do {
  290. if (frame == NULL) {
  291. ret = kErrorCode_Invalid_Param;
  292. break;
  293. }
  294. sampleSize = av_get_bytes_per_sample(decoder->audioCodecContext->sample_fmt);
  295. if (sampleSize < 0) {
  296. simpleLog("Failed to calculate data size.");
  297. ret = kErrorCode_Invalid_Data;
  298. break;
  299. }
  300. if (decoder->pcmBuffer == NULL) {
  301. decoder->pcmBuffer = (unsigned char*)av_mallocz(kInitialPcmBufferSize);
  302. decoder->currentPcmBufferSize = kInitialPcmBufferSize;
  303. simpleLog("Initial PCM buffer size %d.", decoder->currentPcmBufferSize);
  304. }
  305. audioDataSize = frame->nb_samples * decoder->audioCodecContext->channels * sampleSize;
  306. if (decoder->currentPcmBufferSize < audioDataSize) {
  307. targetSize = roundUp(audioDataSize, 4);
  308. simpleLog("Current PCM buffer size %d not sufficient for data size %d, round up to target %d.",
  309. decoder->currentPcmBufferSize,
  310. audioDataSize,
  311. targetSize);
  312. decoder->currentPcmBufferSize = targetSize;
  313. av_free(decoder->pcmBuffer);
  314. decoder->pcmBuffer = (unsigned char*)av_mallocz(decoder->currentPcmBufferSize);
  315. }
  316. for (i = 0; i < frame->nb_samples; i++) {
  317. for (ch = 0; ch < decoder->audioCodecContext->channels; ch++) {
  318. memcpy(decoder->pcmBuffer + offset, frame->data[ch] + sampleSize * i, sampleSize);
  319. offset += sampleSize;
  320. }
  321. }
  322. timestamp = (double)frame->pts * av_q2d(decoder->avformatContext->streams[decoder->audioStreamIdx]->time_base);
  323. if (decoder->accurateSeek && timestamp < decoder->beginTimeOffset) {
  324. //simpleLog("audio timestamp %lf < %lf", timestamp, decoder->beginTimeOffset);
  325. ret = kErrorCode_Old_Frame;
  326. break;
  327. }
  328. if (decoder->audioCallback != NULL) {
  329. decoder->audioCallback(decoder->pcmBuffer, audioDataSize, timestamp);
  330. }
  331. } while (0);
  332. return ret;
  333. }
  334. ErrorCode decodePacket(AVPacket *pkt, int *decodedLen) {
  335. int ret = 0;
  336. int isVideo = 0;
  337. AVCodecContext *codecContext = NULL;
  338. if (pkt == NULL || decodedLen == NULL) {
  339. simpleLog("decodePacket invalid param.");
  340. return kErrorCode_Invalid_Param;
  341. }
  342. *decodedLen = 0;
  343. if (pkt->stream_index == decoder->videoStreamIdx) {
  344. codecContext = decoder->videoCodecContext;
  345. isVideo = 1;
  346. } else if (pkt->stream_index == decoder->audioStreamIdx) {
  347. codecContext = decoder->audioCodecContext;
  348. isVideo = 0;
  349. } else {
  350. return kErrorCode_Invalid_Data;
  351. }
  352. ret = avcodec_send_packet(codecContext, pkt);
  353. if (ret < 0) {
  354. simpleLog("Error sending a packet for decoding %d.", ret);
  355. return kErrorCode_FFmpeg_Error;
  356. }
  357. while (ret >= 0) {
  358. ret = avcodec_receive_frame(codecContext, decoder->avFrame);
  359. if (ret == AVERROR(EAGAIN)) {
  360. return kErrorCode_Success;
  361. } else if (ret == AVERROR_EOF) {
  362. return kErrorCode_Eof;
  363. } else if (ret < 0) {
  364. simpleLog("Error during decoding %d.", ret);
  365. return kErrorCode_FFmpeg_Error;
  366. } else {
  367. int r = isVideo ? processDecodedVideoFrame(decoder->avFrame) : processDecodedAudioFrame(decoder->avFrame);
  368. if (r == kErrorCode_Old_Frame) {
  369. return r;
  370. }
  371. }
  372. }
  373. *decodedLen = pkt->size;
  374. return kErrorCode_Success;
  375. }
  376. int readFromFile(uint8_t *data, int len) {
  377. //simpleLog("readFromFile %d.", len);
  378. int32_t ret = -1;
  379. int availableBytes = 0;
  380. int canReadLen = 0;
  381. do {
  382. if (decoder->fp == NULL) {
  383. break;
  384. }
  385. availableBytes = decoder->fileWritePos - decoder->fileReadPos;
  386. if (availableBytes <= 0) {
  387. break;
  388. }
  389. fseek(decoder->fp, decoder->fileReadPos, SEEK_SET);
  390. canReadLen = MIN(availableBytes, len);
  391. fread(data, canReadLen, 1, decoder->fp);
  392. decoder->fileReadPos += canReadLen;
  393. ret = canReadLen;
  394. } while (0);
  395. //simpleLog("readFromFile ret %d.", ret);
  396. return ret;
  397. }
  398. int readFromFifo(uint8_t *data, int len) {
  399. //simpleLog("readFromFifo %d.", len);
  400. int32_t ret = -1;
  401. int availableBytes = 0;
  402. int canReadLen = 0;
  403. do {
  404. if (decoder->fifo == NULL) {
  405. break;
  406. }
  407. availableBytes = av_fifo_size(decoder->fifo);
  408. if (availableBytes <= 0) {
  409. break;
  410. }
  411. canReadLen = MIN(availableBytes, len);
  412. av_fifo_generic_read(decoder->fifo, data, canReadLen, NULL);
  413. ret = canReadLen;
  414. } while (0);
  415. //simpleLog("readFromFifo ret %d, left %d.", ret, av_fifo_size(decoder->fifo));
  416. return ret;
  417. }
  418. int readCallback(void *opaque, uint8_t *data, int len) {
  419. //simpleLog("readCallback %d.", len);
  420. int32_t ret = -1;
  421. do {
  422. if (decoder == NULL) {
  423. break;
  424. }
  425. if (data == NULL || len <= 0) {
  426. break;
  427. }
  428. ret = decoder->isStream ? readFromFifo(data, len) : readFromFile(data, len);
  429. } while (0);
  430. //simpleLog("readCallback ret %d.", ret);
  431. return ret;
  432. }
  433. int64_t seekCallback(void *opaque, int64_t offset, int whence) {
  434. int64_t ret = -1;
  435. int64_t pos = -1;
  436. int64_t req_pos = -1;
  437. //simpleLog("seekCallback %lld %d.", offset, whence);
  438. do {
  439. if (decoder == NULL || decoder->isStream || decoder->fp == NULL) {
  440. break;
  441. }
  442. if (whence == AVSEEK_SIZE) {
  443. ret = decoder->fileSize;
  444. break;
  445. }
  446. if (whence != SEEK_END && whence != SEEK_SET && whence != SEEK_CUR) {
  447. break;
  448. }
  449. ret = fseek(decoder->fp, (long)offset, whence);
  450. if (ret == -1) {
  451. break;
  452. }
  453. pos = (int64_t)ftell(decoder->fp);
  454. if (pos < decoder->lastRequestOffset || pos > decoder->fileWritePos) {
  455. decoder->lastRequestOffset = pos;
  456. decoder->fileReadPos = pos;
  457. decoder->fileWritePos = pos;
  458. req_pos = pos;
  459. ret = -1; // Forcing not to call read at once.
  460. decoder->requestCallback(pos, getAailableDataSize());
  461. simpleLog("Will request %lld and return %lld.", pos, ret);
  462. break;
  463. }
  464. decoder->fileReadPos = pos;
  465. ret = pos;
  466. } while (0);
  467. //simpleLog("seekCallback return %lld.", ret);
  468. if (decoder != NULL && decoder->requestCallback != NULL) {
  469. decoder->requestCallback(req_pos, getAailableDataSize());
  470. }
  471. return ret;
  472. }
  473. int writeToFile(unsigned char *buff, int size) {
  474. int ret = 0;
  475. int64_t leftBytes = 0;
  476. int canWriteBytes = 0;
  477. do {
  478. if (decoder->fp == NULL) {
  479. ret = -1;
  480. break;
  481. }
  482. leftBytes = decoder->fileSize - decoder->fileWritePos;
  483. if (leftBytes <= 0) {
  484. break;
  485. }
  486. canWriteBytes = MIN(leftBytes, size);
  487. fseek(decoder->fp, decoder->fileWritePos, SEEK_SET);
  488. fwrite(buff, canWriteBytes, 1, decoder->fp);
  489. decoder->fileWritePos += canWriteBytes;
  490. ret = canWriteBytes;
  491. } while (0);
  492. return ret;
  493. }
  494. int writeToFifo(unsigned char *buff, int size) {
  495. int ret = 0;
  496. do {
  497. if (decoder->fifo == NULL) {
  498. ret = -1;
  499. break;
  500. }
  501. int64_t leftSpace = av_fifo_space(decoder->fifo);
  502. if (leftSpace < size) {
  503. int growSize = 0;
  504. do {
  505. leftSpace += decoder->fifoSize;
  506. growSize += decoder->fifoSize;
  507. decoder->fifoSize += decoder->fifoSize;
  508. } while (leftSpace < size);
  509. av_fifo_grow(decoder->fifo, growSize);
  510. simpleLog("Fifo size growed to %d.", decoder->fifoSize);
  511. if (decoder->fifoSize >= kMaxFifoSize) {
  512. simpleLog("[Warn] Fifo size larger than %d.", kMaxFifoSize);
  513. }
  514. }
  515. //simpleLog("Wrote %d bytes to fifo, total %d.", size, av_fifo_size(decoder->fifo));
  516. ret = av_fifo_generic_write(decoder->fifo, buff, size, NULL);
  517. } while (0);
  518. return ret;
  519. }
  520. int getAailableDataSize() {
  521. int ret = 0;
  522. do {
  523. if (decoder == NULL) {
  524. break;
  525. }
  526. if (decoder->isStream) {
  527. ret = decoder->fifo == NULL ? 0 : av_fifo_size(decoder->fifo);
  528. } else {
  529. ret = decoder->fileWritePos - decoder->fileReadPos;
  530. }
  531. } while (0);
  532. return ret;
  533. }
  534. //////////////////////////////////Export methods////////////////////////////////////////
  535. ErrorCode initDecoder(int fileSize, int logLv) {
  536. ErrorCode ret = kErrorCode_Success;
  537. do {
  538. //Log level.
  539. logLevel = logLv;
  540. if (decoder != NULL) {
  541. break;
  542. }
  543. decoder = (WebDecoder *)av_mallocz(sizeof(WebDecoder));
  544. if (fileSize >= 0) {
  545. decoder->fileSize = fileSize;
  546. sprintf(decoder->fileName, "tmp-%lu.mp4", getTickCount());
  547. decoder->fp = fopen(decoder->fileName, "wb+");
  548. if (decoder->fp == NULL) {
  549. simpleLog("Open file %s failed, err: %d.", decoder->fileName, errno);
  550. ret = kErrorCode_Open_File_Error;
  551. av_free(decoder);
  552. decoder = NULL;
  553. }
  554. } else {
  555. decoder->isStream = 1;
  556. decoder->fifoSize = kDefaultFifoSize;
  557. decoder->fifo = av_fifo_alloc(decoder->fifoSize);
  558. }
  559. } while (0);
  560. simpleLog("Decoder initialized %d.", ret);
  561. return ret;
  562. }
  563. ErrorCode uninitDecoder() {
  564. if (decoder != NULL) {
  565. if (decoder->fp != NULL) {
  566. fclose(decoder->fp);
  567. decoder->fp = NULL;
  568. remove(decoder->fileName);
  569. }
  570. if (decoder->fifo != NULL) {
  571. av_fifo_freep(&decoder->fifo);
  572. }
  573. av_freep(&decoder);
  574. }
  575. av_log_set_callback(NULL);
  576. simpleLog("Decoder uninitialized.");
  577. return kErrorCode_Success;
  578. }
  579. ErrorCode openDecoder(int *paramArray, int paramCount, long videoCallback, long audioCallback, long requestCallback) {
  580. ErrorCode ret = kErrorCode_Success;
  581. int r = 0;
  582. int i = 0;
  583. int params[7] = { 0 };
  584. do {
  585. simpleLog("打开编码器.");
  586. av_register_all();
  587. avcodec_register_all();
  588. if (logLevel == kLogLevel_All) {
  589. av_log_set_callback(ffmpegLogCallback);
  590. }
  591. decoder->avformatContext = avformat_alloc_context();
  592. decoder->customIoBuffer = (unsigned char*)av_mallocz(kCustomIoBufferSize);
  593. AVIOContext* ioContext = avio_alloc_context(
  594. decoder->customIoBuffer,
  595. kCustomIoBufferSize,
  596. 0,
  597. NULL,
  598. readCallback,
  599. NULL,
  600. seekCallback);
  601. if (ioContext == NULL) {
  602. ret = kErrorCode_FFmpeg_Error;
  603. simpleLog("avio_alloc_context failed.");
  604. break;
  605. }
  606. decoder->avformatContext->pb = ioContext;
  607. decoder->avformatContext->flags = AVFMT_FLAG_CUSTOM_IO;
  608. simpleLog("avformat_open_input.");
  609. r = avformat_open_input(&decoder->avformatContext, NULL, NULL, NULL);
  610. if (r != 0) {
  611. ret = kErrorCode_FFmpeg_Error;
  612. char err_info[32] = { 0 };
  613. av_strerror(ret, err_info, 32);
  614. simpleLog("avformat_open_input failed %d %s.", ret, err_info);
  615. break;
  616. }
  617. simpleLog("avformat_find_stream_info");
  618. r = avformat_find_stream_info(decoder->avformatContext, NULL);
  619. if (r != 0) {
  620. ret = kErrorCode_FFmpeg_Error;
  621. simpleLog("av_find_stream_info failed %d.", ret);
  622. break;
  623. }
  624. simpleLog("avformat_find_stream_info 成功.");
  625. for (i = 0; i < decoder->avformatContext->nb_streams; i++) {
  626. decoder->avformatContext->streams[i]->discard = AVDISCARD_DEFAULT;
  627. }
  628. r = openCodecContext(
  629. decoder->avformatContext,
  630. AVMEDIA_TYPE_VIDEO,
  631. &decoder->videoStreamIdx,
  632. &decoder->videoCodecContext);
  633. if (r != 0) {
  634. ret = kErrorCode_FFmpeg_Error;
  635. simpleLog("Open video codec context failed %d.", ret);
  636. break;
  637. }
  638. simpleLog("Open video codec context success, video stream index %d %x.",
  639. decoder->videoStreamIdx, (unsigned int)decoder->videoCodecContext);
  640. simpleLog("Video stream index:%d pix_fmt:%d resolution:%d*%d.",
  641. decoder->videoStreamIdx,
  642. decoder->videoCodecContext->pix_fmt,
  643. decoder->videoCodecContext->width,
  644. decoder->videoCodecContext->height);
  645. r = openCodecContext(
  646. decoder->avformatContext,
  647. AVMEDIA_TYPE_AUDIO,
  648. &decoder->audioStreamIdx,
  649. &decoder->audioCodecContext);
  650. if (r != 0) {
  651. ret = kErrorCode_FFmpeg_Error;
  652. simpleLog("Open audio codec context failed %d.", ret);
  653. break;
  654. }
  655. simpleLog("Open audio codec context success, audio stream index %d %x.",
  656. decoder->audioStreamIdx, (unsigned int)decoder->audioCodecContext);
  657. simpleLog("Audio stream index:%d sample_fmt:%d channel:%d, sample rate:%d.",
  658. decoder->audioStreamIdx,
  659. decoder->audioCodecContext->sample_fmt,
  660. decoder->audioCodecContext->channels,
  661. decoder->audioCodecContext->sample_rate);
  662. av_seek_frame(decoder->avformatContext, -1, 0, AVSEEK_FLAG_BACKWARD);
  663. /* For RGB Renderer(2D WebGL).
  664. decoder->swsCtx = sws_getContext(
  665. decoder->videoCodecContext->width,
  666. decoder->videoCodecContext->height,
  667. decoder->videoCodecContext->pix_fmt,
  668. decoder->videoCodecContext->width,
  669. decoder->videoCodecContext->height,
  670. AV_PIX_FMT_RGB32,
  671. SWS_BILINEAR,
  672. 0,
  673. 0,
  674. 0);
  675. if (decoder->swsCtx == NULL) {
  676. simpleLog("sws_getContext failed.");
  677. ret = kErrorCode_FFmpeg_Error;
  678. break;
  679. }
  680. */
  681. decoder->videoSize = avpicture_get_size(
  682. decoder->videoCodecContext->pix_fmt,
  683. decoder->videoCodecContext->width,
  684. decoder->videoCodecContext->height);
  685. decoder->videoBufferSize = 3 * decoder->videoSize;
  686. decoder->yuvBuffer = (unsigned char *)av_mallocz(decoder->videoBufferSize);
  687. decoder->avFrame = av_frame_alloc();
  688. params[0] = 1000 * (decoder->avformatContext->duration + 5000) / AV_TIME_BASE;
  689. params[1] = decoder->videoCodecContext->pix_fmt;
  690. params[2] = decoder->videoCodecContext->width;
  691. params[3] = decoder->videoCodecContext->height;
  692. params[4] = decoder->audioCodecContext->sample_fmt;
  693. params[5] = decoder->audioCodecContext->channels;
  694. params[6] = decoder->audioCodecContext->sample_rate;
  695. enum AVSampleFormat sampleFmt = decoder->audioCodecContext->sample_fmt;
  696. if (av_sample_fmt_is_planar(sampleFmt)) {
  697. const char *packed = av_get_sample_fmt_name(sampleFmt);
  698. params[4] = av_get_packed_sample_fmt(sampleFmt);
  699. }
  700. if (paramArray != NULL && paramCount > 0) {
  701. for (int i = 0; i < paramCount; ++i) {
  702. paramArray[i] = params[i];
  703. }
  704. }
  705. decoder->videoCallback = (VideoCallback)videoCallback;
  706. decoder->audioCallback = (AudioCallback)audioCallback;
  707. decoder->requestCallback = (RequestCallback)requestCallback;
  708. simpleLog("Decoder opened, duration %ds, picture size %d.", params[0], decoder->videoSize);
  709. } while (0);
  710. if (ret != kErrorCode_Success && decoder != NULL) {
  711. av_freep(&decoder);
  712. }
  713. return ret;
  714. }
  715. ErrorCode closeDecoder() {
  716. ErrorCode ret = kErrorCode_Success;
  717. do {
  718. if (decoder == NULL || decoder->avformatContext == NULL) {
  719. break;
  720. }
  721. if (decoder->videoCodecContext != NULL) {
  722. closeCodecContext(decoder->avformatContext, decoder->videoCodecContext, decoder->videoStreamIdx);
  723. decoder->videoCodecContext = NULL;
  724. simpleLog("Video codec context closed.");
  725. }
  726. if (decoder->audioCodecContext != NULL) {
  727. closeCodecContext(decoder->avformatContext, decoder->audioCodecContext, decoder->audioStreamIdx);
  728. decoder->audioCodecContext = NULL;
  729. simpleLog("Audio codec context closed.");
  730. }
  731. AVIOContext *pb = decoder->avformatContext->pb;
  732. if (pb != NULL) {
  733. if (pb->buffer != NULL) {
  734. av_freep(&pb->buffer);
  735. decoder->customIoBuffer = NULL;
  736. }
  737. av_freep(&decoder->avformatContext->pb);
  738. simpleLog("IO context released.");
  739. }
  740. avformat_close_input(&decoder->avformatContext);
  741. decoder->avformatContext = NULL;
  742. simpleLog("Input closed.");
  743. if (decoder->yuvBuffer != NULL) {
  744. av_freep(&decoder->yuvBuffer);
  745. }
  746. if (decoder->pcmBuffer != NULL) {
  747. av_freep(&decoder->pcmBuffer);
  748. }
  749. if (decoder->avFrame != NULL) {
  750. av_freep(&decoder->avFrame);
  751. }
  752. simpleLog("All buffer released.");
  753. } while (0);
  754. return ret;
  755. }
  756. int sendData(unsigned char *buff, int size) {
  757. int ret = 0;
  758. int64_t leftBytes = 0;
  759. int canWriteBytes = 0;
  760. do {
  761. if (decoder == NULL) {
  762. ret = -1;
  763. break;
  764. }
  765. if (buff == NULL || size == 0) {
  766. ret = -2;
  767. break;
  768. }
  769. ret = decoder->isStream ? writeToFifo(buff, size) : writeToFile(buff, size);
  770. } while (0);
  771. return ret;
  772. }
  773. ErrorCode decodeOnePacket() {
  774. ErrorCode ret = kErrorCode_Success;
  775. int decodedLen = 0;
  776. int r = 0;
  777. AVPacket packet;
  778. av_init_packet(&packet);
  779. do {
  780. if (decoder == NULL) {
  781. ret = kErrorCode_Invalid_State;
  782. break;
  783. }
  784. if (getAailableDataSize() <= 0) {
  785. ret = kErrorCode_Invalid_State;
  786. break;
  787. }
  788. packet.data = NULL;
  789. packet.size = 0;
  790. r = av_read_frame(decoder->avformatContext, &packet);
  791. if (r == AVERROR_EOF) {
  792. ret = kErrorCode_Eof;
  793. break;
  794. }
  795. if (r < 0 || packet.size == 0) {
  796. break;
  797. }
  798. do {
  799. ret = decodePacket(&packet, &decodedLen);
  800. if (ret != kErrorCode_Success) {
  801. break;
  802. }
  803. if (decodedLen <= 0) {
  804. break;
  805. }
  806. packet.data += decodedLen;
  807. packet.size -= decodedLen;
  808. } while (packet.size > 0);
  809. } while (0);
  810. av_packet_unref(&packet);
  811. return ret;
  812. }
  813. ErrorCode seekTo(int ms, int accurateSeek) {
  814. int ret = 0;
  815. int64_t pts = (int64_t)ms * 1000;
  816. decoder->accurateSeek = accurateSeek;
  817. ret = avformat_seek_file(decoder->avformatContext,
  818. -1,
  819. INT64_MIN,
  820. pts,
  821. pts,
  822. AVSEEK_FLAG_BACKWARD);
  823. simpleLog("Native seek to %d return %d %d.", ms, ret, decoder->accurateSeek);
  824. if (ret == -1) {
  825. return kErrorCode_FFmpeg_Error;
  826. } else {
  827. avcodec_flush_buffers(decoder->videoCodecContext);
  828. avcodec_flush_buffers(decoder->audioCodecContext);
  829. // Trigger seek callback
  830. AVPacket packet;
  831. av_init_packet(&packet);
  832. av_read_frame(decoder->avformatContext, &packet);
  833. decoder->beginTimeOffset = (double)ms / 1000;
  834. return kErrorCode_Success;
  835. }
  836. }
  837. int main() {
  838. //simpleLog("Native loaded.");
  839. return 0;
  840. }
  841. #ifdef __cplusplus
  842. }
  843. #endif