00001
00002
00003
00004
00005
00006 #include "stdafx.h"
00007
00008 #pragma warning (disable: 4244)
00009
00010 BOOL APIENTRY DllMain( HANDLE hModule,
00011 DWORD ul_reason_for_call,
00012 LPVOID lpReserved
00013 )
00014 {
00015 return TRUE;
00016 }
00017
00018 #define INT64_C __int64
00019
00020 #include <ffmpeg/avformat.h>
00021 #include <ffmpeg/swscale.h>
00022 #include <ffmpeg/avcodec.h>
00023 #include <ffmpeg/fifo.h>
00024 #include <limits.h>
00025 #include <ffmpeg/opt.h>
00026 #include "berrno.h"
00027 #include <math.h>
00028 #include <assert.h>
00029 #include <limits.h>
00030 #include "fifo.c"
00031
00032 typedef struct AVStreamMap {
00033 int file_index;
00034 int stream_index;
00035 int sync_file_index;
00036 int sync_stream_index;
00037 } AVStreamMap;
00038
00039 typedef struct AVMetaDataMap {
00040 int out_file;
00041 int in_file;
00042 } AVMetaDataMap;
00043
00044 #define MAX_FILES 20
00045 char* _psz1 = "tex^qComp";
00046 char* _psz2 = "video4linux";
00047 char* _psz3 = "ntsc";
00048 char* _psz4 = "audio_device";
00049
00050 struct vmsMediaConverterJob {
00051
00052 AVFormatContext *input_files[MAX_FILES];
00053 int64_t input_files_ts_offset[MAX_FILES];
00054 int nb_input_files ;
00055
00056 AVFormatContext *output_files[MAX_FILES];
00057 int nb_output_files ;
00058
00059 AVStreamMap stream_maps[MAX_FILES];
00060 int nb_stream_maps;
00061
00062 AVMetaDataMap meta_data_maps[MAX_FILES];
00063 int nb_meta_data_maps;
00064
00065 AVInputFormat *file_iformat;
00066 AVOutputFormat *file_oformat;
00067 int frame_width ;
00068 int frame_height ;
00069 float frame_aspect_ratio ;
00070 enum PixelFormat frame_pix_fmt ;
00071 int frame_padtop ;
00072 int frame_padbottom ;
00073 int frame_padleft ;
00074 int frame_padright ;
00075 int padcolor[3] ;
00076 int frame_topBand ;
00077 int frame_bottomBand ;
00078 int frame_leftBand ;
00079 int frame_rightBand ;
00080 int max_frames[4] ;
00081 int frame_rate ;
00082 int frame_rate_base ;
00083 float video_qscale ;
00084 int video_qdiff ;
00085 uint16_t *intra_matrix ;
00086 uint16_t *inter_matrix ;
00087 #if 0
00088 float video_rc_qsquish ;
00089 float video_rc_qmod_amp ;
00090 int video_rc_qmod_freq ;
00091 #endif
00092 char *video_rc_override_string ;
00093 char *video_rc_eq ;
00094 int me_method ;
00095 int video_disable ;
00096 int video_discard ;
00097 int video_codec_id ;
00098 int video_codec_tag ;
00099 int same_quality ;
00100 int do_deinterlace ;
00101 int packet_size ;
00102 int strict ;
00103 int top_field_first ;
00104 int me_threshold ;
00105 int intra_dc_precision ;
00106 int loop_input ;
00107 int loop_output ;
00108 int qp_hist ;
00109
00110 int intra_only ;
00111 int audio_sample_rate ;
00112 int audio_bit_rate ;
00113 #define QSCALE_NONE -99999
00114 float audio_qscale ;
00115 int audio_disable ;
00116 int audio_channels ;
00117 int audio_codec_id ;
00118 int audio_codec_tag ;
00119 char *audio_language ;
00120
00121 int subtitle_codec_id ;
00122 char *subtitle_language ;
00123
00124 float mux_preload ;
00125 float mux_max_delay ;
00126
00127 int64_t recording_time ;
00128 int64_t start_time ;
00129 int64_t rec_timestamp ;
00130 int64_t input_ts_offset ;
00131 int file_overwrite ;
00132 char *str_title ;
00133 char *str_author ;
00134 char *str_copyright ;
00135 char *str_comment ;
00136 char *str_album ;
00137 int do_benchmark ;
00138 int do_hex_dump ;
00139 int do_pkt_dump ;
00140 int do_psnr ;
00141 int do_vstats ;
00142 int do_pass ;
00143 char *pass_logfilename ;
00144 int audio_stream_copy ;
00145 int video_stream_copy ;
00146 int subtitle_stream_copy ;
00147 int video_sync_method ;
00148 int audio_sync_method;
00149 int copy_ts;
00150 int opt_shortest ;
00151 int video_global_header ;
00152
00153 int rate_emu ;
00154
00155 const char *video_grab_format ;
00156
00157 char *video_device ;
00158 char *grab_device ;
00159 int video_channel ;
00160 char *video_standard ;
00161
00162 const char *audio_grab_format ;
00163 char *audio_device ;
00164 int audio_volume ;
00165
00166 int using_stdin ;
00167 int using_vhook ;
00168
00169 int thread_count ;
00170 int q_pressed ;
00171 int64_t video_size ;
00172 int64_t audio_size ;
00173 int64_t extra_size ;
00174 int nb_frames_dup ;
00175 int nb_frames_drop ;
00176 int input_sync;
00177 int limit_filesize ;
00178
00179 int pgmyuv_compatibility_hack ;
00180 int dts_delta_threshold ;
00181
00182 int sws_flags ;
00183
00184 const char **opt_names ;
00185 int opt_name_count ;
00186 AVCodecContext *avctx_opts;
00187 AVFormatContext *avformat_opts;
00188
00189 AVBitStreamFilterContext *video_bitstream_filters ;
00190 AVBitStreamFilterContext *audio_bitstream_filters ;
00191 AVBitStreamFilterContext *bitstream_filters[MAX_FILES][MAX_STREAMS];
00192
00193 #define MAX_AUDIO_PACKET_SIZE (128 * 1024)
00194
00195 int bit_buffer_size;
00196 uint8_t *bit_buffer;
00197
00198 uint8_t *audio_buf ;
00199 uint8_t *audio_out ;
00200
00201 uint8_t *input_tmp ;
00202
00203 FILE *fvstats ;
00204
00205 uint8_t *subtitle_out ;
00206
00207 unsigned int samples_size ;
00208 short *samples ;
00209
00210 vmsMediaConverterJob ()
00211 {
00212 ZeroMemory (this, sizeof (vmsMediaConverterJob));
00213
00214 bit_buffer_size = 1024*256;
00215 bit_buffer = NULL;
00216
00217 audio_buf = NULL;
00218 audio_out = NULL;
00219
00220 input_tmp = NULL;
00221
00222 fvstats = NULL;
00223
00224 subtitle_out = NULL;
00225
00226 samples_size = 0;
00227 samples = NULL;
00228
00229 file_iformat = NULL;
00230 file_oformat = NULL;
00231 avctx_opts = NULL;
00232 avformat_opts = NULL;
00233
00234 nb_input_files = 0;
00235 nb_output_files = 0;
00236 frame_width = 0;
00237 frame_height = 0;
00238 frame_aspect_ratio = 0;
00239 PixelFormat frame_pix_fmt = PIX_FMT_NONE;
00240 frame_padtop = 0;
00241 frame_padbottom = 0;
00242 frame_padleft = 0;
00243 frame_padright = 0;
00244 padcolor [0] = 16; padcolor [1] = padcolor [2] = 128;
00245 frame_topBand = 0;
00246 frame_bottomBand = 0;
00247 frame_leftBand = 0;
00248 frame_rightBand = 0;
00249 max_frames [0] = max_frames [1] = max_frames [2] = max_frames [3] = INT_MAX;
00250 frame_rate = 25;
00251 frame_rate_base = 1;
00252 video_qscale = 0;
00253 video_qdiff = 3;
00254 intra_matrix = NULL;
00255 inter_matrix = NULL;
00256 video_rc_override_string =NULL;
00257 video_rc_eq =_psz1;
00258 me_method = ME_EPZS;
00259 video_disable = 0;
00260 video_discard = 0;
00261 video_codec_id = CODEC_ID_NONE;
00262 video_codec_tag = 0;
00263 same_quality = 0;
00264 do_deinterlace = 0;
00265 packet_size = 0;
00266 strict = 0;
00267 top_field_first = -1;
00268 me_threshold = 0;
00269 intra_dc_precision = 8;
00270 loop_input = 0;
00271 loop_output = AVFMT_NOOUTPUTLOOP;
00272 qp_hist = 0;
00273
00274 intra_only = 0;
00275 audio_sample_rate = 44100;
00276 audio_bit_rate = 64000;
00277 audio_qscale = QSCALE_NONE;
00278 audio_disable = 0;
00279 audio_channels = 1;
00280 audio_codec_id = CODEC_ID_NONE;
00281 audio_codec_tag = 0;
00282 audio_language = NULL;
00283
00284 subtitle_codec_id = CODEC_ID_NONE;
00285 subtitle_language = NULL;
00286
00287 mux_preload = 0.5f;
00288 mux_max_delay = 0.7f;
00289
00290 recording_time = 0;
00291 start_time = 0;
00292 rec_timestamp = 0;
00293 input_ts_offset = 0;
00294 file_overwrite = 0;
00295 str_title = NULL;
00296 str_author = NULL;
00297 str_copyright = NULL;
00298 str_comment = NULL;
00299 str_album = NULL;
00300 do_benchmark = 0;
00301 do_hex_dump = 0;
00302 do_pkt_dump = 0;
00303 do_psnr = 0;
00304 do_vstats = 0;
00305 do_pass = 0;
00306 pass_logfilename = NULL;
00307 audio_stream_copy = 0;
00308 video_stream_copy = 0;
00309 subtitle_stream_copy = 0;
00310 video_sync_method = 1;
00311 audio_sync_method = 0;
00312 copy_ts = 0;
00313 opt_shortest = 0;
00314 video_global_header = 0;
00315
00316 rate_emu = 0;
00317
00318 video_grab_format = _psz2;
00319
00320 video_device = NULL;
00321 grab_device = NULL;
00322 video_channel = 0;
00323 video_standard = _psz3;
00324
00325 audio_grab_format = _psz4;
00326 audio_device = NULL;
00327 audio_volume = 256;
00328
00329 using_stdin = 0;
00330 using_vhook = 0;
00331
00332 thread_count = 1;
00333 q_pressed = 0;
00334 video_size = 0;
00335 audio_size = 0;
00336 extra_size = 0;
00337 nb_frames_dup = 0;
00338 nb_frames_drop = 0;
00339 input_sync;
00340 limit_filesize = 0;
00341
00342 pgmyuv_compatibility_hack =0;
00343 dts_delta_threshold = 10;
00344
00345 sws_flags = SWS_BICUBIC;
00346
00347 opt_names =NULL;
00348 opt_name_count = 0;
00349 video_bitstream_filters =NULL;
00350 audio_bitstream_filters =NULL;
00351 }
00352
00353 };
00354
00355 #define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
00356
00357 struct AVInputStream;
00358
00359 typedef struct AVOutputStream {
00360 int file_index;
00361 int index;
00362 int source_index;
00363 AVStream *st;
00364 int encoding_needed;
00365 int frame_number;
00366
00367
00368 struct AVInputStream *sync_ist;
00369 int64_t sync_opts;
00370
00371 int video_resample;
00372 AVFrame pict_tmp;
00373 struct SwsContext *img_resample_ctx;
00374 int resample_height;
00375
00376 int video_crop;
00377 int topBand;
00378 int leftBand;
00379
00380 int video_pad;
00381 int padtop;
00382 int padbottom;
00383 int padleft;
00384 int padright;
00385
00386
00387 int audio_resample;
00388 ReSampleContext *resample;
00389 AVFifoBuffer fifo;
00390 FILE *logfile;
00391 } AVOutputStream;
00392
00393 typedef struct AVInputStream {
00394 int file_index;
00395 int index;
00396 AVStream *st;
00397 int discard;
00398 int decoding_needed;
00399 int64_t sample_index;
00400
00401 int64_t start;
00402 unsigned long frame;
00403 int64_t next_pts;
00404 int64_t pts;
00405 int is_start;
00406 } AVInputStream;
00407
00408 typedef struct AVInputFile {
00409 int eof_reached;
00410 int ist_index;
00411 int buffer_size;
00412 int buffer_size_max;
00413 int nb_streams;
00414 } AVInputFile;
00415
00416 bool opt_input_file(vmsMediaConverterJob *job, const char *filename)
00417 {
00418 AVFormatContext *ic;
00419 AVFormatParameters params, *ap = ¶ms;
00420 int err, i, ret, rfps, rfps_base;
00421 int64_t timestamp;
00422
00423
00424 ic = av_alloc_format_context();
00425
00426 memset(ap, 0, sizeof(*ap));
00427 ap->prealloced_context = 1;
00428 ap->sample_rate = job->audio_sample_rate;
00429 ap->channels = job->audio_channels;
00430 ap->time_base.den = job->frame_rate;
00431 ap->time_base.num = job->frame_rate_base;
00432 ap->width = job->frame_width + job->frame_padleft + job->frame_padright;
00433 ap->height = job->frame_height + job->frame_padtop + job->frame_padbottom;
00434 ap->pix_fmt = job->frame_pix_fmt;
00435 ap->device = job->grab_device;
00436 ap->channel = job->video_channel;
00437 ap->standard = job->video_standard;
00438 ap->video_codec_id = (CodecID)job->video_codec_id;
00439 ap->audio_codec_id = (CodecID)job->audio_codec_id;
00440 if(job->pgmyuv_compatibility_hack)
00441 ap->video_codec_id= CODEC_ID_PGMYUV;
00442
00443
00444
00445
00446 err = av_open_input_file(&ic, filename, job->file_iformat, 0, ap);
00447 if (err < 0)
00448 throw 0;
00449
00450 ic->loop_input = job->loop_input;
00451
00452
00453 ret = av_find_stream_info(ic);
00454 if (ret < 0)
00455 throw 0;
00456
00457 timestamp = job->start_time;
00458
00459 if (ic->start_time != AV_NOPTS_VALUE)
00460 timestamp += ic->start_time;
00461
00462
00463 if (job->start_time != 0) {
00464 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
00465 if (ret < 0) {
00466
00467 }
00468
00469 job->start_time = 0;
00470 }
00471
00472
00473 for(i=0;i<(int)ic->nb_streams;i++) {
00474 AVCodecContext *enc = ic->streams[i]->codec;
00475 #if defined(HAVE_THREADS)
00476 if(job->thread_count>1)
00477 avcodec_thread_init(enc, thread_count);
00478 #endif
00479 enc->thread_count= job->thread_count;
00480 switch(enc->codec_type) {
00481 case CODEC_TYPE_AUDIO:
00482
00483
00484 job->audio_channels = enc->channels;
00485 job->audio_sample_rate = enc->sample_rate;
00486 if(job->audio_disable)
00487 ic->streams[i]->discard= AVDISCARD_ALL;
00488 break;
00489 case CODEC_TYPE_VIDEO:
00490 enc->bit_rate = job->avctx_opts->bit_rate;
00491
00492 job->frame_height = enc->height;
00493 job->frame_width = enc->width;
00494 job->frame_aspect_ratio = (float)av_q2d(enc->sample_aspect_ratio) * enc->width / enc->height;
00495 job->frame_pix_fmt = enc->pix_fmt;
00496 rfps = ic->streams[i]->r_frame_rate.num;
00497 rfps_base = ic->streams[i]->r_frame_rate.den;
00498 if(enc->lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
00499 if(job->me_threshold)
00500 enc->debug |= FF_DEBUG_MV;
00501
00502 if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) {
00503
00504
00505
00506 }
00507
00508 job->frame_rate = rfps;
00509 job->frame_rate_base = rfps_base;
00510
00511 enc->rate_emu = job->rate_emu;
00512 if(job->video_disable)
00513 ic->streams[i]->discard= AVDISCARD_ALL;
00514 else if(job->video_discard)
00515 ic->streams[i]->discard= (AVDiscard)job->video_discard;
00516 break;
00517 case CODEC_TYPE_DATA:
00518 break;
00519 case CODEC_TYPE_SUBTITLE:
00520 break;
00521 case CODEC_TYPE_UNKNOWN:
00522 break;
00523 default:
00524 throw 0;
00525 }
00526 }
00527
00528 job->input_files[job->nb_input_files] = ic;
00529 job->input_files_ts_offset[job->nb_input_files] = job->input_ts_offset - (job->copy_ts ? 0 : timestamp);
00530
00531
00532 job->nb_input_files++;
00533 job->file_iformat = NULL;
00534 job->file_oformat = NULL;
00535
00536 job->grab_device = NULL;
00537 job->video_channel = 0;
00538
00539 job->rate_emu = 0;
00540
00541 return true;
00542 }
00543
00544 static bool check_audio_video_inputs(vmsMediaConverterJob *job, int *has_video_ptr, int *has_audio_ptr)
00545 {
00546 int has_video, has_audio, i, j;
00547 AVFormatContext *ic;
00548
00549 has_video = 0;
00550 has_audio = 0;
00551 for(j=0;j<job->nb_input_files;j++) {
00552 ic = job->input_files[j];
00553 for(i=0;i<(int)ic->nb_streams;i++) {
00554 AVCodecContext *enc = ic->streams[i]->codec;
00555 switch(enc->codec_type) {
00556 case CODEC_TYPE_AUDIO:
00557 has_audio = 1;
00558 break;
00559 case CODEC_TYPE_VIDEO:
00560 has_video = 1;
00561 break;
00562 case CODEC_TYPE_DATA:
00563 case CODEC_TYPE_UNKNOWN:
00564 case CODEC_TYPE_SUBTITLE:
00565 break;
00566 default:
00567 throw 0;
00568 }
00569 }
00570 }
00571 *has_video_ptr = has_video;
00572 *has_audio_ptr = has_audio;
00573 return true;
00574 }
00575
00576 static bool new_video_stream(vmsMediaConverterJob* job, AVFormatContext *oc)
00577 {
00578 AVStream *st;
00579 AVCodecContext *video_enc;
00580 int codec_id;
00581
00582 st = av_new_stream(oc, oc->nb_streams);
00583 if (!st)
00584 throw 0;
00585
00586 job->bitstream_filters[job->nb_output_files][oc->nb_streams - 1]= job->video_bitstream_filters;
00587 job->video_bitstream_filters= NULL;
00588
00589 #if defined(HAVE_THREADS)
00590 if(thread_count>1)
00591 avcodec_thread_init(st->codec, thread_count);
00592 #endif
00593
00594 video_enc = st->codec;
00595
00596 if(job->video_codec_tag)
00597 video_enc->codec_tag= job->video_codec_tag;
00598
00599 if( (job->video_global_header&1)
00600 || (job->video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
00601 video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
00602 job->avctx_opts->flags|= CODEC_FLAG_GLOBAL_HEADER;
00603 }
00604 if(job->video_global_header&2){
00605 video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
00606 job->avctx_opts->flags2|= CODEC_FLAG2_LOCAL_HEADER;
00607 }
00608
00609 if (job->video_stream_copy) {
00610 st->stream_copy = 1;
00611 video_enc->codec_type = CODEC_TYPE_VIDEO;
00612 } else {
00613 char *p;
00614 int i = 0;
00615 AVCodec *codec;
00616
00617 codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
00618 if (job->video_codec_id != CODEC_ID_NONE)
00619 codec_id = job->video_codec_id;
00620
00621 video_enc->codec_id = (CodecID)codec_id;
00622 codec = avcodec_find_encoder((CodecID)codec_id);
00623
00624 video_enc->bit_rate = job->avctx_opts->bit_rate;
00625
00626
00627
00628 video_enc->time_base.den = job->frame_rate;
00629 video_enc->time_base.num = job->frame_rate_base;
00630 if(codec && codec->supported_framerates){
00631 const AVRational *p= codec->supported_framerates;
00632 AVRational req= {job->frame_rate, job->frame_rate_base};
00633 const AVRational *best=NULL;
00634 AVRational best_error= {INT_MAX, 1};
00635 for(; p->den!=0; p++){
00636 AVRational error= av_sub_q(req, *p);
00637 if(error.num <0) error.num *= -1;
00638 if(av_cmp_q(error, best_error) < 0){
00639 best_error= error;
00640 best= p;
00641 }
00642 }
00643 video_enc->time_base.den= best->num;
00644 video_enc->time_base.num= best->den;
00645 }
00646
00647 video_enc->width = job->frame_width + job->frame_padright + job->frame_padleft;
00648 video_enc->height = job->frame_height + job->frame_padtop + job->frame_padbottom;
00649 video_enc->sample_aspect_ratio = av_d2q(job->frame_aspect_ratio*video_enc->height/video_enc->width, 255);
00650 video_enc->pix_fmt = job->frame_pix_fmt;
00651
00652 if(codec && codec->pix_fmts){
00653 const enum PixelFormat *p= codec->pix_fmts;
00654 for(; *p!=-1; p++){
00655 if(*p == video_enc->pix_fmt)
00656 break;
00657 }
00658 if(*p == -1)
00659 video_enc->pix_fmt = codec->pix_fmts[0];
00660 }
00661
00662 if (job->intra_only)
00663 video_enc->gop_size = 0;
00664 if (job->video_qscale || job->same_quality) {
00665 video_enc->flags |= CODEC_FLAG_QSCALE;
00666 video_enc->global_quality=
00667 st->quality = FF_QP2LAMBDA * job->video_qscale;
00668 }
00669
00670 if(job->intra_matrix)
00671 video_enc->intra_matrix = job->intra_matrix;
00672 if(job->inter_matrix)
00673 video_enc->inter_matrix = job->inter_matrix;
00674
00675 video_enc->max_qdiff = job->video_qdiff;
00676 video_enc->rc_eq = job->video_rc_eq;
00677 video_enc->thread_count = job->thread_count;
00678 p= job->video_rc_override_string;
00679
00680 video_enc->rc_override_count=i;
00681 if (!video_enc->rc_initial_buffer_occupancy)
00682 video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4;
00683 video_enc->me_threshold= job->me_threshold;
00684 video_enc->intra_dc_precision= job->intra_dc_precision - 8;
00685 video_enc->strict_std_compliance = job->strict;
00686
00687 if(job->packet_size){
00688 video_enc->rtp_mode= 1;
00689 video_enc->rtp_payload_size= job->packet_size;
00690 }
00691
00692 if (job->do_psnr)
00693 video_enc->flags|= CODEC_FLAG_PSNR;
00694
00695 video_enc->me_method = job->me_method;
00696
00697
00698 if (job->do_pass) {
00699 if (job->do_pass == 1) {
00700 video_enc->flags |= CODEC_FLAG_PASS1;
00701 } else {
00702 video_enc->flags |= CODEC_FLAG_PASS2;
00703 }
00704 }
00705 }
00706
00707
00708 job->video_disable = 0;
00709 job->video_codec_id = CODEC_ID_NONE;
00710 job->video_stream_copy = 0;
00711
00712 return true;
00713 }
00714
00715 static bool new_audio_stream(vmsMediaConverterJob* job, AVFormatContext *oc)
00716 {
00717 AVStream *st;
00718 AVCodecContext *audio_enc;
00719 int codec_id;
00720
00721 st = av_new_stream(oc, oc->nb_streams);
00722 if (!st)
00723 throw 0;
00724
00725 job->bitstream_filters[job->nb_output_files][oc->nb_streams - 1]= job->audio_bitstream_filters;
00726 job->audio_bitstream_filters= NULL;
00727
00728 #if defined(HAVE_THREADS)
00729 if(thread_count>1)
00730 avcodec_thread_init(st->codec, thread_count);
00731 #endif
00732
00733 audio_enc = st->codec;
00734 audio_enc->codec_type = CODEC_TYPE_AUDIO;
00735 audio_enc->strict_std_compliance = job->strict;
00736
00737 if(job->audio_codec_tag)
00738 audio_enc->codec_tag= job->audio_codec_tag;
00739
00740 if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
00741 audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
00742 job->avctx_opts->flags|= CODEC_FLAG_GLOBAL_HEADER;
00743 }
00744 if (job->audio_stream_copy) {
00745 st->stream_copy = 1;
00746 audio_enc->channels = job->audio_channels;
00747 } else {
00748 codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
00749
00750
00751
00752 if (job->audio_codec_id != CODEC_ID_NONE)
00753 codec_id = job->audio_codec_id;
00754 audio_enc->codec_id = (CodecID)codec_id;
00755
00756 audio_enc->bit_rate = job->audio_bit_rate;
00757 if (job->audio_qscale > QSCALE_NONE) {
00758 audio_enc->flags |= CODEC_FLAG_QSCALE;
00759 audio_enc->global_quality = st->quality = FF_QP2LAMBDA * job->audio_qscale;
00760 }
00761 audio_enc->thread_count = job->thread_count;
00762 audio_enc->channels = job->audio_channels;
00763 }
00764 audio_enc->sample_rate = job->audio_sample_rate;
00765 AVRational tmp = {1, job->audio_sample_rate};
00766 audio_enc->time_base= tmp;
00767 if (job->audio_language) {
00768 strcpy(st->language, job->audio_language);
00769 av_free(job->audio_language);
00770 job->audio_language = NULL;
00771 }
00772
00773
00774 job->audio_disable = 0;
00775 job->audio_codec_id = CODEC_ID_NONE;
00776 job->audio_stream_copy = 0;
00777 return true;
00778 }
00779
00780 static bool opt_output_file(vmsMediaConverterJob *job, const char *filename)
00781 {
00782 AVFormatContext *oc;
00783 int use_video, use_audio, input_has_video, input_has_audio;
00784 AVFormatParameters params, *ap = ¶ms;
00785
00786 oc = av_alloc_format_context();
00787
00788 if (!job->file_oformat) {
00789 job->file_oformat = guess_format(NULL, filename, NULL);
00790 if (!job->file_oformat)
00791 throw 0;
00792 }
00793
00794 oc->oformat = job->file_oformat;
00795 strcpy(oc->filename, filename);
00796
00797 if (false) {
00798
00799 } else {
00800 use_video = job->file_oformat->video_codec != CODEC_ID_NONE || job->video_stream_copy || job->video_codec_id != CODEC_ID_NONE;
00801 use_audio = job->file_oformat->audio_codec != CODEC_ID_NONE || job->audio_stream_copy || job->audio_codec_id != CODEC_ID_NONE;
00802
00803
00804 if (job->nb_input_files > 0) {
00805 check_audio_video_inputs(job, &input_has_video, &input_has_audio);
00806 if (!input_has_video)
00807 use_video = 0;
00808 if (!input_has_audio)
00809 use_audio = 0;
00810 }
00811
00812
00813 if (job->audio_disable) {
00814 use_audio = 0;
00815 }
00816 if (job->video_disable) {
00817 use_video = 0;
00818 }
00819
00820 if (use_video) {
00821 new_video_stream(job, oc);
00822 }
00823
00824 if (use_audio) {
00825 new_audio_stream(job, oc);
00826 }
00827
00828 oc->timestamp = job->rec_timestamp;
00829
00830 if (job->str_title)
00831 strcpy(oc->title, job->str_title);
00832 if (job->str_author)
00833 strcpy(oc->author, job->str_author);
00834 if (job->str_copyright)
00835 strcpy(oc->copyright, job->str_copyright);
00836 if (job->str_comment)
00837 strcpy(oc->comment, job->str_comment);
00838 if (job->str_album)
00839 strcpy(oc->album, job->str_album);
00840 }
00841
00842 job->output_files[job->nb_output_files++] = oc;
00843
00844
00845 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
00846 if (!av_filename_number_test(oc->filename))
00847 throw 0;
00848 }
00849
00850 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
00851
00852
00853 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
00854 throw 0;
00855 }
00856 }
00857
00858 memset(ap, 0, sizeof(*ap));
00859 if (av_set_parameters(oc, ap) < 0)
00860 throw 0;
00861
00862 oc->preload= (int)(job->mux_preload*AV_TIME_BASE);
00863 oc->max_delay= (int)(job->mux_max_delay*AV_TIME_BASE);
00864 oc->loop_output = job->loop_output;
00865
00866
00867
00868
00869 job->file_oformat = NULL;
00870 job->file_iformat = NULL;
00871 return true;
00872 }
00873
00874 static void pre_process_video_frame(vmsMediaConverterJob* job, AVInputStream *ist, AVPicture *picture, void **bufp)
00875 {
00876 AVCodecContext *dec;
00877 AVPicture *picture2;
00878 AVPicture picture_tmp;
00879 uint8_t *buf = 0;
00880
00881 dec = ist->st->codec;
00882
00883
00884 if (job->do_deinterlace || job->using_vhook) {
00885 int size;
00886
00887
00888 size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
00889 buf = (unsigned char*)av_malloc(size);
00890 if (!buf)
00891 return;
00892
00893 picture2 = &picture_tmp;
00894 avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
00895
00896 if (job->do_deinterlace){
00897 if(avpicture_deinterlace(picture2, picture,
00898 dec->pix_fmt, dec->width, dec->height) < 0) {
00899
00900 av_free(buf);
00901 buf = NULL;
00902 picture2 = picture;
00903 }
00904 } else {
00905 img_copy(picture2, picture, dec->pix_fmt, dec->width, dec->height);
00906 }
00907 } else {
00908 picture2 = picture;
00909 }
00910
00911
00912
00913 if (picture != picture2)
00914 *picture = *picture2;
00915 *bufp = buf;
00916 }
00917
00918 static double get_sync_ipts(vmsMediaConverterJob* job, const AVOutputStream *ost)
00919 {
00920 const AVInputStream *ist = ost->sync_ist;
00921 return (double)(ist->pts + job->input_files_ts_offset[ist->file_index] - job->start_time)/AV_TIME_BASE;
00922 }
00923
00924 static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){
00925 while(bsfc){
00926 AVPacket new_pkt= *pkt;
00927 int a= av_bitstream_filter_filter(bsfc, avctx, NULL,
00928 &new_pkt.data, &new_pkt.size,
00929 pkt->data, pkt->size,
00930 pkt->flags & PKT_FLAG_KEY);
00931 if(a){
00932 av_free_packet(pkt);
00933 new_pkt.destruct= av_destruct_packet;
00934 }
00935 *pkt= new_pkt;
00936
00937 bsfc= bsfc->next;
00938 }
00939
00940 av_interleaved_write_frame(s, pkt);
00941 }
00942
00943 static void do_audio_out(vmsMediaConverterJob *job,
00944 AVFormatContext *s,
00945 AVOutputStream *ost,
00946 AVInputStream *ist,
00947 unsigned char *buf, int size)
00948 {
00949 uint8_t *buftmp;
00950
00951 const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;
00952
00953 int size_out, frame_bytes, ret;
00954 AVCodecContext *enc= ost->st->codec;
00955
00956
00957 if (!job->audio_buf)
00958 job->audio_buf = (unsigned char*)av_malloc(2*MAX_AUDIO_PACKET_SIZE);
00959 if (!job->audio_out)
00960 job->audio_out = (unsigned char*)av_malloc(audio_out_size);
00961 if (!job->audio_buf || !job->audio_out)
00962 return;
00963
00964 if(job->audio_sync_method){
00965 double delta = get_sync_ipts(job, ost) * enc->sample_rate - ost->sync_opts
00966 - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
00967 double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;
00968 int byte_delta= ((int)idelta)*2*ist->st->codec->channels;
00969
00970
00971 if(fabs(delta) > 50){
00972 if(ist->is_start){
00973 if(byte_delta < 0){
00974 byte_delta= FFMAX(byte_delta, -size);
00975 size += byte_delta;
00976 buf -= byte_delta;
00977
00978 if(!size)
00979 return;
00980 ist->is_start=0;
00981 }else{
00982 job->input_tmp= (unsigned char*)av_realloc(job->input_tmp, byte_delta + size);
00983
00984 if(byte_delta + size <= MAX_AUDIO_PACKET_SIZE)
00985 ist->is_start=0;
00986 else
00987 byte_delta= MAX_AUDIO_PACKET_SIZE - size;
00988
00989 memset(job->input_tmp, 0, byte_delta);
00990 memcpy(job->input_tmp + byte_delta, buf, size);
00991 buf= job->input_tmp;
00992 size += byte_delta;
00993
00994 }
00995 }else if(job->audio_sync_method>1){
00996 int comp= clip(delta, -job->audio_sync_method, job->audio_sync_method);
00997 assert((int)ost->audio_resample);
00998
00999
01000 av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
01001 }
01002 }
01003 }else
01004 ost->sync_opts= (int)(get_sync_ipts(job, ost) * enc->sample_rate + 0.5)
01005 - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
01006
01007 if (ost->audio_resample) {
01008 buftmp = job->audio_buf;
01009 size_out = audio_resample(ost->resample,
01010 (short *)buftmp, (short *)buf,
01011 size / (ist->st->codec->channels * 2));
01012 size_out = size_out * enc->channels * 2;
01013 } else {
01014 buftmp = buf;
01015 size_out = size;
01016 }
01017
01018
01019 if (enc->frame_size > 1) {
01020
01021 av_fifo_write(&ost->fifo, buftmp, size_out);
01022
01023 frame_bytes = enc->frame_size * 2 * enc->channels;
01024
01025 while (av_fifo_read(&ost->fifo, job->audio_buf, frame_bytes) == 0) {
01026 AVPacket pkt;
01027 av_init_packet(&pkt);
01028
01029 ret = avcodec_encode_audio(enc, job->audio_out, audio_out_size,
01030 (short *)job->audio_buf);
01031 job->audio_size += ret;
01032 pkt.stream_index= ost->index;
01033 pkt.data= job->audio_out;
01034 pkt.size= ret;
01035 if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
01036 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
01037 pkt.flags |= PKT_FLAG_KEY;
01038 write_frame(s, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01039
01040 ost->sync_opts += enc->frame_size;
01041 }
01042 } else {
01043 AVPacket pkt;
01044 av_init_packet(&pkt);
01045
01046 ost->sync_opts += size_out / (2 * enc->channels);
01047
01048
01049
01050 switch(enc->codec->id) {
01051 case CODEC_ID_PCM_S32LE:
01052 case CODEC_ID_PCM_S32BE:
01053 case CODEC_ID_PCM_U32LE:
01054 case CODEC_ID_PCM_U32BE:
01055 size_out = size_out << 1;
01056 break;
01057 case CODEC_ID_PCM_S24LE:
01058 case CODEC_ID_PCM_S24BE:
01059 case CODEC_ID_PCM_U24LE:
01060 case CODEC_ID_PCM_U24BE:
01061 case CODEC_ID_PCM_S24DAUD:
01062 size_out = size_out / 2 * 3;
01063 break;
01064 case CODEC_ID_PCM_S16LE:
01065 case CODEC_ID_PCM_S16BE:
01066 case CODEC_ID_PCM_U16LE:
01067 case CODEC_ID_PCM_U16BE:
01068 break;
01069 default:
01070 size_out = size_out >> 1;
01071 break;
01072 }
01073 ret = avcodec_encode_audio(enc, job->audio_out, size_out,
01074 (short *)buftmp);
01075 job->audio_size += ret;
01076 pkt.stream_index= ost->index;
01077 pkt.data= job->audio_out;
01078 pkt.size= ret;
01079 if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
01080 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
01081 pkt.flags |= PKT_FLAG_KEY;
01082 write_frame(s, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01083 }
01084 }
01085
01086 static bool do_video_out(vmsMediaConverterJob *job,
01087 AVFormatContext *s,
01088 AVOutputStream *ost,
01089 AVInputStream *ist,
01090 AVFrame *in_picture,
01091 int *frame_size)
01092 {
01093 int nb_frames, i, ret;
01094 AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
01095 AVFrame picture_crop_temp, picture_pad_temp;
01096 uint8_t *buf = NULL, *buf1 = NULL;
01097 AVCodecContext *enc, *dec;
01098
01099 avcodec_get_frame_defaults(&picture_crop_temp);
01100 avcodec_get_frame_defaults(&picture_pad_temp);
01101
01102 enc = ost->st->codec;
01103 dec = ist->st->codec;
01104
01105
01106 nb_frames = 1;
01107
01108 *frame_size = 0;
01109
01110 if(job->video_sync_method){
01111 double vdelta;
01112 vdelta = get_sync_ipts(job, ost) / av_q2d(enc->time_base) - ost->sync_opts;
01113
01114 if (vdelta < -1.1)
01115 nb_frames = 0;
01116 else if (vdelta > 1.1)
01117 nb_frames = (int)(vdelta + 0.5);
01118
01119 if (nb_frames == 0){
01120 ++job->nb_frames_drop;
01121
01122 }else if (nb_frames > 1) {
01123 job->nb_frames_dup += nb_frames;
01124
01125 }
01126 }else
01127 ost->sync_opts= (int)(get_sync_ipts(job, ost) / av_q2d(enc->time_base) + 0.5);
01128
01129 nb_frames= FFMIN(nb_frames, job->max_frames[CODEC_TYPE_VIDEO] - ost->frame_number);
01130 if (nb_frames <= 0)
01131 return true;
01132
01133 if (ost->video_crop) {
01134 if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
01135
01136 goto the_end;
01137 }
01138 formatted_picture = &picture_crop_temp;
01139 } else {
01140 formatted_picture = in_picture;
01141 }
01142
01143 final_picture = formatted_picture;
01144 padding_src = formatted_picture;
01145 resampling_dst = &ost->pict_tmp;
01146 if (ost->video_pad) {
01147 final_picture = &ost->pict_tmp;
01148 if (ost->video_resample) {
01149 if (img_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, enc->pix_fmt, ost->padtop, ost->padleft) < 0) {
01150
01151 goto the_end;
01152 }
01153 resampling_dst = &picture_pad_temp;
01154 }
01155 }
01156
01157 if (ost->video_resample) {
01158 padding_src = NULL;
01159 final_picture = &ost->pict_tmp;
01160 sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
01161 0, ost->resample_height, resampling_dst->data, resampling_dst->linesize);
01162 }
01163
01164 if (ost->video_pad) {
01165 img_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
01166 enc->height, enc->width, enc->pix_fmt,
01167 ost->padtop, ost->padbottom, ost->padleft, ost->padright, job->padcolor);
01168 }
01169
01170
01171 for(i=0;i<nb_frames;i++) {
01172 AVPacket pkt;
01173 av_init_packet(&pkt);
01174 pkt.stream_index= ost->index;
01175
01176 if (s->oformat->flags & AVFMT_RAWPICTURE) {
01177
01178 AVFrame* old_frame = enc->coded_frame;
01179 enc->coded_frame = dec->coded_frame;
01180 pkt.data= (uint8_t *)final_picture;
01181 pkt.size= sizeof(AVPicture);
01182 if(dec->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
01183 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
01184 if(dec->coded_frame && dec->coded_frame->key_frame)
01185 pkt.flags |= PKT_FLAG_KEY;
01186
01187 write_frame(s, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01188 enc->coded_frame = old_frame;
01189 } else {
01190 AVFrame big_picture;
01191
01192 big_picture= *final_picture;
01193
01194 big_picture.interlaced_frame = in_picture->interlaced_frame;
01195 if(job->avctx_opts->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){
01196 if(job->top_field_first == -1)
01197 big_picture.top_field_first = in_picture->top_field_first;
01198 else
01199 big_picture.top_field_first = job->top_field_first;
01200 }
01201
01202
01203 if (job->same_quality) {
01204 big_picture.quality = (int)ist->st->quality;
01205 }else
01206 big_picture.quality = (int)ost->st->quality;
01207 if(!job->me_threshold)
01208 big_picture.pict_type = 0;
01209
01210 big_picture.pts= ost->sync_opts;
01211
01212 ret = avcodec_encode_video(enc,
01213 job->bit_buffer, job->bit_buffer_size,
01214 &big_picture);
01215 if (ret == -1)
01216 throw 0;
01217
01218
01219 if(ret>0){
01220 pkt.data= job->bit_buffer;
01221 pkt.size= ret;
01222 if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
01223 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
01224
01225 if(enc->coded_frame && enc->coded_frame->key_frame)
01226 pkt.flags |= PKT_FLAG_KEY;
01227 write_frame(s, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01228 *frame_size = ret;
01229
01230
01231 }
01232 }
01233 ost->sync_opts++;
01234 ost->frame_number++;
01235 }
01236 the_end:
01237 av_free(buf);
01238 av_free(buf1);
01239 return true;
01240 }
01241
01242 static bool do_video_stats(vmsMediaConverterJob *job, AVFormatContext *os,
01243 AVOutputStream *ost, int frame_size)
01244 {
01245 char filename[40];
01246 time_t today2;
01247 struct tm *today;
01248 AVCodecContext *enc;
01249 int frame_number;
01250 int64_t ti;
01251 double ti1, bitrate, avg_bitrate;
01252
01253 if (!job->fvstats) {
01254 today2 = time(NULL);
01255 today = localtime(&today2);
01256 sprintf(filename, "vstats_%02d%02d%02d.log", today->tm_hour,
01257 today->tm_min,
01258 today->tm_sec);
01259 job->fvstats = fopen(filename,"w");
01260 if (!job->fvstats)
01261 throw 0;
01262 }
01263
01264 ti = _I64_MAX;
01265 enc = ost->st->codec;
01266 if (enc->codec_type == CODEC_TYPE_VIDEO) {
01267 frame_number = ost->frame_number;
01268
01269 if (enc->flags&CODEC_FLAG_PSNR) {
01270
01271 }
01272
01273
01274
01275 ti1 = ost->sync_opts * av_q2d(enc->time_base);
01276 if (ti1 < 0.01)
01277 ti1 = 0.01;
01278
01279 bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
01280 avg_bitrate = (double)(job->video_size * 8) / ti1 / 1000.0;
01281
01282
01283 }
01284
01285 return true;
01286 }
01287
01288 static void do_subtitle_out(vmsMediaConverterJob *job,
01289 AVFormatContext *s,
01290 AVOutputStream *ost,
01291 AVInputStream *ist,
01292 AVSubtitle *sub,
01293 int64_t pts)
01294 {
01295 int subtitle_out_max_size = 65536;
01296 int subtitle_out_size, nb, i;
01297 AVCodecContext *enc;
01298 AVPacket pkt;
01299
01300 if (pts == AV_NOPTS_VALUE) {
01301
01302 return;
01303 }
01304
01305 enc = ost->st->codec;
01306
01307 if (!job->subtitle_out) {
01308 job->subtitle_out = (unsigned char*)av_malloc(subtitle_out_max_size);
01309 }
01310
01311
01312
01313 if (enc->codec_id == CODEC_ID_DVB_SUBTITLE)
01314 nb = 2;
01315 else
01316 nb = 1;
01317
01318 for(i = 0; i < nb; i++) {
01319 subtitle_out_size = avcodec_encode_subtitle(enc, job->subtitle_out,
01320 subtitle_out_max_size, sub);
01321
01322 av_init_packet(&pkt);
01323 pkt.stream_index = ost->index;
01324 pkt.data = job->subtitle_out;
01325 pkt.size = subtitle_out_size;
01326 AVRational tmp = {1, AV_TIME_BASE};
01327 pkt.pts = av_rescale_q(av_rescale_q(pts, ist->st->time_base, tmp) + job->input_files_ts_offset[ist->file_index], tmp, ost->st->time_base);
01328 if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {
01329
01330 if (i == 0)
01331 pkt.pts += 90 * sub->start_display_time;
01332 else
01333 pkt.pts += 90 * sub->end_display_time;
01334 }
01335 write_frame(s, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01336 }
01337 }
01338
01339 static int output_packet(vmsMediaConverterJob *job,
01340 AVInputStream *ist, int ist_index,
01341 AVOutputStream **ost_table, int nb_ostreams,
01342 const AVPacket *pkt)
01343 {
01344 AVFormatContext *os;
01345 AVOutputStream *ost;
01346 uint8_t *ptr;
01347 int len, ret, i;
01348 uint8_t *data_buf;
01349 int data_size, got_picture;
01350 AVFrame picture;
01351 void *buffer_to_free;
01352 AVSubtitle subtitle, *subtitle_to_free;
01353 int got_subtitle;
01354
01355 if(!pkt){
01356 ist->pts= ist->next_pts;
01357 } else if (pkt->dts != AV_NOPTS_VALUE) {
01358 AVRational tmp = {1, AV_TIME_BASE};
01359 ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, tmp);
01360 } else {
01361
01362 }
01363
01364 if (pkt == NULL) {
01365
01366 ptr = NULL;
01367 len = 0;
01368 goto handle_eof;
01369 }
01370
01371 len = pkt->size;
01372 ptr = pkt->data;
01373 while (len > 0) {
01374 handle_eof:
01375
01376 data_buf = NULL;
01377 data_size = 0;
01378 subtitle_to_free = NULL;
01379 if (ist->decoding_needed) {
01380 switch(ist->st->codec->codec_type) {
01381 case CODEC_TYPE_AUDIO:{
01382 if(pkt)
01383 job->samples= (short*)av_fast_realloc(job->samples, &job->samples_size, FFMAX(pkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE));
01384
01385 ret = avcodec_decode_audio(ist->st->codec, (int*)job->samples, &data_size,
01386 ptr, len);
01387 if (ret < 0)
01388 goto fail_decode;
01389 ptr += ret;
01390 len -= ret;
01391
01392
01393 if (data_size <= 0) {
01394
01395 continue;
01396 }
01397 data_buf = (uint8_t *)job->samples;
01398 ist->next_pts += ((int64_t)AV_TIME_BASE/2 * data_size) /
01399 (ist->st->codec->sample_rate * ist->st->codec->channels);
01400 break;}
01401 case CODEC_TYPE_VIDEO:
01402 data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;
01403
01404 avcodec_get_frame_defaults(&picture);
01405
01406 ret = avcodec_decode_video(ist->st->codec,
01407 &picture, &got_picture, ptr, len);
01408 ist->st->quality= (float)picture.quality;
01409 if (ret < 0)
01410 goto fail_decode;
01411 if (!got_picture) {
01412
01413 goto discard_packet;
01414 }
01415 if (ist->st->codec->time_base.num != 0) {
01416 ist->next_pts += ((int64_t)AV_TIME_BASE *
01417 ist->st->codec->time_base.num) /
01418 ist->st->codec->time_base.den;
01419 }
01420 len = 0;
01421 break;
01422 case CODEC_TYPE_SUBTITLE:
01423 ret = avcodec_decode_subtitle(ist->st->codec,
01424 &subtitle, &got_subtitle, ptr, len);
01425 if (ret < 0)
01426 goto fail_decode;
01427 if (!got_subtitle) {
01428 goto discard_packet;
01429 }
01430 subtitle_to_free = &subtitle;
01431 len = 0;
01432 break;
01433 default:
01434 goto fail_decode;
01435 }
01436 } else {
01437 switch(ist->st->codec->codec_type) {
01438 case CODEC_TYPE_AUDIO:
01439 ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
01440 (ist->st->codec->sample_rate * ist->st->codec->channels);
01441 break;
01442 case CODEC_TYPE_VIDEO:
01443 if (ist->st->codec->time_base.num != 0) {
01444 ist->next_pts += ((int64_t)AV_TIME_BASE *
01445 ist->st->codec->time_base.num) /
01446 ist->st->codec->time_base.den;
01447 }
01448 break;
01449 }
01450 data_buf = ptr;
01451 data_size = len;
01452 ret = len;
01453 len = 0;
01454 }
01455
01456 buffer_to_free = NULL;
01457 if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {
01458 pre_process_video_frame(job, ist, (AVPicture *)&picture,
01459 &buffer_to_free);
01460 }
01461
01462
01463 if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
01464 if (job->audio_volume != 256) {
01465 short *volp;
01466 volp = job->samples;
01467 for(i=0;i<(int)(data_size / sizeof(short));i++) {
01468 int v = ((*volp) * job->audio_volume + 128) >> 8;
01469 if (v < -32768) v = -32768;
01470 if (v > 32767) v = 32767;
01471 *volp++ = v;
01472 }
01473 }
01474 }
01475
01476
01477 if (ist->st->codec->rate_emu) {
01478 int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den);
01479 int64_t now = av_gettime() - ist->start;
01480 if (pts > now)
01481 Sleep((DWORD)((pts - now) / 1000));
01482
01483 ist->frame++;
01484 }
01485
01486 #if 0
01487
01488
01489 if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {
01490 if (ist->st->codec->pict_type != B_TYPE) {
01491 int64_t tmp;
01492 tmp = ist->last_ip_pts;
01493 ist->last_ip_pts = ist->frac_pts.val;
01494 ist->frac_pts.val = tmp;
01495 }
01496 }
01497 #endif
01498
01499 if (job->start_time == 0 || ist->pts >= job->start_time)
01500 for(i=0;i<nb_ostreams;i++) {
01501 int frame_size;
01502
01503 ost = ost_table[i];
01504 if (ost->source_index == ist_index) {
01505 os = job->output_files[ost->file_index];
01506
01507
01508
01509
01510 if (ost->encoding_needed) {
01511 switch(ost->st->codec->codec_type) {
01512 case CODEC_TYPE_AUDIO:
01513 do_audio_out(job, os, ost, ist, data_buf, data_size);
01514 break;
01515 case CODEC_TYPE_VIDEO:
01516 do_video_out(job, os, ost, ist, &picture, &frame_size);
01517 job->video_size += frame_size;
01518 if (job->do_vstats && frame_size)
01519 do_video_stats(job, os, ost, frame_size);
01520 break;
01521 case CODEC_TYPE_SUBTITLE:
01522 do_subtitle_out(job, os, ost, ist, &subtitle, pkt->pts);
01523 break;
01524 default:
01525 throw 0;
01526 }
01527 } else {
01528 AVFrame avframe;
01529 AVPacket opkt;
01530 av_init_packet(&opkt);
01531
01532
01533
01534
01535 avcodec_get_frame_defaults(&avframe);
01536 ost->st->codec->coded_frame= &avframe;
01537 avframe.key_frame = pkt->flags & PKT_FLAG_KEY;
01538
01539 if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO)
01540 job->audio_size += data_size;
01541 else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) {
01542 job->video_size += data_size;
01543 ost->sync_opts++;
01544 }
01545
01546 AVRational tmp = {1, AV_TIME_BASE};
01547 opkt.stream_index= ost->index;
01548 if(pkt->pts != AV_NOPTS_VALUE)
01549 opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, tmp) + job->input_files_ts_offset[ist->file_index], tmp, ost->st->time_base);
01550 else
01551 opkt.pts= AV_NOPTS_VALUE;
01552
01553 {
01554 int64_t dts;
01555 if (pkt->dts == AV_NOPTS_VALUE)
01556 dts = ist->next_pts;
01557 else
01558 dts= av_rescale_q(pkt->dts, ist->st->time_base, tmp);
01559 opkt.dts= av_rescale_q(dts + job->input_files_ts_offset[ist->file_index], tmp, ost->st->time_base);
01560 }
01561 opkt.flags= pkt->flags;
01562
01563
01564 if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))
01565 opkt.destruct= av_destruct_packet;
01566
01567 write_frame(os, &opkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt->stream_index]);
01568 ost->st->codec->frame_number++;
01569 ost->frame_number++;
01570 av_free_packet(&opkt);
01571 }
01572 }
01573 }
01574 av_free(buffer_to_free);
01575
01576 if (subtitle_to_free) {
01577 if (subtitle_to_free->rects != NULL) {
01578 for (i = 0; i < (int)subtitle_to_free->num_rects; i++) {
01579 av_free(subtitle_to_free->rects[i].bitmap);
01580 av_free(subtitle_to_free->rects[i].rgba_palette);
01581 }
01582 av_freep(&subtitle_to_free->rects);
01583 }
01584 subtitle_to_free->num_rects = 0;
01585 subtitle_to_free = NULL;
01586 }
01587 }
01588 discard_packet:
01589 if (pkt == NULL) {
01590
01591
01592 for(i=0;i<nb_ostreams;i++) {
01593 ost = ost_table[i];
01594 if (ost->source_index == ist_index) {
01595 AVCodecContext *enc= ost->st->codec;
01596 os = job->output_files[ost->file_index];
01597
01598 if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO && enc->frame_size <=1)
01599 continue;
01600 if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))
01601 continue;
01602
01603 if (ost->encoding_needed) {
01604 for(;;) {
01605 AVPacket pkt;
01606 int fifo_bytes;
01607 av_init_packet(&pkt);
01608 pkt.stream_index= ost->index;
01609
01610 switch(ost->st->codec->codec_type) {
01611 case CODEC_TYPE_AUDIO:
01612 fifo_bytes = av_fifo_size(&ost->fifo);
01613 ret = 0;
01614
01615 if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
01616 int fs_tmp = enc->frame_size;
01617 enc->frame_size = fifo_bytes / (2 * enc->channels);
01618 if(av_fifo_read(&ost->fifo, (uint8_t*)job->samples, fifo_bytes) == 0) {
01619 ret = avcodec_encode_audio(enc, job->bit_buffer, job->bit_buffer_size, job->samples);
01620 }
01621 enc->frame_size = fs_tmp;
01622 }
01623 if(ret <= 0) {
01624 ret = avcodec_encode_audio(enc, job->bit_buffer, job->bit_buffer_size, NULL);
01625 }
01626 job->audio_size += ret;
01627 pkt.flags |= PKT_FLAG_KEY;
01628 break;
01629 case CODEC_TYPE_VIDEO:
01630 ret = avcodec_encode_video(enc, job->bit_buffer, job->bit_buffer_size, NULL);
01631 job->video_size += ret;
01632 if(enc->coded_frame && enc->coded_frame->key_frame)
01633 pkt.flags |= PKT_FLAG_KEY;
01634 if (ost->logfile && enc->stats_out) {
01635
01636 }
01637 break;
01638 default:
01639 ret=-1;
01640 }
01641
01642 if(ret<=0)
01643 break;
01644 pkt.data= job->bit_buffer;
01645 pkt.size= ret;
01646 if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
01647 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
01648 write_frame(os, &pkt, ost->st->codec, job->bitstream_filters[ost->file_index][pkt.stream_index]);
01649 }
01650 }
01651 }
01652 }
01653 }
01654
01655 return 0;
01656 fail_decode:
01657 return -1;
01658 }
01659
01660 static void av_encode(vmsMediaConverterJob *job,
01661 AVFormatContext **output_files,
01662 int nb_output_files,
01663 AVFormatContext **input_files,
01664 int nb_input_files,
01665 AVStreamMap *stream_maps, int nb_stream_maps,
01666 int *pnProgress, BOOL *pbCancel)
01667 {
01668 int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
01669 AVFormatContext *is, *os;
01670 AVCodecContext *codec, *icodec;
01671 AVOutputStream *ost, **ost_table = NULL;
01672 AVInputStream *ist, **ist_table = NULL;
01673 AVInputFile *file_table;
01674 AVFormatContext *stream_no_data;
01675 int key;
01676
01677 file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));
01678 if (!file_table)
01679 goto fail;
01680
01681
01682 j = 0;
01683 for(i=0;i<nb_input_files;i++) {
01684 is = input_files[i];
01685 file_table[i].ist_index = j;
01686 file_table[i].nb_streams = is->nb_streams;
01687 j += is->nb_streams;
01688 }
01689 nb_istreams = j;
01690
01691 ist_table = (AVInputStream**)av_mallocz(nb_istreams * sizeof(AVInputStream *));
01692 if (!ist_table)
01693 goto fail;
01694
01695 for(i=0;i<nb_istreams;i++) {
01696 ist = (AVInputStream*)av_mallocz(sizeof(AVInputStream));
01697 if (!ist)
01698 goto fail;
01699 ist_table[i] = ist;
01700 }
01701 j = 0;
01702 for(i=0;i<nb_input_files;i++) {
01703 is = input_files[i];
01704 for(k=0;k<(int)is->nb_streams;k++) {
01705 ist = ist_table[j++];
01706 ist->st = is->streams[k];
01707 ist->file_index = i;
01708 ist->index = k;
01709 ist->discard = 1;
01710
01711 if (ist->st->codec->rate_emu) {
01712 ist->start = av_gettime();
01713 ist->frame = 0;
01714 }
01715 }
01716 }
01717
01718
01719 nb_ostreams = 0;
01720 for(i=0;i<nb_output_files;i++) {
01721 os = output_files[i];
01722 if (!os->nb_streams)
01723 throw 0;
01724 nb_ostreams += os->nb_streams;
01725 }
01726 if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams)
01727 throw 0;
01728
01729
01730 for(i=0;i<nb_stream_maps;i++) {
01731 int fi = stream_maps[i].file_index;
01732 int si = stream_maps[i].stream_index;
01733
01734 if (fi < 0 || fi > nb_input_files - 1 ||
01735 si < 0 || si > file_table[fi].nb_streams - 1)
01736 throw 0;
01737
01738 fi = stream_maps[i].sync_file_index;
01739 si = stream_maps[i].sync_stream_index;
01740 if (fi < 0 || fi > nb_input_files - 1 ||
01741 si < 0 || si > file_table[fi].nb_streams - 1)
01742 throw 0;
01743
01744 }
01745
01746 ost_table = (AVOutputStream**)av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);
01747 if (!ost_table)
01748 goto fail;
01749 for(i=0;i<nb_ostreams;i++) {
01750 ost = (AVOutputStream*)av_mallocz(sizeof(AVOutputStream));
01751 if (!ost)
01752 goto fail;
01753 ost_table[i] = ost;
01754 }
01755
01756 n = 0;
01757 for(k=0;k<nb_output_files;k++) {
01758 os = output_files[k];
01759 for(i=0;i<(int)os->nb_streams;i++) {
01760 int found;
01761 ost = ost_table[n++];
01762 ost->file_index = k;
01763 ost->index = i;
01764 ost->st = os->streams[i];
01765 if (nb_stream_maps > 0) {
01766 ost->source_index = file_table[stream_maps[n-1].file_index].ist_index +
01767 stream_maps[n-1].stream_index;
01768
01769
01770 if (ist_table[ost->source_index]->st->codec->codec_type != ost->st->codec->codec_type) {
01771 throw 0;
01772 }
01773
01774 } else {
01775
01776 found = 0;
01777 for(j=0;j<nb_istreams;j++) {
01778 ist = ist_table[j];
01779 if (ist->discard &&
01780 ist->st->codec->codec_type == ost->st->codec->codec_type) {
01781 ost->source_index = j;
01782 found = 1;
01783 break;
01784 }
01785 }
01786
01787 if (!found) {
01788
01789 for(j=0;j<nb_istreams;j++) {
01790 ist = ist_table[j];
01791 if (ist->st->codec->codec_type == ost->st->codec->codec_type) {
01792 ost->source_index = j;
01793 found = 1;
01794 }
01795 }
01796 if (!found) {
01797 throw 0;
01798 }
01799 }
01800 }
01801 ist = ist_table[ost->source_index];
01802 ist->discard = 0;
01803 ost->sync_ist = (nb_stream_maps > 0) ?
01804 ist_table[file_table[stream_maps[n-1].sync_file_index].ist_index +
01805 stream_maps[n-1].sync_stream_index] : ist;
01806 }
01807 }
01808
01809
01810 for(i=0;i<nb_ostreams;i++) {
01811 ost = ost_table[i];
01812 ist = ist_table[ost->source_index];
01813
01814 codec = ost->st->codec;
01815 icodec = ist->st->codec;
01816
01817 if (ost->st->stream_copy) {
01818
01819 codec->codec_id = icodec->codec_id;
01820 codec->codec_type = icodec->codec_type;
01821 if(!codec->codec_tag) codec->codec_tag = icodec->codec_tag;
01822 codec->bit_rate = 128000;
01823 codec->extradata= icodec->extradata;
01824 codec->extradata_size= icodec->extradata_size;
01825 if(av_q2d(icodec->time_base) > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000)
01826 codec->time_base = icodec->time_base;
01827 else
01828 codec->time_base = ist->st->time_base;
01829 switch(codec->codec_type) {
01830 case CODEC_TYPE_AUDIO:
01831 codec->sample_rate = icodec->sample_rate;
01832 codec->channels = icodec->channels;
01833 codec->frame_size = icodec->frame_size;
01834 codec->block_align= icodec->block_align;
01835 break;
01836 case CODEC_TYPE_VIDEO:
01837 codec->pix_fmt = icodec->pix_fmt;
01838 codec->width = icodec->width;
01839 codec->height = icodec->height;
01840 codec->has_b_frames = icodec->has_b_frames;
01841 break;
01842 case CODEC_TYPE_SUBTITLE:
01843 break;
01844 default:
01845 throw 0;
01846 }
01847 } else {
01848 switch(codec->codec_type) {
01849 case CODEC_TYPE_AUDIO:
01850 if (av_fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
01851 goto fail;
01852
01853 if (codec->channels == icodec->channels &&
01854 codec->sample_rate == icodec->sample_rate) {
01855 ost->audio_resample = 0;
01856 } else {
01857 if (codec->channels != icodec->channels &&
01858 (icodec->codec_id == CODEC_ID_AC3 ||
01859 icodec->codec_id == CODEC_ID_DTS)) {
01860
01861
01862
01863 icodec->channels = codec->channels;
01864 if (codec->sample_rate == icodec->sample_rate)
01865 ost->audio_resample = 0;
01866 else {
01867 ost->audio_resample = 1;
01868 }
01869 } else {
01870 ost->audio_resample = 1;
01871 }
01872 }
01873 if(job->audio_sync_method>1)
01874 ost->audio_resample = 1;
01875
01876 if(ost->audio_resample){
01877 ost->resample = audio_resample_init(codec->channels, icodec->channels,
01878 codec->sample_rate, icodec->sample_rate);
01879 if(!ost->resample){
01880 throw 0;
01881 }
01882 }
01883 ist->decoding_needed = 1;
01884 ost->encoding_needed = 1;
01885 break;
01886 case CODEC_TYPE_VIDEO:
01887 ost->video_crop = ((job->frame_leftBand + job->frame_rightBand + job->frame_topBand + job->frame_bottomBand) != 0);
01888 ost->video_pad = ((job->frame_padleft + job->frame_padright + job->frame_padtop + job->frame_padbottom) != 0);
01889 ost->video_resample = ((codec->width != icodec->width -
01890 (job->frame_leftBand + job->frame_rightBand) +
01891 (job->frame_padleft + job->frame_padright)) ||
01892 (codec->height != icodec->height -
01893 (job->frame_topBand + job->frame_bottomBand) +
01894 (job->frame_padtop + job->frame_padbottom)) ||
01895 (codec->pix_fmt != icodec->pix_fmt));
01896 if (ost->video_crop) {
01897 ost->topBand = job->frame_topBand;
01898 ost->leftBand = job->frame_leftBand;
01899 }
01900 if (ost->video_pad) {
01901 ost->padtop = job->frame_padtop;
01902 ost->padleft = job->frame_padleft;
01903 ost->padbottom = job->frame_padbottom;
01904 ost->padright = job->frame_padright;
01905 if (!ost->video_resample) {
01906 avcodec_get_frame_defaults(&ost->pict_tmp);
01907 if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
01908 codec->width, codec->height ) )
01909 goto fail;
01910 }
01911 }
01912 if (ost->video_resample) {
01913 avcodec_get_frame_defaults(&ost->pict_tmp);
01914 if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt,
01915 codec->width, codec->height ) )
01916 goto fail;
01917
01918 ost->img_resample_ctx = sws_getContext(
01919 icodec->width - (job->frame_leftBand + job->frame_rightBand),
01920 icodec->height - (job->frame_topBand + job->frame_bottomBand),
01921 icodec->pix_fmt,
01922 codec->width - (job->frame_padleft + job->frame_padright),
01923 codec->height - (job->frame_padtop + job->frame_padbottom),
01924 codec->pix_fmt,
01925 job->sws_flags, NULL, NULL, NULL);
01926 if (ost->img_resample_ctx == NULL) {
01927 throw 0;
01928 }
01929 ost->resample_height = icodec->height - (job->frame_topBand + job->frame_bottomBand);
01930 }
01931 ost->encoding_needed = 1;
01932 ist->decoding_needed = 1;
01933 break;
01934 case CODEC_TYPE_SUBTITLE:
01935 ost->encoding_needed = 1;
01936 ist->decoding_needed = 1;
01937 break;
01938 default:
01939
01940 break;
01941 }
01942
01943 if (ost->encoding_needed &&
01944 (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
01945 char logfilename[1024];
01946 FILE *f;
01947 int size;
01948 char *logbuffer;
01949
01950 sprintf(logfilename, "%s-%d.log",
01951 job->pass_logfilename ?
01952 job->pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
01953 if (codec->flags & CODEC_FLAG_PASS1) {
01954 f = fopen(logfilename, "w");
01955 if (!f) {
01956 throw 0;
01957 }
01958 ost->logfile = f;
01959 } else {
01960
01961 f = fopen(logfilename, "r");
01962 if (!f) {
01963 throw 0;
01964 }
01965 fseek(f, 0, SEEK_END);
01966 size = ftell(f);
01967 fseek(f, 0, SEEK_SET);
01968 logbuffer = (char*)av_malloc(size + 1);
01969 if (!logbuffer) {
01970 throw 0;
01971 }
01972 size = fread(logbuffer, 1, size, f);
01973 fclose(f);
01974 logbuffer[size] = '\0';
01975 codec->stats_in = logbuffer;
01976 }
01977 }
01978 }
01979 if(codec->codec_type == CODEC_TYPE_VIDEO){
01980 int size= codec->width * codec->height;
01981 job->bit_buffer_size= FFMAX(job->bit_buffer_size, 4*size);
01982 }
01983 }
01984
01985 if (!job->bit_buffer)
01986 job->bit_buffer = (unsigned char*)av_malloc(job->bit_buffer_size);
01987 if (!job->bit_buffer)
01988 goto fail;
01989
01990
01991
01992
01993 for(i=0;i<nb_ostreams;i++) {
01994 ost = ost_table[i];
01995 if (ost->encoding_needed) {
01996 AVCodec *codec;
01997 codec = avcodec_find_encoder(ost->st->codec->codec_id);
01998 if (!codec) {
01999 throw 0;
02000 }
02001 if (avcodec_open(ost->st->codec, codec) < 0) {
02002 throw 0;
02003 }
02004 job->extra_size += ost->st->codec->extradata_size;
02005 }
02006 }
02007
02008
02009 for(i=0;i<nb_istreams;i++) {
02010 ist = ist_table[i];
02011 if (ist->decoding_needed) {
02012 AVCodec *codec;
02013 codec = avcodec_find_decoder(ist->st->codec->codec_id);
02014 if (!codec) {
02015 throw 0;
02016 }
02017 if (avcodec_open(ist->st->codec, codec) < 0) {
02018 throw 0;
02019 }
02020
02021
02022 }
02023 }
02024
02025
02026 for(i=0;i<nb_istreams;i++) {
02027 ist = ist_table[i];
02028 is = input_files[ist->file_index];
02029 ist->pts = 0;
02030 AVRational tmp = {1, AV_TIME_BASE};
02031 ist->next_pts = av_rescale_q(ist->st->start_time, ist->st->time_base, tmp);
02032 if(ist->st->start_time == AV_NOPTS_VALUE)
02033 ist->next_pts=0;
02034 if(job->input_files_ts_offset[ist->file_index])
02035 ist->next_pts= AV_NOPTS_VALUE;
02036 ist->is_start = 1;
02037 }
02038
02039
02040 for(i=0;i<nb_input_files;i++) {
02041 file_table[i].buffer_size_max = 2048;
02042 }
02043
02044
02045 for (i=0;i<job->nb_meta_data_maps;i++) {
02046 AVFormatContext *out_file;
02047 AVFormatContext *in_file;
02048
02049 int out_file_index = job->meta_data_maps[i].out_file;
02050 int in_file_index = job->meta_data_maps[i].in_file;
02051 if ( out_file_index < 0 || out_file_index >= nb_output_files ) {
02052 ret = -EINVAL;
02053 goto fail;
02054 }
02055 if ( in_file_index < 0 || in_file_index >= nb_input_files ) {
02056 ret = -EINVAL;
02057 goto fail;
02058 }
02059
02060 out_file = output_files[out_file_index];
02061 in_file = input_files[in_file_index];
02062
02063 strcpy(out_file->title, in_file->title);
02064 strcpy(out_file->author, in_file->author);
02065 strcpy(out_file->copyright, in_file->copyright);
02066 strcpy(out_file->comment, in_file->comment);
02067 strcpy(out_file->album, in_file->album);
02068 out_file->year = in_file->year;
02069 out_file->track = in_file->track;
02070 strcpy(out_file->genre, in_file->genre);
02071 }
02072
02073
02074 for(i=0;i<nb_output_files;i++) {
02075 os = output_files[i];
02076 if (av_write_header(os) < 0) {
02077 ret = -EINVAL;
02078 goto fail;
02079 }
02080 }
02081
02082
02083
02084 stream_no_data = 0;
02085 key = -1;
02086
02087 int totalsize; totalsize = 0;
02088 bool bWritten; bWritten = false;
02089
02090 for(;;) {
02091 int file_index, ist_index;
02092 AVPacket pkt;
02093 double ipts_min;
02094 double opts_min;
02095
02096 redo:
02097 ipts_min= 1e100;
02098 opts_min= 1e100;
02099
02100
02101 file_index = -1;
02102 for(i=0;i<nb_ostreams;i++) {
02103 double ipts, opts;
02104 ost = ost_table[i];
02105 os = output_files[ost->file_index];
02106 ist = ist_table[ost->source_index];
02107 if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO)
02108 opts = ost->sync_opts * av_q2d(ost->st->codec->time_base);
02109 else
02110 opts = ost->st->pts.val * av_q2d(ost->st->time_base);
02111 ipts = (double)ist->pts;
02112 if (!file_table[ist->file_index].eof_reached){
02113 if(ipts < ipts_min) {
02114 ipts_min = ipts;
02115 if(job->input_sync ) file_index = ist->file_index;
02116 }
02117 if(opts < opts_min) {
02118 opts_min = opts;
02119 if(!job->input_sync) file_index = ist->file_index;
02120 }
02121 }
02122 if(ost->frame_number >= job->max_frames[ost->st->codec->codec_type]){
02123 file_index= -1;
02124 break;
02125 }
02126 }
02127
02128 if (file_index < 0) {
02129 break;
02130 }
02131
02132
02133 if (job->recording_time > 0 && opts_min >= (job->recording_time / 1000000.0))
02134 break;
02135
02136
02137 if (job->limit_filesize != 0 && (job->limit_filesize * 1024) < url_ftell(&output_files[0]->pb))
02138 break;
02139
02140
02141 is = input_files[file_index];
02142 if (av_read_frame(is, &pkt) < 0) {
02143 file_table[file_index].eof_reached = 1;
02144 if (job->opt_shortest) break; else continue;
02145 }
02146
02147 if (!pkt.size) {
02148 stream_no_data = is;
02149 } else {
02150 stream_no_data = 0;
02151 }
02152
02153
02154 if (pkt.stream_index >= file_table[file_index].nb_streams)
02155 goto discard_packet;
02156 ist_index = file_table[file_index].ist_index + pkt.stream_index;
02157 ist = ist_table[ist_index];
02158 if (ist->discard)
02159 goto discard_packet;
02160
02161 if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) {
02162 AVRational tmp = {1, AV_TIME_BASE};
02163 int64_t delta= av_rescale_q(pkt.dts, ist->st->time_base, tmp) - ist->next_pts;
02164 if(FFABS(delta) > 1*job->dts_delta_threshold*AV_TIME_BASE && !job->copy_ts){
02165 job->input_files_ts_offset[ist->file_index]-= delta;
02166
02167 for(i=0; i<file_table[file_index].nb_streams; i++){
02168 int index= file_table[file_index].ist_index + i;
02169 ist_table[index]->next_pts += delta;
02170 ist_table[index]->is_start=1;
02171 }
02172 }
02173 }
02174
02175 totalsize += pkt.size;
02176
02177 if (pbCancel && *pbCancel)
02178 break;
02179
02180
02181 if (output_packet(job, ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {
02182 av_free_packet(&pkt);
02183 goto redo;
02184 }
02185
02186 bWritten = true;
02187
02188 if (pnProgress)
02189 *pnProgress = MulDiv (totalsize, 100, input_files [0]->file_size);
02190
02191 discard_packet:
02192 av_free_packet(&pkt);
02193
02194
02195
02196 }
02197
02198
02199 for(i=0;i<nb_istreams;i++) {
02200 ist = ist_table[i];
02201 if (ist->decoding_needed) {
02202 output_packet(job, ist, i, ost_table, nb_ostreams, NULL);
02203 }
02204 }
02205
02206
02207 for(i=0;i<nb_output_files;i++) {
02208 os = output_files[i];
02209 av_write_trailer(os);
02210 }
02211
02212
02213
02214
02215
02216 for(i=0;i<nb_ostreams;i++) {
02217 ost = ost_table[i];
02218 if (ost->encoding_needed) {
02219 av_freep(&ost->st->codec->stats_in);
02220 avcodec_close(ost->st->codec);
02221 }
02222 }
02223
02224
02225 for(i=0;i<nb_istreams;i++) {
02226 ist = ist_table[i];
02227 if (ist->decoding_needed) {
02228 avcodec_close(ist->st->codec);
02229 }
02230 }
02231
02232
02233
02234 fail1:
02235 av_freep(&job->bit_buffer);
02236 av_free(file_table);
02237
02238 if (ist_table) {
02239 for(i=0;i<nb_istreams;i++) {
02240 ist = ist_table[i];
02241 av_free(ist);
02242 }
02243 av_free(ist_table);
02244 }
02245 if (ost_table) {
02246 for(i=0;i<nb_ostreams;i++) {
02247 ost = ost_table[i];
02248 if (ost) {
02249 if (ost->logfile) {
02250 fclose(ost->logfile);
02251 ost->logfile = NULL;
02252 }
02253 av_fifo_free(&ost->fifo);
02254 av_free(ost->pict_tmp.data[0]);
02255 if (ost->video_resample)
02256 sws_freeContext(ost->img_resample_ctx);
02257 if (ost->audio_resample)
02258 audio_resample_close(ost->resample);
02259 av_free(ost);
02260 }
02261 }
02262 av_free(ost_table);
02263 }
02264
02265 if (bWritten == false)
02266 throw 0;
02267
02268 return;
02269 fail:
02270 ret = -ENOMEM;
02271 goto fail1;
02272 }
02273
02274 static bool opt_format(vmsMediaConverterJob *job, const char *arg)
02275 {
02276
02277 if (!strcmp(arg, "pgmyuv")) {
02278 job->pgmyuv_compatibility_hack=1;
02279
02280 arg = "image2";
02281 }
02282
02283 job->file_iformat = av_find_input_format(arg);
02284 job->file_oformat = guess_format(arg, NULL, NULL);
02285 if (!job->file_iformat && !job->file_oformat) {
02286 throw 0;
02287 }
02288
02289 return true;
02290 }
02291
02292 static bool opt_codec(int *pstream_copy, int *pcodec_id,
02293 int codec_type, const char *arg)
02294 {
02295 AVCodec *p;
02296
02297 if (!strcmp(arg, "copy")) {
02298 *pstream_copy = 1;
02299 } else {
02300 p = first_avcodec;
02301 while (p) {
02302 if (!strcmp(p->name, arg) && p->type == codec_type)
02303 break;
02304 p = p->next;
02305 }
02306 if (p == NULL) {
02307 throw 0;
02308 } else {
02309 *pcodec_id = p->id;
02310 }
02311 }
02312
02313 return true;
02314 }
02315
02316 static void opt_video_codec(vmsMediaConverterJob *job, const char *arg)
02317 {
02318 opt_codec(&job->video_stream_copy, &job->video_codec_id, CODEC_TYPE_VIDEO, arg);
02319 }
02320
02321 static void opt_audio_codec(vmsMediaConverterJob *job, const char *arg)
02322 {
02323 opt_codec(&job->audio_stream_copy, &job->audio_codec_id, CODEC_TYPE_AUDIO, arg);
02324 }
02325
02326 static void opt_audio_channels(vmsMediaConverterJob *job, int n)
02327 {
02328 job->audio_channels = n;
02329 }
02330
02331 static void opt_audio_bitrate(vmsMediaConverterJob *job, int n)
02332 {
02333 job->audio_bit_rate = n * 1000;
02334 }
02335
02336 static bool opt_frame_size(vmsMediaConverterJob *job, int w, int h)
02337 {
02338 job->frame_width = w;
02339 job->frame_height = h;
02340
02341 if ((job->frame_width % 2) != 0 || (job->frame_height % 2) != 0)
02342 throw 0;
02343
02344 return true;
02345 }
02346
02347 static void opt_audio_rate(vmsMediaConverterJob *job, int n)
02348 {
02349 job->audio_sample_rate = n;
02350 }
02351
02352 static bool opt_frame_rate(vmsMediaConverterJob *job, double rate)
02353 {
02354 AVRational time_base = av_d2q(rate, 1001000);
02355 job->frame_rate = time_base.num;
02356 job->frame_rate_base = time_base.den;
02357
02358 if (!job->frame_rate || !job->frame_rate_base)
02359 throw 0;
02360
02361 return true;
02362 }
02363
02364 BOOL ConvertMediaFile (LPCSTR pszSrcFile, LPCSTR pszDstFile, LPCSTR pszDstFormat,
02365 LPCSTR pszAudioCodec, int nAudioChannels, int nAudioBitrate,
02366 int nAudioRate,
02367 LPCSTR pszVideoCodec, int nVideoBitrate, int nVideoFrameRate,
02368 int nVideoFrameWidth, int nVideoFrameHeight,
02369 int* pnProgress, BOOL *pbCancel)
02370 {
02371
02372 vmsMediaConverterJob job;
02373 bool bRes = true;
02374
02375 try{
02376
02377 job.avctx_opts = avcodec_alloc_context();
02378 job.avformat_opts = av_alloc_format_context();
02379
02380 opt_input_file (&job, pszSrcFile);
02381
02382
02383 opt_format (&job, pszDstFormat ? pszDstFormat : "avi");
02384
02385
02386
02387 if (pszVideoCodec && *pszVideoCodec)
02388 {
02389 if (lstrcmpi (pszVideoCodec, "none") == 0)
02390 job.video_disable = true;
02391 else
02392 opt_video_codec (&job, pszVideoCodec);
02393 }
02394
02395 if (nVideoBitrate != -1)
02396 job.avctx_opts->bit_rate = nVideoBitrate * 1000 ;
02397
02398 if (nVideoFrameRate != -1)
02399 opt_frame_rate (&job, nVideoFrameRate );
02400
02401 if (nVideoFrameWidth != -1 && nVideoFrameHeight != -1)
02402 opt_frame_size (&job, nVideoFrameWidth, nVideoFrameHeight);
02403
02404
02405
02406 if (pszAudioCodec && *pszAudioCodec)
02407 {
02408 if (lstrcmpi (pszAudioCodec, "none") == 0)
02409 job.audio_disable = true;
02410 else
02411 opt_audio_codec (&job, pszAudioCodec);
02412 }
02413
02414 if (nAudioChannels != -1)
02415 opt_audio_channels (&job, nAudioChannels );
02416
02417 if (nAudioBitrate != -1)
02418 opt_audio_bitrate (&job, nAudioBitrate );
02419
02420 if (nAudioRate != -1)
02421 opt_audio_rate (&job, nAudioRate );
02422
02423
02424
02425 opt_output_file (&job, pszDstFile);
02426
02427 av_encode(&job, job.output_files, job.nb_output_files, job.input_files, job.nb_input_files,
02428 job.stream_maps, job.nb_stream_maps, pnProgress, pbCancel);
02429
02430 if (pnProgress)
02431 *pnProgress = 100;
02432
02433 }
02434 catch (int) {
02435 bRes = false;
02436 }
02437
02438
02439 for(int i=0;i<job.nb_output_files;i++) {
02440
02441 AVFormatContext *s = job.output_files[i];
02442 int j;
02443 if (!(s->oformat->flags & AVFMT_NOFILE))
02444 url_fclose(&s->pb);
02445 for(j=0;j<(int)s->nb_streams;j++) {
02446 av_free(s->streams[j]->codec);
02447 av_free(s->streams[j]);
02448 }
02449 av_free(s);
02450 }
02451 for(i=0;i<job.nb_input_files;i++)
02452 av_close_input_file(job.input_files[i]);
02453
02454 if(job.intra_matrix)
02455 av_free(job.intra_matrix);
02456 if(job.inter_matrix)
02457 av_free(job.inter_matrix);
02458
02459 if (pbCancel && *pbCancel)
02460 {
02461 DeleteFile (pszDstFile);
02462 bRes = FALSE;
02463 }
02464
02465 return bRes;
02466 }
02467
02468 void Initialize ()
02469 {
02470 av_register_all ();
02471 }
02472
02473 void Shutdown ()
02474 {
02475 av_free_static ();
02476 }
02477