00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019
00020 #include "codec_ffmpeg.h"
00021 #include "iaxclient_lib.h"
00022
00023 #ifdef WIN32
00024 #include "libavcodec/avcodec.h"
00025 #else
00026 #include <ffmpeg/avcodec.h>
00027 #endif
00028
00029 struct slice_header_t
00030 {
00031 unsigned char version;
00032 unsigned short source_id;
00033 unsigned char frame_index;
00034 unsigned char slice_index;
00035 unsigned char num_slices;
00036 };
00037
00038 struct encoder_ctx
00039 {
00040 AVCodecContext * avctx;
00041 AVFrame * picture;
00042
00043 struct slice_header_t slice_header;
00044
00045 unsigned char *frame_buf;
00046 int frame_buf_len;
00047 };
00048
00049 struct decoder_ctx
00050 {
00051 AVCodecContext * avctx;
00052 AVFrame * picture;
00053
00054 struct slice_header_t slice_header;
00055 int frame_size;
00056
00057 unsigned char * frame_buf;
00058 int frame_buf_len;
00059 };
00060
00061 static struct slice_set_t * g_slice_set = 0;
00062
00063 static enum CodecID map_iaxc_codec_to_avcodec(int format)
00064 {
00065 switch (format)
00066 {
00067 case IAXC_FORMAT_H261:
00068 return CODEC_ID_H261;
00069
00070 case IAXC_FORMAT_H263:
00071 return CODEC_ID_H263;
00072
00073 case IAXC_FORMAT_H263_PLUS:
00074 return CODEC_ID_H263P;
00075
00076 case IAXC_FORMAT_MPEG4:
00077 return CODEC_ID_MPEG4;
00078
00079 case IAXC_FORMAT_H264:
00080 return CODEC_ID_H264;
00081
00082 case IAXC_FORMAT_THEORA:
00083 return CODEC_ID_THEORA;
00084
00085 default:
00086 return CODEC_ID_NONE;
00087 }
00088 }
00089
00090 static void destroy(struct iaxc_video_codec *c)
00091 {
00092 if (c)
00093 {
00094 struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
00095 struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
00096
00097 if (e)
00098 {
00099 av_freep(&e->avctx);
00100 av_freep(&e->picture);
00101 if (e->frame_buf)
00102 free(e->frame_buf);
00103 free(e);
00104 }
00105
00106 if (d)
00107 {
00108 av_freep(&d->avctx);
00109 av_freep(&d->picture);
00110 if (d->frame_buf)
00111 free(d->frame_buf);
00112 free(d);
00113 }
00114
00115 free(c);
00116 }
00117 }
00118
00119 static void reset_decoder_frame_state(struct decoder_ctx * d)
00120 {
00121 memset(d->frame_buf, 0, d->frame_buf_len);
00122 d->frame_size = 0;
00123 d->slice_header.slice_index = 0;
00124 }
00125
00126 static int frame_to_frame_xlate(AVCodecContext * avctx, AVFrame * picture,
00127 int * outlen, char * out)
00128 {
00129 int line;
00130
00131 *outlen = avctx->width * avctx->height * 6 / 4;
00132
00133 for ( line = 0; line < avctx->height / 2; ++line )
00134 {
00135
00136 memcpy(out + avctx->width * (2 * line + 0),
00137 picture->data[0] + (2 * line + 0) * picture->linesize[0],
00138 avctx->width);
00139
00140
00141 memcpy(out + avctx->width * (2 * line + 1),
00142 picture->data[0] + (2 * line + 1) * picture->linesize[0],
00143 avctx->width);
00144
00145
00146 memcpy(out + avctx->width * avctx->height
00147 + line * avctx->width / 2,
00148 picture->data[1] + line * picture->linesize[1],
00149 avctx->width / 2);
00150
00151 memcpy(out + avctx->width * avctx->height * 5 / 4
00152 + line * avctx->width / 2,
00153 picture->data[2] + line * picture->linesize[2],
00154 avctx->width / 2);
00155 }
00156
00157 return 0;
00158 }
00159
00160 static int pass_frame_to_decoder(AVCodecContext * avctx, AVFrame * picture,
00161 int inlen, unsigned char * in, int * outlen, char * out)
00162 {
00163 int bytes_decoded;
00164 int got_picture;
00165
00166 bytes_decoded = avcodec_decode_video(avctx, picture, &got_picture,
00167 in, inlen);
00168
00169 if ( bytes_decoded != inlen )
00170 {
00171 fprintf(stderr,
00172 "codec_ffmpeg: decode: failed to decode whole frame %d / %d\n",
00173 bytes_decoded, inlen);
00174 return -1;
00175 }
00176
00177 if ( !got_picture )
00178 {
00179 fprintf(stderr,
00180 "codec_ffmpeg: decode: failed to get picture\n");
00181 return -1;
00182 }
00183
00184 frame_to_frame_xlate(avctx, picture, outlen, out);
00185
00186 return 0;
00187 }
00188
00189 static char *parse_slice_header(char * in, struct slice_header_t * slice_header)
00190 {
00191 slice_header->version = in[0];
00192 slice_header->source_id = (in[1] << 8) | in[2];
00193 slice_header->frame_index = in[3];
00194 slice_header->slice_index = in[4];
00195 slice_header->num_slices = in[5];
00196
00197 if ( slice_header->version != 0 )
00198 {
00199 fprintf(stderr,
00200 "codec_ffmpeg: decode: unknown slice header version %d\n",
00201 slice_header->version);
00202 return 0;
00203 }
00204
00205 return in + 6;
00206 }
00207
00208 static int decode_iaxc_slice(struct iaxc_video_codec * c, int inlen,
00209 char * in, int * outlen, char * out)
00210 {
00211 struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
00212 struct slice_header_t * sh_saved = &d->slice_header;
00213 struct slice_header_t sh_this;
00214 char * inp;
00215 int ret;
00216
00217 inp = parse_slice_header(in, &sh_this);
00218
00219 if ( !inp )
00220 return -1;
00221
00222 inlen -= inp - in;
00223
00224 if ( sh_this.source_id == sh_saved->source_id )
00225 {
00226 unsigned char frame_delta;
00227
00228 frame_delta = sh_this.frame_index - sh_saved->frame_index;
00229
00230 if ( frame_delta > 20 )
00231 {
00232
00233 return 1;
00234 }
00235 else if ( frame_delta > 0 )
00236 {
00237
00238 if ( sh_saved->slice_index > 0 )
00239 {
00240
00241
00242
00243
00244
00245
00246
00247 ret = pass_frame_to_decoder(d->avctx, d->picture,
00248 d->frame_size, d->frame_buf,
00249 outlen, out);
00250
00251 reset_decoder_frame_state(d);
00252
00253 if ( ret )
00254 return -1;
00255 }
00256
00257 sh_saved->frame_index = sh_this.frame_index;
00258 }
00259 }
00260 else
00261 {
00262 sh_saved->source_id = sh_this.source_id;
00263 sh_saved->frame_index = sh_this.frame_index;
00264 sh_saved->slice_index = 0;
00265 d->frame_size = 0;
00266 }
00267
00268 if ( c->fragsize * sh_this.slice_index + inlen > d->frame_buf_len )
00269 {
00270 fprintf(stderr,
00271 "codec_ffmpeg: decode: slice overflows decoder frame buffer\n");
00272 return -1;
00273 }
00274
00275 memcpy(d->frame_buf + c->fragsize * sh_this.slice_index,
00276 inp, inlen);
00277 sh_saved->slice_index++;
00278 d->frame_size = c->fragsize * sh_this.slice_index + inlen;
00279
00280 if ( sh_saved->slice_index < sh_this.num_slices )
00281 {
00282
00283
00284
00285 return 1;
00286 }
00287
00288 ret = pass_frame_to_decoder(d->avctx, d->picture, d->frame_size,
00289 d->frame_buf, outlen, out);
00290
00291 reset_decoder_frame_state(d);
00292
00293 if ( ret )
00294 return -1;
00295
00296 return 0;
00297 }
00298
00299 static int decode_rtp_slice(struct iaxc_video_codec * c,
00300 int inlen, char * in, int * outlen, char * out)
00301 {
00302 struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
00303 int ret = 1;
00304
00305 while ( inlen )
00306 {
00307 int bytes_decoded;
00308 int got_picture;
00309
00310 bytes_decoded = avcodec_decode_video(d->avctx, d->picture,
00311 &got_picture, (unsigned char *)in, inlen);
00312
00313 if ( bytes_decoded < 0 )
00314 {
00315 fprintf(stderr,
00316 "codec_ffmpeg: decode: error decoding frame\n");
00317 return -1;
00318 }
00319
00320 inlen -= bytes_decoded;
00321 in += bytes_decoded;
00322
00323 if ( got_picture && ret == 0)
00324 {
00325 fprintf(stderr,
00326 "codec_ffmpeg: decode: unexpected second frame\n");
00327 return -1;
00328 }
00329
00330 if ( got_picture )
00331 {
00332 frame_to_frame_xlate(d->avctx, d->picture, outlen, out);
00333 ret = 0;
00334 }
00335 }
00336
00337 return ret;
00338 }
00339
00340 static void slice_encoded_frame(struct slice_header_t * sh,
00341 struct slice_set_t * slice_set,
00342 unsigned char * in, int inlen, int fragsize)
00343 {
00344 sh->num_slices = slice_set->num_slices = (inlen - 1) / fragsize + 1;
00345
00346 for (sh->slice_index = 0; sh->slice_index < sh->num_slices;
00347 ++sh->slice_index)
00348 {
00349 int slice_size = (sh->slice_index == sh->num_slices - 1) ?
00350 inlen % fragsize : fragsize;
00351
00352 slice_set->size[sh->slice_index] = slice_size + 6;
00353 slice_set->data[sh->slice_index][0] = sh->version;
00354 slice_set->data[sh->slice_index][1] = sh->source_id >> 8;
00355 slice_set->data[sh->slice_index][2] = sh->source_id & 0xff;
00356 slice_set->data[sh->slice_index][3] = sh->frame_index;
00357 slice_set->data[sh->slice_index][4] = sh->slice_index;
00358 slice_set->data[sh->slice_index][5] = sh->num_slices;
00359
00360 memcpy(&slice_set->data[sh->slice_index][6], in, slice_size);
00361
00362 in += slice_size;
00363 }
00364
00365 sh->frame_index++;
00366 }
00367
00368 static int encode(struct iaxc_video_codec *c,
00369 int inlen, char * in, struct slice_set_t * slice_set)
00370 {
00371 struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
00372 int encoded_size;
00373
00374 avcodec_get_frame_defaults(e->picture);
00375
00376 e->picture->data[0] = (unsigned char *)in;
00377 e->picture->data[1] = (unsigned char *)in
00378 + e->avctx->width * e->avctx->height;
00379 e->picture->data[2] = (unsigned char *)in
00380 + e->avctx->width * e->avctx->height * 5 / 4;
00381
00382 e->picture->linesize[0] = e->avctx->width;
00383 e->picture->linesize[1] = e->avctx->width / 2;
00384 e->picture->linesize[2] = e->avctx->width / 2;
00385
00386
00387 e->picture->pts = AV_NOPTS_VALUE;
00388
00389
00390 e->picture->quality = 10;
00391
00392 g_slice_set = slice_set;
00393 slice_set->num_slices = 0;
00394
00395 encoded_size = avcodec_encode_video(e->avctx,
00396 e->frame_buf, e->frame_buf_len, e->picture);
00397
00398 if (!encoded_size)
00399 {
00400 fprintf(stderr, "codec_ffmpeg: encode failed\n");
00401 return -1;
00402 }
00403
00404 slice_set->key_frame = e->avctx->coded_frame->key_frame;
00405
00406
00407 g_slice_set = 0;
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 if (!e->avctx->rtp_payload_size)
00421 slice_encoded_frame(&e->slice_header, slice_set,
00422 e->frame_buf, encoded_size, c->fragsize);
00423
00424 return 0;
00425 }
00426
00427 void encode_rtp_callback(struct AVCodecContext *avctx, void *data, int size,
00428 int mb_nb)
00429 {
00430 memcpy(&g_slice_set->data[g_slice_set->num_slices], data, size);
00431 g_slice_set->size[g_slice_set->num_slices] = size;
00432 g_slice_set->num_slices++;
00433 }
00434
00435 struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h,
00436 int framerate, int bitrate,
00437 int fragsize)
00438 {
00439 struct encoder_ctx *e;
00440 struct decoder_ctx *d;
00441 AVCodec *codec;
00442 int ff_enc_id, ff_dec_id;
00443 char *name;
00444
00445 struct iaxc_video_codec *c = calloc(sizeof(struct iaxc_video_codec), 1);
00446
00447 if (!c)
00448 {
00449 fprintf(stderr,
00450 "codec_ffmpeg: failed to allocate video context\n");
00451 return NULL;
00452 }
00453
00454 avcodec_init();
00455 avcodec_register_all();
00456
00457 c->format = format;
00458 c->width = w;
00459 c->height = h;
00460 c->framerate = framerate;
00461 c->bitrate = bitrate;
00462
00463
00464
00465 c->fragsize = fragsize;
00466
00467 c->encode = encode;
00468 c->decode = decode_iaxc_slice;
00469 c->destroy = destroy;
00470
00471 c->encstate = calloc(sizeof(struct encoder_ctx), 1);
00472 if (!c->encstate)
00473 goto bail;
00474 e = c->encstate;
00475 e->avctx = avcodec_alloc_context();
00476 if (!e->avctx)
00477 goto bail;
00478 e->picture = avcodec_alloc_frame();
00479 if (!e->picture)
00480 goto bail;
00481
00482
00483
00484
00485
00486
00487 e->frame_buf_len = w * h * 4;
00488 e->frame_buf = malloc(e->frame_buf_len);
00489 if (!e->frame_buf)
00490 goto bail;
00491
00492 c->decstate = calloc(sizeof(struct decoder_ctx), 1);
00493 if (!c->decstate)
00494 goto bail;
00495 d = c->decstate;
00496 d->avctx = avcodec_alloc_context();
00497 if (!d->avctx)
00498 goto bail;
00499 d->picture = avcodec_alloc_frame();
00500 if (!d->picture)
00501 goto bail;
00502 d->frame_buf_len = e->frame_buf_len;
00503 d->frame_buf = malloc(d->frame_buf_len);
00504 if (!d->frame_buf)
00505 goto bail;
00506
00507 e->slice_header.version = 0;
00508 srandom(time(0));
00509 e->slice_header.source_id = random() & 0xffff;
00510
00511 e->avctx->time_base.num = 1;
00512 e->avctx->time_base.den = framerate;
00513
00514 e->avctx->width = w;
00515 e->avctx->height = h;
00516
00517 e->avctx->bit_rate = bitrate;
00518
00519
00520 e->avctx->gop_size = framerate * 3;
00521 e->avctx->pix_fmt = PIX_FMT_YUV420P;
00522 e->avctx->has_b_frames = 0;
00523
00524 e->avctx->mb_qmin = e->avctx->qmin = 10;
00525 e->avctx->mb_qmax = e->avctx->qmax = 10;
00526
00527 e->avctx->lmin = 2 * FF_QP2LAMBDA;
00528 e->avctx->lmax = 10 * FF_QP2LAMBDA;
00529 e->avctx->global_quality = FF_QP2LAMBDA * 2;
00530 e->avctx->qblur = 0.5;
00531 e->avctx->global_quality = 10;
00532
00533 e->avctx->flags |= CODEC_FLAG_PSNR;
00534 e->avctx->flags |= CODEC_FLAG_QSCALE;
00535
00536 e->avctx->mb_decision = FF_MB_DECISION_SIMPLE;
00537
00538 ff_enc_id = ff_dec_id = map_iaxc_codec_to_avcodec(format);
00539
00540
00541
00542
00543
00544 switch (format)
00545 {
00546
00547 case IAXC_FORMAT_H261:
00548
00549 name = "H.261";
00550 break;
00551
00552 case IAXC_FORMAT_H263:
00553
00554 name = "H.263";
00555 e->avctx->flags |= CODEC_FLAG_AC_PRED;
00556 if (fragsize)
00557 {
00558 c->decode = decode_rtp_slice;
00559 e->avctx->rtp_payload_size = fragsize;
00560 e->avctx->flags |=
00561 CODEC_FLAG_TRUNCATED | CODEC_FLAG2_STRICT_GOP;
00562 e->avctx->rtp_callback = encode_rtp_callback;
00563 d->avctx->flags |= CODEC_FLAG_TRUNCATED;
00564 }
00565 break;
00566
00567 case IAXC_FORMAT_H263_PLUS:
00568
00569
00570
00571
00572 ff_dec_id = CODEC_ID_H263;
00573 name = "H.263+";
00574 e->avctx->flags |= CODEC_FLAG_AC_PRED;
00575 if (fragsize)
00576 {
00577 c->decode = decode_rtp_slice;
00578 e->avctx->rtp_payload_size = fragsize;
00579 e->avctx->flags |=
00580 CODEC_FLAG_TRUNCATED |
00581 CODEC_FLAG_H263P_SLICE_STRUCT |
00582 CODEC_FLAG2_STRICT_GOP |
00583 CODEC_FLAG2_LOCAL_HEADER;
00584 e->avctx->rtp_callback = encode_rtp_callback;
00585 d->avctx->flags |= CODEC_FLAG_TRUNCATED;
00586 }
00587 break;
00588
00589 case IAXC_FORMAT_MPEG4:
00590 name = "MPEG4";
00591 c->decode = decode_rtp_slice;
00592 e->avctx->rtp_payload_size = fragsize;
00593 e->avctx->rtp_callback = encode_rtp_callback;
00594 e->avctx->flags |=
00595 CODEC_FLAG_TRUNCATED |
00596 CODEC_FLAG_H263P_SLICE_STRUCT |
00597 CODEC_FLAG2_STRICT_GOP |
00598 CODEC_FLAG2_LOCAL_HEADER;
00599
00600 d->avctx->flags |= CODEC_FLAG_TRUNCATED;
00601 break;
00602
00603 case IAXC_FORMAT_H264:
00604 name = "H.264";
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 e->avctx->flags |= CODEC_FLAG_PASS1;
00617
00618
00619
00620
00621
00622
00623
00624
00625 e->avctx->flags2 |= CODEC_FLAG2_AUD;
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 break;
00659
00660 case IAXC_FORMAT_THEORA:
00661
00662
00663
00664 name = "Theora";
00665 break;
00666
00667 default:
00668 fprintf(stderr, "codec_ffmpeg: unsupported format (0x%08x)\n",
00669 format);
00670 goto bail;
00671 }
00672
00673 strcpy(c->name, "ffmpeg-");
00674 strncat(c->name, name, sizeof(c->name));
00675
00676
00677 codec = avcodec_find_encoder(ff_enc_id);
00678 if (!codec)
00679 {
00680 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
00681 "codec_ffmpeg: cannot find encoder %d\n",
00682 ff_enc_id);
00683 goto bail;
00684 }
00685
00686 if (avcodec_open(e->avctx, codec))
00687 {
00688 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
00689 "codec_ffmpeg: cannot open encoder %s\n", name);
00690 goto bail;
00691 }
00692
00693 codec = avcodec_find_decoder(ff_dec_id);
00694 if (!codec)
00695 {
00696 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
00697 "codec_ffmpeg: cannot find decoder %d\n",
00698 ff_dec_id);
00699 goto bail;
00700 }
00701 if (avcodec_open(d->avctx, codec))
00702 {
00703 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
00704 "codec_ffmpeg: cannot open decoder %s\n", name);
00705 goto bail;
00706 }
00707
00708 {
00709 enum PixelFormat fmts[] = { PIX_FMT_YUV420P, -1 };
00710 if (d->avctx->get_format(d->avctx, fmts) != PIX_FMT_YUV420P)
00711 {
00712 iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
00713 "codec_ffmpeg: cannot set decode format to YUV420P\n");
00714 goto bail;
00715 }
00716 }
00717
00718 return c;
00719
00720 bail:
00721 destroy(c);
00722 return 0;
00723 }
00724
00725 int codec_video_ffmpeg_check_codec(int format)
00726 {
00727 AVCodec *codec;
00728 enum CodecID codec_id;
00729
00730
00731
00732
00733 avcodec_init();
00734 avcodec_register_all();
00735
00736 codec_id = map_iaxc_codec_to_avcodec(format);
00737
00738 if (codec_id == CODEC_ID_NONE)
00739 return 0;
00740
00741 codec = avcodec_find_encoder(codec_id);
00742
00743 return codec ? 1 : 0;
00744 }
00745