video_decoder.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include "video_decoder.h"
  2. #include "../video_common/ffmpeg_api_adapter.h"
  3. #include "base/video_coding_log.h"
  4. typedef struct _VideoDecoder{
  5. AVFrame *dec_picture;
  6. AVPacket dec_avpkt;
  7. AVCodecContext *dec_ctx;
  8. AVCodec *dec;
  9. struct SwsContext *dec_sws_context;
  10. DecoderConfig config_;
  11. }VideoDecoder;
  12. static AVFrame *alloc_picture(int pix_fmt, int width, int height)
  13. {
  14. AVFrame *picture;
  15. uint8_t *picture_buf;
  16. int size;
  17. picture = (AVFrame *)avcodec_alloc_frame();
  18. if (!picture)
  19. return NULL;
  20. size = avpicture_get_size(pix_fmt, width, height);
  21. picture_buf = (uint8_t *)av_malloc(size);
  22. if (!picture_buf) {
  23. av_free(picture);
  24. return NULL;
  25. }
  26. avpicture_fill((AVPicture *)picture, picture_buf,
  27. pix_fmt, width, height);
  28. picture->width = width;
  29. picture->height = height;
  30. picture->format = pix_fmt;
  31. return picture;
  32. }
  33. static void free_picture(AVFrame *picture)
  34. {
  35. av_free(picture->data[0]);
  36. avcodec_free_frame(&picture);
  37. }
  38. static void ffmpeg_yuvframe_copy_to_local_frame(const AVFrame *picture, video_frame *vframe)
  39. {
  40. int i =0, j =0, k =0;
  41. vframe->linesize[0] = picture->width;
  42. vframe->linesize[1] = picture->width/2;
  43. vframe->linesize[2] = picture->width/2;
  44. for(i = 0; i < vframe->height; i++)
  45. {
  46. memcpy(vframe->data[0]+vframe->linesize[0]*i,
  47. picture->data[0]+picture->linesize[0]*i,
  48. picture->width);
  49. }
  50. for(j = 0; j < vframe->height/2; j++)
  51. {
  52. memcpy(vframe->data[1]+vframe->linesize[1]*j,
  53. picture->data[1]+picture->linesize[1]*j,
  54. picture->width/2);
  55. }
  56. for(k =0; k < vframe->height/2; k++)
  57. {
  58. memcpy(vframe->data[2]+vframe->linesize[2]*k,
  59. picture->data[2]+picture->linesize[2]*k,
  60. picture->width/2);
  61. }
  62. }
  63. VideoDecoder *video_decoder_open(const DecoderConfig *config, VideoCodingLogCallBack *log_func){
  64. int rc;
  65. VideoDecoder *obj;
  66. video_decode_setup_log(log_func);
  67. obj = (VideoDecoder *)malloc(sizeof(VideoDecoder));
  68. memset(obj, 0, sizeof(VideoDecoder));
  69. memcpy(&obj->config_, config, sizeof(DecoderConfig));
  70. obj->dec_picture = avcodec_alloc_frame();
  71. if (!obj->dec_picture) {
  72. video_decoder_close(obj);
  73. return NULL;
  74. }
  75. obj->dec = avcodec_find_decoder(obj->config_.decode_id);
  76. if (!obj->dec){
  77. video_decoder_close(obj);
  78. return NULL;
  79. }
  80. obj->dec_ctx = avcodec_alloc_context3(obj->dec);
  81. if (!obj->dec_ctx){
  82. video_decoder_close(obj);
  83. return NULL;
  84. }
  85. obj->dec_ctx->flags |= CODEC_FLAG_LOW_DELAY;
  86. rc = avcodec_open2(obj->dec_ctx, obj->dec, NULL);
  87. if (rc != 0){
  88. video_decoder_close(obj);
  89. return NULL;
  90. }
  91. video_decode_debug(VIDEO_CODING_DEBUG_ENABLE, "video_decoder_open width: %d height: %d decode_id: %d.",
  92. config->width, config->height, obj->config_.decode_id);
  93. return obj;
  94. }
  95. video_frame *video_decoder_process(VideoDecoder *obj, unsigned char *input_packet,
  96. int length, int *remain_length, int *key_frame){
  97. int ret = -1;
  98. int got_picture = -1;
  99. int len = 0;
  100. if (!obj){
  101. return NULL;
  102. }
  103. av_init_packet(&obj->dec_avpkt);
  104. obj->dec_avpkt.data = input_packet;
  105. obj->dec_avpkt.size = length;
  106. video_decode_debug(VIDEO_CODING_DEBUG_DECODER, "video_decoder_process length: %d.", length);
  107. len = avcodec_decode_video2(obj->dec_ctx, obj->dec_picture, &got_picture, &obj->dec_avpkt);
  108. if (0 > len){
  109. return NULL;
  110. }
  111. if (got_picture) {
  112. video_frame *frm = video_frame_new(obj->config_.width, obj->config_.height, obj->config_.color_space);
  113. #if 1
  114. unsigned char *data[4]={0};
  115. int linesize[4]={0};
  116. //miror
  117. data[0] = obj->dec_picture->data[0];
  118. data[1] = obj->dec_picture->data[1];
  119. data[2] = obj->dec_picture->data[2];
  120. data[3] = obj->dec_picture->data[3];
  121. linesize[0] = obj->dec_picture->linesize[0];
  122. linesize[1] = obj->dec_picture->linesize[1];
  123. linesize[2] = obj->dec_picture->linesize[2];
  124. linesize[3] = obj->dec_picture->linesize[3];
  125. data[0] += (obj->dec_picture->height - 1) * linesize[0];
  126. data[1] += (obj->dec_picture->height/2 - 1) * linesize[1];
  127. data[2] += (obj->dec_picture->height/2 - 1) * linesize[2];
  128. linesize[0] = -linesize[0];
  129. linesize[1] = -linesize[1];
  130. linesize[2] = -linesize[2];
  131. //format convert
  132. obj->dec_sws_context = sws_getCachedContext(obj->dec_sws_context,
  133. obj->dec_picture->width,
  134. obj->dec_picture->height,
  135. obj->dec_picture->format,
  136. obj->config_.width,
  137. obj->config_.height,
  138. (obj->config_.color_space != VIDEO_FORMAT_I420 ? PIX_FMT_BGR24 : PIX_FMT_YUV420P),
  139. SWS_FAST_BILINEAR,
  140. NULL,
  141. NULL,
  142. NULL);
  143. sws_scale(obj->dec_sws_context,
  144. data,
  145. linesize,
  146. 0,
  147. obj->dec_picture->height,
  148. frm->data,
  149. frm->linesize);
  150. #else
  151. if((obj->config_.width != obj->dec_picture->width) ||
  152. (obj->config_.height != obj->dec_picture->height) ||
  153. (obj->config_.color_space != obj->dec_picture->format)){
  154. obj->dec_sws_context = sws_getCachedContext(obj->dec_sws_context,
  155. obj->dec_picture->width,
  156. obj->dec_picture->height,
  157. obj->dec_picture->format,
  158. obj->config_.width,
  159. obj->config_.height,
  160. (obj->config_.color_space != VIDEO_FORMAT_I420 ? PIX_FMT_BGR24 : PIX_FMT_YUV420P),
  161. SWS_FAST_BILINEAR,
  162. NULL,
  163. NULL,
  164. NULL);
  165. sws_scale(obj->dec_sws_context,
  166. obj->dec_picture->data,
  167. obj->dec_picture->linesize,
  168. 0,
  169. obj->dec_picture->height,
  170. frm->data,
  171. frm->linesize);
  172. } else {
  173. if (obj->config_.color_space == VIDEO_FORMAT_I420){
  174. ffmpeg_yuvframe_copy_to_local_frame(obj->dec_picture, frm);
  175. } else {
  176. memcpy(frm->data[0], obj->dec_picture->data[0], obj->dec_picture->width*obj->dec_picture->height*3);
  177. frm->linesize[0] = obj->dec_picture->linesize[0];
  178. }
  179. }
  180. #endif
  181. *key_frame = obj->dec_picture->key_frame;
  182. frm->width = obj->config_.width;
  183. frm->height = obj->config_.height;
  184. frm->format = obj->config_.color_space;
  185. *remain_length -= len;
  186. return frm;
  187. }
  188. *remain_length -= len;
  189. return NULL;
  190. }
  191. void video_decoder_close(VideoDecoder *obj){
  192. if (obj != NULL) {
  193. if (obj->dec_picture != NULL) {
  194. avcodec_free_frame(&obj->dec_picture);
  195. obj->dec_picture = NULL;
  196. }
  197. if (obj->dec_ctx != NULL) {
  198. avcodec_close(obj->dec_ctx);
  199. av_free(obj->dec_ctx);
  200. obj->dec_ctx = NULL;
  201. }
  202. free((void *)obj);
  203. video_decode_debug(VIDEO_CODING_DEBUG_DECODER, "video_decoder_close.");
  204. }
  205. video_decode_unsetup_log();
  206. }