gstdspvenc.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /*
  2. * Copyright (C) 2009 Felipe Contreras
  3. *
  4. * Authors:
  5. * Felipe Contreras <felipe.contreras@gmail.com>
  6. * Juha Alanen <juha.m.alanen@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation
  11. * version 2.1 of the License.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. */
  23. #include "gstdspvenc.h"
  24. #include "plugin.h"
  25. #include "util.h"
  26. #include "dsp_bridge.h"
  27. #include <string.h> /* for memcpy */
  28. #include "log.h"
  29. #define GST_CAT_DEFAULT gstdsp_debug
  30. static GstDspBaseClass *parent_class;
  31. enum {
  32. ARG_0,
  33. ARG_BITRATE,
  34. ARG_MODE,
  35. };
  36. #define DEFAULT_BITRATE 0
  37. #define DEFAULT_MODE 0
  38. #define GST_TYPE_DSPVENC_MODE gst_dspvenc_mode_get_type()
  39. static GType
  40. gst_dspvenc_mode_get_type (void)
  41. {
  42. static GType gst_dspvenc_mode_type = 0;
  43. if (!gst_dspvenc_mode_type) {
  44. static GEnumValue modes[] = {
  45. {0, "Storage", "storage"},
  46. {1, "Streaming", "streaming"},
  47. {0, NULL, NULL},
  48. };
  49. gst_dspvenc_mode_type = g_enum_register_static("GstDspVEncMode", modes);
  50. }
  51. return gst_dspvenc_mode_type;
  52. }
  53. static inline GstCaps *
  54. generate_sink_template(void)
  55. {
  56. GstCaps *caps;
  57. GstStructure *struc;
  58. caps = gst_caps_new_empty();
  59. struc = gst_structure_new("video/x-raw-yuv",
  60. "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'),
  61. NULL);
  62. gst_caps_append_structure(caps, struc);
  63. return caps;
  64. }
  65. struct foo_data {
  66. unsigned long size;
  67. unsigned short data[42];
  68. };
  69. struct jpegenc_args {
  70. uint16_t num_streams;
  71. uint16_t in_id;
  72. uint16_t in_type;
  73. uint16_t in_count;
  74. uint16_t out_id;
  75. uint16_t out_type;
  76. uint16_t out_count;
  77. uint16_t max_width;
  78. uint16_t max_height;
  79. uint16_t color_format;
  80. uint16_t max_app0_width;
  81. uint16_t max_app0_height;
  82. uint16_t max_app1_width;
  83. uint16_t max_app1_height;
  84. uint16_t max_app13_width;
  85. uint16_t max_app13_height;
  86. uint16_t scans;
  87. };
  88. static inline void *
  89. get_jpegenc_args(GstDspVEnc *self)
  90. {
  91. GstDspBase *base = GST_DSP_BASE(self);
  92. struct jpegenc_args args = {
  93. .num_streams = 2,
  94. .in_id = 0,
  95. .in_type = 0,
  96. .in_count = base->ports[0]->num_buffers,
  97. .out_id = 1,
  98. .out_type = 0,
  99. .out_count = base->ports[1]->num_buffers,
  100. .max_width = 2592 + 32,
  101. .max_height = 1968 + 32,
  102. .color_format = 1,
  103. .max_app0_width = 0,
  104. .max_app0_height = 0,
  105. .max_app1_width = 0,
  106. .max_app1_height = 0,
  107. .max_app13_width = 0,
  108. .max_app13_height = 0,
  109. .scans = 0,
  110. };
  111. struct foo_data *cb_data;
  112. cb_data = malloc(sizeof(*cb_data));
  113. cb_data->size = sizeof(args);
  114. memcpy(&cb_data->data, &args, sizeof(args));
  115. return cb_data;
  116. }
  117. struct mp4venc_args {
  118. uint16_t num_streams;
  119. uint16_t in_id;
  120. uint16_t in_type;
  121. uint16_t in_count;
  122. uint16_t out_id;
  123. uint16_t out_type;
  124. uint16_t out_count;
  125. uint16_t reserved;
  126. uint32_t width;
  127. uint32_t height;
  128. uint32_t bitrate;
  129. uint32_t vbv_size;
  130. uint32_t gob_interval;
  131. uint8_t is_mpeg4;
  132. uint8_t color_format;
  133. uint8_t hec;
  134. uint8_t resync_marker;
  135. uint8_t data_part;
  136. uint8_t reversible_vlc;
  137. uint8_t unrestricted_mv;
  138. uint8_t framerate;
  139. uint8_t rate_control;
  140. uint8_t qp_first;
  141. uint8_t profile;
  142. uint8_t level;
  143. uint32_t max_delay;
  144. uint32_t vbv_enable;
  145. uint32_t h263_slice_mode;
  146. uint32_t use_gov;
  147. uint32_t use_vos;
  148. uint32_t h263_annex_i;
  149. uint32_t h263_annex_j;
  150. uint32_t h263_annex_t;
  151. };
  152. static inline void *
  153. get_mp4venc_args(GstDspVEnc *self)
  154. {
  155. GstDspBase *base = GST_DSP_BASE(self);
  156. struct mp4venc_args args = {
  157. .num_streams = 2,
  158. .in_id = 0,
  159. .in_type = 0,
  160. .in_count = base->ports[0]->num_buffers,
  161. .out_id = 1,
  162. .out_type = 0,
  163. .out_count = base->ports[1]->num_buffers,
  164. .reserved = 0,
  165. .width = self->width,
  166. .height = self->height,
  167. .bitrate = self->bitrate,
  168. .vbv_size = 112,
  169. .color_format = 2,
  170. .data_part = 0,
  171. .reversible_vlc = 0,
  172. .unrestricted_mv = 1,
  173. .framerate = self->framerate,
  174. .qp_first = 12,
  175. .profile = 1,
  176. .max_delay = 300,
  177. .vbv_enable = 1,
  178. .h263_slice_mode = 0,
  179. .use_gov = 0,
  180. .use_vos = 1,
  181. .h263_annex_i = 0,
  182. .h263_annex_j = 0,
  183. .h263_annex_t = 0,
  184. };
  185. args.is_mpeg4 = base->alg == GSTDSP_MP4VENC ? 1 : 0;
  186. if (base->alg == GSTDSP_MP4VENC)
  187. args.level = 5;
  188. else
  189. args.level = 20;
  190. if (self->mode == 0) {
  191. args.gob_interval = 0;
  192. args.hec = 0;
  193. args.resync_marker = 0;
  194. args.rate_control = 2;
  195. } else {
  196. args.gob_interval = 1;
  197. args.hec = 1;
  198. args.resync_marker = 1;
  199. args.rate_control = 1;
  200. }
  201. struct foo_data *cb_data;
  202. cb_data = malloc(sizeof(*cb_data));
  203. cb_data->size = sizeof(args);
  204. memcpy(&cb_data->data, &args, sizeof(args));
  205. return cb_data;
  206. }
  207. struct h264venc_args {
  208. uint16_t num_streams;
  209. uint16_t in_id;
  210. uint16_t in_type;
  211. uint16_t in_count;
  212. uint16_t out_id;
  213. uint16_t out_type;
  214. uint16_t out_count;
  215. uint16_t reserved;
  216. uint32_t width;
  217. uint32_t height;
  218. uint32_t bitrate;
  219. uint32_t bitstream_buf_size;
  220. uint32_t intra_frame_period;
  221. uint32_t framerate;
  222. uint8_t yuv_format;
  223. uint8_t unrestricted_mv; /* not supported */
  224. uint8_t num_ref_frames; /* not supported */
  225. uint8_t rc_algorithm;
  226. uint8_t idr_enable; /* not used */
  227. uint8_t deblocking_enable;
  228. uint8_t mv_range;
  229. uint8_t qpi_frame;
  230. uint8_t profile;
  231. uint8_t level;
  232. uint16_t nal_mode;
  233. uint32_t encoding_preset;
  234. uint32_t rc_algo;
  235. };
  236. static inline void *
  237. get_h264venc_args(GstDspVEnc *self)
  238. {
  239. GstDspBase *base = GST_DSP_BASE(self);
  240. struct h264venc_args args = {
  241. .num_streams = 2,
  242. .in_id = 0,
  243. .in_type = 0,
  244. .in_count = base->ports[0]->num_buffers,
  245. .out_id = 1,
  246. .out_type = 0,
  247. .out_count = base->ports[1]->num_buffers,
  248. .reserved = 0,
  249. .width = self->width,
  250. .height = self->height,
  251. .bitrate = self->bitrate,
  252. .bitstream_buf_size = base->output_buffer_size,
  253. .intra_frame_period = self->framerate,
  254. .framerate = self->framerate * 1000,
  255. .yuv_format = 2,
  256. .unrestricted_mv = 0, /* not supported */
  257. .num_ref_frames = 1, /* not supported */
  258. .rc_algorithm = 1, /* 0 = var, 1 == constant, 2 == none */
  259. .idr_enable = 0, /* not used */
  260. .deblocking_enable = 1,
  261. .mv_range = 64,
  262. .qpi_frame = 28,
  263. .profile = 66, /* Baseline profile */
  264. .level = 13,
  265. .nal_mode = self->priv.h264.bytestream ? 0 : 1, /* 0 == bytestream, 1 == NALU */
  266. .encoding_preset = 3,
  267. .rc_algo = 0,
  268. };
  269. if (self->mode == 0)
  270. args.rc_algorithm = 0;
  271. else
  272. args.rc_algorithm = 1;
  273. struct foo_data *cb_data;
  274. cb_data = malloc(sizeof(*cb_data));
  275. cb_data->size = sizeof(args);
  276. memcpy(&cb_data->data, &args, sizeof(args));
  277. return cb_data;
  278. }
  279. static inline void *
  280. create_node(GstDspVEnc *self)
  281. {
  282. GstDspBase *base;
  283. int dsp_handle;
  284. dsp_node_t *node;
  285. const dsp_uuid_t *alg_uuid;
  286. const char *alg_fn;
  287. const dsp_uuid_t usn_uuid = { 0x79A3C8B3, 0x95F2, 0x403F, 0x9A, 0x4B,
  288. { 0xCF, 0x80, 0x57, 0x73, 0x05, 0x41 } };
  289. const dsp_uuid_t jpeg_enc_uuid = { 0xcb70c0c1, 0x4c85, 0x11d6, 0xb1, 0x05,
  290. { 0x00, 0xc0, 0x4f, 0x32, 0x90, 0x31 } };
  291. const dsp_uuid_t mp4v_enc_uuid = { 0x98c2e8d8, 0x4644, 0x11d6, 0x81, 0x18,
  292. { 0x00, 0xb0, 0xd0, 0x8d, 0x72, 0x9f } };
  293. const dsp_uuid_t h264_enc_uuid = { 0x63A3581A, 0x09D7, 0x4AD0, 0x80, 0xB8,
  294. { 0x5F, 0x2C, 0x4D, 0x4D, 0x59, 0xC9 } };
  295. base = GST_DSP_BASE(self);
  296. dsp_handle = base->dsp_handle;
  297. if (!gstdsp_register(dsp_handle, &usn_uuid, DSP_DCD_LIBRARYTYPE, "usn.dll64P")) {
  298. pr_err(self, "failed to register usn node library");
  299. return NULL;
  300. }
  301. switch (base->alg) {
  302. case GSTDSP_JPEGENC:
  303. alg_uuid = &jpeg_enc_uuid;
  304. alg_fn = "jpegenc_sn.dll64P";
  305. break;
  306. case GSTDSP_H263ENC:
  307. case GSTDSP_MP4VENC:
  308. alg_uuid = &mp4v_enc_uuid;
  309. alg_fn = "m4venc_sn.dll64P";
  310. break;
  311. case GSTDSP_H264ENC:
  312. alg_uuid = &h264_enc_uuid;
  313. alg_fn = "h264venc_sn.dll64P";
  314. break;
  315. default:
  316. pr_err(self, "unknown algorithm");
  317. return NULL;
  318. }
  319. if (!gstdsp_register(dsp_handle, alg_uuid, DSP_DCD_LIBRARYTYPE, alg_fn)) {
  320. pr_err(self, "failed to register algo node library");
  321. return NULL;
  322. }
  323. if (!gstdsp_register(dsp_handle, alg_uuid, DSP_DCD_NODETYPE, alg_fn)) {
  324. pr_err(self, "failed to register algo node");
  325. return NULL;
  326. }
  327. {
  328. struct dsp_node_attr_in attrs = {
  329. .cb = sizeof(attrs),
  330. .priority = 5,
  331. .timeout = 1000,
  332. .heap_size = 0,
  333. .gpp_va = 0,
  334. };
  335. void *cb_data;
  336. switch (base->alg) {
  337. case GSTDSP_JPEGENC:
  338. attrs.profile_id = 10;
  339. cb_data = get_jpegenc_args(self);
  340. break;
  341. case GSTDSP_H263ENC:
  342. case GSTDSP_MP4VENC:
  343. if (self->width * self->height > 720 * 480)
  344. attrs.profile_id = 4;
  345. else if (self->width * self->height > 640 * 480)
  346. attrs.profile_id = 3;
  347. else if (self->width * self->height > 352 * 288)
  348. attrs.profile_id = 2;
  349. else if (self->width * self->height > 176 * 144)
  350. attrs.profile_id = 1;
  351. else
  352. attrs.profile_id = 0;
  353. cb_data = get_mp4venc_args(self);
  354. break;
  355. case GSTDSP_H264ENC:
  356. if (self->width * self->height > 352 * 288)
  357. attrs.profile_id = 2;
  358. else if (self->width * self->height > 176 * 144)
  359. attrs.profile_id = 1;
  360. else
  361. attrs.profile_id = 0;
  362. cb_data = get_h264venc_args(self);
  363. break;
  364. default:
  365. cb_data = NULL;
  366. }
  367. if (!dsp_node_allocate(dsp_handle, base->proc, alg_uuid, cb_data, &attrs, &node)) {
  368. pr_err(self, "dsp node allocate failed");
  369. free(cb_data);
  370. return NULL;
  371. }
  372. free(cb_data);
  373. }
  374. if (!dsp_node_create(dsp_handle, node)) {
  375. pr_err(self, "dsp node create failed");
  376. return NULL;
  377. }
  378. pr_info(self, "dsp node created");
  379. return node;
  380. }
  381. struct jpegenc_dyn_params {
  382. uint32_t size;
  383. uint32_t num_au; /* set to 0 */
  384. uint32_t color_format;
  385. uint32_t height;
  386. uint32_t width;
  387. uint32_t capture_width;
  388. uint32_t gen_header;
  389. uint32_t quality;
  390. uint32_t capture_height;
  391. uint32_t dri_interval;
  392. uint32_t huffman_table;
  393. uint32_t quant_table;
  394. };
  395. static inline void
  396. jpegenc_send_params(GstDspBase *base)
  397. {
  398. struct jpegenc_dyn_params *params;
  399. dmm_buffer_t *b;
  400. GstDspVEnc *self = GST_DSP_VENC(base);
  401. b = dmm_buffer_new(base->dsp_handle, base->proc);
  402. dmm_buffer_allocate(b, sizeof(*params));
  403. params = b->data;
  404. params->num_au = 0;
  405. params->size = sizeof(*params);
  406. params->color_format = 4;
  407. params->width = self->width;
  408. params->height = self->height;
  409. params->capture_width = self->width;
  410. params->capture_height = self->height;
  411. params->gen_header = 0;
  412. params->quality = self->quality;
  413. params->dri_interval = 0;
  414. params->huffman_table = 0;
  415. params->quant_table = 0;
  416. dmm_buffer_clean(b, sizeof(*params));
  417. base->alg_ctrl = b;
  418. dsp_send_message(base->dsp_handle, base->node, 0x0400, 3, (uint32_t) b->map);
  419. }
  420. struct h264venc_in_stream_params {
  421. uint32_t params_size;
  422. uint32_t input_height;
  423. uint32_t input_width;
  424. uint32_t ref_framerate;
  425. uint32_t target_framerate;
  426. uint32_t target_bitrate;
  427. uint32_t intra_frame_interval;
  428. uint32_t generate_header;
  429. uint32_t capture_width;
  430. uint32_t force_i_frame;
  431. uint32_t qp_intra;
  432. uint32_t qp_inter;
  433. uint32_t qp_max;
  434. uint32_t qp_min;
  435. uint32_t lf_disable_idc;
  436. uint32_t quarter_pel_disable;
  437. uint32_t air_mb_period;
  438. uint32_t max_mbs_per_slice;
  439. uint32_t max_bytes_per_slice;
  440. uint32_t slice_refresh_row_start_number;
  441. uint32_t slice_refresh_row_number;
  442. uint32_t filter_offset_a;
  443. uint32_t filter_offset_b;
  444. uint32_t log2MaxFNumMinus4;
  445. uint32_t chroma_qpi_index_offset;
  446. uint32_t constrained_intra_pred_enable;
  447. uint32_t pic_order_count_type;
  448. uint32_t max_mv_per_mb;
  449. uint32_t intra_4x4_enable_idc;
  450. uint32_t mv_data_enable;
  451. uint32_t hier_coding_enable;
  452. uint32_t stream_format;
  453. uint32_t intra_refresh_method;
  454. uint32_t perceptual_quant;
  455. uint32_t scene_change_det;
  456. void (*nal_callback_func)(uint32_t *buf, uint32_t *buf_size, void *context);
  457. void *context;
  458. uint32_t num_slice_aso;
  459. uint32_t aso_slice_order[8]; /* MAXNUMSLCGPS = 8 */
  460. uint32_t num_slice_groups;
  461. uint32_t slice_group_map_type;
  462. uint32_t slice_group_change_direction_flag;
  463. uint32_t slice_group_change_rate;
  464. uint32_t slice_group_change_cycle;
  465. uint32_t slice_group_params[8]; /* MAXNUMSLCGPS = 8 */
  466. uint32_t frame_index;
  467. };
  468. struct h264venc_out_stream_params {
  469. uint32_t bitstream_size;
  470. int32_t frame_type;
  471. uint32_t nalus_per_frame;
  472. uint32_t nalu_sizes[1618];
  473. uint32_t frame_index; /* Gives the number of the input frame which NAL unit belongs */
  474. uint32_t nalu_index; /* Number of current NAL unit inside the frame */
  475. };
  476. static void
  477. h264venc_in_send_cb(GstDspBase *base,
  478. du_port_t *port,
  479. dmm_buffer_t *p,
  480. dmm_buffer_t *b)
  481. {
  482. struct h264venc_in_stream_params *param;
  483. GstDspVEnc *self = GST_DSP_VENC(base);
  484. param = p->data;
  485. param->frame_index = g_atomic_int_exchange_and_add(&self->frame_index, 1);
  486. param->target_bitrate = g_atomic_int_get(&self->bitrate);
  487. g_mutex_lock(self->keyframe_mutex);
  488. param->force_i_frame = !!self->keyframe_event;
  489. if (self->keyframe_event) {
  490. gst_pad_push_event(base->srcpad, self->keyframe_event);
  491. self->keyframe_event = NULL;
  492. }
  493. g_mutex_unlock(self->keyframe_mutex);
  494. dmm_buffer_clean(p, sizeof(*param));
  495. }
  496. static inline gboolean
  497. gst_dsp_set_codec_data_caps(GstDspBase *base,
  498. GstBuffer *buf)
  499. {
  500. GstCaps *caps = NULL;
  501. GstStructure *structure;
  502. GValue value = { .g_type = 0 };
  503. caps = gst_pad_get_negotiated_caps(base->srcpad);
  504. caps = gst_caps_make_writable(caps);
  505. structure = gst_caps_get_structure(caps, 0);
  506. g_value_init(&value, GST_TYPE_BUFFER);
  507. gst_value_set_buffer(&value, buf);
  508. gst_structure_set_value(structure, "codec_data", &value);
  509. g_value_unset(&value);
  510. return gst_pad_set_caps(base->srcpad, caps);
  511. }
  512. static inline void
  513. gst_dsp_h264venc_create_codec_data(GstDspBase *base)
  514. {
  515. GstDspVEnc *self;
  516. guint8 *sps, *pps, *codec_data;
  517. guint16 sps_size, pps_size, offset;
  518. self = GST_DSP_VENC(base);
  519. sps = GST_BUFFER_DATA(self->priv.h264.sps);
  520. pps = GST_BUFFER_DATA(self->priv.h264.pps);
  521. sps_size = GST_BUFFER_SIZE(self->priv.h264.sps);
  522. pps_size = GST_BUFFER_SIZE(self->priv.h264.pps);
  523. offset = 0;
  524. self->priv.h264.codec_data = gst_buffer_new_and_alloc(sps_size + pps_size + 11);
  525. codec_data = GST_BUFFER_DATA(self->priv.h264.codec_data);
  526. codec_data[offset++] = 0x01;
  527. codec_data[offset++] = sps[1]; /* AVCProfileIndication*/
  528. codec_data[offset++] = sps[2]; /* profile_compatibility*/
  529. codec_data[offset++] = sps[3]; /* AVCLevelIndication */
  530. codec_data[offset++] = 0xff;
  531. codec_data[offset++] = 0xe1;
  532. codec_data[offset++] = (sps_size >> 8) & 0xff;
  533. codec_data[offset++] = sps_size & 0xff;
  534. memcpy(codec_data + offset, sps, sps_size);
  535. offset += sps_size;
  536. codec_data[offset++] = 0x1;
  537. codec_data[offset++] = (pps_size >> 8) & 0xff;
  538. codec_data[offset++] = pps_size & 0xff;
  539. memcpy(codec_data + offset, pps, pps_size);
  540. }
  541. static void
  542. h264venc_out_send_cb(GstDspBase *base,
  543. du_port_t *port,
  544. dmm_buffer_t *p,
  545. dmm_buffer_t *b)
  546. {
  547. struct h264venc_out_stream_params *param;
  548. param = p->data;
  549. dmm_buffer_invalidate(p, sizeof(*param));
  550. }
  551. static void
  552. h264venc_out_recv_cb(GstDspBase *base,
  553. du_port_t *port,
  554. dmm_buffer_t *p,
  555. dmm_buffer_t *b)
  556. {
  557. GstDspVEnc *self = GST_DSP_VENC(base);
  558. struct h264venc_out_stream_params *param;
  559. param = p->data;
  560. g_atomic_int_set(&base->keyframe, param->frame_type == 1);
  561. if (b->len == 0 || self->priv.h264.bytestream)
  562. return;
  563. if (G_LIKELY(self->priv.h264.codec_data_done)) {
  564. /* prefix the NALU with a lenght field, don't count the start code */
  565. uint32_t len = b->len - 4;
  566. ((uint8_t *)b->data)[3] = len & 0xff;
  567. ((uint8_t *)b->data)[2] = (len >> 8) & 0xff;
  568. ((uint8_t *)b->data)[1] = (len >> 16) & 0xff;
  569. ((uint8_t *)b->data)[0] = (len >> 24) & 0xff;
  570. }
  571. else {
  572. if (!self->priv.h264.sps_received) {
  573. /* skip the start code 0x00000001 when storing SPS */
  574. self->priv.h264.sps = gst_buffer_new_and_alloc(b->len - 4);
  575. memcpy(GST_BUFFER_DATA(self->priv.h264.sps), b->data + 4, b->len - 4);
  576. self->priv.h264.sps_received = TRUE;
  577. } else if (!self->priv.h264.pps_received) {
  578. /* skip the start code 0x00000001 when storing PPS */
  579. self->priv.h264.pps = gst_buffer_new_and_alloc(b->len - 4);
  580. memcpy(GST_BUFFER_DATA(self->priv.h264.pps), b->data + 4, b->len - 4);
  581. self->priv.h264.pps_received = TRUE;
  582. }
  583. if (self->priv.h264.pps_received && self->priv.h264.sps_received) {
  584. gst_dsp_h264venc_create_codec_data(base);
  585. if (gst_dsp_set_codec_data_caps(base, self->priv.h264.codec_data)) {
  586. self->priv.h264.codec_data_done = TRUE;
  587. gst_buffer_unref(self->priv.h264.sps);
  588. gst_buffer_unref(self->priv.h264.pps);
  589. gst_buffer_unref(self->priv.h264.codec_data);
  590. }
  591. }
  592. base->skip_hack_2++;
  593. }
  594. }
  595. static inline dmm_buffer_t *
  596. setup_h264params_in(GstDspBase *base)
  597. {
  598. struct h264venc_in_stream_params *in_param;
  599. GstDspVEnc *self = GST_DSP_VENC(base);
  600. dmm_buffer_t *tmp;
  601. tmp = dmm_buffer_new(base->dsp_handle, base->proc);
  602. dmm_buffer_allocate(tmp, sizeof(*in_param));
  603. in_param = tmp->data;
  604. in_param->params_size = sizeof(*in_param);
  605. in_param->input_height = self->height;
  606. in_param->input_width = self->width;
  607. in_param->ref_framerate = self->framerate * 1000;
  608. in_param->target_framerate = self->framerate * 1000;
  609. in_param->target_bitrate = self->bitrate;
  610. in_param->intra_frame_interval = self->framerate;
  611. in_param->generate_header = 0;
  612. in_param->capture_width = 0;
  613. in_param->force_i_frame = 0;
  614. in_param->qp_intra = 0x1c;
  615. in_param->qp_inter = 0x1c;
  616. in_param->qp_max = 0x33;
  617. in_param->qp_min = 0;
  618. in_param->lf_disable_idc = 0;
  619. in_param->quarter_pel_disable = 0;
  620. in_param->air_mb_period = 0;
  621. in_param->max_mbs_per_slice = 3620;
  622. in_param->max_bytes_per_slice = 327680;
  623. in_param->slice_refresh_row_start_number = 0;
  624. in_param->slice_refresh_row_number = 0;
  625. in_param->filter_offset_a = 0;
  626. in_param->filter_offset_b = 0;
  627. in_param->log2MaxFNumMinus4 = 0;
  628. in_param->chroma_qpi_index_offset= 0;
  629. in_param->constrained_intra_pred_enable = 0;
  630. in_param->pic_order_count_type = 0;
  631. in_param->max_mv_per_mb = 4;
  632. in_param->intra_4x4_enable_idc = 2;
  633. in_param->mv_data_enable = 0;
  634. in_param->hier_coding_enable = 0;
  635. in_param->stream_format = 0; /* byte stream */
  636. in_param->intra_refresh_method = 0;
  637. in_param->perceptual_quant = 0;
  638. in_param->scene_change_det = 0;
  639. in_param->nal_callback_func = NULL;
  640. in_param->context = NULL;
  641. in_param->num_slice_aso = 0;
  642. {
  643. int i;
  644. for (i = 0; i < 8; i++)
  645. in_param->aso_slice_order[i] = 0; /* MAXNUMSLCGPS = 8 */
  646. }
  647. in_param->num_slice_groups = 0;
  648. in_param->slice_group_map_type = 0;
  649. in_param->slice_group_change_direction_flag = 0;
  650. in_param->slice_group_change_rate = 0;
  651. in_param->slice_group_change_cycle = 0;
  652. {
  653. int i;
  654. for (i = 0; i < 8; i++)
  655. in_param->slice_group_params[i] = 0; /* MAXNUMSLCGPS = 8 */
  656. }
  657. in_param->frame_index = 0;
  658. dmm_buffer_clean(tmp, sizeof(*in_param));
  659. return tmp;
  660. }
  661. static inline void
  662. setup_h264params(GstDspBase *base)
  663. {
  664. struct h264venc_out_stream_params *out_param;
  665. unsigned int i;
  666. for (i = 0; i < base->ports[0]->num_buffers; i++)
  667. base->ports[0]->params[i] = setup_h264params_in(base);
  668. base->ports[0]->send_cb = h264venc_in_send_cb;
  669. for (i = 0; i < base->ports[1]->num_buffers; i++) {
  670. dmm_buffer_t *tmp;
  671. tmp = dmm_buffer_new(base->dsp_handle, base->proc);
  672. dmm_buffer_allocate(tmp, sizeof(*out_param));
  673. base->ports[1]->params[i] = tmp;
  674. }
  675. base->ports[1]->send_cb = h264venc_out_send_cb;
  676. base->ports[1]->recv_cb = h264venc_out_recv_cb;
  677. }
  678. struct mp4venc_in_stream_params {
  679. uint32_t frame_index;
  680. uint32_t framerate;
  681. uint32_t bitrate;
  682. uint32_t i_frame_interval;
  683. uint32_t generate_header;
  684. uint32_t force_i_frame;
  685. uint32_t resync_interval;
  686. uint32_t hec_interval;
  687. uint32_t air_rate;
  688. uint32_t mir_rate;
  689. uint32_t qp_intra;
  690. uint32_t f_code;
  691. uint32_t half_pel;
  692. uint32_t ac_pred;
  693. uint32_t mv;
  694. uint32_t use_umv;
  695. uint32_t mv_data_enable;
  696. uint32_t resync_data_enable;
  697. uint32_t qp_inter;
  698. uint32_t last_frame;
  699. uint32_t width;
  700. };
  701. struct mp4venc_out_stream_params {
  702. uint32_t bitstream_size;
  703. uint32_t frame_type;
  704. uint32_t mv_data_size;
  705. uint32_t num_packets;
  706. uint8_t mv_data[12960];
  707. uint8_t resync_data[6480];
  708. };
  709. static void
  710. mp4venc_out_send_cb(GstDspBase *base,
  711. du_port_t *port,
  712. dmm_buffer_t *p,
  713. dmm_buffer_t *b)
  714. {
  715. struct mp4venc_out_stream_params *param;
  716. param = p->data;
  717. dmm_buffer_invalidate(p, sizeof(*param));
  718. }
  719. static void
  720. mp4venc_out_recv_cb(GstDspBase *base,
  721. du_port_t *port,
  722. dmm_buffer_t *p,
  723. dmm_buffer_t *b)
  724. {
  725. struct mp4venc_out_stream_params *param;
  726. param = p->data;
  727. g_atomic_int_set(&base->keyframe, param->frame_type == 1);
  728. }
  729. static void
  730. mp4venc_in_send_cb(GstDspBase *base,
  731. du_port_t *port,
  732. dmm_buffer_t *p,
  733. dmm_buffer_t *b)
  734. {
  735. struct mp4venc_in_stream_params *param;
  736. GstDspVEnc *self = GST_DSP_VENC(base);
  737. param = p->data;
  738. param->frame_index = g_atomic_int_exchange_and_add(&self->frame_index, 1);
  739. param->bitrate = g_atomic_int_get(&self->bitrate);
  740. g_mutex_lock(self->keyframe_mutex);
  741. param->force_i_frame = !!self->keyframe_event;
  742. if (self->keyframe_event) {
  743. gst_pad_push_event(base->srcpad, self->keyframe_event);
  744. self->keyframe_event = NULL;
  745. }
  746. g_mutex_unlock(self->keyframe_mutex);
  747. dmm_buffer_clean(p, sizeof(*param));
  748. }
  749. static inline dmm_buffer_t *
  750. setup_mp4param_in(GstDspBase *base)
  751. {
  752. struct mp4venc_in_stream_params *in_param;
  753. GstDspVEnc *self = GST_DSP_VENC(base);
  754. dmm_buffer_t *tmp;
  755. tmp = dmm_buffer_new(base->dsp_handle, base->proc);
  756. dmm_buffer_allocate(tmp, sizeof(*in_param));
  757. in_param = tmp->data;
  758. in_param->frame_index = 0;
  759. in_param->framerate = self->framerate;
  760. in_param->bitrate = self->bitrate;
  761. in_param->i_frame_interval = self->framerate;
  762. in_param->generate_header = 0;
  763. in_param->force_i_frame = 0;
  764. in_param->air_rate = 10;
  765. in_param->mir_rate = 0;
  766. in_param->qp_intra = 8;
  767. in_param->f_code = 6;
  768. in_param->half_pel = 1;
  769. in_param->mv = 0;
  770. in_param->mv_data_enable = 0;
  771. in_param->resync_data_enable = 0;
  772. in_param->qp_inter = 8;
  773. in_param->last_frame = 0;
  774. in_param->width = 0;
  775. if (base->alg == GSTDSP_MP4VENC)
  776. in_param->ac_pred = 1;
  777. else
  778. in_param->ac_pred = 0;
  779. if (self->mode == 0) {
  780. in_param->resync_interval = 0;
  781. in_param->hec_interval = 0;
  782. in_param->use_umv = 1;
  783. } else {
  784. in_param->resync_interval = 1024;
  785. in_param->hec_interval = 3;
  786. in_param->use_umv = 0;
  787. }
  788. dmm_buffer_clean(tmp, sizeof(*in_param));
  789. return tmp;
  790. }
  791. static inline void
  792. setup_mp4params(GstDspBase *base)
  793. {
  794. struct mp4venc_out_stream_params *out_param;
  795. unsigned int i;
  796. for (i = 0; i < base->ports[0]->num_buffers; i++)
  797. base->ports[0]->params[i] = setup_mp4param_in(base);
  798. base->ports[0]->send_cb = mp4venc_in_send_cb;
  799. for (i = 0; i < base->ports[1]->num_buffers; i++) {
  800. dmm_buffer_t *tmp;
  801. tmp = dmm_buffer_new(base->dsp_handle, base->proc);
  802. dmm_buffer_allocate(tmp, sizeof(*out_param));
  803. base->ports[1]->params[i] = tmp;
  804. }
  805. base->ports[1]->send_cb = mp4venc_out_send_cb;
  806. base->ports[1]->recv_cb = mp4venc_out_recv_cb;
  807. }
  808. static inline int calculate_bitrate(GstDspVEnc* self)
  809. {
  810. GstDspBase *base = GST_DSP_BASE(self);
  811. float coeff, scale;
  812. int bitrate, ref_bitrate;
  813. const int reference_fps = 15;
  814. const float twiddle = 1.2;
  815. switch (base->alg) {
  816. case GSTDSP_MP4VENC:
  817. coeff = 0.2;
  818. break;
  819. case GSTDSP_H263ENC:
  820. coeff = 0.3;
  821. break;
  822. case GSTDSP_H264ENC:
  823. coeff = 0.35;
  824. break;
  825. default:
  826. coeff = 0.1;
  827. break;
  828. }
  829. ref_bitrate = (self->width * self->height) / coeff;
  830. scale = 1 + ((float) self->framerate / reference_fps - 1) * twiddle;
  831. bitrate = ref_bitrate * scale;
  832. pr_info(self, "bitrate: %d", bitrate);
  833. return bitrate;
  834. }
  835. static gboolean
  836. sink_setcaps(GstPad *pad,
  837. GstCaps *caps)
  838. {
  839. GstDspVEnc *self;
  840. GstDspBase *base;
  841. GstStructure *in_struc;
  842. GstCaps *out_caps;
  843. GstStructure *out_struc;
  844. gint width = 0, height = 0;
  845. self = GST_DSP_VENC(GST_PAD_PARENT(pad));
  846. base = GST_DSP_BASE(self);
  847. {
  848. gchar *str = gst_caps_to_string(caps);
  849. pr_info(self, "sink caps: %s", str);
  850. g_free(str);
  851. }
  852. in_struc = gst_caps_get_structure(caps, 0);
  853. out_caps = gst_caps_new_empty();
  854. switch (base->alg) {
  855. case GSTDSP_JPEGENC:
  856. out_struc = gst_structure_new("image/jpeg",
  857. NULL);
  858. break;
  859. case GSTDSP_H263ENC:
  860. out_struc = gst_structure_new("video/x-h263",
  861. "variant", G_TYPE_STRING, "itu",
  862. NULL);
  863. break;
  864. case GSTDSP_MP4VENC:
  865. out_struc = gst_structure_new("video/mpeg",
  866. "mpegversion", G_TYPE_INT, 4,
  867. "systemstream", G_TYPE_BOOLEAN, FALSE,
  868. NULL);
  869. break;
  870. case GSTDSP_H264ENC:
  871. out_struc = gst_structure_new("video/x-h264",
  872. NULL);
  873. break;
  874. default:
  875. return FALSE;
  876. }
  877. if (gst_structure_get_int(in_struc, "width", &width))
  878. gst_structure_set(out_struc, "width", G_TYPE_INT, width, NULL);
  879. if (gst_structure_get_int(in_struc, "height", &height))
  880. gst_structure_set(out_struc, "height", G_TYPE_INT, height, NULL);
  881. switch (base->alg) {
  882. case GSTDSP_H263ENC:
  883. case GSTDSP_MP4VENC:
  884. case GSTDSP_H264ENC:
  885. base->output_buffer_size = width * height / 2;
  886. break;
  887. case GSTDSP_JPEGENC:
  888. base->input_buffer_size = ROUND_UP(width, 16) * ROUND_UP(height, 16) * 2;
  889. base->output_buffer_size = width * height;
  890. self->quality = 90;
  891. if (self->quality < 10)
  892. base->output_buffer_size /= 10;
  893. else if (self->quality < 100)
  894. base->output_buffer_size /= (100 / self->quality);
  895. break;
  896. default:
  897. break;
  898. }
  899. self->width = width;
  900. self->height = height;
  901. {
  902. const GValue *framerate = NULL;
  903. framerate = gst_structure_get_value(in_struc, "framerate");
  904. if (framerate) {
  905. gst_structure_set_value(out_struc, "framerate", framerate);
  906. /* calculate nearest integer */
  907. self->framerate = (gst_value_get_fraction_numerator(framerate) * 2 /
  908. gst_value_get_fraction_denominator(framerate) + 1) / 2;
  909. }
  910. }
  911. if (self->bitrate == 0)
  912. self->bitrate = calculate_bitrate(self);
  913. gst_caps_append_structure(out_caps, out_struc);
  914. {
  915. gchar *str = gst_caps_to_string(out_caps);
  916. pr_info(self, "src caps: %s", str);
  917. g_free(str);
  918. }
  919. if (!gst_pad_set_caps(base->srcpad, out_caps))
  920. return FALSE;
  921. base->node = create_node(self);
  922. if (!base->node) {
  923. pr_err(self, "dsp node creation failed");
  924. return FALSE;
  925. }
  926. /* setup stream params */
  927. switch (base->alg) {
  928. case GSTDSP_H263ENC:
  929. case GSTDSP_MP4VENC:
  930. setup_mp4params(base);
  931. break;
  932. case GSTDSP_H264ENC:
  933. setup_h264params(base);
  934. break;
  935. default:
  936. break;
  937. }
  938. if (!gstdsp_start(base)) {
  939. pr_err(self, "dsp start failed");
  940. return FALSE;
  941. }
  942. /* send dynamic params */
  943. switch (base->alg) {
  944. case GSTDSP_JPEGENC:
  945. jpegenc_send_params(base);
  946. break;
  947. default:
  948. break;
  949. }
  950. return TRUE;
  951. }
  952. static gboolean
  953. sink_event(GstDspBase *base,
  954. GstEvent *event)
  955. {
  956. GstDspVEnc *self;
  957. self = GST_DSP_VENC(base);
  958. switch (GST_EVENT_TYPE(event)) {
  959. case GST_EVENT_CUSTOM_DOWNSTREAM:
  960. {
  961. const GstStructure *s;
  962. s = gst_event_get_structure(event);
  963. if (gst_structure_has_name(s, "GstForceKeyUnit")) {
  964. g_mutex_lock(self->keyframe_mutex);
  965. if (self->keyframe_event)
  966. gst_event_unref(self->keyframe_event);
  967. self->keyframe_event = event;
  968. g_mutex_unlock(self->keyframe_mutex);
  969. return TRUE;
  970. }
  971. break;
  972. }
  973. default:
  974. break;
  975. }
  976. if (parent_class->sink_event)
  977. return parent_class->sink_event(base, event);
  978. return gst_pad_push_event(base->srcpad, event);
  979. }
  980. static gboolean
  981. src_event(GstDspBase *base,
  982. GstEvent *event)
  983. {
  984. GstDspVEnc *self;
  985. self = GST_DSP_VENC(base);
  986. switch (GST_EVENT_TYPE(event)) {
  987. case GST_EVENT_CUSTOM_UPSTREAM:
  988. {
  989. const GstStructure *s;
  990. s = gst_event_get_structure(event);
  991. if (gst_structure_has_name(s, "GstForceKeyUnit")) {
  992. g_mutex_lock(self->keyframe_mutex);
  993. /* make it downstream */
  994. GST_EVENT_TYPE(event) = GST_EVENT_CUSTOM_DOWNSTREAM;
  995. if (self->keyframe_event)
  996. gst_event_unref(self->keyframe_event);
  997. self->keyframe_event = event;
  998. g_mutex_unlock(self->keyframe_mutex);
  999. return TRUE;
  1000. }
  1001. break;
  1002. }
  1003. default:
  1004. break;
  1005. }
  1006. if (parent_class->src_event)
  1007. return parent_class->src_event(base, event);
  1008. return gst_pad_push_event(base->sinkpad, event);
  1009. }
  1010. static void
  1011. set_property(GObject *obj,
  1012. guint prop_id,
  1013. const GValue *value,
  1014. GParamSpec *pspec)
  1015. {
  1016. GstDspVEnc *self;
  1017. self = GST_DSP_VENC(obj);
  1018. switch (prop_id) {
  1019. case ARG_BITRATE:
  1020. g_atomic_int_set(&self->bitrate, g_value_get_uint(value));
  1021. break;
  1022. case ARG_MODE:
  1023. g_atomic_int_set(&self->mode, g_value_get_enum(value));
  1024. break;
  1025. default:
  1026. G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
  1027. break;
  1028. }
  1029. }
  1030. static void
  1031. get_property(GObject *obj,
  1032. guint prop_id,
  1033. GValue *value,
  1034. GParamSpec *pspec)
  1035. {
  1036. GstDspVEnc *self;
  1037. self = GST_DSP_VENC(obj);
  1038. switch (prop_id) {
  1039. case ARG_BITRATE:
  1040. g_value_set_uint(value, g_atomic_int_get(&self->bitrate));
  1041. break;
  1042. case ARG_MODE:
  1043. g_value_set_enum(value, g_atomic_int_get(&self->mode));
  1044. break;
  1045. default:
  1046. G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
  1047. break;
  1048. }
  1049. }
  1050. static void
  1051. instance_init(GTypeInstance *instance,
  1052. gpointer g_class)
  1053. {
  1054. GstDspBase *base;
  1055. GstDspVEnc *self;
  1056. base = GST_DSP_BASE(instance);
  1057. self = GST_DSP_VENC(instance);
  1058. base->ports[0] = du_port_new(0, 2);
  1059. base->ports[1] = du_port_new(1, 2);
  1060. gst_pad_set_setcaps_function(base->sinkpad, sink_setcaps);
  1061. self->bitrate = DEFAULT_BITRATE;
  1062. self->keyframe_mutex = g_mutex_new();
  1063. }
  1064. static void
  1065. finalize(GObject *obj)
  1066. {
  1067. GstDspVEnc *self = GST_DSP_VENC(obj);
  1068. g_mutex_free(self->keyframe_mutex);
  1069. if (self->keyframe_event)
  1070. gst_event_unref(self->keyframe_event);
  1071. G_OBJECT_CLASS(parent_class)->finalize(obj);
  1072. }
  1073. static void
  1074. base_init(gpointer g_class)
  1075. {
  1076. GstElementClass *element_class;
  1077. GstPadTemplate *template;
  1078. element_class = GST_ELEMENT_CLASS(g_class);
  1079. template = gst_pad_template_new("sink", GST_PAD_SINK,
  1080. GST_PAD_ALWAYS,
  1081. generate_sink_template());
  1082. gst_element_class_add_pad_template(element_class, template);
  1083. gst_object_unref(template);
  1084. }
  1085. static void
  1086. class_init(gpointer g_class,
  1087. gpointer class_data)
  1088. {
  1089. GObjectClass *gobject_class;
  1090. GstDspBaseClass *base_class;
  1091. parent_class = g_type_class_peek_parent(g_class);
  1092. gobject_class = G_OBJECT_CLASS(g_class);
  1093. base_class = GST_DSP_BASE_CLASS(g_class);
  1094. gobject_class->set_property = set_property;
  1095. gobject_class->get_property = get_property;
  1096. g_object_class_install_property(gobject_class, ARG_BITRATE,
  1097. g_param_spec_uint("bitrate", "Bit-rate",
  1098. "Encoding bit-rate (0 for auto)",
  1099. 0, G_MAXUINT, DEFAULT_BITRATE,
  1100. G_PARAM_READWRITE));
  1101. g_object_class_install_property(gobject_class, ARG_MODE,
  1102. g_param_spec_enum("mode", "Encoding mode",
  1103. "Encoding mode",
  1104. GST_TYPE_DSPVENC_MODE,
  1105. DEFAULT_MODE,
  1106. G_PARAM_READWRITE));
  1107. gobject_class->finalize = finalize;
  1108. base_class->src_event = src_event;
  1109. base_class->sink_event = sink_event;
  1110. }
  1111. GType
  1112. gst_dsp_venc_get_type(void)
  1113. {
  1114. static GType type = 0;
  1115. if (G_UNLIKELY(type == 0)) {
  1116. GTypeInfo type_info = {
  1117. .class_size = sizeof(GstDspVEncClass),
  1118. .class_init = class_init,
  1119. .base_init = base_init,
  1120. .instance_size = sizeof(GstDspVEnc),
  1121. .instance_init = instance_init,
  1122. };
  1123. type = g_type_register_static(GST_DSP_BASE_TYPE, "GstDspVEnc", &type_info, 0);
  1124. }
  1125. return type;
  1126. }