td_hdmp4venc.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Copyright (C) 2009-2010 Felipe Contreras
  3. * Copyright (C) 2009-2010 Nokia Corporation
  4. *
  5. * Author: Felipe Contreras <felipe.contreras@gmail.com>
  6. *
  7. * This file may be used under the terms of the GNU Lesser General Public
  8. * License version 2.1, a copy of which is found in LICENSE included in the
  9. * packaging of this file.
  10. */
  11. #include "dsp_bridge.h"
  12. #include "dmm_buffer.h"
  13. #include "gstdspbase.h"
  14. #include "gstdspvenc.h"
  15. #include "td_mp4venc_common.h"
  16. struct create_args {
  17. uint32_t size;
  18. uint16_t num_streams;
  19. uint16_t in_id;
  20. uint16_t in_type;
  21. uint16_t in_count;
  22. uint16_t out_id;
  23. uint16_t out_type;
  24. uint16_t out_count;
  25. uint32_t width;
  26. uint32_t height;
  27. uint32_t bitrate;
  28. uint32_t vbv_size;
  29. uint32_t gob_interval;
  30. uint8_t is_mpeg4;
  31. uint8_t color_format;
  32. uint8_t hec;
  33. uint8_t resync_marker;
  34. uint8_t data_part;
  35. uint8_t reversible_vlc;
  36. uint8_t unrestricted_mv;
  37. uint8_t framerate;
  38. uint8_t rate_control;
  39. uint8_t qp_first;
  40. uint8_t profile;
  41. uint8_t level;
  42. };
  43. static void create_args(GstDspBase *base, unsigned *profile_id, void **arg_data)
  44. {
  45. GstDspVEnc *self = GST_DSP_VENC(base);
  46. gint vbv;
  47. struct create_args args = {
  48. .size = sizeof(args) - 4,
  49. .num_streams = 2,
  50. .in_id = 0,
  51. .in_type = 0,
  52. .in_count = base->ports[0]->num_buffers,
  53. .out_id = 1,
  54. .out_type = 0,
  55. .out_count = base->ports[1]->num_buffers,
  56. .width = self->width,
  57. .height = self->height,
  58. .bitrate = self->bitrate,
  59. .gob_interval = self->keyframe_interval * self->framerate,
  60. .is_mpeg4 = 1,
  61. .color_format = (self->color_format == GST_MAKE_FOURCC('U','Y','V','Y') ? 1 : 0),
  62. .unrestricted_mv = 1,
  63. .framerate = self->framerate,
  64. .qp_first = 5,
  65. };
  66. if (self->mode == 0)
  67. args.rate_control = 3;
  68. else
  69. args.rate_control = 0;
  70. args.is_mpeg4 = base->alg == GSTDSP_HDMP4VENC ? 1 : 0;
  71. if (base->alg == GSTDSP_HDMP4VENC) {
  72. /* additional framerate and resolution checks for level-0 */
  73. if (self->level == 0 && (self->framerate > 15 || self->width > 176 || self->height > 144))
  74. self->level = 2;
  75. /* for qcif 15fps @ 128kpbs */
  76. if (self->level == 0 && self->bitrate > 64000)
  77. /* setting level=10 indicates level 0b*/
  78. self->level = 10;
  79. switch (self->level) {
  80. case 0:
  81. case 1:
  82. vbv = 10; break;
  83. case 10:
  84. vbv = 20; break;
  85. case 2:
  86. case 3:
  87. vbv = 40; break;
  88. case 4:
  89. vbv = 80; break;
  90. case 5:
  91. vbv = 112; break;
  92. case 6:
  93. vbv = 248; break;
  94. default:
  95. vbv = 0; break;
  96. }
  97. } else {
  98. /* additional framerate/resolution checks with each level
  99. * are due to their restriction as per standard
  100. */
  101. switch (self->level) {
  102. case 10:
  103. case 45:
  104. if (self->framerate > 15)
  105. self->level = 20;
  106. break;
  107. case 20:
  108. if (self->width > 176 && self->framerate > 15)
  109. self->level = 30;
  110. if (self->width <= 176 && self->framerate > 30)
  111. self->level = 50;
  112. break;
  113. case 30:
  114. case 40:
  115. if (self->framerate > 30)
  116. self->level = 60;
  117. break;
  118. case 50:
  119. if (self->width > 176 && self->framerate > 50)
  120. self->level = 60;
  121. break;
  122. default:
  123. break;
  124. }
  125. vbv = (self->level == 20) ? 16 : 32;
  126. }
  127. args.level = self->level;
  128. args.vbv_size = vbv;
  129. self->priv.mpeg4.vbv_size = vbv;
  130. *profile_id = 0;
  131. *arg_data = malloc(sizeof(args));
  132. memcpy(*arg_data, &args, sizeof(args));
  133. }
  134. struct in_params {
  135. uint32_t frame_index;
  136. uint32_t framerate;
  137. uint32_t bitrate;
  138. uint32_t i_frame_interval;
  139. uint32_t generate_header;
  140. uint32_t force_i_frame;
  141. uint32_t resync_interval;
  142. uint32_t hec_interval;
  143. uint32_t air_rate;
  144. uint32_t mir_rate;
  145. uint32_t qp_intra;
  146. uint32_t f_code;
  147. uint32_t half_pel;
  148. uint32_t ac_pred;
  149. uint32_t mv;
  150. };
  151. struct out_params {
  152. uint32_t bitstream_size;
  153. uint8_t frame_type;
  154. uint8_t skip_frame;
  155. int32_t ext_error_code;
  156. };
  157. static void out_recv_cb(GstDspBase *base, struct td_buffer *tb)
  158. {
  159. dmm_buffer_t *b = tb->data;
  160. struct out_params *param;
  161. param = tb->params->data;
  162. if (XDM_ERROR_IS_FATAL(param->ext_error_code)) {
  163. pr_err(base, "invalid i/p params or insufficient o/p buf size");
  164. g_atomic_int_set(&base->status, GST_FLOW_ERROR);
  165. }
  166. tb->keyframe = (param->frame_type == 1);
  167. if (base->alg == GSTDSP_HDMP4VENC)
  168. td_mp4venc_try_extract_extra_data(base, b);
  169. if (G_UNLIKELY(param->skip_frame))
  170. b->skip = TRUE;
  171. else
  172. b->skip = FALSE;
  173. }
  174. static void in_send_cb(GstDspBase *base, struct td_buffer *tb)
  175. {
  176. struct in_params *param;
  177. GstDspVEnc *self = GST_DSP_VENC(base);
  178. param = tb->params->data;
  179. param->frame_index = g_atomic_int_exchange_and_add(&self->frame_index, 1);
  180. g_mutex_lock(self->keyframe_mutex);
  181. param->force_i_frame = self->keyframe_event ? 1 : 0;
  182. if (self->keyframe_event) {
  183. gst_pad_push_event(base->srcpad, self->keyframe_event);
  184. self->keyframe_event = NULL;
  185. }
  186. g_mutex_unlock(self->keyframe_mutex);
  187. }
  188. static void setup_in_params(GstDspBase *base, dmm_buffer_t *tmp)
  189. {
  190. struct in_params *in_param;
  191. GstDspVEnc *self = GST_DSP_VENC(base);
  192. in_param = tmp->data;
  193. in_param->framerate = self->framerate;
  194. in_param->bitrate = self->bitrate;
  195. in_param->i_frame_interval = 15;
  196. in_param->resync_interval = 1024;
  197. in_param->hec_interval = 3;
  198. in_param->air_rate = 10;
  199. in_param->qp_intra = 10;
  200. in_param->f_code = 5;
  201. in_param->half_pel = 1;
  202. in_param->mv = 1;
  203. }
  204. static void setup_params(GstDspBase *base)
  205. {
  206. struct in_params *in_param;
  207. struct out_params *out_param;
  208. GstDspVEnc *self = GST_DSP_VENC(base);
  209. du_port_t *p;
  210. p = base->ports[0];
  211. gstdsp_port_setup_params(base, p, sizeof(*in_param), setup_in_params);
  212. p->send_cb = in_send_cb;
  213. p = base->ports[1];
  214. gstdsp_port_setup_params(base, p, sizeof(*out_param), NULL);
  215. p->recv_cb = out_recv_cb;
  216. base->output_buffer_size = (self->priv.mpeg4.vbv_size * 2048) +
  217. (self->bitrate / self->framerate);
  218. }
  219. struct td_codec td_hdmp4venc_codec = {
  220. .uuid = &(const struct dsp_uuid) { 0x34f881de, 0xefad, 0x4a7e, 0x8b, 0xe0,
  221. { 0xa6, 0x06, 0x8b, 0xdc, 0x9b, 0x1e } },
  222. .filename = "m4vhdenc_sn.dll64P",
  223. .setup_params = setup_params,
  224. .create_args = create_args,
  225. };