gstdspvenc.c 36 KB

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