/** \fn open */ uint8_t OpenDMLHeader::open(const char *name) { uint8_t badAvi=0; uint32_t rd; printf("** opening OpenDML files **"); _fd=ADM_fopen(name,"rb"); if(!_fd) { printf("\n cannot open %s \n",name); return 0; } myName=ADM_strdup(name); #define CLR(x) memset(& x,0,sizeof( x)); CLR( _videostream); CLR( _mainaviheader); _isvideopresent=1; _isaudiopresent=0; _nbTrack=0; riffParser *parser=new riffParser(name); if(MKFCC('R','I','F','F')!=(rd=parser->read32())) { printf("Not riff\n");badAvi=1; printf("%x != %x\n",rd,MKFCC('R','I','F','F')); } parser->read32(); if(MKFCC('A','V','I',' ')!=parser->read32()) { printf("Not Avi\n");badAvi=1; } if(!badAvi) { walk(parser); } delete parser; aprintf("Found %d tracks\n:-----------\n",_nbTrack); // check if it looks like a correct avi if(!_nbTrack) badAvi=1; // if we are up to here -> good avi :) if(badAvi) { printf("FAIL\n"); return 0; } // now read up each parts... //____________________________ #define DUMP_TRACK(i) aprintf(" at %"PRIu64" (%"PRIx64") size : %"PRIu64" (%"PRIx64")\n", \ _Tracks[i].strh.offset,\ _Tracks[i].strh.offset,\ _Tracks[i].strh.size,\ _Tracks[i].strh.size); for(uint32_t i=0;i<_nbTrack;i++) { DUMP_TRACK(i); } uint32_t vidTrack=0xff; // search wich track is the video one // and load it to _videoheader for(uint32_t i=0;i<_nbTrack;i++) { fseeko(_fd,_Tracks[i].strh.offset,SEEK_SET); if(_Tracks[i].strh.size!=sizeof(_videostream)) { printf("[AVI]Mmm(1) we have a bogey here, size mismatch : %"PRIu64"\n",_Tracks[i].strh.size); printf("[AVI]expected %d\n",(int)sizeof(_videostream)); if(_Tracks[i].strh.size<sizeof(_videostream)-8) // RECT is not mandatory { GUI_Error_HIG(QT_TR_NOOP("Malformed header"), NULL); return 0; } printf("[AVI]Trying to continue anyway\n"); } fread(&_videostream,sizeof(_videostream),1,_fd); #ifdef ADM_BIG_ENDIAN Endian_AviStreamHeader(&_videostream); #endif if(_videostream.fccType==MKFCC('v','i','d','s')) { vidTrack=i; printf("Video track is %u\n",i); break; } } if(0xff==vidTrack) { printf("Could not identify video track!"); return 0; } // then bih stuff int32_t extra; // _fd=fopen(name,"rb"); fseeko(_fd,_Tracks[vidTrack].strf.offset,SEEK_SET); extra=_Tracks[vidTrack].strf.size-sizeof(_video_bih); if(extra<0) { printf("[AVI]bih is not big enough (%"PRIu64"/%d)!\n",_Tracks[vidTrack].strf.size,(int)sizeof(_video_bih)); return 0; } fread(&_video_bih,sizeof(_video_bih),1,_fd); #ifdef ADM_BIG_ENDIAN Endian_BitMapInfo(&_video_bih); #endif if(extra>0) { _videoExtraLen=extra; _videoExtraData=new uint8_t [extra]; fread(_videoExtraData,extra,1,_fd); } _isvideopresent=1; //-------------------------------------------------- // Read audio trak info, select if there is // several //-------------------------------------------------- // and audio track if(_mainaviheader.dwStreams>=2) { // which one is the audio track, is there several ? if(!(_nbAudioTracks=countAudioTrack())) { printf("Weird, there is no audio track, but more than one stream...\n"); } else { uint32_t run=0,audio=0; odmlAudioTrack *track; _audioTracks=new odmlAudioTrack[_nbAudioTracks]; _audioStreams=new ADM_audioStream *[_nbAudioTracks]; while(audio<_nbAudioTracks) { ADM_assert(run<_nbTrack); track=&(_audioTracks[audio]); fseeko(_fd,_Tracks[run].strh.offset,SEEK_SET); if(_Tracks[run].strh.size != sizeof(_audiostream)) { printf("[AVI]Mmm(2) we have a bogey here, size mismatch : %"PRIu64"\n",_Tracks[run].strh.size); printf("[AVI]expected %d\n",(int)sizeof(_audiostream)); if(_Tracks[run].strh.size<sizeof(_audiostream)-8) { GUI_Error_HIG(QT_TR_NOOP("Malformed header"), NULL); return 0; } printf("[AVI]Trying to continue anyway\n"); } fread(track->avistream,sizeof(_audiostream),1,_fd); #ifdef ADM_BIG_ENDIAN Endian_AviStreamHeader(track->avistream); #endif if(track->avistream->fccType!=MKFCC('a','u','d','s')) { printf("Not an audio track!\n"); run++; continue; } // now read extra stuff fseeko(_fd,_Tracks[run].strf.offset,SEEK_SET); extra=_Tracks[run].strf.size-sizeof(WAVHeader); if(extra<0) { printf("[AVI]WavHeader is not big enough (%"PRIu64"/%d)!\n", _Tracks[run].strf.size,(int)sizeof(WAVHeader)); return 0; } fread(track->wavHeader,sizeof(WAVHeader),1,_fd); #ifdef ADM_BIG_ENDIAN Endian_WavHeader(track->wavHeader); #endif if(extra>2) { fgetc(_fd);fgetc(_fd); extra-=2; track->extraDataLen=extra; track->extraData=new uint8_t [extra]; fread(track->extraData,extra,1,_fd); } track->trackNum=run; audio++; run++; } } } // now look at the index stuff // there could be 3 cases: // 1- It is a openDML index, meta index + several smaller index // 2- It is a legacy index (type 1 , most common) // 3- It is a broken index or no index at all // // If it is a openDML index we will find a "indx" field in the Tracks // Else we will find it in _regularIndex Track // Since openDML often also have a regular index we will try open DML first uint8_t ret=0; Dump(); // take the size of riff header and actual file size uint64_t riffSize; fseeko(_fd,0,SEEK_END); _fileSize=ftello(_fd); fseeko(_fd,0,SEEK_SET); read32(); riffSize=(uint64_t )read32(); // 1st case, we have an avi < 4 Gb // potentially avi type 1 #if 0 if((_fileSize<4*1024*1024*1024LL)&& // if riff size is ~ fileSize try regular index (abs(riffSize-_fileSize)<1024*1024)) #endif #define HAS(x) if(x) printf(#x" : yes\n"); else printf(#x" : no\n"); // If there is no openDML index HAS( _regularIndex.offset); HAS( _Tracks[vidTrack].indx.offset); if(!ret && _regularIndex.offset &&!_Tracks[vidTrack].indx.offset) // try regular avi if a idx1 field is there (avi index) ret=indexRegular(vidTrack); if (!ret && _Tracks[vidTrack].indx.offset) // Try openDML if a index field is there (openDML) ret=indexODML(vidTrack); if(!ret) { printf("Could not index it properly...\n"); return 0; } if(!_nbAudioTracks) { _isaudiopresent=0; } else { odmlAudioTrack *track; // Check it is not a weird DV file if(fourCC::check(_video_bih.biCompression,(uint8_t *)"dvsd")) { for(int i=0;i<_nbAudioTracks;i++) { track=&(_audioTracks[i]); WAVHeader *hdr= track->wavHeader; if(!hdr->frequency) { ADM_warning("Fixing audio track to be PCM\n"); hdr->frequency=48000; //hdr->channels=2; hdr->byterate=48000*hdr->channels*2; hdr->blockalign=2*hdr->channels; } } } // build audio stream for(int i=0;i<_nbAudioTracks;i++) { track=&(_audioTracks[i]); ADM_aviAudioAccess *access=new ADM_aviAudioAccess(track->index,track->wavHeader, track->nbChunks, myName, track->extraDataLen,track->extraData); _audioStreams[i]= ADM_audioCreateStream((track->wavHeader), access); } } if(!_video_bih.biCompression && fourCC::check(_videostream.fccHandler,(uint8_t*)"DIB ")) { _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t*)"DIB "); } else _videostream.fccHandler=_video_bih.biCompression; printf("\nOpenDML file successfully read..\n"); if(ret==1) { computePtsDts(); removeEmptyFrames(); } ADM_info("PtsAvailable : %d\n",(int)ptsAvailable); return ret; }
//___________________________________________________ uint8_t ADM_ogmWrite::writeVideo(uint32_t frame) { ADM_assert(0); return 0; }
uint8_t lavMuxer::open(const char *filename,uint32_t inbitrate, ADM_MUXER_TYPE type, aviInfo *info, uint32_t videoExtraDataSize, uint8_t *videoExtraData, WAVHeader *audioheader, uint32_t audioextraSize,uint8_t *audioextraData) { AVCodecContext *c; _type=type; _fps1000=info->fps1000; switch(_type) { case MUXER_TS: fmt=guess_format("mpegts", NULL, NULL); break; case MUXER_DVD: fmt = guess_format("dvd", NULL, NULL); break; case MUXER_VCD: fmt = guess_format("vcd", NULL, NULL); break; case MUXER_SVCD: fmt = guess_format("svcd", NULL, NULL); break; case MUXER_MP4: fmt = guess_format("mp4", NULL, NULL); break; case MUXER_PSP: fmt = guess_format("psp", NULL, NULL); break; case MUXER_FLV: fmt = guess_format("flv", NULL, NULL); break; case MUXER_MATROSKA: fmt = guess_format("matroska", NULL, NULL); break; default: fmt=NULL; } if (!fmt) { printf("Lav:Cannot guess format\n"); ADM_assert(0); return 0; } oc = av_alloc_format_context(); if (!oc) { printf("Lav:Cannot allocate context\n"); return 0; } oc->oformat = fmt; snprintf(oc->filename,1000,"file://%s",filename); // Video //________ video_st = av_new_stream(oc, 0); if (!video_st) { printf("Lav: new stream failed\n"); return 0; } c = video_st->codec; switch(_type) { case MUXER_FLV: c->codec=new AVCodec; memset(c->codec,0,sizeof(AVCodec)); if(fourCC::check(info->fcc,(uint8_t *)"FLV1")) { c->codec_id=CODEC_ID_FLV1; c->codec->name=ADM_strdup("FLV1"); }else { if(fourCC::check(info->fcc,(uint8_t *)"VP6F")) { c->codec_id=CODEC_ID_VP6F; c->codec->name=ADM_strdup("VP6F"); } else ADM_assert(0); } break; case MUXER_MATROSKA: strcpy(oc->title,"Avidemux"); strcpy(oc->author,"Avidemux"); c->sample_aspect_ratio.num=1; c->sample_aspect_ratio.den=1; if(isMpeg4Compatible(info->fcc)) { c->codec_id = CODEC_ID_MPEG4; c->has_b_frames=1; // in doubt... }else { if(isH264Compatible(info->fcc)) { c->has_b_frames=1; // in doubt... c->codec_id = CODEC_ID_H264; c->codec=new AVCodec; memset(c->codec,0,sizeof(AVCodec)); c->codec->name=ADM_strdup("H264"); } else { if(!ADM_4cc_to_lavcodec((const char *)&(info->fcc),&(c->codec_id))) { printf("[lavFormat] Cannot map this\n"); return 0; } } } if(videoExtraDataSize) { c->extradata=videoExtraData; c->extradata_size= videoExtraDataSize; } break; case MUXER_MP4: case MUXER_PSP: { // probably a memeleak here char *foo=ADM_strdup(filename); strcpy(oc->title,ADM_GetFileName(foo)); strcpy(oc->author,"Avidemux"); c->sample_aspect_ratio.num=1; c->sample_aspect_ratio.den=1; if(isMpeg4Compatible(info->fcc)) { c->codec_id = CODEC_ID_MPEG4; c->has_b_frames=1; // in doubt... }else { if(isH264Compatible(info->fcc)) { c->has_b_frames=1; // in doubt... c->codec_id = CODEC_ID_H264; c->codec=new AVCodec; memset(c->codec,0,sizeof(AVCodec)); c->codec->name=ADM_strdup("H264"); } else { if(isDVCompatible(info->fcc)) { c->codec_id = CODEC_ID_DVVIDEO; }else { if(fourCC::check(info->fcc,(uint8_t *)"H263")) { c->codec_id=CODEC_ID_H263; }else{ c->codec_id = CODEC_ID_MPEG4; // Default value printf("Ooops, cant mux that...\n"); printf("Ooops, cant mux that...\n"); printf("Ooops, cant mux that...\n"); } } } } if(videoExtraDataSize) { c->extradata=videoExtraData; c->extradata_size= videoExtraDataSize; } if(MUXER_PSP==_type) { c->rc_buffer_size=0; //8*1024*224; c->rc_max_rate=0; //768*1000; c->rc_min_rate=0; c->bit_rate=768*1000; } else { c->rc_buffer_size=8*1024*224; c->rc_max_rate=9500*1000; c->rc_min_rate=0; if(!inbitrate) c->bit_rate=9000*1000; else c->bit_rate=inbitrate; } } break; case MUXER_TS: c->codec_id = CODEC_ID_MPEG2VIDEO; c->rc_buffer_size=8*1024*224; c->rc_max_rate=9500*1000; c->rc_min_rate=0; if(!inbitrate) c->bit_rate=9000*1000; else c->bit_rate=inbitrate; break; case MUXER_DVD: c->codec_id = CODEC_ID_MPEG2VIDEO; c->rc_buffer_size=8*1024*224; c->rc_max_rate=9500*1000; c->rc_min_rate=0; if(!inbitrate) c->bit_rate=9000*1000; else c->bit_rate=inbitrate; break; case MUXER_VCD: c->codec_id = CODEC_ID_MPEG1VIDEO; c->rc_buffer_size=8*1024*40; c->rc_max_rate=1152*1000; c->rc_min_rate=1152*1000; c->bit_rate=1152*1000; break; case MUXER_SVCD: c->codec_id = CODEC_ID_MPEG2VIDEO; c->rc_buffer_size=8*1024*112; c->rc_max_rate=2500*1000; c->rc_min_rate=0*1000; if(!inbitrate) c->bit_rate=2040*1000; else c->bit_rate=inbitrate; break; default: ADM_assert(0); } c->codec_type = CODEC_TYPE_VIDEO; c->flags=CODEC_FLAG_QSCALE; c->width = info->width; c->height = info->height; AVRational fps25=(AVRational){1001,25025}; AVRational fps24=(AVRational){1001,24000}; AVRational fps30= (AVRational){1001,30000}; AVRational fpsfree= (AVRational){1000,_fps1000}; switch(_fps1000) { case 25000: { c->time_base= fps25; break; } case 23976: if(_type==MUXER_MP4 || _type==MUXER_PSP || _type==MUXER_FLV || _type==MUXER_MATROSKA) { c->time_base= fps24; //(AVRational){1001,24000}; break; } case 29970: c->time_base=fps30; break; default: { if(_type==MUXER_MP4 || _type==MUXER_PSP || _type==MUXER_FLV || _type==MUXER_MATROSKA) { c->time_base=fpsfree;// (AVRational){1000,_fps1000}; break; } else { GUI_Error_HIG(QT_TR_NOOP("Incompatible frame rate"), NULL); return 0; } } break; } c->gop_size=15; c->max_b_frames=2; c->has_b_frames=1; // Audio //________ if(audioheader) { audio_st = av_new_stream(oc, 1); if (!audio_st) { printf("Lav: new stream failed\n"); return 0; } c = audio_st->codec; c->frame_size=1024; //For AAC mainly, sample per frame printf("[LavFormat] Bitrate %u\n",(audioheader->byterate*8)/1000); _audioFq=c->sample_rate = audioheader->frequency; #if 0 if(_type== MUXER_PSP && audioheader->encoding==WAV_AAC) { _audioFq=c->sample_rate = audioheader->frequency/2; //_audioFq*=2; // SBR } #endif switch(audioheader->encoding) { case WAV_AC3: c->codec_id = CODEC_ID_AC3;break; case WAV_MP2: c->codec_id = CODEC_ID_MP2;break; case WAV_MP3: #warning FIXME : Probe deeper c->frame_size=1152; c->codec_id = CODEC_ID_MP3; break; case WAV_PCM: // One chunk is 10 ms (1/100 of fq) c->frame_size=4; c->codec_id = CODEC_ID_PCM_S16LE;break; case WAV_AAC: c->extradata=audioextraData; c->extradata_size= audioextraSize; c->codec_id = CODEC_ID_AAC; break; default: if(_type==MUXER_MATROSKA) { if(ADM_WaveTag_to_lavcodec(audioheader->encoding, &(c->codec_id))) { if(audioextraData) { c->extradata=audioextraData; c->extradata_size= audioextraSize; } // Put a dummy time increment c->time_base= fps25; break; } } printf("Cant mux that ! audio\n"); printf("Cant mux that ! audio\n"); c->codec_id = CODEC_ID_MP2; return 0; break; } c->codec_type = CODEC_TYPE_AUDIO; c->bit_rate = audioheader->byterate*8; c->rc_buffer_size=(c->bit_rate/(2*8)); // 500 ms worth c->channels = audioheader->channels; _audioByterate=audioheader->byterate; } // /audio //---------------------- switch(_type) { case MUXER_FLV: case MUXER_PSP: case MUXER_MP4: case MUXER_MATROSKA: oc->mux_rate=10080*1000; // Needed ? break; case MUXER_TS: oc->mux_rate=10080*1000; break; case MUXER_DVD: oc->packet_size=2048; oc->mux_rate=10080*1000; break; case MUXER_VCD: oc->packet_size=2324; oc->mux_rate=2352 * 75 * 8; break; case MUXER_SVCD: oc->packet_size=2324; oc->mux_rate=2*2352 * 75 * 8; // ? break; default: ADM_assert(0); } oc->preload=AV_TIME_BASE/10; // 100 ms preloading oc->max_delay=200*1000; // 500 ms if (av_set_parameters(oc, NULL) < 0) { printf("Lav: set param failed \n"); return 0; } if (url_fopen(&(oc->pb), filename, URL_WRONLY) < 0) { printf("Lav: Failed to open file :%s\n",filename); return 0; } ADM_assert(av_write_header(oc)>=0); dump_format(oc, 0, filename, 1); printf("lavformat mpeg muxer initialized\n"); _running=1; one=(1000*1000*1000)/_fps1000; _curDTS=one; return 1; }
//-------------------------------- uint8_t EncoderFFMPEG::configure (AVDMGenericVideoStream * instream, int useExistingLogFile) { ADM_assert (instream); ADV_Info * info; uint32_t flag1, flag2, flag3; flag1 = flag2 = flag3 = 0; info = instream->getInfo (); _fps = info->fps1000; _w = info->width; _h = info->height; _vbuffer = new ADMImage (_w, _h); ADM_assert (_vbuffer); _in = instream; switch (_param.mode) { case COMPRESS_SAME: printf ("FFmpeg in follow quant mode\n"); _state = enc_Same; _codec = new ffmpegEncoderVBRExternal (_w, _h, _id); _codec->setConfig (&_settings); _codec->init (2, _fps, 0); break; case COMPRESS_CQ: printf ("ffmpeg cq mode: %ld\n", _param.qz); _state = enc_CQ; _codec = new ffmpegEncoderCQ (_w, _h, _id); _codec->setConfig (&_settings); _codec->init (_param.qz, _fps, 0); break; case COMPRESS_CBR: printf ("ffmpeg cbr mode: %ld\n", _param.bitrate); _state = enc_CBR; _codec = new ffmpegEncoderCBR (_w, _h, _id); _codec->setConfig (&_settings); _codec->init (_param.bitrate, _fps, flag1); break; case COMPRESS_2PASS: case COMPRESS_2PASS_BITRATE: ffmpegEncoderCQ * cdec; if(_param.mode==COMPRESS_2PASS) printf ("\n ffmpeg dual size: %lu", _param.finalsize); else printf ("\n ffmpeg dual bitrate: %lu", _param.avg_bitrate); _state = enc_Pass1; cdec = new ffmpegEncoderCQ (_w, _h, _id); // Pass1 cdec->setConfig (&_settings); // 1+ VBR stats required // no stats // force internal cdec->setLogFile (_logname); cdec->init (2, _fps, 1); _codec = cdec; if (flag1) _internal = 0; else _internal = 1; break; break; default: ADM_assert (0); } _in = instream; printf ("\n ffmpeg Encoder , w: %lu h:%lu mode:%d", _w, _h, _state); return 1; }
uint8_t dmx_demuxerTS::sync( uint8_t *stream,uint64_t *abs,uint64_t *r,uint64_t *pts,uint64_t *dts) { uint32_t val,hnt; retry: *r=0; val=0; hnt=0; // preload hnt=(read8i()<<16) + (read8i()<<8) +read8i(); if(_lastErr) { _lastErr=0; printf("\n io error , aborting sync\n"); return 0; } while((hnt!=0x00001)) { hnt<<=8; val=read8i(); hnt+=val; hnt&=0xffffff; if(_lastErr) { _lastErr=0; printf("\n io error , aborting sync\n"); return 0; } } *stream=read8i(); // Case 1 : assume we are still in the same packet if(_pesBufferIndex>=4) { *abs=_pesBufferStart; *r=_pesBufferIndex-4; *pts=_pesPTS; *dts=_pesDTS; } else { // pick what is needed from oldPesStart etc... // since the beginning in the previous packet uint32_t left=4-_pesBufferIndex; if(left>_oldPesLen) { // previous Packet which len is very shoty // Ignore _pesBufferIndex=0; printf("Ignoring too short packet"); goto retry; } left=_oldPesLen-left; #if 0 printf("Next packet : %I64X Len :%lu, using previous packet %I64X len:%u as pos=%lu\n", _pesBufferStart,_pesBufferLen,_oldPesStart,_oldPesLen,_pesBufferIndex); #endif if(left>_oldPesLen) { printf("Need %lu bytes from previous packet, which len is %lu\n",left,_oldPesLen); ADM_assert(0); } *abs=_oldPesStart; *r=left; *pts=_oldPTS; *dts=_oldDTS; } return 1; }
void GUI_FileSelWrite(const char *label,char * * name) { ADM_assert(fileSelDescriptor); return fileSelDescriptor->fileWriteName(label,name); }
//________________________________________________ // Init lame encoder // frequence : Impose frequency , 0 means reuse the incoming fq // mode : ADM_STEREO etc... // bitrate : Bitrate in kbps (96,192...) // return 0 : init failed // 1 : init succeeded //_______________________________________________ uint8_t AUDMEncoder_Twolame::init(ADM_audioEncoderDescriptor *config) { int ret; TWOLAME_MPEG_mode mmode; uint32_t frequence; TWOLAME_encoderParam *lameConf=(TWOLAME_encoderParam *)config->param; ADM_assert(config->paramSize==sizeof(TWOLAME_encoderParam)); _twolameOptions = twolame_init(); if (_twolameOptions == NULL) return 0; if(_wavheader->channels>2) { printf("[TwoLame]Too many channels\n"); return 0; } _wavheader->byterate=(config->bitrate*1000)>>3; _chunk = 1152*_wavheader->channels; printf("[TwoLame]Incoming :fq : %lu, channel : %lu bitrate: %lu \n", _wavheader->frequency,_wavheader->channels,config->bitrate); twolame_set_in_samplerate(OPTIONS, _wavheader->frequency); twolame_set_out_samplerate (OPTIONS, _wavheader->frequency); twolame_set_num_channels(OPTIONS, _wavheader->channels); if(_wavheader->channels==1) mmode=TWOLAME_MONO; else switch (lameConf->mode) { case ADM_STEREO: mmode = TWOLAME_STEREO; break; case ADM_JSTEREO: mmode = TWOLAME_JOINT_STEREO; break; case ADM_MONO: mmode=TWOLAME_MONO; break; default: printf("\n **** unknown mode, going stereo ***\n"); mmode = TWOLAME_STEREO; break; } twolame_set_mode(OPTIONS,mmode); twolame_set_error_protection(OPTIONS,TRUE); //toolame_setPadding (options,TRUE); twolame_set_bitrate (OPTIONS,config->bitrate); twolame_set_verbosity(OPTIONS, 2); if(twolame_init_params(OPTIONS)) { printf("[TwoLame]Twolame init failed\n"); return 0; } printf("[TwoLame]Libtoolame successfully initialized\n"); return 1; }
//************************************* void update( void ) { uint32_t audioSize; uint32_t totalSize; char string[200]; aviInfo info; video_body->getVideoInfo(&info); track1=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(GW(spinbuttonTrack1))); track2=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(GW(spinbuttonTrack2))); gtk_spin_button_set_value(GTK_SPIN_BUTTON(GW(spinbuttonTrack1)), track1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(GW(spinbuttonTrack2)), track1); // kb->Byte audioSize=(track1+track2)*1000; audioSize/=8; audioSize*=videoDuration; audioSize>>=20; sprintf(string,"%"PRIu32,audioSize); gtk_label_set_text(GTK_LABEL(GW(labelAudio)),string); // Compute total size (for Avi) uint32_t s74,s80,dvd; // For avi/ogm int f = gtk_combo_box_get_active(GTK_COMBO_BOX(GW(comboboxFormat))); if(f==2) { // Mpeg s74=730; s80=790; dvd=4300; } else {//AVI or OGM s74=650; s80=700; dvd=4300; } int j=gtk_combo_box_get_active(GTK_COMBO_BOX(GW(comboboxMedium))); switch(j) { case 2: totalSize=1*s74;break; case 3: totalSize=2*s74;break; case 0: totalSize=1*s80;break; case 1: totalSize=2*s80;break; case 4: totalSize=dvd;break; case 5: totalSize=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(GW(spinbuttonCustom))); if(totalSize<1) totalSize=1; break; default: ADM_assert(0); } sprintf(string,"%"PRIu32,totalSize); gtk_label_set_text(GTK_LABEL(GW(labelTotal)),string); // Compute muxing overhead size uint32_t muxingOverheadSize; int numberOfAudioTracks = 0; int numberOfChunks; switch (f) { case 0: // AVI /* Muxing overhead is 8 + 32 = 40 bytes per chunk. More or less: numberOfChunks = (x + 1) * numberOfVideoFrames, where x - the number of audio tracks */ if (track1 != 0) { numberOfAudioTracks++; } if (track2 != 0) { numberOfAudioTracks++; } numberOfChunks = (numberOfAudioTracks + 1) * numberOfVideoFrames; muxingOverheadSize = (uint32_t) ceil((numberOfChunks * 40) / 1048576.0);; break; case 1: // OGM // Muxing overhead is 1.1% to 1.2% of (videoSize + audioSize) muxingOverheadSize = (uint32_t) ceil(totalSize - totalSize / 1.012); break; case 2: // MPEG // Muxing overhead is 1% to 2% of (videoSize + audioSize) muxingOverheadSize = (uint32_t) ceil(totalSize - totalSize / 1.02); break; default: ADM_assert(0); } //sprintf(string,"%lu",muxingOverheadSize); //gtk_label_set_text(GTK_LABEL(GW(labelMux)),string); // and compute // //uint32_t videoSize; if(audioSize>=totalSize) sprintf(string,"** NO ROOM LEFT**"); else { uint32_t picSize; videoSize=totalSize-audioSize - muxingOverheadSize; // Compute average bps float avg; float bpp; avg=videoSize; avg*=1024.*1024.; avg/=videoDuration; // now we have byte /sec // convert to kb per sec avg=(avg*8)/1000; videoBitrate=(uint32_t)avg; sprintf(string,"%"PRIu32,(uint32_t)videoBitrate); gtk_label_set_text(GTK_LABEL(GW(labelBitrate)),string); // sprintf(string,"%"PRIu32,videoSize); gtk_label_set_text(GTK_LABEL(GW(labelVideo)),string); // Bpp bpp=videoBitrate; bpp=bpp*1000000.; // kbit->bit + compensate for fps1000 // Fetch info from filter if(videoProcessMode()) picSize=getPicSize(); else picSize=info.width*info.height; bpp/=picSize; //printf("w:%d h:%d\n",info.width,info.height); bpp/=info.fps1000; sprintf(string,"%1.3f",bpp); gtk_label_set_text(GTK_LABEL(GW(labelBPP)),string); } }
/** \fn decodeSEI \brief decode SEI to get short ref I @param recoveryLength # of recovery frame \return true if recovery found */ bool TsIndexer::decodeSEI(uint32_t nalSize, uint8_t *org,uint32_t *recoveryLength, pictureStructure *picStruct) { ADM_assert(nalSize+16<ADM_NAL_BUFFER_SIZE) uint8_t *payload=payloadBuffer; bool r=false; nalSize=ADM_unescapeH264(nalSize,org,payload); uint8_t *tail=payload+nalSize; *picStruct=pictureFrame; // frame while( payload<tail-2) { uint32_t sei_type=0,sei_size=0; while(payload[0]==0xff) {sei_type+=0xff;payload++;}; sei_type+=payload[0];payload++; while(payload[0]==0xff) {sei_size+=0xff;payload++;}; sei_size+=payload[0];payload++; aprintf(" [SEI] Type : 0x%x size:%d\n",sei_type,sei_size); switch(sei_type) // Recovery point { case 1: { if(spsInfo.hasStructInfo) { getBits bits(sei_size,payload); payload+=sei_size; if(spsInfo.CpbDpbToSkip) { bits.get(spsInfo.CpbDpbToSkip); } //printf("Consumed: %d,\n",bits.getConsumedBits()); int pic=bits.get(4); aprintf("Pic struct: %d,\n",pic); switch(pic) { case 0: *picStruct=pictureFrame; break; case 3: case 4: *picStruct=pictureFrame; case 1: *picStruct=pictureTopField;break; case 2: *picStruct=pictureBottomField;break; default:*picStruct=pictureFrame; } }else payload+=sei_size; } break; case 6: { getBits bits(sei_size,payload); payload+=sei_size; *recoveryLength=bits.getUEG(); aprintf("[SEI] Recovery :%"PRIu32"\n",*recoveryLength); r=true; break; } default: payload+=sei_size; break; } } //if(payload+1<tail) ADM_warning("Bytes left in SEI %d\n",(int)(tail-payload)); return r; }
uint8_t AVDMBufferedAudioStream::goToTime(uint32_t newoffset) { ADM_assert(!newoffset); _instream->goToTime(0); _headBuff=_tailBuff=0; return 1; }
void GenericAviSave::guiSetPhasis(const char *str) { ADM_assert(encoding_gui); encoding_gui->setPhasis(str); }
uint8_t AVDMBufferedAudioStream::goTo(uint32_t newoffset) { ADM_assert(!newoffset); goToTime(0); return 1; }
uint8_t OpenDMLHeader::indexRegular(uint32_t vidTrack) { uint32_t fcc,flags,offset,len; uint32_t count,total=0; uint32_t trackId,ccType; uint32_t audioCount[9]={0,0,0,0, 0,0,0,0,0}; uint32_t forward[9]; uint32_t backward[9]; int64_t startOfData; printf("Trying avi type 1 index\n"); if(!_regularIndex.offset) { printf("No regular index\n"); return 0; } fseeko(_fd,_regularIndex.offset,SEEK_SET); // first pass : count how much count=_regularIndex.size >> 4; while(count) { fcc=len=0; fcc=read32(); flags=read32(); offset=read32(); len=read32(); if(fcc==MKFCC('r','e','c',' ')) { _recHack=1; count--; continue; } trackId=((fcc>>8) & 0xFF) -'0';; if(trackId>9) trackId=0; ccType=fcc >>16; switch(ccType) { case MKFCC('d','c',0,0): // video tracks case MKFCC('d','b',0,0): total++; break; case MKFCC('w','b',0,0): audioCount[trackId]++; break; default: printf("Unknown fcc:");fourCC::print(fcc);printf("\n"); } count--; } printf("Found %u videos chunk\n",total); for(int i=0;i<9;i++) printf("Audio track :%d, %u audio chunk\n",i,audioCount[i]); fseeko(_fd,_regularIndex.offset,SEEK_SET); _idx=new odmlIndex[total]; memset(_idx,0,sizeof(odmlIndex)*total); count=0; int run=0; // Pack tracks for(int i=0;i<9;i++) { if(audioCount[i]) { forward[run]=i; backward[i]=run; run++; } } if(!run) { _nbAudioTracks=0; printf("No audio chunk found in index..\n"); }else ADM_assert(run==_nbAudioTracks); // Create index uint32_t nb; for(int i=0;i<_nbAudioTracks;i++) { nb=audioCount[forward[i]]; _audioTracks[i].index=new odmlIndex[nb+1]; memset(_audioTracks[i].index,0,(sizeof(odmlIndex)*(nb+1))); _audioTracks[i].nbChunks=0; } uint32_t audiocount=0,videocount=0; uint32_t audiototal=0; uint32_t audioSize=0; odmlIndex *track; int Achunk; count=_regularIndex.size >> 4; while(count) { _again: fcc=len=0; fcc=read32(); flags=read32(); offset=read32(); len=read32(); count--; trackId=((fcc>>8) & 0xFF) -'0';; if(trackId>9) trackId=0; ccType=fcc >>16; if(videocount==0 && audiocount==0) // first chunk met { // the first one is at movie_offset-4+8 // Its offset + startoff data should be there startOfData=_movi.offset+8; startOfData-=offset; if(_recHack) { startOfData+=4+4+4; } } if(fcc==MKFCC('r','e','c',' ')) { _recHack=1; continue; } switch(ccType) { case MKFCC('d','c',0,0): // video tracks case MKFCC('d','b',0,0): _idx[videocount].offset=offset; _idx[videocount].offset+=startOfData; _idx[videocount].size=len; _idx[videocount].intra=flags; #ifdef ODML_INDEX_VERBOSE printf("Vid:at %llx size %lu (%lu/%lu) |",_idx[videocount].offset,len,videocount,total);fourCC::print(fcc);printf("|\n"); if(offset & 1) printf("!!!! ODD !!!"); #endif videocount++; break; case MKFCC('w','b',0,0): nb=backward[trackId]; ADM_assert(nb<_nbAudioTracks); track=_audioTracks[nb].index; Achunk=_audioTracks[nb].nbChunks; _audioTracks[nb].nbChunks++; track[Achunk].offset=offset; track[Achunk].offset+=startOfData; track[Achunk].size=len; track[Achunk].intra=flags; _audioTracks[nb].totalLen+=len; audioSize+=len; if(offset & 1) printf("!!!! ODD !!!"); audiocount++; break; default: printf("Idx Regulat: Unknown fcc:");fourCC::print(fcc);printf("\n"); } } _videostream.dwLength= _mainaviheader.dwTotalFrames=total; if(total) _idx[0].intra=AVI_KEY_FRAME; printf("Found %u video \n",total); return 1; }
/* Uncompress frame, set flags if needed */ uint8_t decoderPng::uncompress(ADMCompressedImage * in, ADMImage * out) { int bpp; int colortype; // Check if it is png, and fill it if (!!png_sig_cmp (in->data, 0, 8)) { printf ("[PNG] wrong sig\n"); return 0; } // // gain2: Init (); io.data = in->data; io.size = in->dataLength; io.cur = 0; png_read_png (PNG_PTR, INFO_PTR, PNG_TRANSFORM_IDENTITY, NULL); // Check if it is 24 or 32 bits RGB bpp = png_get_bit_depth (PNG_PTR, INFO_PTR); // printf("Bpp:%u\n",bpp); // if needed we change colorspace colortype = png_get_color_type (PNG_PTR, INFO_PTR); // if (colorspace == ADM_COLOR_RGB24 && colortype == PNG_COLOR_TYPE_RGB_ALPHA) // RGB32 { // Switch to 32 bits colorspace = ADM_COLOR_RGB32A; recalc (); goto gain2; } else if (colorspace == ADM_COLOR_RGB32A && colortype == PNG_COLOR_TYPE_RGB) { // Switch to 24 bits colorspace = ADM_COLOR_RGB24; recalc (); goto gain2; } ADM_assert (out->_isRef); out->_planes[0] = decoded; out->_planes[1] = NULL; out->_planes[2] = NULL; if (colorspace == ADM_COLOR_RGB32A) out->_planeStride[0] = _w * 4; else out->_planeStride[0] = _w * 3; out->_planeStride[1] = 0; out->_planeStride[2] = 0; out->_colorspace = colorspace; Cleanup (); return 1; }
/** * \fn GUI_FileSelWrite * \brief Select a file for Writing, when ok the CB callback is called with the name as argument */ void GUI_FileSelWrite(const char *label,SELFILE_CB *cb) { ADM_assert(fileSelDescriptor); return fileSelDescriptor->fileWriteCb(label,cb); }
/** * \fn automation * @return */ int automation(void ) { static char **argv; static int argc; static int cur; static int myargc; static int index; static three_arg_type three; static two_arg_type two; argc=global_argc; argv = global_argv; //the port change has to be done before the video load for( int runParaSearch=2 ; runParaSearch < argc ; ){ if(*argv[runParaSearch] == '-' && *(argv[runParaSearch]+1) == '-') { index = searchReactionTable(argv[runParaSearch]+2); if(index != -1) { if(!strcmp(avs_port_change, argv[runParaSearch] +2 )) { A_set_avisynth_port(argv[runParaSearch+1]); break; } runParaSearch += reaction_table[index].have_arg +1; } else runParaSearch += 1; } else runParaSearch += 1; } printf("\n *** Automated : %" PRIu32" entries*************\n",(uint32_t)NB_AUTO); // we need to process argc-=1; cur=1; myargc=argc; while(myargc>0) { if(( *argv[cur]!='-') || (*(argv[cur]+1)!='-')) { if(cur==1) { loadCB(argv[cur]); } else printf("\n Found garbage %s\n",argv[cur]); cur+=1;myargc-=1; continue; } // else it begins with -- if(!strcmp(argv[cur]+2,"portable")) // portable mode switch has been already taken care of, ignore { cur++; myargc--; continue; } index= searchReactionTable(argv[cur]+2); if(index==-1) // not found { printf("\n Unknown command :%s\n",argv[cur] ); cur+=1;myargc-=1; } else { printf("%s-->%d\n", reaction_table[index].string,reaction_table[index].have_arg); one_arg_type call=reaction_table[index].callback; switch( reaction_table[index].have_arg) { case 3: three=(three_arg_type)call; three( argv[cur+1],argv[cur+2],argv[cur+3]); break; case 2: two=(two_arg_type)call; two( argv[cur+1],argv[cur+2]); break; case 1: call(argv[cur+1]); break; case 0: call(NULL); break; default: ADM_assert(0); break; } cur+=1+reaction_table[index].have_arg; myargc-=1+reaction_table[index].have_arg; } } // end while GUI_Verbose(); printf("\n ********** Automation ended***********\n"); return 0; // Do not call me anymore }
/** * \fn GUI_FileSelRead * \brief Select a file for reading, name is allocated with a copy of the name, null if fail. */ void GUI_FileSelRead(const char *label,char * * name) { ADM_assert(fileSelDescriptor); return fileSelDescriptor->fileReadName(label,name); }
int preferences::set_lastfile(const char* file){ char *internal_file; if( ! file ){ fprintf(stderr,"Prefs: set_lastfile(NULL) called\n"); return RC_FAILED; } internal_file = ADM_PathCanonize(file); if( !internal_file ){ fprintf(stderr,"Prefs: set_lastfile(): PathCanonize() returns NULL\n"); return RC_FAILED; } #ifdef DEBUG_PREFS fprintf(stderr,"Prefs: set_lastfile(%s)\n",file); if( strcmp(file,internal_file) ) fprintf(stderr,"Prefs: set_lastfile(%s) (with appended current dir)\n",internal_file); PRT_LAFI("<= LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val); PRT_LAFI("<= LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val); PRT_LAFI("<= LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val); PRT_LAFI("<= LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val); #endif // change opt_defs array // // ToDo: // * a call with a file already in lastfiles will resort lastfiles with // the actual argument on top // * a call with a file new to lastfiles will drop LASTFILE_4, move all // one step down and add the file as LASTFILE_1 if( opt_defs[LASTFILES_FILE4].current_val && !strncmp(opt_defs[LASTFILES_FILE4].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE4].current_val)) ){ char *x = opt_defs[LASTFILES_FILE4].current_val; opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE3].current_val && !strncmp(opt_defs[LASTFILES_FILE3].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE3].current_val)) ){ char *x = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE2].current_val && !strncmp(opt_defs[LASTFILES_FILE2].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE2].current_val)) ){ char *x = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE1].current_val && !strncmp(opt_defs[LASTFILES_FILE1].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE1].current_val)) ){ ; // nothing to do - always on top }else{ if( opt_defs[LASTFILES_FILE4].current_val ) ADM_dealloc(opt_defs[LASTFILES_FILE4].current_val); opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = ADM_strdup(internal_file); } #ifdef USE_LIBXML2 // change the xmlDocument if( ! xdoc ){ // no .avidemuxrc file or not loaded yet load(); // try to load it if( ! xdoc ){ // really: no .avidemuxrc file save(); // generate one from internal defaults and actual changes if( xdoc ) erase_blank_nodes(xdoc->children); } } if( ! xdoc ){ fprintf(stderr,"Prefs: no xml document generated ny load() nor save()\n"); }else{ xmlNodePtr p; xmlNodePtr q; // we assume a valid xml document, but maybe an older version ADM_assert( xdoc->children ); p = xdoc->children; // ->avidemux (should be there) p = goto_node_with_create(p, "lastfiles"); // ->avidemux->lastfile q = goto_node_with_create(p, "file1"); // ->avidemux->lastfile->1 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE1].current_val?opt_defs[LASTFILES_FILE1].current_val:"")); q = goto_node_with_create(p, "file2"); // ->avidemux->lastfile->2 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE2].current_val?opt_defs[LASTFILES_FILE2].current_val:"")); q = goto_node_with_create(p, "file3"); // ->avidemux->lastfile->3 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE3].current_val?opt_defs[LASTFILES_FILE3].current_val:"")); q = goto_node_with_create(p, "file4"); // ->avidemux->lastfile->4 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE4].current_val?opt_defs[LASTFILES_FILE4].current_val:"")); save_xml_to_file(); } #endif #ifdef DEBUG_PREFS PRT_LAFI("=> LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val); PRT_LAFI("=> LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val); PRT_LAFI("=> LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val); PRT_LAFI("=> LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val); #endif delete[] internal_file; return RC_OK; }
/** * \fn FileSel_SelectRead * \brief Select a file for Reading, name is allocated with a copy of the name, null if fail. * @param title : [in] Title of the dialog box * @param target: [in/out] Buffer that will hold the name, must be at least max bytes big * @param max : [in] Max number of bytes the buffer will hold * @param source : [in] Initial value for the file, can be null */ uint8_t FileSel_SelectRead(const char *title,char *target,uint32_t max, const char *source) { ADM_assert(fileSelDescriptor); return fileSelDescriptor->fileSelectRead(title,target,max, source); }
uint8_t ADM_queue::isEmpty(void) { if(head) return 0; ADM_assert(!tail); return 1; }
Decimate::Decimate(AVDMGenericVideoStream *in,CONFcouple *couples) { { int count = 0; char buf[80]; unsigned int *p; _in=in; memcpy(&_info,_in->getInfo(),sizeof(_info)); _info.encoding=1; _uncompressed=NULL; _info.encoding=1; // // Init here debug=0; show=0; #ifdef USE_SSE if(CpuCaps::hasSSE()) { printf("Decimate:SSE enabled\n"); } #endif // _param=new DECIMATE_PARAM; if(couples) { GET(cycle); GET(mode); GET(quality); GET(threshold); GET(threshold2); } else // Default { _param->cycle=5; _param->mode=0; _param->quality=2; _param->threshold=0; _param->threshold2=3.0; } ADM_assert(_param->cycle); vidCache=new VideoCache(_param->cycle*2+1,in); if (_param->mode == 0 || _param->mode == 2 || _param->mode == 3) { num_frames_hi = _info.nb_frames; _info.nb_frames = _info.nb_frames * (_param->cycle - 1) / _param->cycle; _info.fps1000=_info.fps1000*(_param->cycle-1); _info.fps1000=(uint32_t)(_info.fps1000/_param->cycle); } last_request = -1; firsttime = true; sum = (unsigned int *) ADM_alloc(MAX_BLOCKS * MAX_BLOCKS * sizeof(unsigned int)); ADM_assert(sum); all_video_cycle = true; if (debug) { char b[80]; sprintf(b, "Decimate %s by Donald Graft, Copyright 2003\n", VERSION); OutputDebugString(b); } } }
uint8_t oplug_mpegff(const char *name, ADM_OUT_FORMAT type) { AVDMGenericVideoStream *_incoming; //EncoderFFMPEGMpeg1 *encoder; Encoder *encoder; ADMMpegMuxer *muxer=NULL; FILE *file=NULL; uint8_t audioBuffer[48000]; uint32_t audioLen=0; uint32_t _w,_h,_fps1000,_page,total; AVDMGenericAudioStream *audio; uint32_t len,flags; uint32_t size; ADM_MUXER_TYPE mux; uint32_t audio_encoding=0; uint32_t real_framenum=0; uint8_t ret=0; uint32_t sample_target=0; uint32_t total_sample=0; ADMBitstream bitstream(0); uint32_t audioSum=0; twoPass=new char[strlen(name)+6]; twoFake=new char[strlen(name)+6]; strcpy(twoPass,name); strcat(twoPass,".stat"); /* orig: strcat(twoFake,".fake"); */ strcpy(twoFake,name); strcat(twoFake,".fake"); _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart); _w=_incoming->getInfo()->width; _h=_incoming->getInfo()->height; _fps1000=_incoming->getInfo()->fps1000; _page=_w*_h; _page+=_page>>1; total=_incoming->getInfo()->nb_frames; if(!total) return 0; switch(type) { default: ADM_assert(0); case ADM_ES: // Else open file (if possible) mux=MUXER_NONE; break; case ADM_TS: if(!currentaudiostream) { GUI_Error_HIG(_("There is no audio track"), NULL); return 0; } audio=mpt_getAudioStream(); mux=MUXER_TS; break; case ADM_PS: { if(!currentaudiostream) { GUI_Error_HIG(_("There is no audio track"), NULL); return 0; } audio=mpt_getAudioStream(); // Have to check the type // If it is mpeg2 we use DVD-PS // If it is mpeg1 we use VCD-PS // Later check if it is SVCD if(!audio) { GUI_Error_HIG(_("Audio track is not suitable"), NULL); return 0; } // Check WAVHeader *hdr=audio->getInfo(); audio_encoding=hdr->encoding; if(current_codec==CodecXVCD ||current_codec==CodecVCD) { if(hdr->frequency!=44100 || hdr->encoding != WAV_MP2) { GUI_Error_HIG(("Incompatible audio"),_( "For VCD, audio must be 44.1 kHz MP2.")); deleteAudioFilter(audio); return 0; } mux=MUXER_VCD; printf("X*CD: Using VCD PS\n"); }else { aviInfo info; video_body->getVideoInfo(&info); if(hdr->frequency==44100 && _w==480&&hdr->encoding == WAV_MP2 ) // SVCD ? { mux=MUXER_SVCD; printf("X*VCD: Using SVCD PS\n"); } else { // mpeg2, we do only DVD right now if(hdr->frequency!=48000 || (hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM)) { deleteAudioFilter(audio); GUI_Error_HIG(_("Incompatible audio"), _("For DVD, audio must be 48 kHz MP2, AC3 or LPCM.")); return 0 ; } mux=MUXER_DVD; printf("X*VCD: Using DVD PS\n"); } } } } // Create muxer switch(current_codec) { case CodecXVCD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG1,&ffmpeg1Codec); printf("\n Using ffmpeg mpeg1 encoder\n"); break; case CodecXSVCD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2SVCDCodec); printf("\n Using ffmpeg mpeg2 encoder\n"); break; case CodecXDVD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2DVDCodec); printf("\n Using ffmpeg mpeg2 encoder (DVD)\n"); break; case CodecDVD: encoder=new EncoderMpeg2enc(MPEG2ENC_DVD,&DVDCodec); printf("\n Using mpeg2enc encoder (DVD)\n"); break; case CodecRequant: if(!isMpeg12Compatible(avifileinfo->fcc)) { GUI_Error_HIG("Incompatible Input","The input file must be mpeg2 to be able to use requant!"); return 0; // Fixme, do some cleanup } encoder=new EncoderRequant(&RequantCodec); printf("\n Using mpeg2 requant\n"); break; break; case CodecSVCD: encoder=new EncoderMpeg2enc(MPEG2ENC_SVCD,&SVCDCodec); printf("\n Using mpeg2enc encoder (SVCD)\n"); break; case CodecVCD: encoder=new EncoderMpeg2enc(MPEG2ENC_VCD,&VCDCodec); printf("\n Using mpeg2enc encoder (VCD)\n"); break; default: ADM_assert(0); } encoder->setLogFile(twoPass,total); if(!encoder->configure(_incoming)) { delete encoder; return 0; } _buffer=new uint8_t[_page]; // Might overflow if _page only _outbuffer=new uint8_t[_page]; ADM_assert( _buffer); ADM_assert( _outbuffer); DIA_encoding *encoding; encoding =new DIA_encoding(_fps1000); switch(current_codec) { case CodecVCD: encoding->setCodec("libmpeg2enc VCD"); break; case CodecSVCD: encoding->setCodec("libmpeg2enc SVCD"); break; case CodecDVD: encoding->setCodec("libmpeg2enc DVD"); break; case CodecXVCD: encoding->setCodec("FFmpeg Mpeg1 VBR"); break; case CodecXSVCD: encoding->setCodec("FFmpeg Mpeg2 SVCD VBR"); break; case CodecXDVD: encoding->setCodec("FFmpeg Mpeg2 DVD VBR"); break; case CodecRequant: encoding->setCodec("Mpeg Requantizer"); break; default: ADM_assert(0); } switch(mux) { case MUXER_NONE:encoding->setContainer("Mpeg ES");break; case MUXER_TS: encoding->setContainer("Mpeg TS");break; case MUXER_VCD: encoding->setContainer("Mpeg VCD");break; case MUXER_SVCD:encoding->setContainer("Mpeg SVCD");break; case MUXER_DVD: encoding->setContainer("Mpeg DVD");break; default: ADM_assert(0); } // pass 1 if(encoder->isDualPass()) { FILE *fd; uint8_t reuse=0; fd=fopen(twoPass,"rt"); if(fd) { if(GUI_Question(_("Reuse log file ?"))) { reuse=1; } fclose(fd); } if(!reuse) { encoding->setPhasis ("Pass 1/2"); encoder->startPass1(); bitstream.data=_buffer; bitstream.bufferSize=_page; for(uint32_t i=0;i<total;i++) { bitstream.cleanup(i); if(!encoder->encode( i, &bitstream))//&len,(uint8_t *) _buffer,&flags)) { GUI_Error_HIG(_("Error in pass 1"), NULL); } encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total); if(!encoding->isAlive()) { goto finishvcdff; } } } encoder->startPass2(); encoding->reset(); } switch(type) { case ADM_PS: muxer=new mplexMuxer; break; case ADM_TS: muxer=new tsMuxer; break; case ADM_ES: break; default: ADM_assert(0); } if(muxer) { if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo())) { delete muxer; muxer=NULL; deleteAudioFilter(audio); printf("Muxer init failed\n"); return 0 ; } double sample_time; sample_time=total; sample_time*=1000; sample_time/=_fps1000; // target_time in second sample_time*=audio->getInfo()->frequency; sample_target=(uint32_t)floor(sample_time); } else { file=fopen(name,"wb"); if(!file) { GUI_Error_HIG(_("File error"), _("Cannot open \"%s\" for writing."), name); return 0 ; } } if(encoder->isDualPass()) encoding->setPhasis ("Pass 2/2"); else encoding->setPhasis ("Encoding"); // Set info for audio if any if(muxer) { if(!audioProcessMode()) encoding->setAudioCodec("Copy"); else encoding->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding)); } //********************************************************** // In that case we do multithreadedwriting (yes!) //********************************************************** if(mux==MUXER_DVD || mux==MUXER_SVCD || mux==MUXER_VCD) { pthread_t audioThread,videoThread,muxerThread; muxerMT context; // bitstream.data=_outbuffer; bitstream.bufferSize=_page; // memset(&context,0,sizeof(context)); context.videoEncoder=encoder; context.audioEncoder=audio; context.muxer=(mplexMuxer *)muxer; context.nbVideoFrame=total; context.audioTargetSample=sample_target; context.audioBuffer=audioBuffer; context.bitstream=&bitstream; context.opaque=(void *)encoding; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)defaultVideoSlave,&context)); while(1) { accessMutex.lock(); if(!encoding->isAlive()) { context.audioAbort=1; context.videoAbort=1; printf("[mpegFF]Waiting for slaves\n"); accessMutex.unlock(); while(1) { accessMutex.lock(); if(context.audioDone && context.videoDone) { printf("[mpegFF]Both audio & video done\n"); if(context.audioDone==1 && context.videoDone==1) ret=1; else ret=0; accessMutex.unlock(); goto finishvcdff; } accessMutex.unlock(); ADM_usleep(50000); } } if(context.audioDone==2 || context.videoDone==2 ) //ERROR { context.audioAbort=1; context.videoAbort=1; } if(context.audioDone && context.videoDone) { printf("[mpegFF]Both audio & video done\n"); if(context.audioDone==1 && context.videoDone==1) ret=1; else ret=0; accessMutex.unlock(); goto finishvcdff; } accessMutex.unlock(); ADM_usleep(1000*1000); } } //********************************************************** // NOT MULTITHREADED //********************************************************** bitstream.data=_outbuffer; for(uint32_t i=0;i<total;i++) { // get frame bitstream.cleanup(i); if(!encoder->encode( i,&bitstream))// &len,(uint8_t *) _outbuffer,&flags)) { GUI_Error_HIG(_("Error in pass 2"), NULL); goto finishvcdff; } if(!bitstream.len) continue; if(file) { fwrite(_outbuffer,bitstream.len,1,file); } else { uint32_t samples; //printf("%lu %lu\n",i,dts); muxer->writeVideoPacket(&bitstream); real_framenum++; // _muxer->writeVideoPacket(len,_buffer_out, //i-MPEG_PREFILL,_codec->getCodedPictureNumber()); if(total_sample<sample_target) { while(muxer->needAudio() && total_sample<sample_target) { if(!audio->getPacket(audioBuffer, &audioLen, &samples)) { break; } if(audioLen) { muxer->writeAudioPacket(audioLen,audioBuffer); total_sample+=samples; audioSum+=audioLen; } } } } encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total); encoding->setAudioSize(audioSum); if(!encoding->isAlive ()) { ret=0; goto finishvcdff; } } ret=1; finishvcdff: printf("[MPEGFF] Finishing..\n"); delete encoding; end(); if(file) { fclose(file); file=NULL; } else { if(muxer) { muxer->close(); delete muxer; muxer=NULL; } } delete encoder; return ret; }
//______________________________ uint8_t EncoderFFMPEG::encode (uint32_t frame, ADMBitstream *out) { uint32_t l, f; //ENC_RESULT enc; ADM_assert (_codec); ADM_assert (_in); if (frame != UINT32_MAX) { if (!_in->getFrameNumberNoAlloc (frame, &l, _vbuffer, &f)) { printf ("\n Error : Cannot read incoming frame !"); return 0; } } switch (_state) { case enc_CBR: case enc_CQ: return _codec->encode (frame == UINT32_MAX ? NULL : _vbuffer, out ); break; case enc_Same: { if (frame != UINT32_MAX) { if (_vbuffer->flags & AVI_KEY_FRAME) out->flags = AVI_KEY_FRAME; else out->flags = 0; int inq = _vbuffer->_Qp; if (inq > 31) inq = 31; if (inq < 2) inq = 2; out->in_quantizer = inq; } if (!_codec->encode (frame == UINT32_MAX ? NULL : _vbuffer, out )) { printf ("\n codec error on 1st pass !"); return 0; } //printf("Inq:%lu outq:%lu\n",inq,enc.out_quantizer); _frametogo++; return 1; break; } case enc_Pass1: // ADM_assert(fd); if (!_codec->encode (frame == UINT32_MAX ? NULL : _vbuffer, out )) { printf ("\n codec error on 1st pass !"); return 0; } _frametogo++; return 1; break; case enc_Pass2: // Encode it ! if (!_codec->encode (frame == UINT32_MAX ? NULL : _vbuffer, out )) return 0; return 1; break; default: ADM_assert (0); } return 0; }
/** \fn getFFCompressParams \brief Dialog for lavcodec mpeg4/... codec settings */ uint8_t DIA_xvid4(COMPRES_PARAMS *incoming) { int b; int ret=0; int code; xvid4EncParam localParam; ADM_assert(incoming->extraSettingsLen==sizeof(localParam)); memcpy(&localParam,incoming->extraSettings,sizeof(localParam)); #define PX(x) &(localParam.x) // Our tabs /* Tab 1 main */ diaElemBitrate bitrate(incoming,NULL); #define MKTOGGLE(y,x) diaElemToggle t_##x(PX(x),y) MKTOGGLE(QT_TR_NOOP("_Interlaced"), interlaced); MKTOGGLE(QT_TR_NOOP("Ca_rtoon mode"), cartoon); MKTOGGLE(QT_TR_NOOP("_Greyscale"), greyscale); MKTOGGLE(QT_TR_NOOP("Turbo mode"), turbo); MKTOGGLE(QT_TR_NOOP("C_hroma optimizer"), chroma_opt); diaElem *main[]={&bitrate,&t_interlaced,&t_cartoon,&t_greyscale,&t_turbo,&t_chroma_opt}; diaElemTabs tabMain(QT_TR_NOOP("Main"),6,main); /* Tab 2 motion */ diaMenuEntry motionMenu[] = { {0, QT_TR_NOOP("None"),NULL} ,{1, QT_TR_NOOP("Very Low"),NULL} ,{2, QT_TR_NOOP("Low"),NULL} ,{3, QT_TR_NOOP("Medium"),NULL} ,{4, QT_TR_NOOP("High"),NULL} ,{5, QT_TR_NOOP("Very High"),NULL} ,{6, QT_TR_NOOP("Ultra High"),NULL}}; diaElemMenu motion(PX(guiLevel),QT_TR_NOOP("Motion Search Precision"),7,motionMenu); diaMenuEntry vhqMenu[] = { {0, QT_TR_NOOP("Off"),NULL} ,{1, QT_TR_NOOP("Mode Decision"),NULL} ,{2, QT_TR_NOOP("Limited Search"),NULL} ,{3, QT_TR_NOOP("Medium Search"),NULL} ,{4, QT_TR_NOOP("Wide Search"),NULL} }; diaElemMenu vhq(PX(vhqmode),QT_TR_NOOP("VHQ Mode"),5,vhqMenu); /* Tab2-ASP */ diaElemUInteger bframe(PX(bframes),QT_TR_NOOP("Max B Frames"),0,3); diaElemToggle qpel(PX(qpel),QT_TR_NOOP("Quarter Pixel")); diaElemToggle gmc(PX(gmc),QT_TR_NOOP("GMC")); diaElemToggle bvhq(PX(bvhq),QT_TR_NOOP("BVHQ")); diaElemFrame frameASP(QT_TR_NOOP("Advanced Simple Profile")); frameASP.swallow(&bframe); frameASP.swallow(&qpel); frameASP.swallow(&gmc); frameASP.swallow(&bvhq); /* Tab 2 motion extra */ diaElemToggle inter4mv(PX(inter4mv),QT_TR_NOOP("4MV")); diaElemToggle chroma_me(PX(chroma_me),QT_TR_NOOP("Chroma ME")); diaElemToggle hqac(PX(chroma_me),QT_TR_NOOP("HQ AC")); diaElemFrame frameMore(QT_TR_NOOP("More Search")); frameMore.swallow(&inter4mv); frameMore.swallow(&chroma_me); frameMore.swallow(&hqac); /* Tab 2 gop size */ diaElemUInteger min_key_interval(PX(min_key_interval),QT_TR_NOOP("Min Gop Size"),1,900); diaElemUInteger max_key_interval(PX(max_key_interval),QT_TR_NOOP("Max Gop Size"),1,900); diaElemFrame frameGop(QT_TR_NOOP("GOP Size")); frameGop.swallow(&min_key_interval); frameGop.swallow(&max_key_interval); diaElem *motions[]={&motion,&vhq,&frameMore,&frameGop,&frameASP}; diaElemTabs tabMotion(QT_TR_NOOP("Motion"),5,motions); /* Tab 3 Qz*/ diaMenuEntry qzMenu[] = { {0, QT_TR_NOOP("H263"),NULL} ,{1, QT_TR_NOOP("Mpeg"),NULL}} ; diaElemMenu h263(PX(mpegQuantizer),QT_TR_NOOP("Quantization Matrix"),2,qzMenu); diaElemToggle trellis(PX(trellis),QT_TR_NOOP("Trellis Quantization")); diaElem *qz[]={&h263,&trellis}; diaElemTabs tabQz(QT_TR_NOOP("Quantization"),2,qz); /* Tab 4 : 2nd pass */ #define MKENTRY(y,x) diaElemUInteger x(PX(x),y,0,100); frameOne.swallow(&x); diaElemFrame frameOne(QT_TR_NOOP("Two Pass Tuning")); MKENTRY(QT_TR_NOOP("Key Frame Boost(%)"), keyframe_boost); MKENTRY(QT_TR_NOOP("I-frames closer than..."), kfthreshold); MKENTRY(QT_TR_NOOP(".. are reduced by(%)"), kfreduction); MKENTRY(QT_TR_NOOP("Max Overflow Improvement(%)"), max_overflow_improvement); MKENTRY(QT_TR_NOOP("Max Overglow Degradation(%)"), max_overflow_degradation); #undef MKENTRY #define MKENTRY(y,x) diaElemUInteger x(PX(x),y,0,100);frameTwo.swallow(&x); diaElemFrame frameTwo(QT_TR_NOOP("Curve Compression")); MKENTRY(QT_TR_NOOP("High Bitrate Scenes (%)"), curve_compression_high); MKENTRY(QT_TR_NOOP("Low Bitrate Scenes (%)"), curve_compression_low); MKENTRY(QT_TR_NOOP("Overflow Control Strength"), overflow_control_strength); diaElem *twopass[]={&frameOne,&frameTwo}; diaElemTabs tabPass(QT_TR_NOOP("Two Pass"),2,twopass); /**/ /* End of tabs */ diaElemTabs *tabs[4]={&tabMain,&tabMotion,&tabQz,&tabPass}; if( diaFactoryRunTabs(QT_TR_NOOP("Xvid4 Configuration"),4,tabs)) { memcpy(incoming->extraSettings,&localParam,sizeof(localParam)); return 1; } return 0; }
// Dummy ones uint8_t ADM_ogmWrite::initVideo(const char *name) { ADM_assert(0); return 0; }
uint8_t ADMVideoStabilize::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags) { UNUSED_ARG(flags); uint32_t uvlen; uint32_t dlen,dflags; ADMImage *_next; ADMImage *_previous; ADMImage *_current; uvlen= _info.width*_info.height; *len=uvlen+(uvlen>>1); if(frame> _info.nb_frames-1) return 0; _current=vidCache->getImage(frame); if(!_current) return 0; data->copyInfo(_current); if(!frame || (frame==_info.nb_frames-1)) { data->duplicate(_current); vidCache->unlockAll(); return 1; } _previous=vidCache->getImage(frame-1); if(!_previous) { vidCache->unlockAll(); return 0; } _next=vidCache->getImage(frame+1); if(!_next) { vidCache->unlockAll(); return 0; } // for u & v , no action -> copy it as is memcpy(UPLANE(data),UPLANE(_current),uvlen>>2); memcpy(VPLANE(data),VPLANE(_current),uvlen>>2); uint8_t *inprev,*innext,*incur,*zout; inprev=YPLANE(_previous)+1+_info.width; innext=YPLANE(_next)+1+_info.width; incur =YPLANE(_current)+1+_info.width; zout=YPLANE(data)+_info.width+1; uint8_t *nl,*pl,*nc,*pc; uint16_t c,coeff; uint32_t x; for(uint32_t y= _info.height-1;y>1;y--) { nl=incur+_info.width; pl=incur-_info.width; nc=incur+1; pc=incur-1; for(x= _info.width-1;x>1;x--) { c=*incur*4;; coeff=4; #define PONDERATE(x,p) if(distMatrix[*incur][x]<*_param) \ { c+=x;coeff++;} PONDERATE(*innext,1); PONDERATE(*inprev,1); PONDERATE(*(pc),1); PONDERATE(*(nc),1); PONDERATE(*(nl),1); PONDERATE(*(pl),1); //*zout=(uint8_t)floor(0.49+(c/coeff)); ADM_assert(coeff); ADM_assert(coeff<16); *zout=(c*fixMul[coeff])>>16; zout++; incur++; innext++; inprev++; nl++;pl++;nc++;pc++; } zout+=2; incur+=2; innext+=2; inprev+=2; } vidCache->unlockAll(); return 1; }
void DIA_working::closeDialog( void ) { workWindow *wind=(workWindow *)_priv; ADM_assert(wind); if(wind) delete wind; wind=NULL; }
uint8_t OGMDemuxer::readHeader(uint32_t *paySize, uint32_t *flags, uint64_t *frame,uint8_t *id) { uint8_t gotcha=0,c=0; uint32_t total=0,failed=0; uint64_t seq; *frame=0; if(_payload) fseeko(_fd,_payload,SEEK_CUR); _payload=0; while(1) { _hdrpos=ftello(_fd); if(fread(&_page,sizeof(_page),1,_fd)!=1) return 0; if(!fourCC::check(_page.sig,(uint8_t *)"OggS")) { printf("Bad at offset :%lu 0x %x\n",_hdrpos,_hdrpos); ADM_assert(0); } *id=fourCC::get(_page.serial); // seq=_page.page_sequence[0]+(_page.page_sequence[1]<<8); //printf("seq:%x \n",seq); uint64_t *ll; ll=(uint64_t *)_page.abs_pos; //printf("abs:%llx \n",*ll); // //if(fourCC::check(_trackId,_page.serial)) // got it { gotcha=1; } total=0; _nbLace=_page.nb_segment; _nbFrag=0; for(uint32_t i=0;i<_page.nb_segment;i++) { c=fgetc(_fd); _lace[i]=c; if(c!=0xff) _nbFrag++; total+=c; } if(gotcha) { #if 0 *frame=*(unsigned long long *)_page.abs_pos; #else *frame+=_page.abs_pos[4]+(_page.abs_pos[5]<<8)+(_page.abs_pos[6]<<16)+ (_page.abs_pos[7]<<24); *frame=(*frame)<<32; *frame=_page.abs_pos[0]+(_page.abs_pos[1]<<8)+(_page.abs_pos[2]<<16)+ (_page.abs_pos[3]<<24); if(*frame>48000*3 && seq==3) { printf("Fixing stupid abs_pos\n"); *frame=0; } #endif *flags=_page.header_type; *paySize=total; _payload=total; return 1; } // skipt it fseek(_fd,total,SEEK_CUR); failed++; if(failed>10) { _payload=0; return 0; // we allow 10 fails } } return 0; }
AVDMGenericVideoStream *getFirstCurrentVideoFilter( void) { ADM_assert(nb_active_filter); return videofilters[ 0].filter; }
///_____________________________________________________ /// retrieve gtkwidget through their name /// the aim is to avoid having to modify the glade generated file ///_____________________________________________________ uint8_t bindGUI( void ) { #define ADM_LOOKUP(a,b) a= lookup_widget (guiRootWindow,#b);if(!a) return 0; ADM_LOOKUP(guiDrawingArea,guiDrawing); ADM_LOOKUP(guiSlider,sliderNavigate); sliderAdjustment=gtk_range_get_adjustment (GTK_RANGE(guiSlider)); ADM_LOOKUP(guiMarkA,labelMarkA); ADM_LOOKUP(guiMarkB,labelMarkB); ADM_LOOKUP(guiCurFrame,boxCurFrame); ADM_LOOKUP(guiTotalFrame,labelTotalFrame); ADM_LOOKUP(guiCurTime,boxCurTime); ADM_LOOKUP(guiTotalTime,labelTotalTime); #if 0 ADM_LOOKUP(guiPreviewToggle,toggletoolbuttonPreview); ADM_LOOKUP(guiOutputToggle,toggletoolbuttonOutput); ADM_LOOKUP(guiAudioToggle,togglebuttonAudio); ADM_LOOKUP(guiVideoToggle,togglebuttonVideo); #endif #undef ADM_LOOKUP // bind menu #define CALLBACK(x,y) gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,#x)), "activate", \ GTK_SIGNAL_FUNC(guiCallback), (void *) y) #include "GUI_menumap.h" #undef CALLBACK /// /bind menu // destroy gtk_object_set_data_full(GTK_OBJECT(guiRootWindow), "guiRootWindow", guiRootWindow, (GtkDestroyNotify) destroyCallback); // now add callbacks gtk_widget_add_events(guiRootWindow, GDK_BUTTON_PRESS_MASK); gtk_signal_connect(GTK_OBJECT(guiRootWindow), "button_press_event", GTK_SIGNAL_FUNC(UI_returnFocus), NULL); gtk_signal_connect(GTK_OBJECT(guiSlider), "button_press_event", GTK_SIGNAL_FUNC(UI_SliderPressed), NULL); gtk_signal_connect(GTK_OBJECT(guiSlider), "button_release_event", GTK_SIGNAL_FUNC(UI_SliderReleased), NULL); // Current Frame gtk_signal_connect(GTK_OBJECT(guiCurFrame), "focus_in_event", GTK_SIGNAL_FUNC(UI_grabFocus), (void *) NULL); gtk_signal_connect(GTK_OBJECT(guiCurFrame), "focus_out_event", GTK_SIGNAL_FUNC(UI_loseFocus), (void *) NULL); gtk_signal_connect(GTK_OBJECT(guiCurFrame), "activate", GTK_SIGNAL_FUNC(UI_focusAfterActivate), (void *) ACT_JumpToFrame); // Volume gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,"hscalVolume")), "value_changed", GTK_SIGNAL_FUNC(volumeChange), (void *) NULL); // Jog gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,"jogg")), "value_changed", GTK_SIGNAL_FUNC(jogChange), (void *) NULL); // Time Shift gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,"spinbuttonTimeShift")), "focus_in_event", GTK_SIGNAL_FUNC(UI_grabFocus), (void *) NULL); gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,"spinbuttonTimeShift")), "focus_out_event", GTK_SIGNAL_FUNC(UI_loseFocus), (void *) NULL); gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,"spinbuttonTimeShift")), "activate", GTK_SIGNAL_FUNC(UI_focusAfterActivate), (void *) ACT_TimeShift); #define ADD_SIGNAL(a,b,c) gtk_signal_connect(GTK_OBJECT(a), b, GTK_SIGNAL_FUNC(guiCallback), (void *) c); ADD_SIGNAL(guiSlider,"value_changed",ACT_Scale); ADD_SIGNAL(lookup_widget(guiRootWindow,"spinbuttonTimeShift"),"value_changed",ACT_TimeShift); // Callbacks for buttons uint32_t nb=sizeof(buttonCallback)/sizeof(buttonCallBack_S); GtkWidget *bt; for(uint32_t i=0;i<nb;i++) { bt= lookup_widget (guiRootWindow,buttonCallback[i].name); if(!bt) { printf("Binding failed for %s\n",buttonCallback[i].name); ADM_assert(0); } ADD_SIGNAL(bt,buttonCallback[i].signal,buttonCallback[i].action); GTK_WIDGET_UNSET_FLAGS (bt, GTK_CAN_FOCUS); } GTK_WIDGET_SET_FLAGS (lookup_widget(guiRootWindow,"boxCurFrame"), GTK_CAN_FOCUS); // set some tuning gtk_widget_set_usize(guiDrawingArea, 512, 288); // hscale GTK_WIDGET_UNSET_FLAGS (guiSlider, GTK_CAN_FOCUS); gtk_widget_show(guiSlider); // And, the size now scales to the width of the window. gtk_widget_set_usize(guiSlider, 0, 0); // Plus, two-decimal precision. gtk_scale_set_digits(GTK_SCALE(guiSlider), 2); // And continuous updates! gtk_range_set_update_policy (GTK_RANGE (guiSlider), GTK_UPDATE_CONTINUOUS); gtk_range_set_range(GTK_RANGE(guiSlider),0,100.00); // keyboard events gtk_signal_connect(GTK_OBJECT(guiDrawingArea), "expose_event", GTK_SIGNAL_FUNC(on_drawingarea1_expose_event), NULL); // Finally add video codec... uint32_t nbVid; const char *name; GtkComboBox *combo_box; nbVid=encoderGetNbEncoder(); combo_box=GTK_COMBO_BOX(lookup_widget(guiRootWindow,VIDEO_WIDGET)); gtk_combo_box_remove_text(combo_box,0); printf("Found %d video encoder\n",nbVid); for(uint32_t i=0;i<nbVid;i++) { name=encoderGetIndexedName(i); gtk_combo_box_append_text (combo_box,QT_TR_NOOP(name)); } gtk_combo_box_set_active(combo_box,0); on_video_change(); // And A codec // Finally add video codec... uint32_t nbAud; nbAud=audioFilterGetNbEncoder(); combo_box=GTK_COMBO_BOX(lookup_widget(guiRootWindow,AUDIO_WIDGET)); gtk_combo_box_remove_text(combo_box,0); printf("Found %d audio encoder\n",nbAud); for(uint32_t i=0;i<nbAud;i++) { name=audioFilterGetIndexedName(i); gtk_combo_box_append_text (combo_box,QT_TR_NOOP(name)); } gtk_combo_box_set_active(combo_box,0); on_audio_change(); /* Fill in output format window */ uint32_t nbFormat; nbFormat=sizeof(ADM_allOutputFormat)/sizeof(ADM_FORMAT_DESC); combo_box=GTK_COMBO_BOX(lookup_widget(guiRootWindow,FORMAT_WIDGET)); gtk_combo_box_remove_text(combo_box,0); printf("Found %d Format \n",nbFormat); for(uint32_t i=0;i<nbFormat;i++) { gtk_combo_box_append_text (combo_box,QT_TR_NOOP(ADM_allOutputFormat[i].text)); } gtk_combo_box_set_active(combo_box,0); /* File in preview mode combobox */ const char *previewText[]= { QT_TR_NOOP("Input"), QT_TR_NOOP("Output"), QT_TR_NOOP("Side"), QT_TR_NOOP("Top"), QT_TR_NOOP("Separate") }; combo_box=GTK_COMBO_BOX(lookup_widget(guiRootWindow,PREVIEW_WIDGET)); gtk_combo_box_remove_text(combo_box,0); for(uint32_t i=0;i<sizeof(previewText)/sizeof(char*);i++) { name=previewText[i]; gtk_combo_box_append_text (combo_box,(name)); } gtk_combo_box_set_active(combo_box,0); // Format gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(guiRootWindow,FORMAT_WIDGET)),0); // gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,VIDEO_WIDGET)), "changed", GTK_SIGNAL_FUNC(on_video_change), NULL); gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,AUDIO_WIDGET)), "changed", GTK_SIGNAL_FUNC(on_audio_change), NULL); gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,PREVIEW_WIDGET)), "changed", GTK_SIGNAL_FUNC(on_preview_change), NULL); gtk_signal_connect(GTK_OBJECT(lookup_widget(guiRootWindow,FORMAT_WIDGET)), "changed", GTK_SIGNAL_FUNC(on_format_change), NULL); // Add initial recent files UI_updateRecentMenu( ); // //CYB 2005.02.22: DND (START) // Set up avidemux as an available drag'n'drop target. gtk_drag_dest_set(guiRootWindow, GTK_DEST_DEFAULT_ALL, target_table,sizeof(target_table)/sizeof(GtkTargetEntry), (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_DEFAULT)); g_signal_connect(GTK_OBJECT(guiRootWindow), "drag_data_received", GTK_SIGNAL_FUNC(DNDDataReceived),NULL); //CYB 2005.02.22: DND (END) // Allow shrink //GTK_WINDOW ( guiRootWindow ) ->allow_shrink = FALSE; //GTK_WINDOW ( guiDrawingArea ) ->allow_shrink = FALSE; // By default enable arrow keys UI_arrow_enabled(); // Add custom menu GUI_initCustom(); return 1; }