ffmpegTest.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include "libavformat/avformat.h"
  4. #include "libswscale/swscale.h"
  5. #include "libavutil/imgutils.h"
  6. //#include "libswresample/swresample.h"
  7. #include "libavcodec/avcodec.h"
  8. #include "libavutil/time.h"
  9. int rgbSize = 0;
  10. typedef unsigned char byte;
  11. uint8_t *out_buffer = NULL;
  12. AVCodec *videoCodec = NULL;
  13. AVFrame *frame = NULL;
  14. AVFrame *yuvFrame = NULL;
  15. AVCodecContext *videoCodecCtx = NULL;
  16. struct SwsContext* m_img_convert_ctx = NULL;
  17. void ffmpegLog()
  18. {
  19. }
  20. //打开解码器
  21. int openDecoder(int width, int height)
  22. {
  23. int ret;
  24. int errorCode = 0;
  25. uint8_t *out_buffer = NULL;
  26. videoCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
  27. videoCodecCtx = avcodec_alloc_context3(videoCodec);
  28. frame = av_frame_alloc();
  29. yuvFrame = av_frame_alloc();
  30. if ((errorCode = avcodec_open2(videoCodecCtx, videoCodec, NULL)) < 0)
  31. {
  32. return errorCode;
  33. }
  34. videoCodecCtx->width = width;
  35. videoCodecCtx->height = height;
  36. videoCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
  37. rgbSize = videoCodecCtx->width * videoCodecCtx->height * 3 / 2;
  38. out_buffer = (unsigned char *)av_malloc(rgbSize);
  39. av_image_fill_arrays(yuvFrame->data, yuvFrame->linesize, out_buffer, AV_PIX_FMT_YUV420P, videoCodecCtx->width, videoCodecCtx->height, 1);
  40. m_img_convert_ctx = sws_getContext(videoCodecCtx->width, videoCodecCtx->height,
  41. videoCodecCtx->pix_fmt, videoCodecCtx->width, videoCodecCtx->height,
  42. AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
  43. printf("c 端已经打开编码器, 哈哈\n");
  44. return 0;
  45. }
  46. void PrintArry(byte*data, size_t size)
  47. {
  48. printf("打印数组:");
  49. for(size_t i = 0;i < size;i++)
  50. {
  51. printf("%02X", data[i]);
  52. }
  53. printf("\n");
  54. }
  55. int feedData(byte*data, size_t size, byte* outBuffer)
  56. {
  57. int ret = -1;
  58. int len = videoCodecCtx->width*videoCodecCtx->height;
  59. AVPacket *videoPacket = av_packet_alloc();
  60. av_new_packet(videoPacket, size);
  61. //printf("准备拷贝\n");
  62. memcpy(videoPacket->data, data, size);
  63. //printf("准备解码\n");
  64. uint64_t start = av_gettime();
  65. avcodec_send_packet(videoCodecCtx, videoPacket);
  66. ret = avcodec_receive_frame(videoCodecCtx, frame);
  67. //PrintArry(data, size);
  68. uint64_t cost = av_gettime() - start/1000;
  69. printf("解码耗时 %d ms", cost);
  70. if(ret == 0)
  71. {
  72. ret = sws_scale(m_img_convert_ctx, (const uint8_t* const*)frame->data, frame->linesize, 0, videoCodecCtx->height, yuvFrame->data, yuvFrame->linesize);
  73. byte *p= outBuffer;
  74. memcpy(p, yuvFrame->data[0], len);
  75. p = p + len;
  76. memcpy(p, yuvFrame->data[1], len / 4);
  77. p = p + len / 4;
  78. memcpy(p, yuvFrame->data[2], len / 4);
  79. }
  80. if(ret < 0)
  81. {
  82. char temp[4096];
  83. av_strerror(ret, temp, 4096);
  84. // printf("错误打印 %s \n", temp);
  85. }
  86. av_packet_free(&videoPacket);
  87. return ret;
  88. }
  89. //关闭解码器
  90. void closeDecoder()
  91. {
  92. if(out_buffer)
  93. {
  94. free(out_buffer);
  95. }
  96. av_frame_unref(frame);
  97. av_frame_unref(yuvFrame);
  98. av_frame_free(&frame);
  99. av_frame_free(&yuvFrame);
  100. if (m_img_convert_ctx)
  101. {
  102. sws_freeContext(m_img_convert_ctx);
  103. }
  104. if (videoCodecCtx)
  105. {
  106. avcodec_free_context(&videoCodecCtx);
  107. }
  108. }
  109. int main(int argc, char**argv)
  110. {
  111. //openDecoder(720, 1280);
  112. return 0;
  113. }