1 Index: configure 2 =================================================================== 3 --- configure (revision 8090) 4 +++ configure (working copy) 5 @@ -69,6 +69,7 @@ 6 echo " --disable-shared do not build shared libraries [default=yes]" 7 echo " --enable-gpl allow use of GPL code, the resulting libav*" 8 echo " and ffmpeg will be under GPL [default=no]" 9 + echo " --enable-dirac enable dirac codec support via libdirac_encoder [default=no]" 10 echo " --enable-pp enable GPLed postprocessing support [default=no]" 11 echo " --enable-swscaler software scaler support [default=no]" 12 echo " --enable-beosthreads use BeOS threads [default=no]" 13 @@ -573,6 +574,7 @@ 14 wince 15 x11grab 16 x264 17 + dirac 18 xvid 19 zlib 20 ' 21 @@ -648,6 +650,7 @@ 22 png_decoder_deps="zlib" 23 png_encoder_deps="zlib" 24 x264_encoder_deps="x264" 25 +dirac_encoder_deps="dirac" 26 xvid_encoder_deps="xvid" 27 zmbv_decoder_deps="zlib" 28 zmbv_encoder_deps="zlib" 29 @@ -793,6 +796,7 @@ 30 ffplay="yes" 31 ffserver="yes" 32 gpl="no" 33 +dirac="no" 34 gprof="no" 35 ipv6="yes" 36 shared="no" 37 @@ -1552,6 +1556,12 @@ 38 enabled libfaad && require2 libfaad faad.h faacDecOpen -lfaad 39 enabled avisynth && require2 vfw32 "windows.h vfw.h" AVIFileInit -lvfw32 40 41 +if enabled dirac; then 42 + add_cflags "`pkg-config --cflags dirac`" 43 + require dirac libdirac_encoder/dirac_encoder.h dirac_encoder_init -ldirac_encoder 44 + require dirac libdirac_decoder/decoder_types.h dirac_decoder_init -ldirac_decoder 45 +fi 46 + 47 # test for lrintf in math.h 48 check_exec <<EOF && lrintf=yes || lrintf=no 49 #define _ISOC9X_SOURCE 1 50 @@ -1807,6 +1817,7 @@ 51 echo "libtheora enabled $libtheora" 52 echo "libvorbis enabled $libvorbis" 53 echo "x264 enabled $x264" 54 +echo "dirac enabled $dirac" 55 echo "XviD enabled $xvid" 56 echo "zlib enabled $zlib" 57 echo "AMR-NB float support $amr_nb" 58 Index: libavcodec/dirac.c 59 =================================================================== 60 --- libavcodec/dirac.c (revision 0) 61 +++ libavcodec/dirac.c (revision 0) 62 @@ -0,0 +1,709 @@ 63 +/** 64 + * @file dirac.c 65 + * Dirac codec support via dirac_encoder. 66 + * @author Andrew Kennedy <dirac@rd.bbc.co.uk> 67 + * www.sourceforge.net/projects/dirac 68 + * 69 + * This file is part of libavcodec. 70 + * 71 + * This library is free software; you can redistribute it and/or 72 + * modify it under the terms of the GNU Lesser General Public 73 + * License as published by the Free Software Foundation; either 74 + * version 2 of the License, or (at your option) any later version. 75 + * 76 + * This library is distributed in the hope that it will be useful, 77 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 78 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 79 + * Lesser General Public License for more details. 80 + * 81 + * You should have received a copy of the GNU Lesser General Public 82 + * License along with this library; if not, write to the Free Software 83 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 84 + */ 85 + 86 + 87 +#include "avcodec.h" 88 + 89 +#undef NDEBUG 90 +#include <assert.h> 91 + 92 + 93 +#include <libdirac_encoder/dirac_encoder.h> 94 +#include <libdirac_decoder/dirac_parser.h> 95 + 96 +/** ffmpeg qscale to Dirac quality conversion table */ 97 +static const float quality_factor_conv[] = {10.0, 9.8, 9.6, 9.4, 9.2, 9.0, 8.8, 98 + 8.6, 8.4, 8.2, 8.0, 7.8, 7.6, 7.3, 7.0, 6.7, 6.4, 6.0, 5.6, 5.2, 4.8, 99 + 4.4, 4.0, 3.6, 3.2, 2.8, 2.4, 2.0, 1.6, 1.2, 1.0 }; 100 + 101 +/** contains a single frame returned from Dirac*/ 102 +typedef struct FfmpegDiracOutputFrame 103 +{ 104 + /** frame data */ 105 + unsigned char *p_data; 106 + 107 + /** frame size */ 108 + int size; 109 + 110 + /** frame type */ 111 + int type; 112 + 113 + /** next frame to be output in sequence */ 114 + struct FfmpegDiracOutputFrame *p_next_frame; 115 + 116 + } FfmpegDiracOutputFrame; 117 + 118 +typedef struct FfmpegDiracParams 119 +{ 120 + /* context params */ 121 + dirac_encoder_context_t enc_ctx; 122 + 123 + /* frame being encoded */ 124 + AVFrame picture; 125 + 126 + /* decoder */ 127 + dirac_decoder_t* p_decoder; 128 + 129 + /* encoder */ 130 + dirac_encoder_t* p_encoder; 131 + 132 + /* input frame buffer */ 133 + unsigned char *p_in_frame_buf; 134 + 135 + /** output frame buf */ 136 + unsigned char* p_out_frame_buf; 137 + 138 + /** next frame to be output*/ 139 + struct FfmpegDiracOutputFrame *p_next_output_frame; 140 + 141 + /** last frame to be output*/ 142 + struct FfmpegDiracOutputFrame *p_last_output_frame; 143 + 144 +} FfmpegDiracParams; 145 + 146 + 147 +typedef struct FfmpegDiracParseContext 148 +{ 149 + 150 + /** stream buffer variables */ 151 + unsigned char* p_dirac_videobuffer; 152 + int dirac_videobuf_code_len; 153 + unsigned char dirac_videobuf_code[5]; 154 + int dirac_videobuf_len; 155 + int in_frame; 156 + int dirac_overread_size; 157 + 158 +} FfmpegDiracParseContext ; 159 + 160 + 161 +/** 162 +* Works out Dirac-compatible pre-set option from file size 163 +*/ 164 +static dirac_encoder_presets_t GetDiracPreset(AVCodecContext *avccontext) 165 +{ 166 + 167 + if(avccontext->width==720 && avccontext->height==576) 168 + return VIDEO_FORMAT_SD_625_DIGITAL; 169 + 170 + if(avccontext->height==1280 && avccontext->height==720) 171 + return VIDEO_FORMAT_HD_720; 172 + 173 + if(avccontext->height==1920 && avccontext->width==1080) 174 + return VIDEO_FORMAT_HD_1080; 175 + 176 + if(avccontext->height==352 && avccontext->width==288) 177 + return VIDEO_FORMAT_CIF; 178 + 179 + return VIDEO_FORMAT_CUSTOM; 180 +} 181 + 182 +/** 183 +* Works out Dirac-compatible chroma format 184 +*/ 185 +static int GetDiracChromaFormat(AVCodecContext *avccontext) 186 +{ 187 + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; 188 + 189 + switch(avccontext->pix_fmt) 190 + { 191 + case PIX_FMT_YUV420P: 192 + p_dirac_params->enc_ctx.seq_params.chroma = format420; 193 + break; 194 + 195 + case PIX_FMT_YUV422P: 196 + p_dirac_params->enc_ctx.seq_params.chroma = format422; 197 + break; 198 + 199 + case PIX_FMT_YUV444P: 200 + p_dirac_params->enc_ctx.seq_params.chroma = format444; 201 + break; 202 + 203 + default: 204 + av_log (avccontext, AV_LOG_ERROR, "this codec supports only Planar YUV formats (yuv420p, yuv422p, yuv444p\n"); 205 + return -1; 206 + } 207 + return format420; 208 +} 209 + 210 + /** 211 + * returns Ffmppeg chroma format 212 + */ 213 +static int GetFfmpegChromaFormat(dirac_chroma_t dirac_chroma) 214 +{ 215 + switch(dirac_chroma) 216 + { 217 + case format420: 218 + return PIX_FMT_YUV420P; 219 + case format422: 220 + return PIX_FMT_YUV422P; 221 + case format444: 222 + return PIX_FMT_YUV444P; 223 + 224 + default: 225 + break; 226 + } 227 + 228 + return PIX_FMT_YUV420P; 229 +} 230 + 231 + 232 +static int dirac_encode_init(AVCodecContext *avccontext) 233 +{ 234 + 235 + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; 236 + int no_local=0; 237 + int verbose=avccontext->debug; 238 + dirac_encoder_presets_t preset; 239 + 240 + if(avccontext->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ 241 + av_log(avccontext, AV_LOG_ERROR, "this codec is under development, files encoded with it may not be decodable with future versions!!!\n" 242 + "use vstrict=-2 / -strict -2 to use it anyway\n"); 243 + return -1; 244 + } 245 + 246 + /* get dirac preset*/ 247 + preset = GetDiracPreset(avccontext); 248 + 249 + /* set data to zero */ 250 + memset (p_dirac_params, 0, sizeof(FfmpegDiracParams)); 251 + 252 + 253 + /* initialise the encoder context */ 254 + dirac_encoder_context_init (&(p_dirac_params->enc_ctx), preset); 255 + 256 + if (GetDiracChromaFormat(avccontext) == -1) 257 + return -1; 258 + p_dirac_params->enc_ctx.src_params.frame_rate.numerator=avccontext->time_base.den; 259 + p_dirac_params->enc_ctx.src_params.frame_rate.denominator=avccontext->time_base.num; 260 + p_dirac_params->enc_ctx.seq_params.width=avccontext->width; 261 + p_dirac_params->enc_ctx.seq_params.height=avccontext->height; 262 + 263 + avccontext->frame_size = avpicture_get_size(avccontext->pix_fmt, avccontext->width, avccontext->height); 264 + avccontext->coded_frame= &p_dirac_params->picture; 265 + 266 + if (no_local) 267 + { 268 + p_dirac_params->enc_ctx.decode_flag = 0; 269 + p_dirac_params->enc_ctx.instr_flag = 0; 270 + } 271 + else 272 + { 273 + p_dirac_params->enc_ctx.decode_flag = 1; 274 + p_dirac_params->enc_ctx.instr_flag = 1; 275 + } 276 + 277 + if(avccontext->global_quality!=0) 278 + p_dirac_params->enc_ctx.enc_params.qf=quality_factor_conv[(avccontext->global_quality/FF_QP2LAMBDA)-1]; 279 + 280 + p_dirac_params->p_encoder = dirac_encoder_init( &(p_dirac_params->enc_ctx), verbose ); 281 + 282 + 283 + 284 + if (!p_dirac_params->p_encoder) 285 + { 286 + av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Error: dirac_encoder_init failed. "); 287 + return EXIT_FAILURE; 288 + } 289 + 290 + 291 + /* allocate enough memory for the incoming data */ 292 + p_dirac_params->p_in_frame_buf = (unsigned char*) av_malloc(avccontext->frame_size); 293 + 294 + return 0 ; 295 +} 296 + 297 + 298 +static int dirac_encode_frame(AVCodecContext *avccontext, 299 + unsigned char *frame, 300 + int buf_size, void *data) 301 +{ 302 + int enc_size=0; 303 + dirac_encoder_state_t state; 304 + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; 305 + AVFrame* p_frame_src; 306 + struct FfmpegDiracOutputFrame* p_frame_output=NULL; 307 + struct FfmpegDiracOutputFrame* p_next_output_frame=NULL; 308 + 309 + 310 + if(data==0) 311 + { 312 + /* look for any delayed frames at EOF*/ 313 + p_next_output_frame=p_dirac_params->p_next_output_frame; 314 + if(p_next_output_frame==NULL) 315 + { 316 + /* get terminate data*/ 317 + p_dirac_params->p_encoder->enc_buf.buffer=frame; 318 + p_dirac_params->p_encoder->enc_buf.size = buf_size; 319 + if (dirac_encoder_end_sequence( p_dirac_params->p_encoder ) > 0) 320 + return p_dirac_params->p_encoder->enc_buf.size; 321 + 322 + return 0; 323 + } 324 + 325 + memcpy(frame, p_next_output_frame->p_data, p_next_output_frame->size); 326 + enc_size=p_next_output_frame->size; 327 + 328 + /*remove frame*/ 329 + p_dirac_params->p_next_output_frame=p_next_output_frame->p_next_frame; 330 + av_free(p_next_output_frame->p_data); 331 + av_free(p_next_output_frame); 332 + 333 + return enc_size; 334 + } 335 + 336 + p_dirac_params->picture = *(AVFrame*)data; 337 + p_frame_src=(AVFrame*)data; 338 + 339 + /** allocate frame data to dirac input buffer */ 340 + /* 341 + * input line size may differe from what the codec supports. Especially 342 + * when transcoding from one format to another. So use avpicture_layout 343 + * to copy the frame. 344 + */ 345 + avpicture_layout ((AVPicture *)data, avccontext->pix_fmt, avccontext->width, avccontext->height,p_dirac_params->p_in_frame_buf, avccontext->frame_size); 346 + 347 + /* load next frame*/ 348 + if (dirac_encoder_load( p_dirac_params->p_encoder, p_dirac_params->p_in_frame_buf, avccontext->frame_size ) < 0) 349 + { 350 + av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error. Quitting...\n"); 351 + return -1; 352 + } 353 + 354 + 355 + do { 356 + p_dirac_params->p_encoder->enc_buf.buffer = frame; 357 + p_dirac_params->p_encoder->enc_buf.size = buf_size; 358 + /* process frame */ 359 + state = dirac_encoder_output ( p_dirac_params->p_encoder ); 360 + 361 + switch (state) 362 + { 363 + case ENC_STATE_AVAIL: 364 + assert (p_dirac_params->p_encoder->enc_buf.size > 0); 365 + /* create output frame*/ 366 + p_frame_output=(struct FfmpegDiracOutputFrame*)av_malloc(sizeof(FfmpegDiracOutputFrame)); 367 + memset(p_frame_output, 0, sizeof(FfmpegDiracOutputFrame)); 368 + 369 + /* set output data */ 370 + p_frame_output->p_data=(unsigned char*)av_malloc(p_dirac_params->p_encoder->enc_buf.size); 371 + memcpy(p_frame_output->p_data,p_dirac_params->p_encoder->enc_buf.buffer,p_dirac_params->p_encoder->enc_buf.size); 372 + p_frame_output->size=p_dirac_params->p_encoder->enc_buf.size; 373 + p_frame_output->type=p_dirac_params->p_encoder->enc_fparams.ftype; 374 + if(p_dirac_params->p_next_output_frame==NULL) 375 + { 376 + p_dirac_params->p_next_output_frame=p_frame_output; 377 + p_dirac_params->p_last_output_frame=p_frame_output; 378 + } 379 + else 380 + { 381 + p_dirac_params->p_last_output_frame->p_next_frame=p_frame_output; 382 + p_dirac_params->p_last_output_frame=p_frame_output; 383 + } 384 + break; 385 + 386 + case ENC_STATE_BUFFER: 387 + break; 388 + 389 + case ENC_STATE_INVALID: 390 + av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error. Quitting...\n"); 391 + return -1; 392 + 393 + default: 394 + av_log(avccontext, AV_LOG_ERROR, "Unknown Encoder state\n"); 395 + return -1; 396 + } 397 + } 398 + while(state==ENC_STATE_AVAIL); 399 + 400 + /* copy 'next' frame in queue */ 401 + p_next_output_frame=p_dirac_params->p_next_output_frame; 402 + if(p_next_output_frame==NULL) 403 + return 0; 404 + 405 + memcpy(frame, p_next_output_frame->p_data, p_next_output_frame->size); 406 + avccontext->coded_frame->key_frame= p_next_output_frame->type == INTRA_FRAME; 407 + avccontext->coded_frame->pts= 0; 408 + enc_size=p_next_output_frame->size; 409 + 410 + /*remove frame*/ 411 + p_dirac_params->p_next_output_frame=p_next_output_frame->p_next_frame; 412 + av_free(p_next_output_frame->p_data); 413 + av_free(p_next_output_frame); 414 + 415 + return enc_size; 416 +} 417 + 418 + 419 +static int dirac_encode_close(AVCodecContext *avccontext) 420 +{ 421 + 422 + FfmpegDiracParams* p_dirac_params = avccontext->priv_data; 423 + 424 + // close the encoder 425 + dirac_encoder_close(p_dirac_params->p_encoder ); 426 + 427 + av_free(p_dirac_params->p_in_frame_buf); 428 + 429 + return 0 ; 430 +} 431 + 432 + 433 +AVCodec dirac_encoder = { 434 + "dirac", 435 + CODEC_TYPE_VIDEO, 436 + CODEC_ID_DIRAC, 437 + sizeof(FfmpegDiracParams), 438 + dirac_encode_init, 439 + dirac_encode_frame, 440 + dirac_encode_close, 441 + .capabilities= CODEC_CAP_DELAY, 442 +} ; 443 + 444 +/**-------------------------DECODER------------------------------------------*/ 445 + 446 +static int dirac_decode_init(AVCodecContext *avccontext) 447 +{ 448 + 449 + FfmpegDiracParams *p_dirac_params = (FfmpegDiracParams*)avccontext->priv_data ; 450 + p_dirac_params->p_decoder = dirac_decoder_init(avccontext->debug); 451 + 452 + if (!p_dirac_params->p_decoder) 453 + return -1; 454 + 455 + return 0 ; 456 +} 457 + 458 +static int dirac_decode_frame(AVCodecContext *avccontext, 459 + void *data, int *data_size, 460 + uint8_t *buf, int buf_size) 461 +{ 462 + 463 + FfmpegDiracParams *p_dirac_params=(FfmpegDiracParams*)avccontext->priv_data; 464 + AVPicture *picture = (AVPicture*)data; 465 + AVPicture pic; 466 + int pict_size; 467 + unsigned char *buffer[3]; 468 + 469 + if(buf_size>0) 470 + /* set data to decode into buffer */ 471 + dirac_buffer (p_dirac_params->p_decoder, buf, buf+buf_size); 472 + while (1) 473 + { 474 + /* parse data and process result */ 475 + DecoderState state = dirac_parse (p_dirac_params->p_decoder); 476 + switch (state) 477 + { 478 + case STATE_BUFFER: 479 + return buf_size; 480 + 481 + case STATE_SEQUENCE: 482 + 483 + /* tell ffmpeg about sequence details*/ 484 + avccontext->height=p_dirac_params->p_decoder->seq_params.height; 485 + avccontext->width=p_dirac_params->p_decoder->seq_params.width; 486 + avccontext->pix_fmt=GetFfmpegChromaFormat(p_dirac_params->p_decoder->seq_params.chroma); 487 + avccontext->time_base.den =p_dirac_params->p_decoder->src_params.frame_rate.numerator; 488 + avccontext->time_base.num =p_dirac_params->p_decoder->src_params.frame_rate.denominator; 489 + 490 + /* calc output dimensions */ 491 + avpicture_fill(&pic, NULL, avccontext->pix_fmt, avccontext->width, avccontext->height); 492 + pict_size = avpicture_get_size(avccontext->pix_fmt, avccontext->width, avccontext->height); 493 + 494 + /* allocate output buffer */ 495 + if(p_dirac_params->p_out_frame_buf==0) 496 + p_dirac_params->p_out_frame_buf = (unsigned char *)av_malloc (pict_size); 497 + buffer[0]=p_dirac_params->p_out_frame_buf; 498 + buffer[1]=p_dirac_params->p_out_frame_buf+(pic.linesize[0]*avccontext->height); 499 + buffer[2]=buffer[1]+(pic.linesize[1]*p_dirac_params->p_decoder->seq_params.chroma_height); 500 + 501 + /* tell dirac about output destination */ 502 + dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL); 503 + break; 504 + 505 + case STATE_SEQUENCE_END: 506 + break; 507 + 508 + case STATE_PICTURE_AVAIL: 509 + /* fill pic with current buffer data from dirac*/ 510 + avpicture_fill(picture, p_dirac_params->p_out_frame_buf, avccontext->pix_fmt, avccontext->width, avccontext->height); 511 + //*data_size=avpicture_get_size(avccontext->pix_fmt, avccontext->width, avccontext->height); 512 + *data_size=1; 513 + return buf_size; 514 + 515 + case STATE_PICTURE_START: 516 + break; 517 + 518 + case STATE_INVALID: 519 + return -1; 520 + 521 + default: 522 + break; 523 + } 524 + } 525 + 526 + return buf_size; 527 +} 528 + 529 + 530 +static int dirac_decode_close(AVCodecContext *avccontext) 531 +{ 532 + FfmpegDiracParams *p_dirac_params=(FfmpegDiracParams*)avccontext->priv_data; 533 + 534 + dirac_decoder_close (p_dirac_params->p_decoder); 535 + 536 + av_free(p_dirac_params->p_out_frame_buf); 537 + 538 + return 0 ; 539 +} 540 + 541 + 542 +AVCodec dirac_decoder = { 543 + "dirac", 544 + CODEC_TYPE_VIDEO, 545 + CODEC_ID_DIRAC, 546 + sizeof(FfmpegDiracParams), 547 + dirac_decode_init, 548 + NULL, 549 + dirac_decode_close, 550 + dirac_decode_frame, 551 + CODEC_CAP_DELAY 552 +} ; 553 + 554 + 555 +static int dirac_sync_video_packet (const uint8_t **buf, int buf_size, 556 + FfmpegDiracParseContext *p_dirac_params, 557 + int *start) 558 +{ 559 + int bytes_read = 0; 560 + unsigned char* p_dirac_videobuf_code = p_dirac_params->dirac_videobuf_code; 561 + p_dirac_params->dirac_videobuf_len=0; 562 + 563 + while(p_dirac_params->dirac_videobuf_code_len<5) 564 + { 565 + p_dirac_videobuf_code[p_dirac_params->dirac_videobuf_code_len++]=*(*buf); 566 + (*buf)++; 567 + ++bytes_read; 568 + } 569 + while (1) 570 + { 571 + int c; 572 + if(p_dirac_videobuf_code[0]==0x42 && p_dirac_videobuf_code[1]==0x42 && p_dirac_videobuf_code[2]==0x43 && p_dirac_videobuf_code[3]==0x44) 573 + break; 574 + 575 + if (bytes_read >= buf_size ) 576 + return -1; 577 + 578 + ++(*start); 579 + p_dirac_videobuf_code[0]=p_dirac_videobuf_code[1]; 580 + p_dirac_videobuf_code[1]=p_dirac_videobuf_code[2]; 581 + p_dirac_videobuf_code[2]=p_dirac_videobuf_code[3]; 582 + p_dirac_videobuf_code[3]=p_dirac_videobuf_code[4]; 583 + c = *(*buf); 584 + (*buf)++; 585 + ++bytes_read; 586 + p_dirac_videobuf_code[4]=c; 587 + } 588 + 589 + return p_dirac_videobuf_code[4]; 590 +} 591 + 592 +static int dirac_find_frame_end(FfmpegDiracParseContext *p_dirac_params, 593 + const uint8_t *buf, 594 + uint8_t *p_buf_end, int cur_idx) 595 +{ 596 + int byte; 597 + int end_idx=cur_idx; 598 + 599 + /* find end of frame */ 600 + int shift = 0xffffffff; 601 + p_dirac_params->dirac_videobuf_code_len = 0; 602 + while (p_dirac_params->in_frame) 603 + { 604 + if(buf==p_buf_end) 605 + return -1; 606 + 607 + byte = *buf; 608 + if (byte < 0) 609 + return -1; 610 + 611 + if (shift == 0x42424344) 612 + { 613 + p_dirac_params->in_frame = 0; 614 + p_dirac_params->dirac_videobuf_code_len = 5; 615 + p_dirac_params->dirac_videobuf_code[0] = 0x42; 616 + p_dirac_params->dirac_videobuf_code[1] = 0x42; 617 + p_dirac_params->dirac_videobuf_code[2] = 0x43; 618 + p_dirac_params->dirac_videobuf_code[3] = 0x44; 619 + p_dirac_params->dirac_videobuf_code[4] = byte; 620 + return end_idx; 621 + } 622 + shift = (shift << 8 ) | byte; 623 + buf++; 624 + end_idx++; 625 + } 626 + 627 + return -1; 628 + 629 +} 630 + 631 +/* 632 +* Access unit header = 0x00 633 +* Intra_Ref start = 0x0C 634 +* Intra_NonRef start = 0x08 635 +* Inter_Ref_1Ref start = 0x0D 636 +* Inter_Ref_2Ref start = 0x0E 637 +* Inter_NonRef_1Ref start = 0x09 638 +* Inter_NonRef_2Ref start = 0x0A 639 +* End of sequence = 0x10 640 +*/ 641 +#define FRAME_START(c) ((c) == 0x00 || (c) == 0x0C || (c) == 0x08 || (c) == 0x0D || (c) == 0x0E || (c) == 0x09 || (c) == 0x0A || (c) == 0x10) 642 + 643 +static int dirac_find_frame_start(FfmpegDiracParseContext *p_dirac_params, const uint8_t **buf, int buf_size) 644 +{ 645 + unsigned int shift = 0xffffffff; 646 + int msg_type = 0; 647 + int start=0; 648 + 649 + /* find start of data */ 650 + msg_type = dirac_sync_video_packet(buf, buf_size, p_dirac_params, &start); 651 + 652 + if (msg_type < 0) 653 + return -1; 654 + 655 + 656 + /* find start of frame */ 657 + while (!p_dirac_params->in_frame) 658 + { 659 + int byte; 660 + if (FRAME_START(msg_type)) 661 + { 662 + p_dirac_params->in_frame = 1; 663 + return start; 664 + } 665 + 666 + byte = *(*buf); 667 + (*buf)++; 668 + 669 + if (byte < 0) 670 + { 671 + p_dirac_params->dirac_videobuf_code_len = 0; 672 + return -1; 673 + } 674 + 675 + if (shift == 0x42424344) 676 + { 677 + if (FRAME_START(byte)) 678 + { 679 + p_dirac_params->in_frame = 1; 680 + return start; 681 + } 682 + } 683 + shift = (shift << 8 ) | byte; 684 + start++; 685 + } 686 + 687 + return -1; 688 + 689 +} 690 + 691 + 692 +static int parse_dirac(AVCodecParserContext *s, 693 + AVCodecContext *avctx, 694 + uint8_t **poutbuf, int *poutbuf_size, 695 + const uint8_t *buf, int buf_size) 696 +{ 697 + 698 + int frame_start=0; 699 + int frame_end; 700 + uint8_t *p_cur=buf; 701 + 702 + FfmpegDiracParseContext *p_dirac_params = (FfmpegDiracParseContext*)s->priv_data ; 703 + 704 + if(buf_size==0) 705 + return 0; 706 + 707 + 708 + if(!p_dirac_params->in_frame) 709 + { 710 + frame_start=dirac_find_frame_start(p_dirac_params, &p_cur, buf_size); 711 + if(frame_start==-1) 712 + { 713 + *poutbuf = NULL; 714 + *poutbuf_size = 0; 715 + return buf_size; 716 + } 717 + } 718 + 719 + frame_end = dirac_find_frame_end(p_dirac_params, p_cur, buf+buf_size, p_cur-buf); 720 + 721 + /* no frame end - store data */ 722 + if(frame_end < 0) 723 + { 724 + memcpy(p_dirac_params->p_dirac_videobuffer+p_dirac_params->dirac_videobuf_len, 725 + buf+frame_start, buf_size-frame_start); 726 + p_dirac_params->dirac_videobuf_len+=buf_size-frame_start; 727 + 728 + *poutbuf = NULL; 729 + *poutbuf_size = 0; 730 + return buf_size; 731 + } 732 + 733 + /* have frame end */ 734 + memcpy(p_dirac_params->p_dirac_videobuffer+p_dirac_params->dirac_videobuf_len, 735 + buf+frame_start, frame_end-frame_start+1); 736 + p_dirac_params->dirac_videobuf_len+=frame_end-frame_start+1; 737 + 738 + /* construct new frame */ 739 + *poutbuf=av_malloc(p_dirac_params->dirac_videobuf_len); 740 + memcpy(*poutbuf, p_dirac_params->p_dirac_videobuffer, p_dirac_params->dirac_videobuf_len); 741 + *poutbuf_size = p_dirac_params->dirac_videobuf_len; 742 + 743 + 744 + return frame_end+1; 745 +} 746 + 747 + 748 + 749 +static int dirac_parse_close(AVCodecParserContext *s) 750 +{ 751 + FfmpegDiracParseContext *pc = s->priv_data; 752 + av_freep(&pc->p_dirac_videobuffer); 753 + return 0; 754 +} 755 + 756 +static int dirac_parse_open(AVCodecParserContext *s) 757 +{ 758 + FfmpegDiracParseContext *pc = s->priv_data; 759 + pc->p_dirac_videobuffer = (unsigned char *)av_malloc(0x100000); 760 + return 0; 761 + 762 +} 763 + 764 + 765 +AVCodecParser dirac_parser = { 766 + { CODEC_ID_DIRAC }, 767 + sizeof(FfmpegDiracParseContext), 768 + dirac_parse_open, 769 + parse_dirac, 770 + dirac_parse_close 771 +}; 772 Index: libavcodec/allcodecs.c 773 =================================================================== 774 --- libavcodec/allcodecs.c (revision 8090) 775 +++ libavcodec/allcodecs.c (working copy) 776 @@ -195,6 +195,7 @@ 777 REGISTER_ENCDEC(WMAV1, wmav1); 778 REGISTER_ENCDEC(WMAV2, wmav2); 779 REGISTER_DECODER(WS_SND1, ws_snd1); 780 + REGISTER_ENCDEC(DIRAC, dirac); 781 782 /* pcm codecs */ 783 REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); 784 @@ -246,6 +247,7 @@ 785 REGISTER_ENCDEC (DVDSUB, dvdsub); 786 787 /* parsers */ 788 + REGISTER_PARSER (DIRAC, dirac); 789 REGISTER_PARSER (AAC, aac); 790 REGISTER_PARSER (AC3, ac3); 791 REGISTER_PARSER (CAVSVIDEO, cavsvideo); 792 Index: libavcodec/Makefile 793 =================================================================== 794 --- libavcodec/Makefile (revision 8090) 795 +++ libavcodec/Makefile (working copy) 796 @@ -253,6 +253,7 @@ 797 OBJS-$(CONFIG_LIBFAAC) += faac.o 798 OBJS-$(CONFIG_LIBFAAD) += faad.o 799 OBJS-$(CONFIG_LIBGSM) += libgsm.o 800 +OBJS-$(CONFIG_DIRAC) += dirac.o 801 OBJS-$(CONFIG_LIBMP3LAME) += mp3lameaudio.o 802 OBJS-$(CONFIG_LIBTHEORA) += libtheoraenc.o 803 OBJS-$(CONFIG_LIBVORBIS) += oggvorbis.o 804 Index: libavcodec/avcodec.h 805 =================================================================== 806 --- libavcodec/avcodec.h (revision 8090) 807 +++ libavcodec/avcodec.h (working copy) 808 @@ -245,6 +245,8 @@ 809 CODEC_ID_DVD_SUBTITLE= 0x17000, 810 CODEC_ID_DVB_SUBTITLE, 811 812 + CODEC_ID_DIRAC= 0x18000, 813 + 814 CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport 815 stream (only used by libavformat) */ 816 }; 817 @@ -2202,6 +2204,7 @@ 818 extern AVCodec xvid_encoder; 819 extern AVCodec zlib_encoder; 820 extern AVCodec zmbv_encoder; 821 +extern AVCodec dirac_encoder; 822 823 extern AVCodec aac_decoder; 824 extern AVCodec aasc_decoder; 825 @@ -2329,6 +2332,7 @@ 826 extern AVCodec xl_decoder; 827 extern AVCodec zlib_decoder; 828 extern AVCodec zmbv_decoder; 829 +extern AVCodec dirac_decoder; 830 831 /* pcm codecs */ 832 #define PCM_CODEC(id, name) \ 833 @@ -2854,8 +2858,8 @@ 834 extern AVCodecParser mpegvideo_parser; 835 extern AVCodecParser pnm_parser; 836 extern AVCodecParser vc1_parser; 837 +extern AVCodecParser dirac_parser; 838 839 - 840 typedef struct AVBitStreamFilterContext { 841 void *priv_data; 842 struct AVBitStreamFilter *filter; 843 Index: libavformat/raw.c 844 =================================================================== 845 --- libavformat/raw.c (revision 8090) 846 +++ libavformat/raw.c (working copy) 847 @@ -222,6 +222,23 @@ 848 return 0; 849 } 850 851 +/* drc read */ 852 +static int dirac_read_header(AVFormatContext *s, 853 + AVFormatParameters *ap) 854 +{ 855 + AVStream *st; 856 + 857 + st = av_new_stream(s, 0); 858 + if (!st) 859 + return AVERROR_NOMEM; 860 + 861 + st->codec->codec_type = CODEC_TYPE_VIDEO; 862 + st->codec->codec_id = CODEC_ID_DIRAC; 863 + st->need_parsing = 1; 864 + /* the parameters will be extracted from the compressed bitstream */ 865 + return 0; 866 +} 867 + 868 static int shorten_read_header(AVFormatContext *s, 869 AVFormatParameters *ap) 870 { 871 @@ -728,6 +745,32 @@ 872 .value = CODEC_ID_VC1, 873 }; 874 875 +AVInputFormat dirac_iformat = { 876 + "dirac", 877 + "raw dirac", 878 + 0, 879 + NULL, 880 + dirac_read_header, 881 + raw_read_partial_packet, 882 + raw_read_close, 883 + .extensions = "drc", 884 +}; 885 + 886 +#ifdef CONFIG_MUXERS 887 +AVOutputFormat dirac_oformat = { 888 + "dirac", 889 + "raw dirac", 890 + "dirac", 891 + "drc", 892 + 0, 893 + CODEC_ID_DIRAC, 894 + 0, 895 + raw_write_header, 896 + raw_write_packet, 897 + raw_write_trailer, 898 +}; 899 +#endif //CONFIG_MUXERS 900 + 901 /* pcm formats */ 902 903 #define PCMINPUTDEF(name, long_name, ext, codec) \ 904 Index: libavformat/allformats.c 905 =================================================================== 906 --- libavformat/allformats.c (revision 8090) 907 +++ libavformat/allformats.c (working copy) 908 @@ -155,6 +155,8 @@ 909 REGISTER_DEMUXER (WV, wv); 910 REGISTER_DEMUXER (X11_GRAB_DEVICE, x11_grab_device); 911 REGISTER_MUXDEMUX(YUV4MPEGPIPE, yuv4mpegpipe); 912 + if(ENABLE_DIRAC_ENCODER) av_register_output_format(&dirac_oformat); 913 + if(ENABLE_DIRAC_DECODER) av_register_input_format(&dirac_iformat); 914 915 #ifdef CONFIG_PROTOCOLS 916 /* file protocols */ 917 Index: libavformat/allformats.h 918 =================================================================== 919 --- libavformat/allformats.h (revision 8090) 920 +++ libavformat/allformats.h (working copy) 921 @@ -167,6 +167,8 @@ 922 extern AVInputFormat yuv4mpegpipe_demuxer; 923 extern AVInputFormat tiertexseq_demuxer; 924 extern AVInputFormat x11_grab_device_demuxer; 925 +extern AVOutputFormat dirac_oformat; 926 +extern AVInputFormat dirac_iformat; 927 928 /* raw.c */ 929 int pcm_read_seek(AVFormatContext *s, 930 Index: libavformat/riff.c 931 =================================================================== 932 --- libavformat/riff.c (revision 8090) 933 +++ libavformat/riff.c (working copy) 934 @@ -166,6 +166,7 @@ 935 { CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') }, 936 { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') }, 937 { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') }, 938 + { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, 939 { CODEC_ID_NONE, 0 }, 940 }; 941 |