1 /*
2  * iaxclient: a cross-platform IAX softphone library
3  *
4  * Copyrights:
5  * Copyright (C) 2003-2006, Horizon Wimba, Inc.
6  * Copyright (C) 2007, Wimba, Inc.
7  *
8  * Contributors:
9  * Steve Kann <stevek@stevek.com>
10  * Peter Grayson <jpgrayson@gmail.com>
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU Lesser (Library) General Public License.
14  *
15  * A video codec using the ffmpeg library.
16  *
17  * TODO: this code still uses its own slicing mechanism
18  * It should be converted to use the API provided in slice.[ch]
19  */
20 
21 #include <stdlib.h>
22 
23 #include "codec_ffmpeg.h"
24 #include "iaxclient_lib.h"
25 
26 #ifdef WIN32
27 #include "libavcodec/avcodec.h"
28 #else
29 #include <ffmpeg/avcodec.h>
30 #endif
31 
32 struct slice_header_t
33 {
34 	unsigned char version;
35 	unsigned short source_id;
36 	unsigned char frame_index;
37 	unsigned char slice_index;
38 	unsigned char num_slices;
39 };
40 
41 struct encoder_ctx
42 {
43 	AVCodecContext * avctx;
44 	AVFrame * picture;
45 
46 	struct slice_header_t slice_header;
47 
48 	unsigned char *frame_buf;
49 	int frame_buf_len;
50 };
51 
52 struct decoder_ctx
53 {
54 	AVCodecContext * avctx;
55 	AVFrame * picture;
56 
57 	struct slice_header_t slice_header;
58 	int frame_size;
59 
60 	unsigned char * frame_buf;
61 	int frame_buf_len;
62 };
63 
64 static struct slice_set_t * g_slice_set = 0;
65 
map_iaxc_codec_to_avcodec(int format)66 static enum CodecID map_iaxc_codec_to_avcodec(int format)
67 {
68 	switch (format)
69 	{
70 	case IAXC_FORMAT_H261:
71 		return CODEC_ID_H261;
72 
73 	case IAXC_FORMAT_H263:
74 		return CODEC_ID_H263;
75 
76 	case IAXC_FORMAT_H263_PLUS:
77 		return CODEC_ID_H263P;
78 
79 	case IAXC_FORMAT_MPEG4:
80 		return CODEC_ID_MPEG4;
81 
82 	case IAXC_FORMAT_H264:
83 		return CODEC_ID_H264;
84 
85 	case IAXC_FORMAT_THEORA:
86 		return CODEC_ID_THEORA;
87 
88 	default:
89 		return CODEC_ID_NONE;
90 	}
91 }
92 
destroy(struct iaxc_video_codec * c)93 static void destroy(struct iaxc_video_codec *c)
94 {
95 	if (c)
96 	{
97 		struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
98 		struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
99 
100 		if (e)
101 		{
102 			av_freep(&e->avctx);
103 			av_freep(&e->picture);
104 			if (e->frame_buf)
105 				free(e->frame_buf);
106 			free(e);
107 		}
108 
109 		if (d)
110 		{
111 			av_freep(&d->avctx);
112 			av_freep(&d->picture);
113 			if (d->frame_buf)
114 				free(d->frame_buf);
115 			free(d);
116 		}
117 
118 		free(c);
119 	}
120 }
121 
reset_decoder_frame_state(struct decoder_ctx * d)122 static void reset_decoder_frame_state(struct decoder_ctx * d)
123 {
124 	memset(d->frame_buf, 0, d->frame_buf_len);
125 	d->frame_size = 0;
126 	d->slice_header.slice_index = 0;
127 }
128 
frame_to_frame_xlate(AVCodecContext * avctx,AVFrame * picture,int * outlen,char * out)129 static int frame_to_frame_xlate(AVCodecContext * avctx, AVFrame * picture,
130 		int * outlen, char * out)
131 {
132 	int line;
133 
134 	*outlen = avctx->width * avctx->height * 6 / 4;
135 
136 	for ( line = 0; line < avctx->height / 2; ++line )
137 	{
138 		/* y even */
139 		memcpy(out + avctx->width * (2 * line + 0),
140 		       picture->data[0] + (2 * line + 0) * picture->linesize[0],
141 		       avctx->width);
142 
143 		/* y odd */
144 		memcpy(out + avctx->width * (2 * line + 1),
145 		       picture->data[0] + (2 * line + 1) * picture->linesize[0],
146 		       avctx->width);
147 
148 		/* u + v */
149 		memcpy(out + avctx->width * avctx->height
150 				+ line * avctx->width / 2,
151 		       picture->data[1] + line * picture->linesize[1],
152 		       avctx->width / 2);
153 
154 		memcpy(out + avctx->width * avctx->height * 5 / 4
155 				+ line * avctx->width / 2,
156 		       picture->data[2] + line * picture->linesize[2],
157 		       avctx->width / 2);
158 	}
159 
160 	return 0;
161 }
162 
pass_frame_to_decoder(AVCodecContext * avctx,AVFrame * picture,int inlen,unsigned char * in,int * outlen,char * out)163 static int pass_frame_to_decoder(AVCodecContext * avctx, AVFrame * picture,
164 		int inlen, unsigned char * in, int * outlen, char * out)
165 {
166 	int bytes_decoded;
167 	int got_picture;
168 
169 	bytes_decoded = avcodec_decode_video(avctx, picture, &got_picture,
170 			in, inlen);
171 
172 	if ( bytes_decoded != inlen )
173 	{
174 		fprintf(stderr,
175 			"codec_ffmpeg: decode: failed to decode whole frame %d / %d\n",
176 			bytes_decoded, inlen);
177 		return -1;
178 	}
179 
180 	if ( !got_picture )
181 	{
182 		fprintf(stderr,
183 			"codec_ffmpeg: decode: failed to get picture\n");
184 		return -1;
185 	}
186 
187 	frame_to_frame_xlate(avctx, picture, outlen, out);
188 
189 	return 0;
190 }
191 
parse_slice_header(char * in,struct slice_header_t * slice_header)192 static char *parse_slice_header(char * in, struct slice_header_t * slice_header)
193 {
194 	slice_header->version     = in[0];
195 	slice_header->source_id   = (in[1] << 8) | in[2];
196 	slice_header->frame_index = in[3];
197 	slice_header->slice_index = in[4];
198 	slice_header->num_slices  = in[5];
199 
200 	if ( slice_header->version != 0 )
201 	{
202 		fprintf(stderr,
203 			"codec_ffmpeg: decode: unknown slice header version %d\n",
204 			slice_header->version);
205 		return 0;
206 	}
207 
208 	return in + 6;
209 }
210 
decode_iaxc_slice(struct iaxc_video_codec * c,int inlen,char * in,int * outlen,char * out)211 static int decode_iaxc_slice(struct iaxc_video_codec * c, int inlen,
212 		char * in, int * outlen, char * out)
213 {
214 	struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
215 	struct slice_header_t * sh_saved = &d->slice_header;
216 	struct slice_header_t sh_this;
217 	char * inp;
218 	int ret;
219 
220 	inp = parse_slice_header(in, &sh_this);
221 
222 	if ( !inp )
223 		return -1;
224 
225 	inlen -= inp - in;
226 
227 	if ( sh_this.source_id == sh_saved->source_id )
228 	{
229 		unsigned char frame_delta;
230 
231 		frame_delta = sh_this.frame_index - sh_saved->frame_index;
232 
233 		if ( frame_delta > 20 )
234 		{
235 			/* This is an old slice. It's too late, we ignore it. */
236 			return 1;
237 		}
238 		else if ( frame_delta > 0 )
239 		{
240 			/* This slice belongs to a future frame */
241 			if ( sh_saved->slice_index > 0 )
242 			{
243 				/* We have received slices for a previous
244 				 * frame (e.g. the one we were previously
245 				 * working on), so we go ahead and send this
246 				 * partial frame to the decoder and get setup
247 				 * for the new frame.
248 				 */
249 
250 				ret = pass_frame_to_decoder(d->avctx, d->picture,
251 						d->frame_size, d->frame_buf,
252 						outlen, out);
253 
254 				reset_decoder_frame_state(d);
255 
256 				if ( ret )
257 					return -1;
258 			}
259 
260 			sh_saved->frame_index = sh_this.frame_index;
261 		}
262 	}
263 	else
264 	{
265 		sh_saved->source_id = sh_this.source_id;
266 		sh_saved->frame_index = sh_this.frame_index;
267 		sh_saved->slice_index = 0;
268 		d->frame_size = 0;
269 	}
270 
271 	if ( c->fragsize * sh_this.slice_index + inlen > d->frame_buf_len )
272 	{
273 		fprintf(stderr,
274 			"codec_ffmpeg: decode: slice overflows decoder frame buffer\n");
275 		return -1;
276 	}
277 
278 	memcpy(d->frame_buf + c->fragsize * sh_this.slice_index,
279 			inp, inlen);
280 	sh_saved->slice_index++;
281 	d->frame_size = c->fragsize * sh_this.slice_index + inlen;
282 
283 	if ( sh_saved->slice_index < sh_this.num_slices )
284 	{
285 		/* Do not decode yet, there are more slices coming for
286 		 * this frame.
287 		 */
288 		return 1;
289 	}
290 
291 	ret = pass_frame_to_decoder(d->avctx, d->picture, d->frame_size,
292 			d->frame_buf, outlen, out);
293 
294 	reset_decoder_frame_state(d);
295 
296 	if ( ret )
297 		return -1;
298 
299 	return 0;
300 }
301 
decode_rtp_slice(struct iaxc_video_codec * c,int inlen,char * in,int * outlen,char * out)302 static int decode_rtp_slice(struct iaxc_video_codec * c,
303 		  int inlen, char * in, int * outlen, char * out)
304 {
305 	struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
306 	int ret = 1;
307 
308 	while ( inlen )
309 	{
310 		int bytes_decoded;
311 		int got_picture;
312 
313 		bytes_decoded = avcodec_decode_video(d->avctx, d->picture,
314 				&got_picture, (unsigned char *)in, inlen);
315 
316 		if ( bytes_decoded < 0 )
317 		{
318 			fprintf(stderr,
319 				"codec_ffmpeg: decode: error decoding frame\n");
320 			return -1;
321 		}
322 
323 		inlen -= bytes_decoded;
324 		in += bytes_decoded;
325 
326 		if ( got_picture && ret == 0)
327 		{
328 			fprintf(stderr,
329 				"codec_ffmpeg: decode: unexpected second frame\n");
330 			return -1;
331 		}
332 
333 		if ( got_picture )
334 		{
335 			frame_to_frame_xlate(d->avctx, d->picture, outlen, out);
336 			ret = 0;
337 		}
338 	}
339 
340 	return ret;
341 }
342 
slice_encoded_frame(struct slice_header_t * sh,struct slice_set_t * slice_set,unsigned char * in,int inlen,int fragsize)343 static void slice_encoded_frame(struct slice_header_t * sh,
344 		struct slice_set_t * slice_set,
345 		unsigned char * in, int inlen, int fragsize)
346 {
347 	sh->num_slices = slice_set->num_slices = (inlen - 1) / fragsize + 1;
348 
349 	for (sh->slice_index = 0; sh->slice_index < sh->num_slices;
350 			++sh->slice_index)
351 	{
352 		int slice_size = (sh->slice_index == sh->num_slices - 1) ?
353 			inlen % fragsize : fragsize;
354 
355 		slice_set->size[sh->slice_index] = slice_size + 6;
356 		slice_set->data[sh->slice_index][0] = sh->version;
357 		slice_set->data[sh->slice_index][1] = sh->source_id >> 8;
358 		slice_set->data[sh->slice_index][2] = sh->source_id & 0xff;
359 		slice_set->data[sh->slice_index][3] = sh->frame_index;
360 		slice_set->data[sh->slice_index][4] = sh->slice_index;
361 		slice_set->data[sh->slice_index][5] = sh->num_slices;
362 
363 		memcpy(&slice_set->data[sh->slice_index][6], in, slice_size);
364 
365 		in += slice_size;
366 	}
367 
368 	sh->frame_index++;
369 }
370 
encode(struct iaxc_video_codec * c,int inlen,char * in,struct slice_set_t * slice_set)371 static int encode(struct iaxc_video_codec *c,
372 		int inlen, char * in, struct slice_set_t * slice_set)
373 {
374 	struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
375 	int encoded_size;
376 
377 	avcodec_get_frame_defaults(e->picture);
378 
379 	e->picture->data[0] = (unsigned char *)in;
380 	e->picture->data[1] = (unsigned char *)in
381 		+ e->avctx->width * e->avctx->height;
382 	e->picture->data[2] = (unsigned char *)in
383 		+ e->avctx->width * e->avctx->height * 5 / 4;
384 
385 	e->picture->linesize[0] = e->avctx->width;
386 	e->picture->linesize[1] = e->avctx->width / 2;
387 	e->picture->linesize[2] = e->avctx->width / 2;
388 
389 	/* TODO: investigate setting a real pts value */
390 	e->picture->pts = AV_NOPTS_VALUE;
391 
392 	/* TODO: investigate quality */
393 	e->picture->quality = 10;
394 
395 	g_slice_set = slice_set;
396 	slice_set->num_slices = 0;
397 
398 	encoded_size = avcodec_encode_video(e->avctx,
399 			e->frame_buf, e->frame_buf_len, e->picture);
400 
401 	if (!encoded_size)
402 	{
403 		fprintf(stderr, "codec_ffmpeg: encode failed\n");
404 		return -1;
405 	}
406 
407 	slice_set->key_frame = e->avctx->coded_frame->key_frame;
408 
409 	/* This is paranoia, of course. */
410 	g_slice_set = 0;
411 
412 	/* We are in one of two modes here.
413 	 *
414 	 * The first possibility is that the codec supports rtp
415 	 * packetization. In this case, the slice_set has already been
416 	 * filled via encode_rtp_callback() calls made during the call
417 	 * to avcodec_encode_video().
418 	 *
419 	 * The second possibility is that we have one big encoded frame
420 	 * that we need to slice-up ourselves.
421 	 */
422 
423 	if (!e->avctx->rtp_payload_size)
424 		slice_encoded_frame(&e->slice_header, slice_set,
425 				e->frame_buf, encoded_size, c->fragsize);
426 
427 	return 0;
428 }
429 
encode_rtp_callback(struct AVCodecContext * avctx,void * data,int size,int mb_nb)430 void encode_rtp_callback(struct AVCodecContext *avctx, void *data, int size,
431 		     int mb_nb)
432 {
433 	memcpy(&g_slice_set->data[g_slice_set->num_slices], data, size);
434 	g_slice_set->size[g_slice_set->num_slices] = size;
435 	g_slice_set->num_slices++;
436 }
437 
codec_video_ffmpeg_new(int format,int w,int h,int framerate,int bitrate,int fragsize)438 struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h,
439 						     int framerate, int bitrate,
440 						     int fragsize)
441 {
442 	struct encoder_ctx *e;
443 	struct decoder_ctx *d;
444 	AVCodec *codec;
445 	int ff_enc_id, ff_dec_id;
446 	char *name;
447 
448 	struct iaxc_video_codec *c = calloc(sizeof(struct iaxc_video_codec), 1);
449 
450 	if (!c)
451 	{
452 		fprintf(stderr,
453 			"codec_ffmpeg: failed to allocate video context\n");
454 		return NULL;
455 	}
456 
457 	avcodec_init();
458 	avcodec_register_all();
459 
460 	c->format = format;
461 	c->width = w;
462 	c->height = h;
463 	c->framerate = framerate;
464 	c->bitrate = bitrate;
465 	/* TODO: Is a fragsize of zero valid? If so, there's a divide
466 	 * by zero error to contend with.
467 	 */
468 	c->fragsize = fragsize;
469 
470 	c->encode = encode;
471 	c->decode = decode_iaxc_slice;
472 	c->destroy = destroy;
473 
474 	c->encstate = calloc(sizeof(struct encoder_ctx), 1);
475 	if (!c->encstate)
476 		goto bail;
477 	e = c->encstate;
478 	e->avctx = avcodec_alloc_context();
479 	if (!e->avctx)
480 		goto bail;
481 	e->picture = avcodec_alloc_frame();
482 	if (!e->picture)
483 		goto bail;
484 	/* The idea here is that the encoded frame that will land in this
485 	 * buffer will be no larger than the size of an uncompressed 32-bit
486 	 * rgb frame.
487 	 *
488 	 * TODO: Is this assumption really valid?
489 	 */
490 	e->frame_buf_len = w * h * 4;
491 	e->frame_buf = malloc(e->frame_buf_len);
492 	if (!e->frame_buf)
493 		goto bail;
494 
495 	c->decstate = calloc(sizeof(struct decoder_ctx), 1);
496 	if (!c->decstate)
497 		goto bail;
498 	d = c->decstate;
499 	d->avctx = avcodec_alloc_context();
500 	if (!d->avctx)
501 		goto bail;
502 	d->picture = avcodec_alloc_frame();
503 	if (!d->picture)
504 		goto bail;
505 	d->frame_buf_len = e->frame_buf_len;
506 	d->frame_buf = malloc(d->frame_buf_len);
507 	if (!d->frame_buf)
508 		goto bail;
509 
510 	e->slice_header.version = 0;
511 	srandom(time(0));
512 	e->slice_header.source_id = random() & 0xffff;
513 
514 	e->avctx->time_base.num = 1;
515 	e->avctx->time_base.den = framerate;
516 
517 	e->avctx->width = w;
518 	e->avctx->height = h;
519 
520 	e->avctx->bit_rate = bitrate;
521 
522 	/* This determines how often i-frames are sent */
523 	e->avctx->gop_size = framerate * 3;
524 	e->avctx->pix_fmt = PIX_FMT_YUV420P;
525 	e->avctx->has_b_frames = 0;
526 
527 	e->avctx->mb_qmin = e->avctx->qmin = 10;
528 	e->avctx->mb_qmax = e->avctx->qmax = 10;
529 
530 	e->avctx->lmin = 2 * FF_QP2LAMBDA;
531 	e->avctx->lmax = 10 * FF_QP2LAMBDA;
532 	e->avctx->global_quality = FF_QP2LAMBDA * 2;
533 	e->avctx->qblur = 0.5;
534 	e->avctx->global_quality = 10;
535 
536 	e->avctx->flags |= CODEC_FLAG_PSNR;
537 	e->avctx->flags |= CODEC_FLAG_QSCALE;
538 
539 	e->avctx->mb_decision = FF_MB_DECISION_SIMPLE;
540 
541 	ff_enc_id = ff_dec_id = map_iaxc_codec_to_avcodec(format);
542 
543 	/* Note, when fragsize is used (non-zero) ffmpeg will use a "best
544 	 * effort" strategy: the fragment size will be fragsize +/- 20%
545 	 */
546 
547 	switch (format)
548 	{
549 
550 	case IAXC_FORMAT_H261:
551 		/* TODO: H261 only works with specific resolutions. */
552 		name = "H.261";
553 		break;
554 
555 	case IAXC_FORMAT_H263:
556 		/* TODO: H263 only works with specific resolutions. */
557 		name = "H.263";
558 		e->avctx->flags |= CODEC_FLAG_AC_PRED;
559 		if (fragsize)
560 		{
561 			c->decode = decode_rtp_slice;
562 			e->avctx->rtp_payload_size = fragsize;
563 			e->avctx->flags |=
564 				CODEC_FLAG_TRUNCATED | CODEC_FLAG2_STRICT_GOP;
565 			e->avctx->rtp_callback = encode_rtp_callback;
566 			d->avctx->flags |= CODEC_FLAG_TRUNCATED;
567 		}
568 		break;
569 
570 	case IAXC_FORMAT_H263_PLUS:
571 		/* Although the encoder is CODEC_ID_H263P, the decoder
572 		 * is the regular h.263, so we handle this special case
573 		 * here.
574 		 */
575 		ff_dec_id = CODEC_ID_H263;
576 		name = "H.263+";
577 		e->avctx->flags |= CODEC_FLAG_AC_PRED;
578 		if (fragsize)
579 		{
580 			c->decode = decode_rtp_slice;
581 			e->avctx->rtp_payload_size = fragsize;
582 			e->avctx->flags |=
583 				CODEC_FLAG_TRUNCATED |
584 				CODEC_FLAG_H263P_SLICE_STRUCT |
585 				CODEC_FLAG2_STRICT_GOP |
586 				CODEC_FLAG2_LOCAL_HEADER;
587 			e->avctx->rtp_callback = encode_rtp_callback;
588 			d->avctx->flags |= CODEC_FLAG_TRUNCATED;
589 		}
590 		break;
591 
592 	case IAXC_FORMAT_MPEG4:
593 		name = "MPEG4";
594 		c->decode = decode_rtp_slice;
595 		e->avctx->rtp_payload_size = fragsize;
596 		e->avctx->rtp_callback = encode_rtp_callback;
597 		e->avctx->flags |=
598 			CODEC_FLAG_TRUNCATED |
599 			CODEC_FLAG_H263P_SLICE_STRUCT |
600 			CODEC_FLAG2_STRICT_GOP |
601 			CODEC_FLAG2_LOCAL_HEADER;
602 
603 		d->avctx->flags |= CODEC_FLAG_TRUNCATED;
604 		break;
605 
606 	case IAXC_FORMAT_H264:
607 		name = "H.264";
608 
609 		/*
610 		 * Encoder flags
611 		 */
612 
613 		/* Headers are not repeated */
614 		/* e->avctx->flags |= CODEC_FLAG_GLOBAL_HEADER; */
615 
616 		/* Slower, less blocky */
617 		/* e->avctx->flags |= CODEC_FLAG_LOOP_FILTER; */
618 
619 		e->avctx->flags |= CODEC_FLAG_PASS1;
620 		/* e->avctx->flags |= CODEC_FLAG_PASS2; */
621 
622 		/* Compute psnr values at encode-time (avctx->error[]) */
623 		/* e->avctx->flags |= CODEC_FLAG_PSNR; */
624 
625 		/* e->avctx->flags2 |= CODEC_FLAG2_8X8DCT; */
626 
627 		/* Access Unit Delimiters */
628 		e->avctx->flags2 |= CODEC_FLAG2_AUD;
629 
630 		/* Allow b-frames to be used as reference */
631 		/* e->avctx->flags2 |= CODEC_FLAG2_BPYRAMID; */
632 
633 		/* b-frame rate distortion optimization */
634 		/* e->avctx->flags2 |= CODEC_FLAG2_BRDO; */
635 
636 		/* e->avctx->flags2 |= CODEC_FLAG2_FASTPSKIP; */
637 
638 		/* Multiple references per partition */
639 		/* e->avctx->flags2 |= CODEC_FLAG2_MIXED_REFS; */
640 
641 		/* Weighted biprediction for b-frames */
642 		/* e->avctx->flags2 |= CODEC_FLAG2_WPRED; */
643 
644 		/*
645 		 * Decoder flags
646 		 */
647 
648 		/* Do not draw edges */
649 		/* d->avctx->flags |= CODEC_FLAG_EMU_EDGE; */
650 
651 		/* Decode grayscale only */
652 		/* d->avctx->flags |= CODEC_FLAG_GRAY; */
653 
654 		/* d->avctx->flags |= CODEC_FLAG_LOW_DELAY; */
655 
656 		/* Allow input bitstream to be randomly truncated */
657 		/* d->avctx->flags |= CODEC_FLAG_TRUNCATED; */
658 
659 		/* Allow out-of-spec speed tricks */
660 		/* d->avctx->flags2 |= CODEC_FLAG2_FAST; */
661 		break;
662 
663 	case IAXC_FORMAT_THEORA:
664 		/* TODO: ffmpeg only has a theora decoder. Until it has
665 		 * an encoder also, we cannot use ffmpeg for theora.
666 		 */
667 		name = "Theora";
668 		break;
669 
670 	default:
671 		fprintf(stderr, "codec_ffmpeg: unsupported format (0x%08x)\n",
672 				format);
673 		goto bail;
674 	}
675 
676 	strcpy(c->name, "ffmpeg-");
677 	strncat(c->name, name, sizeof(c->name));
678 
679 	/* Get the codecs */
680 	codec = avcodec_find_encoder(ff_enc_id);
681 	if (!codec)
682 	{
683 		iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
684 			     "codec_ffmpeg: cannot find encoder %d\n",
685 			     ff_enc_id);
686 		goto bail;
687 	}
688 
689 	if (avcodec_open(e->avctx, codec))
690 	{
691 		iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
692 			     "codec_ffmpeg: cannot open encoder %s\n", name);
693 		goto bail;
694 	}
695 
696 	codec = avcodec_find_decoder(ff_dec_id);
697 	if (!codec)
698 	{
699 		iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
700 			     "codec_ffmpeg: cannot find decoder %d\n",
701 			     ff_dec_id);
702 		goto bail;
703 	}
704 	if (avcodec_open(d->avctx, codec))
705 	{
706 		iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
707 			     "codec_ffmpeg: cannot open decoder %s\n", name);
708 		goto bail;
709 	}
710 
711 	{
712 		enum PixelFormat fmts[] = { PIX_FMT_YUV420P, -1 };
713 		if (d->avctx->get_format(d->avctx, fmts) != PIX_FMT_YUV420P)
714 		{
715 			iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
716 					"codec_ffmpeg: cannot set decode format to YUV420P\n");
717 			goto bail;
718 		}
719 	}
720 
721 	return c;
722 
723 bail:
724 	destroy(c);
725 	return 0;
726 }
727 
codec_video_ffmpeg_check_codec(int format)728 int codec_video_ffmpeg_check_codec(int format)
729 {
730 	AVCodec *codec;
731 	enum CodecID codec_id;
732 
733 	/* These functions are idempotent, so it is okay that we
734 	 * may call them elsewhere at a different time.
735 	 */
736 	avcodec_init();
737 	avcodec_register_all();
738 
739 	codec_id = map_iaxc_codec_to_avcodec(format);
740 
741 	if (codec_id == CODEC_ID_NONE)
742 		return 0;
743 
744 	codec = avcodec_find_encoder(codec_id);
745 
746 	return codec ? 1 : 0;
747 }
748 
749