bitstreamwriter.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2018, Chips&Media
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "main_helper.h"
  26. #ifdef SUPPORT_FFMPEG
  27. extern BitstreamWriterImpl containerWriter;
  28. #endif /* SUPPORT_FFMPEG */
  29. /* --------------------------------------------------------------------------
  30. * ES writer
  31. --------------------------------------------------------------------------- */
  32. typedef struct ESWriterContext {
  33. FILE* fp;
  34. } ESWriterContext;
  35. static BOOL ESWriter_Create(BitstreamWriterImpl* impl, EncConfigParam* config, const char* path)
  36. {
  37. FILE* fp;
  38. ESWriterContext* ctx = NULL;
  39. if ((fp=fopen(path, "wb")) == NULL) {
  40. JLOG(ERR, "<%s:%d> Failed to create file: %s\n", __FUNCTION__, __LINE__, path);
  41. return FALSE;
  42. }
  43. if (NULL == (ctx=(ESWriterContext*)malloc(sizeof(ESWriterContext)))) {
  44. JLOG(ERR, "<%s:%d> Failed to allocate memory(%d)\n", __FUNCTION__, __LINE__, sizeof(ESWriterContext));
  45. return FALSE;
  46. }
  47. ctx->fp = fp;
  48. impl->context = ctx;
  49. return TRUE;
  50. }
  51. static Uint32 ESWriter_Act(BitstreamWriterImpl* impl, Uint8* data, Uint32 size)
  52. {
  53. ESWriterContext* ctx = (ESWriterContext*)impl->context;
  54. Uint32 nwrite = 0;
  55. nwrite = fwrite(data, 1, size, ctx->fp);
  56. fflush(ctx->fp);
  57. return nwrite;
  58. }
  59. //lint -e482 To avoid the balanced pair function rule: fopen - fclose
  60. static BOOL ESWriter_Destroy(BitstreamWriterImpl* impl)
  61. {
  62. ESWriterContext* ctx = (ESWriterContext*)impl->context;
  63. if (ctx->fp) fclose(ctx->fp);
  64. free(ctx);
  65. return TRUE;
  66. }
  67. //lint +e482
  68. static BitstreamWriterImpl esWriter = {
  69. NULL,
  70. ESWriter_Create,
  71. ESWriter_Act,
  72. ESWriter_Destroy
  73. };
  74. #define DELAYED_BUFFER_SIZE 0x400000 /* 4MB */
  75. typedef struct {
  76. BitstreamWriterImpl impl;
  77. Uint8* delayedBuf;
  78. Uint32 delayedBufSize;
  79. Uint32 delayedBufOffset;
  80. } AbstractBitstreamWriter;
  81. BSWriter BitstreamWriter_Create(BSWriterType type, EncConfigParam* config, const char* path)
  82. {
  83. AbstractBitstreamWriter* writer;
  84. BitstreamWriterImpl* impl;
  85. switch (type) {
  86. case BSWRITER_ES:
  87. impl = &esWriter;
  88. break;
  89. case BSWRITER_CONTAINER:
  90. #ifdef SUPPORT_FFMPEG
  91. impl = &containerWriter;
  92. break;
  93. #endif /* SUPPORT_FFMPEG */
  94. default:
  95. JLOG(ERR, "<%s:%d> Not supported type: %d\n", __FUNCTION__, __LINE__, (Uint32)type);
  96. return NULL;
  97. }
  98. if ((writer=(AbstractBitstreamWriter*)malloc(sizeof(AbstractBitstreamWriter))) == NULL) {
  99. JLOG(ERR, "<%s:%d> Failed to allocate memory(%d)\n", __FUNCTION__, __LINE__, sizeof(AbstractBitstreamWriter));
  100. return NULL;
  101. }
  102. memset((void*)writer, 0x00, sizeof(AbstractBitstreamWriter));
  103. memcpy((void*)&writer->impl, impl, sizeof(BitstreamWriterImpl));
  104. if (FALSE == writer->impl.Create(&writer->impl, config, path)) {
  105. free(writer);
  106. writer = NULL;
  107. }
  108. else {
  109. writer->delayedBuf = (Uint8*)malloc(DELAYED_BUFFER_SIZE);
  110. writer->delayedBufSize = DELAYED_BUFFER_SIZE;
  111. writer->delayedBufOffset = 0;
  112. }
  113. return writer;
  114. }
  115. BOOL BitstreamWriter_Act(BSWriter writer, Uint8* data, Uint32 size, BOOL delayedWrite)
  116. {
  117. AbstractBitstreamWriter* absWriter = (AbstractBitstreamWriter*)writer;
  118. if (TRUE == delayedWrite) {
  119. Uint32 offset = absWriter->delayedBufOffset;
  120. if ((size+offset) > absWriter->delayedBufSize) {
  121. JLOG(ERR, "<%s:%d> Delayed Buffer Full: bufferSize:%d, offset: %d, size: %d\n",
  122. __FUNCTION__, __LINE__, absWriter->delayedBufSize, absWriter->delayedBufOffset, size);
  123. return FALSE;
  124. }
  125. else {
  126. Uint8* p = absWriter->delayedBuf + offset;
  127. memcpy(p, data, size);
  128. absWriter->delayedBufOffset += size;
  129. return TRUE;
  130. }
  131. }
  132. else {
  133. if (0 < absWriter->delayedBufOffset) {
  134. Uint32 totalSize = absWriter->delayedBufOffset + size;
  135. Uint8* p = (Uint8*)malloc(totalSize);
  136. BOOL success;
  137. if (p == NULL) {
  138. JLOG(ERR, "<%s:%d> Failed to allocate memory(%d)\n", __FUNCTION__, __LINE__, totalSize);
  139. return FALSE;
  140. }
  141. memcpy(p, absWriter->delayedBuf, absWriter->delayedBufOffset);
  142. memcpy(p+absWriter->delayedBufOffset, data, size);
  143. success = absWriter->impl.Act(&absWriter->impl, p, totalSize);
  144. free(p);
  145. absWriter->delayedBufOffset = 0;
  146. return success;
  147. }
  148. else {
  149. return absWriter->impl.Act(&absWriter->impl, data, size);
  150. }
  151. }
  152. }
  153. void BitstreamWriter_Destroy(BSWriter writer)
  154. {
  155. AbstractBitstreamWriter* absWriter = (AbstractBitstreamWriter*)writer;
  156. absWriter->impl.Destroy(&absWriter->impl);
  157. free(absWriter->delayedBuf);
  158. free(absWriter);
  159. }