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