1 /**
2  * @file avcodec/encode.c  Video codecs using libavcodec -- encoder
3  *
4  * Copyright (C) 2010 - 2013 Creytiv.com
5  */
6 #include <re.h>
7 #include <rem.h>
8 #include <baresip.h>
9 #include <libavcodec/avcodec.h>
10 #include <libavutil/mem.h>
11 #if LIBAVUTIL_VERSION_INT >= ((50<<16)+(29<<8)+0)
12 #include <libavutil/opt.h>
13 #else
14 #include <libavcodec/opt.h>
15 #endif
16 #ifdef USE_X264
17 #include <x264.h>
18 #endif
19 #include "h26x.h"
20 #include "avcodec.h"
21 
22 
23 #if LIBAVUTIL_VERSION_MAJOR < 52
24 #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
25 #define AV_PIX_FMT_NV12    PIX_FMT_NV12
26 #endif
27 
28 
29 #ifndef AV_INPUT_BUFFER_MIN_SIZE
30 #define AV_INPUT_BUFFER_MIN_SIZE FF_MIN_BUFFER_SIZE
31 #endif
32 
33 
34 enum {
35 	DEFAULT_GOP_SIZE =   10,
36 };
37 
38 
39 struct picsz {
40 	enum h263_fmt fmt;  /**< Picture size */
41 	uint8_t mpi;        /**< Minimum Picture Interval (1-32) */
42 };
43 
44 
45 struct videnc_state {
46 	AVCodec *codec;
47 	AVCodecContext *ctx;
48 	AVFrame *pict;
49 	struct mbuf *mb;
50 	size_t sz_max; /* todo: figure out proper buffer size */
51 	int64_t pts;
52 	struct mbuf *mb_frag;
53 	struct videnc_param encprm;
54 	struct vidsz encsize;
55 	enum AVCodecID codec_id;
56 	videnc_packet_h *pkth;
57 	void *arg;
58 
59 	union {
60 		struct {
61 			struct picsz picszv[8];
62 			uint32_t picszn;
63 		} h263;
64 
65 		struct {
66 			uint32_t packetization_mode;
67 			uint32_t profile_idc;
68 			uint32_t profile_iop;
69 			uint32_t level_idc;
70 			uint32_t max_fs;
71 			uint32_t max_smbps;
72 		} h264;
73 	} u;
74 
75 #ifdef USE_X264
76 	x264_t *x264;
77 #endif
78 };
79 
80 
destructor(void * arg)81 static void destructor(void *arg)
82 {
83 	struct videnc_state *st = arg;
84 
85 	mem_deref(st->mb);
86 	mem_deref(st->mb_frag);
87 
88 #ifdef USE_X264
89 	if (st->x264)
90 		x264_encoder_close(st->x264);
91 #endif
92 
93 	if (st->ctx) {
94 		if (st->ctx->codec)
95 			avcodec_close(st->ctx);
96 #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
97 		av_opt_free(st->ctx);
98 #endif
99 		av_free(st->ctx);
100 	}
101 
102 	if (st->pict)
103 		av_free(st->pict);
104 }
105 
106 
h263_fmt(const struct pl * name)107 static enum h263_fmt h263_fmt(const struct pl *name)
108 {
109 	if (0 == pl_strcasecmp(name, "sqcif")) return H263_FMT_SQCIF;
110 	if (0 == pl_strcasecmp(name, "qcif"))  return H263_FMT_QCIF;
111 	if (0 == pl_strcasecmp(name, "cif"))   return H263_FMT_CIF;
112 	if (0 == pl_strcasecmp(name, "cif4"))  return H263_FMT_4CIF;
113 	if (0 == pl_strcasecmp(name, "cif16")) return H263_FMT_16CIF;
114 	return H263_FMT_OTHER;
115 }
116 
117 
decode_sdpparam_h263(struct videnc_state * st,const struct pl * name,const struct pl * val)118 static int decode_sdpparam_h263(struct videnc_state *st, const struct pl *name,
119 				const struct pl *val)
120 {
121 	enum h263_fmt fmt = h263_fmt(name);
122 	const int mpi = pl_u32(val);
123 
124 	if (fmt == H263_FMT_OTHER) {
125 		info("h263: unknown param '%r'\n", name);
126 		return 0;
127 	}
128 	if (mpi < 1 || mpi > 32) {
129 		info("h263: %r: MPI out of range %d\n", name, mpi);
130 		return 0;
131 	}
132 
133 	if (st->u.h263.picszn >= ARRAY_SIZE(st->u.h263.picszv)) {
134 		info("h263: picszv overflow: %r\n", name);
135 		return 0;
136 	}
137 
138 	st->u.h263.picszv[st->u.h263.picszn].fmt = fmt;
139 	st->u.h263.picszv[st->u.h263.picszn].mpi = mpi;
140 
141 	++st->u.h263.picszn;
142 
143 	return 0;
144 }
145 
146 
init_encoder(struct videnc_state * st)147 static int init_encoder(struct videnc_state *st)
148 {
149 	/*
150 	 * Special handling of H.264 encoder
151 	 */
152 	if (st->codec_id == AV_CODEC_ID_H264 && avcodec_h264enc) {
153 
154 #ifdef USE_X264
155 		warning("avcodec: h264enc specified, but using libx264\n");
156 		return EINVAL;
157 #else
158 		st->codec = avcodec_h264enc;
159 
160 		info("avcodec: h264 encoder activated\n");
161 
162 		return 0;
163 #endif
164 	}
165 
166 	st->codec = avcodec_find_encoder(st->codec_id);
167 	if (!st->codec)
168 		return ENOENT;
169 
170 	return 0;
171 }
172 
173 
open_encoder(struct videnc_state * st,const struct videnc_param * prm,const struct vidsz * size,int pix_fmt)174 static int open_encoder(struct videnc_state *st,
175 			const struct videnc_param *prm,
176 			const struct vidsz *size,
177 			int pix_fmt)
178 {
179 	int err = 0;
180 
181 	if (st->ctx) {
182 		if (st->ctx->codec)
183 			avcodec_close(st->ctx);
184 #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
185 		av_opt_free(st->ctx);
186 #endif
187 		av_free(st->ctx);
188 	}
189 
190 	if (st->pict)
191 		av_free(st->pict);
192 
193 #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(92<<8)+0)
194 	st->ctx = avcodec_alloc_context3(st->codec);
195 #else
196 	st->ctx = avcodec_alloc_context();
197 #endif
198 
199 #if LIBAVUTIL_VERSION_INT >= ((52<<16)+(20<<8)+100)
200 	st->pict = av_frame_alloc();
201 #else
202 	st->pict = avcodec_alloc_frame();
203 #endif
204 
205 	if (!st->ctx || !st->pict) {
206 		err = ENOMEM;
207 		goto out;
208 	}
209 
210 	av_opt_set_defaults(st->ctx);
211 
212 	st->ctx->bit_rate  = prm->bitrate;
213 	st->ctx->width     = size->w;
214 	st->ctx->height    = size->h;
215 	st->ctx->gop_size  = DEFAULT_GOP_SIZE;
216 	st->ctx->pix_fmt   = pix_fmt;
217 	st->ctx->time_base.num = 1;
218 	st->ctx->time_base.den = prm->fps;
219 
220 	/* params to avoid libavcodec/x264 default preset error */
221 	if (st->codec_id == AV_CODEC_ID_H264) {
222 		st->ctx->me_range = 16;
223 		st->ctx->qmin = 10;
224 		st->ctx->qmax = 51;
225 		st->ctx->max_qdiff = 4;
226 
227 #ifndef USE_X264
228 		if (st->codec == avcodec_find_encoder_by_name("nvenc_h264") ||
229 		st->codec == avcodec_find_encoder_by_name("h264_nvenc")) {
230 
231 #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(21<<8)+0)
232 			err = av_opt_set(st->ctx->priv_data,
233 				"preset", "llhp", 0);
234 
235 			if (err < 0) {
236 				debug("avcodec: h264 nvenc setting preset "
237 					"\"llhp\" failed; error: %u\n", err);
238 			}
239 			else {
240 				debug("avcodec: h264 nvenc preset "
241 					"\"llhp\" selected\n");
242 			}
243 			err = av_opt_set_int(st->ctx->priv_data,
244 				"2pass", 1, 0);
245 
246 			if (err < 0) {
247 				debug("avcodec: h264 nvenc option "
248 					"\"2pass\" failed; error: %u\n", err);
249 			}
250 			else {
251 				debug("avcodec: h264 nvenc option "
252 					"\"2pass\" selected\n");
253 			}
254 #endif
255 		}
256 #endif
257 	}
258 
259 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
260 	if (avcodec_open2(st->ctx, st->codec, NULL) < 0) {
261 		err = ENOENT;
262 		goto out;
263 	}
264 #else
265 	if (avcodec_open(st->ctx, st->codec) < 0) {
266 		err = ENOENT;
267 		goto out;
268 	}
269 #endif
270 
271 #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(5<<8)+0)
272 	st->pict->format = pix_fmt;
273 	st->pict->width = size->w;
274 	st->pict->height = size->h;
275 #endif
276 
277  out:
278 	if (err) {
279 		if (st->ctx) {
280 			if (st->ctx->codec)
281 				avcodec_close(st->ctx);
282 #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(8<<8)+0)
283 			av_opt_free(st->ctx);
284 #endif
285 			av_free(st->ctx);
286 			st->ctx = NULL;
287 		}
288 
289 		if (st->pict) {
290 			av_free(st->pict);
291 			st->pict = NULL;
292 		}
293 	}
294 	else
295 		st->encsize = *size;
296 
297 	return err;
298 }
299 
300 
decode_sdpparam_h264(struct videnc_state * st,const struct pl * name,const struct pl * val)301 int decode_sdpparam_h264(struct videnc_state *st, const struct pl *name,
302 			 const struct pl *val)
303 {
304 	if (0 == pl_strcasecmp(name, "packetization-mode")) {
305 		st->u.h264.packetization_mode = pl_u32(val);
306 
307 		if (st->u.h264.packetization_mode != 0) {
308 			warning("avcodec: illegal packetization-mode %u\n",
309 				st->u.h264.packetization_mode);
310 			return EPROTO;
311 		}
312 	}
313 	else if (0 == pl_strcasecmp(name, "profile-level-id")) {
314 		struct pl prof = *val;
315 		if (prof.l != 6) {
316 			warning("avcodec: invalid profile-level-id (%r)\n",
317 				val);
318 			return EPROTO;
319 		}
320 
321 		prof.l = 2;
322 		st->u.h264.profile_idc = pl_x32(&prof); prof.p += 2;
323 		st->u.h264.profile_iop = pl_x32(&prof); prof.p += 2;
324 		st->u.h264.level_idc   = pl_x32(&prof);
325 	}
326 	else if (0 == pl_strcasecmp(name, "max-fs")) {
327 		st->u.h264.max_fs = pl_u32(val);
328 	}
329 	else if (0 == pl_strcasecmp(name, "max-smbps")) {
330 		st->u.h264.max_smbps = pl_u32(val);
331 	}
332 
333 	return 0;
334 }
335 
336 
param_handler(const struct pl * name,const struct pl * val,void * arg)337 static void param_handler(const struct pl *name, const struct pl *val,
338 			  void *arg)
339 {
340 	struct videnc_state *st = arg;
341 
342 	if (st->codec_id == AV_CODEC_ID_H263)
343 		(void)decode_sdpparam_h263(st, name, val);
344 	else if (st->codec_id == AV_CODEC_ID_H264)
345 		(void)decode_sdpparam_h264(st, name, val);
346 }
347 
348 
general_packetize(uint32_t rtp_ts,struct mbuf * mb,size_t pktsize,videnc_packet_h * pkth,void * arg)349 static int general_packetize(uint32_t rtp_ts, struct mbuf *mb, size_t pktsize,
350 			     videnc_packet_h *pkth, void *arg)
351 {
352 	int err = 0;
353 
354 	/* Assemble frame into smaller packets */
355 	while (!err) {
356 		size_t sz, left = mbuf_get_left(mb);
357 		bool last = (left < pktsize);
358 		if (!left)
359 			break;
360 
361 		sz = last ? left : pktsize;
362 
363 		err = pkth(last, rtp_ts, NULL, 0, mbuf_buf(mb), sz,
364 			   arg);
365 
366 		mbuf_advance(mb, sz);
367 	}
368 
369 	return err;
370 }
371 
372 
h263_packetize(struct videnc_state * st,uint32_t rtp_ts,struct mbuf * mb,videnc_packet_h * pkth,void * arg)373 static int h263_packetize(struct videnc_state *st,
374 			  uint32_t rtp_ts, struct mbuf *mb,
375 			  videnc_packet_h *pkth, void *arg)
376 {
377 	struct h263_strm h263_strm;
378 	struct h263_hdr h263_hdr;
379 	size_t pos;
380 	int err;
381 
382 	/* Decode bit-stream header, used by packetizer */
383 	err = h263_strm_decode(&h263_strm, mb);
384 	if (err)
385 		return err;
386 
387 	h263_hdr_copy_strm(&h263_hdr, &h263_strm);
388 
389 	st->mb_frag->pos = st->mb_frag->end = 0;
390 	err = h263_hdr_encode(&h263_hdr, st->mb_frag);
391 	pos = st->mb_frag->pos;
392 
393 	/* Assemble frame into smaller packets */
394 	while (!err) {
395 		size_t sz, left = mbuf_get_left(mb);
396 		bool last = (left < st->encprm.pktsize);
397 		if (!left)
398 			break;
399 
400 		sz = last ? left : st->encprm.pktsize;
401 
402 		st->mb_frag->pos = st->mb_frag->end = pos;
403 		err = mbuf_write_mem(st->mb_frag, mbuf_buf(mb), sz);
404 		if (err)
405 			break;
406 
407 		st->mb_frag->pos = 0;
408 
409 		err = pkth(last, rtp_ts, NULL, 0, mbuf_buf(st->mb_frag),
410 			   mbuf_get_left(st->mb_frag), arg);
411 
412 		mbuf_advance(mb, sz);
413 	}
414 
415 	return err;
416 }
417 
418 
419 #ifdef USE_X264
open_encoder_x264(struct videnc_state * st,struct videnc_param * prm,const struct vidsz * size,int csp)420 static int open_encoder_x264(struct videnc_state *st, struct videnc_param *prm,
421 			     const struct vidsz *size, int csp)
422 {
423 	x264_param_t xprm;
424 
425 	if (x264_param_default_preset(&xprm, "ultrafast", "zerolatency"))
426 		return ENOSYS;
427 
428 	x264_param_apply_profile(&xprm, "baseline");
429 
430 	xprm.i_level_idc = h264_level_idc;
431 	xprm.i_width = size->w;
432 	xprm.i_height = size->h;
433 	xprm.i_csp = csp;
434 	xprm.i_fps_num = prm->fps;
435 	xprm.i_fps_den = 1;
436 	xprm.rc.i_bitrate = prm->bitrate / 1000; /* kbit/s */
437 	xprm.rc.i_rc_method = X264_RC_ABR;
438 	xprm.i_log_level = X264_LOG_WARNING;
439 
440 	/* ultrafast preset */
441 	xprm.i_frame_reference = 1;
442 	xprm.i_scenecut_threshold = 0;
443 	xprm.b_deblocking_filter = 0;
444 	xprm.b_cabac = 0;
445 	xprm.i_bframe = 0;
446 	xprm.analyse.intra = 0;
447 	xprm.analyse.inter = 0;
448 	xprm.analyse.b_transform_8x8 = 0;
449 	xprm.analyse.i_me_method = X264_ME_DIA;
450 	xprm.analyse.i_subpel_refine = 0;
451 #if X264_BUILD >= 59
452 	xprm.rc.i_aq_mode = 0;
453 #endif
454 	xprm.analyse.b_mixed_references = 0;
455 	xprm.analyse.i_trellis = 0;
456 #if X264_BUILD >= 63
457 	xprm.i_bframe_adaptive = X264_B_ADAPT_NONE;
458 #endif
459 #if X264_BUILD >= 70
460 	xprm.rc.b_mb_tree = 0;
461 #endif
462 
463 	/* slice-based threading (--tune=zerolatency) */
464 #if X264_BUILD >= 80
465 	xprm.rc.i_lookahead = 0;
466 	xprm.i_sync_lookahead = 0;
467 	xprm.i_bframe = 0;
468 #endif
469 
470 	/* put SPS/PPS before each keyframe */
471 	xprm.b_repeat_headers = 1;
472 
473 #if X264_BUILD >= 82
474 	/* needed for x264_encoder_intra_refresh() */
475 	xprm.b_intra_refresh = 1;
476 #endif
477 
478 	if (st->x264)
479 		x264_encoder_close(st->x264);
480 
481 	st->x264 = x264_encoder_open(&xprm);
482 	if (!st->x264) {
483 		warning("avcodec: x264_encoder_open() failed\n");
484 		return ENOENT;
485 	}
486 
487 	st->encsize = *size;
488 
489 	return 0;
490 }
491 #endif
492 
493 
encode_update(struct videnc_state ** vesp,const struct vidcodec * vc,struct videnc_param * prm,const char * fmtp,videnc_packet_h * pkth,void * arg)494 int encode_update(struct videnc_state **vesp, const struct vidcodec *vc,
495 		  struct videnc_param *prm, const char *fmtp,
496 		  videnc_packet_h *pkth, void *arg)
497 {
498 	struct videnc_state *st;
499 	int err = 0;
500 
501 	if (!vesp || !vc || !prm || !pkth)
502 		return EINVAL;
503 
504 	if (*vesp)
505 		return 0;
506 
507 	st = mem_zalloc(sizeof(*st), destructor);
508 	if (!st)
509 		return ENOMEM;
510 
511 	st->encprm = *prm;
512 	st->pkth = pkth;
513 	st->arg = arg;
514 
515 	st->codec_id = avcodec_resolve_codecid(vc->name);
516 	if (st->codec_id == AV_CODEC_ID_NONE) {
517 		err = EINVAL;
518 		goto out;
519 	}
520 
521 	st->mb  = mbuf_alloc(AV_INPUT_BUFFER_MIN_SIZE * 20);
522 	st->mb_frag = mbuf_alloc(1024);
523 	if (!st->mb || !st->mb_frag) {
524 		err = ENOMEM;
525 		goto out;
526 	}
527 
528 	st->sz_max = st->mb->size;
529 
530 	if (st->codec_id == AV_CODEC_ID_H264) {
531 #ifndef USE_X264
532 		err = init_encoder(st);
533 #endif
534 	}
535 	else
536 		err = init_encoder(st);
537 	if (err) {
538 		warning("avcodec: %s: could not init encoder\n", vc->name);
539 		goto out;
540 	}
541 
542 	if (str_isset(fmtp)) {
543 		struct pl sdp_fmtp;
544 
545 		pl_set_str(&sdp_fmtp, fmtp);
546 
547 		fmt_param_apply(&sdp_fmtp, param_handler, st);
548 	}
549 
550 	debug("avcodec: video encoder %s: %d fps, %d bit/s, pktsize=%u\n",
551 	      vc->name, prm->fps, prm->bitrate, prm->pktsize);
552 
553  out:
554 	if (err)
555 		mem_deref(st);
556 	else
557 		*vesp = st;
558 
559 	return err;
560 }
561 
562 
563 #ifdef USE_X264
encode_x264(struct videnc_state * st,bool update,const struct vidframe * frame)564 int encode_x264(struct videnc_state *st, bool update,
565 		const struct vidframe *frame)
566 {
567 	x264_picture_t pic_in, pic_out;
568 	x264_nal_t *nal;
569 	int i_nal;
570 	int i, err, ret;
571 	int csp, pln;
572 	uint32_t ts;
573 
574 	if (!st || !frame)
575 		return EINVAL;
576 
577 	switch (frame->fmt) {
578 
579 	case VID_FMT_YUV420P:
580 		csp = X264_CSP_I420;
581 		pln = 3;
582 		break;
583 
584 	case VID_FMT_NV12:
585 		csp = X264_CSP_NV12;
586 		pln = 2;
587 		break;
588 
589 	case VID_FMT_YUV444P:
590 		csp = X264_CSP_I444;
591 		pln = 3;
592 		break;
593 
594 	default:
595 		warning("avcodec: pixel format not supported (%s)\n",
596 			vidfmt_name(frame->fmt));
597 		return ENOTSUP;
598 	}
599 
600 	if (!st->x264 || !vidsz_cmp(&st->encsize, &frame->size)) {
601 
602 		err = open_encoder_x264(st, &st->encprm, &frame->size, csp);
603 		if (err)
604 			return err;
605 	}
606 
607 	if (update) {
608 #if X264_BUILD >= 95
609 		x264_encoder_intra_refresh(st->x264);
610 #endif
611 		debug("avcodec: x264 picture update\n");
612 	}
613 
614 	x264_picture_init(&pic_in);
615 
616 	pic_in.i_type = update ? X264_TYPE_IDR : X264_TYPE_AUTO;
617 	pic_in.i_qpplus1 = 0;
618 	pic_in.i_pts = ++st->pts;
619 
620 	pic_in.img.i_csp = csp;
621 	pic_in.img.i_plane = pln;
622 	for (i=0; i<pln; i++) {
623 		pic_in.img.i_stride[i] = frame->linesize[i];
624 		pic_in.img.plane[i]    = frame->data[i];
625 	}
626 
627 	ret = x264_encoder_encode(st->x264, &nal, &i_nal, &pic_in, &pic_out);
628 	if (ret < 0) {
629 		warning("avcodec: x264 [error]: x264_encoder_encode failed\n");
630 	}
631 	if (i_nal == 0)
632 		return 0;
633 
634 	ts = video_calc_rtp_timestamp(pic_out.i_pts, st->encprm.fps);
635 
636 	err = 0;
637 	for (i=0; i<i_nal && !err; i++) {
638 		const uint8_t hdr = nal[i].i_ref_idc<<5 | nal[i].i_type<<0;
639 		int offset = 0;
640 
641 #if X264_BUILD >= 76
642 		const uint8_t *p = nal[i].p_payload;
643 
644 		/* Find the NAL Escape code [00 00 01] */
645 		if (nal[i].i_payload > 4 && p[0] == 0x00 && p[1] == 0x00) {
646 			if (p[2] == 0x00 && p[3] == 0x01)
647 				offset = 4 + 1;
648 			else if (p[2] == 0x01)
649 				offset = 3 + 1;
650 		}
651 #endif
652 
653 		/* skip Supplemental Enhancement Information (SEI) */
654 		if (nal[i].i_type == H264_NAL_SEI)
655 			continue;
656 
657 		err = h264_nal_send(true, true, (i+1)==i_nal, hdr, ts,
658 				    nal[i].p_payload + offset,
659 				    nal[i].i_payload - offset,
660 				    st->encprm.pktsize,
661 				    st->pkth, st->arg);
662 	}
663 
664 	return err;
665 }
666 #endif
667 
668 
encode(struct videnc_state * st,bool update,const struct vidframe * frame)669 int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
670 {
671 	int i, err, ret;
672 	int pix_fmt;
673 	uint32_t ts;
674 
675 	if (!st || !frame)
676 		return EINVAL;
677 
678 	switch (frame->fmt) {
679 
680 	case VID_FMT_YUV420P:
681 		pix_fmt = AV_PIX_FMT_YUV420P;
682 		break;
683 
684 	case VID_FMT_NV12:
685 		pix_fmt = AV_PIX_FMT_NV12;
686 		break;
687 
688 	case VID_FMT_YUV444P:
689 		pix_fmt = AV_PIX_FMT_YUV444P;
690 		break;
691 
692 	default:
693 		warning("avcodec: pixel format not supported (%s)\n",
694 			vidfmt_name(frame->fmt));
695 		return ENOTSUP;
696 	}
697 
698 	if (!st->ctx || !vidsz_cmp(&st->encsize, &frame->size)) {
699 
700 		err = open_encoder(st, &st->encprm, &frame->size, pix_fmt);
701 		if (err) {
702 			warning("avcodec: open_encoder: %m\n", err);
703 			return err;
704 		}
705 	}
706 
707 	for (i=0; i<4; i++) {
708 		st->pict->data[i]     = frame->data[i];
709 		st->pict->linesize[i] = frame->linesize[i];
710 	}
711 	st->pict->pts = st->pts++;
712 	if (update) {
713 		debug("avcodec: encoder picture update\n");
714 		st->pict->key_frame = 1;
715 #ifdef FF_I_TYPE
716 		st->pict->pict_type = FF_I_TYPE;  /* Infra Frame */
717 #else
718 		st->pict->pict_type = AV_PICTURE_TYPE_I;
719 #endif
720 	}
721 	else {
722 		st->pict->key_frame = 0;
723 		st->pict->pict_type = 0;
724 	}
725 
726 	mbuf_rewind(st->mb);
727 
728 #if LIBAVCODEC_VERSION_INT >= ((57<<16)+(37<<8)+100)
729 	do {
730 		AVPacket *pkt;
731 
732 		ret = avcodec_send_frame(st->ctx, st->pict);
733 		if (ret < 0)
734 			return EBADMSG;
735 
736 		pkt = av_packet_alloc();
737 		if (!pkt)
738 			return ENOMEM;
739 
740 		ret = avcodec_receive_packet(st->ctx, pkt);
741 		if (ret < 0) {
742 			av_packet_free(&pkt);
743 			return 0;
744 		}
745 
746 		ts = video_calc_rtp_timestamp(pkt->dts, st->encprm.fps);
747 
748 		err = mbuf_write_mem(st->mb, pkt->data, pkt->size);
749 		st->mb->pos = 0;
750 
751 		av_packet_free(&pkt);
752 
753 		if (err)
754 			return err;
755 	} while (0);
756 #elif LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0)
757 	do {
758 		AVPacket avpkt;
759 		int got_packet;
760 
761 		av_init_packet(&avpkt);
762 
763 		avpkt.data = st->mb->buf;
764 		avpkt.size = (int)st->mb->size;
765 
766 		ret = avcodec_encode_video2(st->ctx, &avpkt,
767 					    st->pict, &got_packet);
768 		if (ret < 0)
769 			return EBADMSG;
770 		if (!got_packet)
771 			return 0;
772 
773 		mbuf_set_end(st->mb, avpkt.size);
774 
775 		ts = video_calc_rtp_timestamp(avpkt.dts, st->encprm.fps);
776 
777 	} while (0);
778 #else
779 	ret = avcodec_encode_video(st->ctx, st->mb->buf,
780 				   (int)st->mb->size, st->pict);
781 	if (ret < 0 )
782 		return EBADMSG;
783 
784 	/* todo: figure out proper buffer size */
785 	if (ret > (int)st->sz_max) {
786 		debug("avcodec: grow encode buffer %u --> %d\n",
787 		      st->sz_max, ret);
788 		st->sz_max = ret;
789 	}
790 
791 	mbuf_set_end(st->mb, ret);
792 
793 	ts = video_calc_rtp_timestamp(st->pict->pts, st->encprm.fps);
794 #endif
795 
796 	switch (st->codec_id) {
797 
798 	case AV_CODEC_ID_H263:
799 		err = h263_packetize(st, ts, st->mb, st->pkth, st->arg);
800 		break;
801 
802 	case AV_CODEC_ID_H264:
803 		err = h264_packetize(ts, st->mb->buf, st->mb->end,
804 				     st->encprm.pktsize,
805 				     st->pkth, st->arg);
806 		break;
807 
808 	case AV_CODEC_ID_MPEG4:
809 		err = general_packetize(ts, st->mb, st->encprm.pktsize,
810 					st->pkth, st->arg);
811 		break;
812 
813 	default:
814 		err = EPROTO;
815 		break;
816 	}
817 
818 	return err;
819 }
820