td_mp4venc.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. struct create_args {
  16. uint32_t size;
  17. uint16_t num_streams;
  18. uint16_t in_id;
  19. uint16_t in_type;
  20. uint16_t in_count;
  21. uint16_t out_id;
  22. uint16_t out_type;
  23. uint16_t out_count;
  24. uint16_t reserved;
  25. uint32_t width;
  26. uint32_t height;
  27. uint32_t max_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. uint32_t max_delay;
  43. uint32_t vbv_enable;
  44. uint32_t h263_slice_mode;
  45. uint32_t use_gov;
  46. uint32_t use_vos;
  47. uint32_t h263_annex_i;
  48. uint32_t h263_annex_j;
  49. uint32_t h263_annex_t;
  50. };
  51. static void create_args(GstDspBase *base, unsigned *profile_id, void **arg_data)
  52. {
  53. GstDspVEnc *self = GST_DSP_VENC(base);
  54. struct create_args args = {
  55. .size = sizeof(args) - 4,
  56. .num_streams = 2,
  57. .in_id = 0,
  58. .in_type = 0,
  59. .in_count = base->ports[0]->num_buffers,
  60. .out_id = 1,
  61. .out_type = 0,
  62. .out_count = base->ports[1]->num_buffers,
  63. .width = self->width,
  64. .height = self->height,
  65. .max_bitrate = self->max_bitrate,
  66. .vbv_size = 112,
  67. .color_format = (self->color_format == GST_MAKE_FOURCC('U','Y','V','Y') ? 2 : 0),
  68. .unrestricted_mv = 1,
  69. .framerate = self->framerate,
  70. .qp_first = 12,
  71. .profile = 1,
  72. .max_delay = 300,
  73. .vbv_enable = 1,
  74. .use_vos = 1,
  75. };
  76. args.is_mpeg4 = base->alg == GSTDSP_MP4VENC ? 1 : 0;
  77. if (base->alg == GSTDSP_MP4VENC)
  78. args.level = 5;
  79. else
  80. args.level = 20;
  81. if (self->mode == 0) {
  82. args.gob_interval = 0;
  83. args.hec = 0;
  84. args.resync_marker = 0;
  85. args.rate_control = 2;
  86. } else {
  87. args.gob_interval = 1;
  88. args.hec = 1;
  89. args.resync_marker = 1;
  90. args.rate_control = 1;
  91. }
  92. if (self->width * self->height > 720 * 480)
  93. *profile_id = 4;
  94. else if (self->width * self->height > 640 * 480)
  95. *profile_id = 3;
  96. else if (self->width * self->height > 352 * 288)
  97. *profile_id = 2;
  98. else if (self->width * self->height > 176 * 144)
  99. *profile_id = 1;
  100. else
  101. *profile_id = 0;
  102. *arg_data = malloc(sizeof(args));
  103. memcpy(*arg_data, &args, sizeof(args));
  104. }
  105. static void try_extract_codec_data(GstDspBase *base, dmm_buffer_t *b)
  106. {
  107. GstDspVEnc *self = GST_DSP_VENC(base);
  108. guint8 gov[] = { 0x0, 0x0, 0x1, 0xB3 };
  109. guint8 vop[] = { 0x0, 0x0, 0x1, 0xB6 };
  110. guint8 *data;
  111. GstBuffer *codec_buf;
  112. if (G_LIKELY(self->priv.mpeg4.codec_data_done))
  113. return;
  114. if (!b->len)
  115. return;
  116. /* only mind codec-data for storage */
  117. if (self->mode)
  118. goto done;
  119. /*
  120. * Codec data expected in first frame,
  121. * and runs from VOSH to GOP (not including); so locate the latter one.
  122. */
  123. data = memmem(b->data, b->len, gov, 4);
  124. if (!data) {
  125. /* maybe no GOP is in the stream, look for first VOP */
  126. data = memmem(b->data, b->len, vop, 4);
  127. }
  128. if (!data) {
  129. pr_err(self, "failed to extract mpeg4 codec-data");
  130. goto done;
  131. }
  132. codec_buf = gst_buffer_new_and_alloc(data - (guint8 *) b->data);
  133. memcpy(GST_BUFFER_DATA(codec_buf), b->data, GST_BUFFER_SIZE(codec_buf));
  134. gstdsp_set_codec_data_caps(base, codec_buf);
  135. gst_buffer_unref(codec_buf);
  136. done:
  137. self->priv.mpeg4.codec_data_done = TRUE;
  138. }
  139. struct in_params {
  140. uint32_t frame_index;
  141. uint32_t framerate;
  142. uint32_t bitrate;
  143. uint32_t i_frame_interval;
  144. uint32_t generate_header;
  145. uint32_t force_i_frame;
  146. uint32_t resync_interval;
  147. uint32_t hec_interval;
  148. uint32_t air_rate;
  149. uint32_t mir_rate;
  150. uint32_t qp_intra;
  151. uint32_t f_code;
  152. uint32_t half_pel;
  153. uint32_t ac_pred;
  154. uint32_t mv;
  155. uint32_t use_umv;
  156. uint32_t mv_data_enable;
  157. uint32_t resync_data_enable;
  158. uint32_t qp_inter;
  159. uint32_t last_frame;
  160. uint32_t width;
  161. /* SN_API >= 1 */
  162. uint32_t qp_max;
  163. uint32_t qp_min;
  164. };
  165. struct out_params {
  166. uint32_t bitstream_size;
  167. uint32_t frame_type;
  168. uint32_t mv_data_size;
  169. uint32_t num_packets;
  170. uint8_t mv_data[12960];
  171. uint8_t resync_data[6480];
  172. /* SN_API >= 1 */
  173. uint32_t frame_index;
  174. uint32_t error_code;
  175. };
  176. static void out_recv_cb(GstDspBase *base, struct td_buffer *tb)
  177. {
  178. struct out_params *param;
  179. param = tb->params->data;
  180. tb->keyframe = (param->frame_type == 1);
  181. if (base->alg == GSTDSP_MP4VENC)
  182. try_extract_codec_data(base, tb->data);
  183. }
  184. static void in_send_cb(GstDspBase *base, struct td_buffer *tb)
  185. {
  186. struct in_params *param;
  187. GstDspVEnc *self = GST_DSP_VENC(base);
  188. param = tb->params->data;
  189. param->frame_index = g_atomic_int_exchange_and_add(&self->frame_index, 1);
  190. param->bitrate = g_atomic_int_get(&self->bitrate);
  191. g_mutex_lock(self->keyframe_mutex);
  192. param->force_i_frame = self->keyframe_event ? 1 : 0;
  193. if (self->keyframe_event) {
  194. gst_pad_push_event(base->srcpad, self->keyframe_event);
  195. self->keyframe_event = NULL;
  196. }
  197. g_mutex_unlock(self->keyframe_mutex);
  198. }
  199. static void setup_in_params(GstDspBase *base, dmm_buffer_t *tmp)
  200. {
  201. struct in_params *in_param;
  202. GstDspVEnc *self = GST_DSP_VENC(base);
  203. in_param = tmp->data;
  204. in_param->framerate = self->framerate;
  205. in_param->bitrate = self->bitrate;
  206. in_param->i_frame_interval = self->keyframe_interval * self->framerate;
  207. in_param->air_rate = 10;
  208. in_param->qp_intra = 8;
  209. in_param->f_code = 6;
  210. in_param->half_pel = 1;
  211. in_param->qp_inter = 8;
  212. if (base->alg == GSTDSP_MP4VENC)
  213. in_param->ac_pred = 1;
  214. if (self->mode == 0) {
  215. in_param->use_umv = 1;
  216. } else {
  217. in_param->resync_interval = 1024;
  218. in_param->hec_interval = 3;
  219. }
  220. }
  221. static void setup_params(GstDspBase *base)
  222. {
  223. struct in_params *in_param;
  224. struct out_params *out_param;
  225. du_port_t *p;
  226. p = base->ports[0];
  227. gstdsp_port_setup_params(base, p, sizeof(*in_param), setup_in_params);
  228. p->send_cb = in_send_cb;
  229. p = base->ports[1];
  230. gstdsp_port_setup_params(base, p, sizeof(*out_param), NULL);
  231. p->recv_cb = out_recv_cb;
  232. }
  233. struct td_codec td_mp4venc_codec = {
  234. .uuid = &(const struct dsp_uuid) { 0x98c2e8d8, 0x4644, 0x11d6, 0x81, 0x18,
  235. { 0x00, 0xb0, 0xd0, 0x8d, 0x72, 0x9f } },
  236. .filename = "m4venc_sn.dll64P",
  237. .setup_params = setup_params,
  238. .create_args = create_args,
  239. };