encoder_video_x264.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "encoder_video_x264.h"
  2. #include "log_helper.h"
  3. #include "error_define.h"
  4. namespace am {
  5. encoder_video_x264::encoder_video_x264()
  6. {
  7. av_register_all();
  8. _encoder = NULL;
  9. _encoder_ctx = NULL;
  10. _frame = NULL;
  11. _buff = NULL;
  12. _buff_size = 0;
  13. _y_size = 0;
  14. }
  15. encoder_video_x264::~encoder_video_x264()
  16. {
  17. stop();
  18. cleanup();
  19. }
  20. int encoder_video_x264::init(int pic_width, int pic_height, int frame_rate, int bit_rate ,int qb, int key_pic_sec)
  21. {
  22. if (_inited == true)
  23. return AE_NO;
  24. int err = AE_NO;
  25. int ret = 0;
  26. AVDictionary *options = 0;
  27. av_dict_set(&options, "preset", "superfast", 0);
  28. av_dict_set(&options, "tune", "zerolatency", 0);
  29. do {
  30. _encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
  31. if (!_encoder) {
  32. err = AE_FFMPEG_FIND_ENCODER_FAILED;
  33. break;
  34. }
  35. _encoder_ctx = avcodec_alloc_context3(_encoder);
  36. if (!_encoder_ctx) {
  37. err = AE_FFMPEG_ALLOC_CONTEXT_FAILED;
  38. break;
  39. }
  40. _encoder_ctx->codec_id = AV_CODEC_ID_H264;
  41. _encoder_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
  42. _encoder_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
  43. _encoder_ctx->width = pic_width;
  44. _encoder_ctx->height = pic_height;
  45. _encoder_ctx->time_base.num = 1;
  46. _encoder_ctx->time_base.den = frame_rate;
  47. _encoder_ctx->framerate = { frame_rate,1 };
  48. _encoder_ctx->bit_rate = bit_rate;
  49. if (key_pic_sec == 0)
  50. _encoder_ctx->gop_size = 250;
  51. else
  52. _encoder_ctx->gop_size = key_pic_sec * _encoder_ctx->time_base.den / _encoder_ctx->time_base.num;
  53. //qb is 0 ~ 100
  54. qb = max(min(qb, 100), 0);
  55. //for qmax more larger,quality is more less, max qmax is qmin + 30*(100 - 0)/100 = qmin + 30
  56. _encoder_ctx->qmin = 30;
  57. _encoder_ctx->qmax = _encoder_ctx->qmin + 15 * (100 - qb) / 100;
  58. _encoder_ctx->max_b_frames = 0;//NO B Frame
  59. _encoder_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  60. ret = avcodec_open2(_encoder_ctx, _encoder, &options);
  61. if (ret != 0) {
  62. err = AE_FFMPEG_OPEN_CODEC_FAILED;
  63. break;
  64. }
  65. _frame = av_frame_alloc();
  66. _buff_size = av_image_get_buffer_size(_encoder_ctx->pix_fmt, _encoder_ctx->width, _encoder_ctx->height, 1);
  67. _buff = (uint8_t*)av_malloc(_buff_size);
  68. if (!_buff) {
  69. break;
  70. }
  71. av_image_fill_arrays(_frame->data, _frame->linesize, _buff, _encoder_ctx->pix_fmt, _encoder_ctx->width, _encoder_ctx->height, 1);
  72. _frame->format = _encoder_ctx->pix_fmt;
  73. _frame->width = _encoder_ctx->width;
  74. _frame->height = _encoder_ctx->height;
  75. _y_size = _encoder_ctx->width * _encoder_ctx->height;
  76. _time_base = _encoder_ctx->time_base;
  77. _inited = true;
  78. } while (0);
  79. if (err != AE_NO) {
  80. al_debug("%s,error:%d %lu", err2str(err), ret, GetLastError());
  81. cleanup();
  82. }
  83. if(options)
  84. av_dict_free(&options);
  85. return err;
  86. }
  87. int encoder_video_x264::get_extradata_size()
  88. {
  89. return _encoder_ctx->extradata_size;
  90. }
  91. const uint8_t * encoder_video_x264::get_extradata()
  92. {
  93. return (const uint8_t*)_encoder_ctx->extradata;
  94. }
  95. AVCodecID encoder_video_x264::get_codec_id()
  96. {
  97. if (_inited == false) return AV_CODEC_ID_NONE;
  98. return _encoder->id;
  99. }
  100. void encoder_video_x264::cleanup()
  101. {
  102. if (_frame)
  103. av_free(_frame);
  104. _frame = NULL;
  105. if (_buff)
  106. av_free(_buff);
  107. _buff = NULL;
  108. if (_encoder)
  109. avcodec_close(_encoder_ctx);
  110. _encoder = NULL;
  111. if (_encoder_ctx)
  112. avcodec_free_context(&_encoder_ctx);
  113. _encoder_ctx = NULL;
  114. }
  115. int encoder_video_x264::encode(AVFrame * frame, AVPacket * packet)
  116. {
  117. int ret = avcodec_send_frame(_encoder_ctx, frame);
  118. if (ret < 0) {
  119. return AE_FFMPEG_ENCODE_FRAME_FAILED;
  120. }
  121. while (ret >= 0) {
  122. av_init_packet(packet);
  123. ret = avcodec_receive_packet(_encoder_ctx, packet);
  124. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
  125. break;
  126. }
  127. if (ret < 0) {
  128. return AE_FFMPEG_READ_PACKET_FAILED;
  129. }
  130. if (ret == 0 && _on_data)
  131. _on_data(packet);
  132. av_packet_unref(packet);
  133. }
  134. return AE_NO;
  135. }
  136. void encoder_video_x264::encode_loop()
  137. {
  138. AVPacket *packet = av_packet_alloc();
  139. AVFrame yuv_frame;
  140. int error = AE_NO;
  141. while (_running)
  142. {
  143. std::unique_lock<std::mutex> lock(_mutex);
  144. while (!_cond_notify && _running)
  145. _cond_var.wait_for(lock, std::chrono::milliseconds(300));
  146. while (_ring_buffer->get(_buff, _buff_size, yuv_frame)) {
  147. _frame->pkt_dts = yuv_frame.pkt_dts;
  148. _frame->pkt_dts = yuv_frame.pkt_dts;
  149. _frame->pts = yuv_frame.pts;
  150. if ((error = encode(_frame, packet)) != AE_NO) {
  151. if (_on_error)
  152. _on_error(error);
  153. al_fatal("encode 264 packet failed:%d", error);
  154. break;
  155. }
  156. }
  157. _cond_notify = false;
  158. }
  159. //flush frame in encoder
  160. encode(NULL, packet);
  161. av_packet_free(&packet);
  162. }
  163. }