You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
13KB

  1. /*
  2. * V4L2 mem2mem encoders
  3. *
  4. * Copyright (C) 2017 Alexis Ballier <aballier@gentoo.org>
  5. * Copyright (C) 2017 Jorge Ramirez <jorge.ramirez-ortiz@linaro.org>
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include <linux/videodev2.h>
  24. #include <sys/ioctl.h>
  25. #include <search.h>
  26. #include "libavcodec/avcodec.h"
  27. #include "libavutil/pixdesc.h"
  28. #include "libavutil/pixfmt.h"
  29. #include "libavutil/opt.h"
  30. #include "v4l2_context.h"
  31. #include "v4l2_m2m.h"
  32. #include "v4l2_fmt.h"
  33. #define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x
  34. #define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x
  35. static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, unsigned int den)
  36. {
  37. struct v4l2_streamparm parm = { 0 };
  38. parm.type = V4L2_TYPE_IS_MULTIPLANAR(s->output.type) ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
  39. parm.parm.output.timeperframe.denominator = den;
  40. parm.parm.output.timeperframe.numerator = num;
  41. if (ioctl(s->fd, VIDIOC_S_PARM, &parm) < 0)
  42. av_log(s->avctx, AV_LOG_WARNING, "Failed to set timeperframe");
  43. }
  44. static inline void v4l2_set_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed int value, const char *name)
  45. {
  46. struct v4l2_ext_controls ctrls = { { 0 } };
  47. struct v4l2_ext_control ctrl = { 0 };
  48. /* set ctrls */
  49. ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
  50. ctrls.controls = &ctrl;
  51. ctrls.count = 1;
  52. /* set ctrl*/
  53. ctrl.value = value;
  54. ctrl.id = id;
  55. if (ioctl(s->fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
  56. av_log(s->avctx, AV_LOG_WARNING, "Failed to set %s: %s\n", name, strerror(errno));
  57. else
  58. av_log(s->avctx, AV_LOG_DEBUG, "Encoder: %s = %d\n", name, value);
  59. }
  60. static inline int v4l2_get_ext_ctrl(V4L2m2mContext *s, unsigned int id, signed int *value, const char *name)
  61. {
  62. struct v4l2_ext_controls ctrls = { { 0 } };
  63. struct v4l2_ext_control ctrl = { 0 };
  64. int ret;
  65. /* set ctrls */
  66. ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
  67. ctrls.controls = &ctrl;
  68. ctrls.count = 1;
  69. /* set ctrl*/
  70. ctrl.id = id ;
  71. ret = ioctl(s->fd, VIDIOC_G_EXT_CTRLS, &ctrls);
  72. if (ret < 0) {
  73. av_log(s->avctx, AV_LOG_WARNING, "Failed to get %s\n", name);
  74. return ret;
  75. }
  76. *value = ctrl.value;
  77. return 0;
  78. }
  79. static inline unsigned int v4l2_h264_profile_from_ff(int p)
  80. {
  81. static const struct h264_profile {
  82. unsigned int ffmpeg_val;
  83. unsigned int v4l2_val;
  84. } profile[] = {
  85. { FF_PROFILE_H264_CONSTRAINED_BASELINE, MPEG_VIDEO(H264_PROFILE_CONSTRAINED_BASELINE) },
  86. { FF_PROFILE_H264_HIGH_444_PREDICTIVE, MPEG_VIDEO(H264_PROFILE_HIGH_444_PREDICTIVE) },
  87. { FF_PROFILE_H264_HIGH_422_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_422_INTRA) },
  88. { FF_PROFILE_H264_HIGH_444_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_444_INTRA) },
  89. { FF_PROFILE_H264_HIGH_10_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_10_INTRA) },
  90. { FF_PROFILE_H264_HIGH_422, MPEG_VIDEO(H264_PROFILE_HIGH_422) },
  91. { FF_PROFILE_H264_BASELINE, MPEG_VIDEO(H264_PROFILE_BASELINE) },
  92. { FF_PROFILE_H264_EXTENDED, MPEG_VIDEO(H264_PROFILE_EXTENDED) },
  93. { FF_PROFILE_H264_HIGH_10, MPEG_VIDEO(H264_PROFILE_HIGH_10) },
  94. { FF_PROFILE_H264_MAIN, MPEG_VIDEO(H264_PROFILE_MAIN) },
  95. { FF_PROFILE_H264_HIGH, MPEG_VIDEO(H264_PROFILE_HIGH) },
  96. };
  97. int i;
  98. for (i = 0; i < FF_ARRAY_ELEMS(profile); i++) {
  99. if (profile[i].ffmpeg_val == p)
  100. return profile[i].v4l2_val;
  101. }
  102. return AVERROR(ENOENT);
  103. }
  104. static inline int v4l2_mpeg4_profile_from_ff(int p)
  105. {
  106. static const struct mpeg4_profile {
  107. unsigned int ffmpeg_val;
  108. unsigned int v4l2_val;
  109. } profile[] = {
  110. { FF_PROFILE_MPEG4_ADVANCED_CODING, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY) },
  111. { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_SIMPLE) },
  112. { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE_SCALABLE) },
  113. { FF_PROFILE_MPEG4_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE) },
  114. { FF_PROFILE_MPEG4_CORE, MPEG_VIDEO(MPEG4_PROFILE_CORE) },
  115. };
  116. int i;
  117. for (i = 0; i < FF_ARRAY_ELEMS(profile); i++) {
  118. if (profile[i].ffmpeg_val == p)
  119. return profile[i].v4l2_val;
  120. }
  121. return AVERROR(ENOENT);
  122. }
  123. static int v4l2_check_b_frame_support(V4L2m2mContext *s)
  124. {
  125. if (s->avctx->max_b_frames)
  126. av_log(s->avctx, AV_LOG_WARNING, "Encoder does not support b-frames yet\n");
  127. v4l2_set_ext_ctrl(s, MPEG_CID(B_FRAMES), 0, "number of B-frames");
  128. v4l2_get_ext_ctrl(s, MPEG_CID(B_FRAMES), &s->avctx->max_b_frames, "number of B-frames");
  129. if (s->avctx->max_b_frames == 0)
  130. return 0;
  131. avpriv_report_missing_feature(s->avctx, "DTS/PTS calculation for V4L2 encoding");
  132. return AVERROR_PATCHWELCOME;
  133. }
  134. static int v4l2_prepare_encoder(V4L2m2mContext *s)
  135. {
  136. AVCodecContext *avctx = s->avctx;
  137. int qmin_cid, qmax_cid, qmin, qmax;
  138. int ret, val;
  139. /**
  140. * requirements
  141. */
  142. ret = v4l2_check_b_frame_support(s);
  143. if (ret)
  144. return ret;
  145. /**
  146. * settingss
  147. */
  148. if (avctx->framerate.num || avctx->framerate.den)
  149. v4l2_set_timeperframe(s, avctx->framerate.den, avctx->framerate.num);
  150. /* set ext ctrls */
  151. v4l2_set_ext_ctrl(s, MPEG_CID(HEADER_MODE), MPEG_VIDEO(HEADER_MODE_SEPARATE), "header mode");
  152. v4l2_set_ext_ctrl(s, MPEG_CID(BITRATE) , avctx->bit_rate, "bit rate");
  153. v4l2_set_ext_ctrl(s, MPEG_CID(GOP_SIZE), avctx->gop_size,"gop size");
  154. av_log(avctx, AV_LOG_DEBUG,
  155. "Encoder Context: id (%d), profile (%d), frame rate(%d/%d), number b-frames (%d), "
  156. "gop size (%d), bit rate (%"PRId64"), qmin (%d), qmax (%d)\n",
  157. avctx->codec_id, avctx->profile, avctx->framerate.num, avctx->framerate.den,
  158. avctx->max_b_frames, avctx->gop_size, avctx->bit_rate, avctx->qmin, avctx->qmax);
  159. switch (avctx->codec_id) {
  160. case AV_CODEC_ID_H264:
  161. val = v4l2_h264_profile_from_ff(avctx->profile);
  162. if (val < 0)
  163. av_log(avctx, AV_LOG_WARNING, "h264 profile not found\n");
  164. else
  165. v4l2_set_ext_ctrl(s, MPEG_CID(H264_PROFILE), val, "h264 profile");
  166. qmin_cid = MPEG_CID(H264_MIN_QP);
  167. qmax_cid = MPEG_CID(H264_MAX_QP);
  168. qmin = 0;
  169. qmax = 51;
  170. break;
  171. case AV_CODEC_ID_MPEG4:
  172. val = v4l2_mpeg4_profile_from_ff(avctx->profile);
  173. if (val < 0)
  174. av_log(avctx, AV_LOG_WARNING, "mpeg4 profile not found\n");
  175. else
  176. v4l2_set_ext_ctrl(s, MPEG_CID(MPEG4_PROFILE), val, "mpeg4 profile");
  177. qmin_cid = MPEG_CID(MPEG4_MIN_QP);
  178. qmax_cid = MPEG_CID(MPEG4_MAX_QP);
  179. if (avctx->flags & AV_CODEC_FLAG_QPEL)
  180. v4l2_set_ext_ctrl(s, MPEG_CID(MPEG4_QPEL), 1, "qpel");
  181. qmin = 1;
  182. qmax = 31;
  183. break;
  184. case AV_CODEC_ID_H263:
  185. qmin_cid = MPEG_CID(H263_MIN_QP);
  186. qmax_cid = MPEG_CID(H263_MAX_QP);
  187. qmin = 1;
  188. qmax = 31;
  189. break;
  190. case AV_CODEC_ID_VP8:
  191. qmin_cid = MPEG_CID(VPX_MIN_QP);
  192. qmax_cid = MPEG_CID(VPX_MAX_QP);
  193. qmin = 0;
  194. qmax = 127;
  195. break;
  196. case AV_CODEC_ID_VP9:
  197. qmin_cid = MPEG_CID(VPX_MIN_QP);
  198. qmax_cid = MPEG_CID(VPX_MAX_QP);
  199. qmin = 0;
  200. qmax = 255;
  201. break;
  202. default:
  203. return 0;
  204. }
  205. if (qmin != avctx->qmin || qmax != avctx->qmax)
  206. av_log(avctx, AV_LOG_WARNING, "Encoder adjusted: qmin (%d), qmax (%d)\n", qmin, qmax);
  207. v4l2_set_ext_ctrl(s, qmin_cid, qmin, "minimum video quantizer scale");
  208. v4l2_set_ext_ctrl(s, qmax_cid, qmax, "maximum video quantizer scale");
  209. return 0;
  210. }
  211. static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame)
  212. {
  213. V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
  214. V4L2Context *const output = &s->output;
  215. #ifdef V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
  216. if (frame && frame->pict_type == AV_PICTURE_TYPE_I)
  217. v4l2_set_ext_ctrl(s, MPEG_CID(FORCE_KEY_FRAME), 0, "force key frame");
  218. #endif
  219. return ff_v4l2_context_enqueue_frame(output, frame);
  220. }
  221. static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
  222. {
  223. V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
  224. V4L2Context *const capture = &s->capture;
  225. V4L2Context *const output = &s->output;
  226. int ret;
  227. if (s->draining)
  228. goto dequeue;
  229. if (!output->streamon) {
  230. ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON);
  231. if (ret) {
  232. av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMON failed on output context\n");
  233. return ret;
  234. }
  235. }
  236. if (!capture->streamon) {
  237. ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON);
  238. if (ret) {
  239. av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMON failed on capture context\n");
  240. return ret;
  241. }
  242. }
  243. dequeue:
  244. return ff_v4l2_context_dequeue_packet(capture, avpkt);
  245. }
  246. static av_cold int v4l2_encode_init(AVCodecContext *avctx)
  247. {
  248. V4L2Context *capture, *output;
  249. V4L2m2mContext *s;
  250. V4L2m2mPriv *priv = avctx->priv_data;
  251. enum AVPixelFormat pix_fmt_output;
  252. uint32_t v4l2_fmt_output;
  253. int ret;
  254. ret = ff_v4l2_m2m_create_context(priv, &s);
  255. if (ret < 0)
  256. return ret;
  257. capture = &s->capture;
  258. output = &s->output;
  259. /* common settings output/capture */
  260. output->height = capture->height = avctx->height;
  261. output->width = capture->width = avctx->width;
  262. /* output context */
  263. output->av_codec_id = AV_CODEC_ID_RAWVIDEO;
  264. output->av_pix_fmt = avctx->pix_fmt;
  265. /* capture context */
  266. capture->av_codec_id = avctx->codec_id;
  267. capture->av_pix_fmt = AV_PIX_FMT_NONE;
  268. s->avctx = avctx;
  269. ret = ff_v4l2_m2m_codec_init(priv);
  270. if (ret) {
  271. av_log(avctx, AV_LOG_ERROR, "can't configure encoder\n");
  272. return ret;
  273. }
  274. if (V4L2_TYPE_IS_MULTIPLANAR(output->type))
  275. v4l2_fmt_output = output->format.fmt.pix_mp.pixelformat;
  276. else
  277. v4l2_fmt_output = output->format.fmt.pix.pixelformat;
  278. pix_fmt_output = ff_v4l2_format_v4l2_to_avfmt(v4l2_fmt_output, AV_CODEC_ID_RAWVIDEO);
  279. if (pix_fmt_output != avctx->pix_fmt) {
  280. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt_output);
  281. av_log(avctx, AV_LOG_ERROR, "Encoder requires %s pixel format.\n", desc->name);
  282. return AVERROR(EINVAL);
  283. }
  284. return v4l2_prepare_encoder(s);
  285. }
  286. static av_cold int v4l2_encode_close(AVCodecContext *avctx)
  287. {
  288. return ff_v4l2_m2m_codec_end(avctx->priv_data);
  289. }
  290. #define OFFSET(x) offsetof(V4L2m2mPriv, x)
  291. #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  292. static const AVOption options[] = {
  293. V4L_M2M_DEFAULT_OPTS,
  294. { "num_capture_buffers", "Number of buffers in the capture context",
  295. OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS },
  296. { NULL },
  297. };
  298. #define M2MENC_CLASS(NAME) \
  299. static const AVClass v4l2_m2m_ ## NAME ## _enc_class = { \
  300. .class_name = #NAME "_v4l2m2m_encoder", \
  301. .item_name = av_default_item_name, \
  302. .option = options, \
  303. .version = LIBAVUTIL_VERSION_INT, \
  304. };
  305. #define M2MENC(NAME, LONGNAME, CODEC) \
  306. M2MENC_CLASS(NAME) \
  307. AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \
  308. .name = #NAME "_v4l2m2m" , \
  309. .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " encoder wrapper"), \
  310. .type = AVMEDIA_TYPE_VIDEO, \
  311. .id = CODEC , \
  312. .priv_data_size = sizeof(V4L2m2mPriv), \
  313. .priv_class = &v4l2_m2m_ ## NAME ##_enc_class, \
  314. .init = v4l2_encode_init, \
  315. .send_frame = v4l2_send_frame, \
  316. .receive_packet = v4l2_receive_packet, \
  317. .close = v4l2_encode_close, \
  318. .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
  319. .wrapper_name = "v4l2m2m", \
  320. };
  321. M2MENC(mpeg4,"MPEG4", AV_CODEC_ID_MPEG4);
  322. M2MENC(h263, "H.263", AV_CODEC_ID_H263);
  323. M2MENC(h264, "H.264", AV_CODEC_ID_H264);
  324. M2MENC(hevc, "HEVC", AV_CODEC_ID_HEVC);
  325. M2MENC(vp8, "VP8", AV_CODEC_ID_VP8);