00001
00019 #include "vetCodec_XVID.h"
00020 #include "../vetUtility.h"
00021
00022
00023
00024 vetCodec_XVID::vetCodec_XVID(char *filename, int stream) : vetCodec()
00033 {
00034 DEBUGMSG("vetCodec_XVID::vetCodec_XVID(char *filename, FileFormat format) [CONTRUCTOR] ", *filename)
00035
00036 stream_handle = NULL;
00037 mp4_buffer = NULL;
00038 buffer = NULL;
00039
00040 setParameters(NULL);
00041 reset();
00042
00043 init();
00044
00045 load( filename, stream );
00046
00047 }
00048
00049 vetCodec_XVID::vetCodec_XVID( vetCodec_XVIDParameters* initParams ) : vetCodec()
00050 {
00051 DEBUGMSG("vetCodec_XVID::vetCodec_XVID(vetCodec_XVIDParameters* initParams) [CONTRUCTOR] ", *filename)
00052
00053 stream_handle = NULL;
00054 mp4_buffer = NULL;
00055 buffer = NULL;
00056
00057 setParameters(initParams);
00058 reset();
00059
00060 init();
00061 }
00062
00063 VETRESULT vetCodec_XVID::reset()
00064 {
00065 INFO("VETRESULT vetCodec_XVID::reset() [SET DEFAULT PARAMETERS]")
00066
00067 setName("XVID Coder");
00068 setDescription("Read or write video stream.");
00069 setVersion(1.0);
00070
00071 use_assembler = 0;
00072 debug_level = 0;
00073 mp4_ptr = NULL;
00074
00075 height = 0;
00076 width = 0;
00077
00078 totaldectime = 0;
00079 totalsize = 0;
00080 filenr = 0;
00081
00082 chunk = 0;
00083 if (myParams != NULL)
00084 myParams->reset();
00085
00086
00087 if (stream_handle != NULL)
00088 close();
00089
00090 if (mp4_buffer != NULL || buffer != NULL)
00091 release();
00092
00093 mp4_buffer = NULL;
00094 buffer = NULL;
00095
00096 return VETRET_OK;
00097 }
00098
00099
00100 VETRESULT vetCodec_XVID::setParameters (vetCodec_XVIDParameters* initParams)
00101 {
00102
00103 if ( initParams == NULL )
00104 myParams = new vetCodec_XVIDParameters();
00105 else
00106 myParams = initParams;
00107
00108 return VETRET_OK;
00109 }
00110
00111 vetCodec_XVID::~vetCodec_XVID()
00112 {
00113
00114
00115 if (stream_handle != NULL)
00116 close();
00117
00118 if (buffer != NULL)
00119 release();
00120 }
00121
00122 bool vetCodec_XVID::EoF()
00123 {
00124 if (stream_handle == NULL)
00125 return true;
00126
00127
00128 return false;
00129 }
00130
00131
00132
00133 VETRESULT vetCodec_XVID::extractTo(vetFrameYUV420& img)
00134 {
00135 DEBUGMSG("VETRESULT vetCodec_XVID::extractTo(vetFrameYUV420& img) [pushing data]", doBuffering)
00136
00137 if (stream_handle == NULL)
00138 return VETRET_ILLEGAL_USE;
00139
00140 return VETRET_NOT_IMPLEMENTED;
00141
00142 }
00143
00144 VETRESULT vetCodec_XVID::extractTo(vetFrameRGB24& img)
00145 {
00146 DEBUGMSG("VETRESULT vetCodec_XVID::extractTo(vetFrameRGB24& img) [pushing data]", doBuffering)
00147
00148 if (stream_handle == NULL)
00149 return VETRET_ILLEGAL_USE;
00150
00151 if (width != img.width || height != img.height)
00152 img.reAllocCanvas(width, height);
00153
00154 int ret = doDecodeFrame();
00155
00156 vetUtility::conv_bgr_rgb((unsigned char*)img.data[0], buffer, width, height);
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 return ret;
00180
00181
00182 }
00183
00184
00185 VETRESULT vetCodec_XVID::extractTo(vetFrameT<unsigned char>& img)
00186 {
00187 DEBUGMSG("VETRESULT vetCodec_XVID::extractTo(vetFrameT& img) [pushing data]", doBuffering)
00188
00189 if (stream_handle == NULL)
00190 return VETRET_ILLEGAL_USE;
00191
00192 int ret = VETRET_OK;
00193
00194 if ( img.profile == vetFrame::VETFRAME_BGR24 )
00195 {
00196 if (width != img.width || height != img.height)
00197 img.reAllocCanvas(width, height);
00198
00199 ret = doDecodeFrame();
00200
00201 memcpy( (unsigned char*)img.data[0], buffer, width * height * 3 );
00202
00203 return ret;
00204 }
00205
00206 return VETRET_NOT_IMPLEMENTED;
00207
00208 }
00209
00210
00211
00212 VETRESULT vetCodec_XVID::importFrom(vetFrameYUV420& img)
00213 {
00214 DEBUGMSG("VETRESULT vetCodec_XVID::importFrom(vetFrameYUV420& img) [reading data]", doBuffering)
00215
00216 return VETRET_NOT_IMPLEMENTED;
00217
00218 }
00219
00220
00221 VETRESULT vetCodec_XVID::importFrom(vetFrameRGB24& img)
00222 {
00223 DEBUGMSG("VETRESULT vetCodec_XVID::importFrom(vetFrameRGB24& img) [reading data]", doBuffering)
00224
00225 return VETRET_NOT_IMPLEMENTED;
00226
00227 }
00228
00229
00230 VETRESULT vetCodec_XVID::importFrom(vetFrameT<unsigned char>& img)
00231 {
00232 DEBUGMSG("VETRESULT vetCodec_XVID::importFrom(vetFrameT<unsigned char>& img) [reading data]", doBuffering)
00233
00234 return VETRET_NOT_IMPLEMENTED;
00235
00236 }
00237
00238
00239
00240 VETRESULT vetCodec_XVID::save(char *filename, int stream)
00241 {
00242 INFO("VETRESULT vetCodec_XVID::save() [saving buffered data]")
00243
00244 return VETRET_NOT_IMPLEMENTED;
00245 }
00246
00247 VETRESULT vetCodec_XVID::save()
00248 {
00249 INFO("VETRESULT vetCodec_XVID::save() [saving buffered data]")
00250
00251 return VETRET_NOT_IMPLEMENTED;
00252 }
00253
00254
00255 VETRESULT vetCodec_XVID::load(char *filename, int stream)
00256 {
00257 DEBUGMSG("VETRESULT vetCodec_XVID::load(char *filename, FileFormat format) [loading data to buffer]", filename)
00258
00259 myParams->setFileName(filename);
00260 myParams->setStream(stream);
00261
00262 return load();
00263 }
00264
00265
00266
00267
00268
00269
00270 VETRESULT vetCodec_XVID::init()
00271 {
00272 INFO("VETRESULT vetCodec_XVID::init() [INITIALIZING MEMORY]")
00273
00274
00275 mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
00276 mp4_ptr = mp4_buffer;
00277
00278 if (!mp4_buffer)
00279 {
00280 free(mp4_buffer);
00281 return VETRET_INTERNAL_ERR;
00282 }
00283
00284 if ( dec_init(use_assembler, debug_level) )
00285 {
00286
00287 close();
00288 return VETRET_INTERNAL_ERR;
00289 }
00290
00291 return VETRET_OK;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 VETRESULT vetCodec_XVID::close()
00304 {
00305 INFO("VETRESULT vetCodec_XVID::close() [DESTROYING HANDLE]")
00306
00307 int ret;
00308 ret = xvid_decore(stream_handle, XVID_DEC_DESTROY, NULL, NULL);
00309 return ret;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 VETRESULT vetCodec_XVID::release()
00322 {
00323 INFO("VETRESULT vetCodec_XVID::release() [RELEASING MEMORY]")
00324
00325 free(buffer);
00326 free(mp4_buffer);
00327 return VETRET_OK;
00328 }
00329
00330 VETRESULT vetCodec_XVID::updateBuffer(unsigned int width, unsigned int height)
00331 {
00332 INFO("VETRESULT vetCodec_XVID::release() [RELEASING MEMORY]")
00333
00334
00335
00336 if ( buffer )
00337 free(buffer);
00338
00339
00340 buffer = (unsigned char*)malloc( width * height * 4);
00341 if ( buffer == NULL )
00342 {
00343 release();
00344 return VETRET_INTERNAL_ERR;
00345 }
00346
00347 return VETRET_OK;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 VETRESULT vetCodec_XVID::load()
00367 {
00368 INFO("VETRESULT vetCodec_XVID::load() [loading data to buffer]")
00369
00370 file = fopen(myParams->fileName, "rb");
00371
00372 if (file == NULL)
00373 return VETRET_PARAM_ERR;
00374
00375
00376
00377 INFO("VETRESULT vetCodec_XVID::dodecode()")
00378
00379 if ( file == NULL)
00380 return VETRET_ILLEGAL_USE;
00381
00382
00383 useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, file);
00384
00385 totaldectime = 0;
00386 totalsize = 0;
00387 filenr = 0;
00388 mp4_ptr = mp4_buffer;
00389
00390 chunk = 0;
00391
00392 int ret = doDecodeFrame();
00393
00394 return VETRET_OK;
00395 }
00396
00397
00398
00399 VETRESULT vetCodec_XVID::doDecodeFrame()
00400 {
00401 int used_bytes = 0;
00402 double dectime;
00403
00404
00405
00406
00407 if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2)
00408 {
00409 int already_in_buffer = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
00410
00411
00412 if (already_in_buffer > 0)
00413 memcpy(mp4_buffer, mp4_ptr, already_in_buffer);
00414
00415
00416 mp4_ptr = mp4_buffer;
00417
00418
00419 if( feof(file) )
00420 {
00421 flush();
00422 return VETRET_INTERNAL_ERR;
00423 }
00424
00425 useful_bytes += fread(mp4_buffer + already_in_buffer,
00426 1, BUFFER_SIZE - already_in_buffer,
00427 file);
00428
00429 }
00430
00431
00432
00433 do
00434 {
00435
00436
00437 dectime =vetUtility::getTime_usec();
00438 used_bytes = dec_main(mp4_ptr, buffer, useful_bytes, &xvid_dec_stats);
00439 dectime = vetUtility::getTime_usec() - dectime;
00440
00441
00442
00443
00444
00445 if(xvid_dec_stats.type == XVID_TYPE_VOL) {
00446
00447
00448 if(width*height < xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height) {
00449
00450
00451 width = xvid_dec_stats.data.vol.width;
00452 height = xvid_dec_stats.data.vol.height;
00453
00454 if ( updateBuffer(width, height) )
00455 return VETRET_INTERNAL_ERR;
00456
00457 }
00458
00459 }
00460
00461
00462 if(used_bytes > 0) {
00463 mp4_ptr += used_bytes;
00464 useful_bytes -= used_bytes;
00465
00466
00467 totalsize += used_bytes;
00468 }
00469
00470 DEBUGMSG("Data chunk", chunk)
00471 DEBUGMSG("bytes consumed", used_bytes)
00472 DEBUGMSG("bytes in buffer", useful_bytes)
00473 ++chunk;
00474
00475
00476 } while (xvid_dec_stats.type <= 0 && useful_bytes > 0);
00477
00478
00479
00480 if(useful_bytes < 0)
00481 {
00482 flush();
00483 return VETRET_INTERNAL_ERR;
00484 }
00485
00486
00487 totaldectime += dectime;
00488
00489
00490 DEBUGMSG("Frame", filenr)
00491 DEBUGMSG("type", type2str(xvid_dec_stats.type) )
00492 DEBUGMSG("dectime(ms) =", dectime)
00493 DEBUGMSG("length(bytes)", used_bytes)
00494
00495
00496
00497 filenr++;
00498
00499 return VETRET_OK;
00500 }
00501
00502
00503 VETRESULT vetCodec_XVID::flush()
00504 {
00505 useful_bytes = 0;
00506
00507
00508
00509
00510
00511 do {
00512
00513
00514 int used_bytes;
00515 double dectime;
00516
00517 do {
00518 dectime = vetUtility::getTime_usec();
00519 used_bytes = dec_main(NULL, buffer, -1, &xvid_dec_stats);
00520 dectime = vetUtility::getTime_usec() - dectime;
00521
00522 DEBUGMSG("Data chunk", chunk)
00523 DEBUGMSG("bytes consumed", used_bytes)
00524 DEBUGMSG("bytes in buffer", useful_bytes)
00525 ++chunk;
00526
00527 } while(used_bytes>=0 && xvid_dec_stats.type <= 0);
00528
00529 if (used_bytes < 0) {
00530 break;
00531 }
00532
00533
00534 totaldectime += dectime;
00535
00536
00537 DEBUGMSG("Frame", filenr)
00538 DEBUGMSG("type", type2str(xvid_dec_stats.type) )
00539 DEBUGMSG("dectime(ms) =", dectime)
00540 DEBUGMSG("length(bytes)", used_bytes)
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 filenr++;
00555
00556 }while(1);
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 if (filenr>0) {
00569 totalsize /= filenr;
00570 totaldectime /= filenr;
00571
00572
00573 }
00574
00575
00576
00577
00578 return VETRET_OK;
00579 }
00580
00581
00582
00583
00584
00585
00586 VETRESULT vetCodec_XVID::doDecode(long frameCount)
00587 {
00588 bool temp;
00589 do
00590 {
00591 if ( doDecodeFrame() )
00592 temp = false;
00593
00594 filenr++;
00595
00596 if (frameCount && filenr > frameCount)
00597 temp = false;
00598
00599 } while ( ( useful_bytes>0 || !feof(file) ) && temp);
00600
00601 return flush();
00602 }
00603
00604
00605
00606
00607
00608
00609
00610 const char * type2str(int type)
00611 {
00612 if (type==XVID_TYPE_IVOP)
00613 return "I";
00614 if (type==XVID_TYPE_PVOP)
00615 return "P";
00616 if (type==XVID_TYPE_BVOP)
00617 return "B";
00618 return "S";
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00641
00642
00643
00644
00645 VETRESULT vetCodec_XVID::dec_init(int use_assembler, int debug_level)
00646 {
00647 INFO("VETRESULT vetCodec_XVID::dec_init(int use_assembler, int debug_level) [INITIALIZING MEMORY]")
00648
00649 int ret;
00650
00651 xvid_gbl_init_t xvid_gbl_init;
00652 xvid_dec_create_t xvid_dec_create;
00653
00654
00655 memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t));
00656 memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t));
00657
00658
00659
00660
00661
00662
00663 xvid_gbl_init.version = XVID_VERSION;
00664
00665
00666 if(use_assembler)
00667 #ifdef ARCH_IS_IA64
00668 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
00669 #else
00670 xvid_gbl_init.cpu_flags = 0;
00671 #endif
00672 else
00673 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
00674
00675 xvid_gbl_init.debug = debug_level;
00676
00677 xvid_global(NULL, 0, &xvid_gbl_init, NULL);
00678
00679
00680
00681
00682
00683
00684 xvid_dec_create.version = XVID_VERSION;
00685
00686
00687
00688
00689
00690 xvid_dec_create.width = 0;
00691 xvid_dec_create.height = 0;
00692
00693 ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL);
00694
00695 stream_handle = xvid_dec_create.handle;
00696
00697 return(ret);
00698 }
00699
00700
00701 static int BPP = 3;
00702 static int CSP = XVID_CSP_BGR;
00703
00704
00705
00706 VETRESULT vetCodec_XVID::dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats)
00707 {
00708 INFO("VETRESULT vetCodec_XVID::dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, xvid_dec_stats_t *xvid_dec_stats) [DECODE ONE FRAME]")
00709 DEBUG(istream)
00710 DEBUG(ostream)
00711 DEBUG(istream_size)
00712
00713 int ret;
00714
00715 xvid_dec_frame_t xvid_dec_frame;
00716
00717
00718 memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t));
00719 memset(xvid_dec_stats, 0, sizeof(xvid_dec_stats_t));
00720
00721
00722 xvid_dec_frame.version = XVID_VERSION;
00723 xvid_dec_stats->version = XVID_VERSION;
00724
00725
00726 xvid_dec_frame.general = 0;
00727
00728
00729 xvid_dec_frame.bitstream = istream;
00730 xvid_dec_frame.length = istream_size;
00731
00732
00733 xvid_dec_frame.output.plane[0] = ostream;
00734 xvid_dec_frame.output.stride[0] = width*BPP;
00735 xvid_dec_frame.output.csp = CSP;
00736
00737 ret = xvid_decore(stream_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats);
00738
00739
00740
00741 return(ret);
00742 }
00743
00744
00745
00746
00747
00748
00749 VETRESULT vetCodec_XVID::write_pnm(char *filename, unsigned char *image)
00750 {
00751 INFO("VETRESULT vetCodec_XVID::write_pnm(char *filename, unsigned char *image)")
00752
00753 FILE * f;
00754
00755 f = fopen(filename, "wb");
00756 if ( f == NULL) {
00757 return -1;
00758 }
00759
00760 if (BPP == 1) {
00761 unsigned int i;
00762 fprintf(f, "P5\n#xvid\n%i %i\n255\n", width, height*3/2);
00763
00764 fwrite(image, 1, width*height, f);
00765
00766 for (i=0; i<height/2;i++) {
00767 fwrite(image+width*height + i*width/2, 1, width/2, f);
00768 fwrite(image+5*width*height/4 + i*width/2, 1, width/2, f);
00769 }
00770 } else if (BPP == 3) {
00771 unsigned int i;
00772 fprintf(f, "P6\n#xvid\n%i %i\n255\n", width, height);
00773 for (i=0; i<width*height*3; i+=3) {
00774
00775
00776
00777
00778
00779 fputc(image[i+0], f);
00780 fputc(image[i+1], f);
00781 fputc(image[i+2], f);
00782
00783 }
00784 }
00785
00786 fclose(f);
00787
00788 return 0;
00789 }
00790
00791
00792
00793 VETRESULT vetCodec_XVID::write_image(char *prefix, unsigned char *image)
00794 {
00795 INFO("VETRESULT vetCodec_XVID::write_image(char *prefix, unsigned char *image)")
00796
00797 char filename[1024];
00798 char *ext;
00799 int ret;
00800
00801 if (BPP == 1) {
00802 ext = "pgm";
00803 } else if (BPP == 3) {
00804 ext = "pnm";
00805 } else {
00806 fprintf(stderr, "Bug: should not reach this path code -- please report to xvid-devel@xvid.org with command line options used");
00807 exit(-1);
00808 }
00809
00810 sprintf(filename, "%s.%s", prefix, ext);
00811
00812 ret = write_pnm(filename, image);
00813
00814 return(ret);
00815 }
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 vetCodec_XVIDParameters::vetCodec_XVIDParameters()
00840 {
00841 reset();
00842 }
00843
00844 vetCodec_XVIDParameters::vetCodec_XVIDParameters(const char* filename, int stream, long frameIndex)
00845 {
00846 reset();
00847 setFileName(filename);
00848 setStream(stream);
00849 setFrameIndex(frameIndex);
00850 }
00851
00852 void vetCodec_XVIDParameters::reset()
00853 {
00854 strcpy(fileName, (const char*)"input.avi\0");
00855 frameIndex = 0;
00856 stream = 0;
00857 }
00858
00859
00860 void vetCodec_XVIDParameters::setFileName(const char *filename)
00861 {
00862 strncpy(fileName, filename, 64);
00863 }
00864
00865 void vetCodec_XVIDParameters::setFrameIndex(long index)
00866 {
00867 frameIndex = index;
00868 }
00869
00870 void vetCodec_XVIDParameters::setStream(int s)
00871 {
00872 stream = s;
00873 }
00874
00875
00876 int vetCodec_XVIDParameters::saveToStreamXML(FILE *fp)
00877 {
00878 if ( fp == NULL )
00879 return VETRET_PARAM_ERR;
00880
00881 if( fprintf(fp, "<vetCodec_XVIDParameters>\n") == EOF )
00882 return VETRET_INTERNAL_ERR;
00883
00884 if ( fprintf(fp, " <filename value=\"%s\" />\n", fileName) == EOF)
00885 return VETRET_INTERNAL_ERR;
00886
00887 if ( fprintf(fp, " <stream value=\"%d\" />\n", stream) == EOF)
00888 return VETRET_INTERNAL_ERR;
00889
00890 if ( fprintf(fp, " <frameIndex value=\"%ld\" />\n", frameIndex) == EOF)
00891 return VETRET_INTERNAL_ERR;
00892
00893 if( fprintf(fp, "</vetCodec_XVIDParameters>\n") == EOF )
00894 return VETRET_INTERNAL_ERR;
00895
00896 return VETRET_OK;
00897 }
00898
00899
00900 int vetCodec_XVIDParameters::loadFromStreamXML(FILE *fp)
00901 {
00902 if ( fscanf(fp, "<vetCodec_XVIDParameters>\n") == EOF )
00903 throw "error in XML file, unable to import data.";
00904
00905 if ( fscanf(fp, " <filename value=\"%s\" />\n", fileName) == EOF )
00906 throw "error in XML file, unable to import data.";
00907
00908 if ( fscanf(fp, " <stream value=\"%d\" />\n", &stream) == EOF )
00909 throw "error in XML file, unable to import data.";
00910
00911 if ( fscanf(fp, " <frameIndex value=\"%ld\" />\n", &frameIndex) == EOF )
00912 throw "error in XML file, unable to import data.";
00913
00914 return VETRET_OK;
00915 }
00916
00917
00918
00919