Esempio n. 1
0
void dump_frame(BIFSVID b2v, char *conv_buf, char *out_path, u32 dump_type, avi_t *avi_out, u32 frameNum)
{
	u32 k;
	M4VideoSurface fb;

	/*lock it*/
	SR_GetScreenBuffer(b2v.sr, &fb);
	/*export frame*/
	switch (dump_type) {
	case 0:
		/*reverse frame*/
		for (k=0; k<fb.height; k++) {
			memcpy(conv_buf + k*fb.width*3, fb.video_buffer + (fb.height-k-1) * fb.pitch, sizeof(char) * fb.width  * 3);
		}
		if (AVI_write_frame(avi_out, conv_buf, fb.height*fb.width*3, 1) <0)
			printf("Error writing frame\n");
		break;
	case 2:
		write_raw(&fb, out_path, frameNum);
		break;
	case 1:
		write_bmp(&fb, out_path, frameNum);
		break;
	}
	/*unlock it*/
	SR_ReleaseScreenBuffer(b2v.sr, &fb);
}
Esempio n. 2
0
static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *pixels,
                      int rectx, int recty, ReportList *UNUSED(reports))
{
    unsigned int *rt1, *rt2, *rectot;
    int x, y;
    char *cp, rt;

    if (avi == NULL)
        return 0;

    /* note that libavi free's the buffer... stupid interface - zr */
    rectot = MEM_mallocN(rectx * recty * sizeof(int), "rectot");
    rt1 = rectot;
    rt2 = (unsigned int *)pixels + (recty - 1) * rectx;
    /* flip y and convert to abgr */
    for (y = 0; y < recty; y++, rt1 += rectx, rt2 -= rectx) {
        memcpy(rt1, rt2, rectx * sizeof(int));

        cp = (char *)rt1;
        for (x = rectx; x > 0; x--) {
            rt = cp[0];
            cp[0] = cp[3];
            cp[3] = rt;
            rt = cp[1];
            cp[1] = cp[2];
            cp[2] = rt;
            cp += 4;
        }
    }

    AVI_write_frame(avi, (frame - start_frame), AVI_FORMAT_RGB32, rectot, rectx * recty * 4);
//	printf ("added frame %3d (frame %3d in avi): ", frame, frame-start_frame);

    return 1;
}
Esempio n. 3
0
/* /////////////////////////////////////////////////////////////////////////////
 * Write AVI file
 */
int TTAVIWriter::writeAVI(int startIndex, int endIndex, const QFileInfo& aviFInfo)
{
  QTime       searchTime;
  TFrameInfo* frameInfo;
  int         frameCount = endIndex - startIndex + 1;

  log->debugMsg(__FILE__, __LINE__, "---------------------------------------------");
  log->debugMsg(__FILE__, __LINE__, QString("write AVI start %1 / end %2 / count %3").
      arg(startIndex).arg(endIndex).arg(frameCount));

  avi_file = AVI_open_output_file(aviFInfo.absoluteFilePath().toLatin1().data());

  //TODO: go back to previous sequence to ensure correct encoding of
  //      open GOP's
  current_frame = decoder->moveToFrameIndex(startIndex);

  // decode the current slice
  //frameInfo = decoder->decodeMPEG2Frame( formatYV12 );
  frameInfo = decoder->getFrameInfo();

  log->debugMsg(__FILE__, __LINE__, QString("AVI %1 width %2 x height %3").
      arg(aviFInfo.absoluteFilePath()).
      arg(frameInfo->width).
      arg(frameInfo->height));

  AVI_set_video(avi_file, frameInfo->width, frameInfo->height, mFrameRate, (char*)"YV12");

  ref_data = new quint8[frameInfo->size+2*frameInfo->chroma_size];

  //for (int i = start_frame_pos; i <= end_frame_pos; i++)
  for (int i = 1; i <= frameCount; i++)
  {
    // get decoded mpeg-frame data
    decoder->getCurrentFrameData(ref_data);

    log->debugMsg(__FILE__, __LINE__, QString("write frame %1 with frame-type %2").
        arg(startIndex+i-1).
        arg(frameInfo->type));

    // write the mpeg-frame data to AVI file
    AVI_write_frame(avi_file, (char*)ref_data, frameInfo->size+2*frameInfo->chroma_size, 2);

    // decode the next mpeg-frame
    decoder->moveToFrameIndex(startIndex+i);
    frameInfo = decoder->getFrameInfo();
    //frameInfo = decoder->decodeMPEG2Frame( formatYV12 );

  }
  log->debugMsg(__FILE__, __LINE__, "---------------------------------------------");

  delete [] ref_data;

  return frameCount;
}
Esempio n. 4
0
static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
                                   short *stop, short *do_update, float *progress)
{
	int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
	int i, pos;
	struct anim *anim = context->anim;

	for (pos = 0; pos < cnt; pos++) {
		struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
		struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf);
		float next_progress = (float) pos / (float) cnt;

		if (*progress != next_progress) {
			*progress = next_progress;
			*do_update = TRUE;
		}
		
		if (*stop) {
			break;
		}

		IMB_flipy(tmp_ibuf);

		for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
			if (context->proxy_sizes_in_use & proxy_sizes[i]) {
				int x = anim->x * proxy_fac[i];
				int y = anim->y * proxy_fac[i];

				struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf);

				IMB_scalefastImBuf(s_ibuf, x, y);

				IMB_convert_rgba_to_abgr(s_ibuf);
	
				AVI_write_frame(context->proxy_ctx[i], pos,
				                AVI_FORMAT_RGB32,
				                s_ibuf->rect, x * y * 4);

				/* note that libavi free's the buffer... */
				s_ibuf->rect = NULL;

				IMB_freeImBuf(s_ibuf);
			}
		}

		IMB_freeImBuf(tmp_ibuf);
		IMB_freeImBuf(ibuf);
	}
}
Esempio n. 5
0
/* ///////////////////////////////////////////////////////////////////////////// 
 * Write AVI file
 */
int TTAVIWriter::writeAVI(int start_frame_pos, int end_frame_pos, const QFileInfo& avi_finfo)
{
  QTime       searchTime;
  TFrameInfo* frameInfo;
  int         frame_count = end_frame_pos - start_frame_pos;

  //qDebug( "%s------------------------------------------------",c_name );
  //qDebug( "%swrite AVI: start: %ld | end: %ld | count: %d",c_name,start_frame_pos,end_frame_pos,frame_count );
  //qDebug( "%s------------------------------------------------",c_name );

  avi_file = AVI_open_output_file( avi_finfo.absoluteFilePath().toLatin1().data() );


  //TODO: go back to previous sequence to ensure correct encoding of
  //      open GOP's
  // move decode position to "ref_frame_pos"
  current_frame = decoder->moveToFrameIndex( start_frame_pos );
  
  // decode the current slice
  frameInfo = decoder->decodeMPEG2Frame( formatYV12 );

  //qDebug( "%sAVI frame info: width: %d x height: %d",c_name,frameInfo->width,frameInfo->height );

  //TODO: avoid setting hard coded frame rate!
  AVI_set_video(avi_file, frameInfo->width, frameInfo->height, 25.0, (char*)"YV12");
  
  ref_data = new quint8[frameInfo->size+2*frameInfo->chroma_size];
  

  for (int i = start_frame_pos; i <= end_frame_pos; i++)
  {
    // get decoded mpeg-frame data
    decoder->getCurrentFrameData( ref_data );

    // write the mpeg-frame data to AVI file
    AVI_write_frame(avi_file, (char*)ref_data, frameInfo->size+2*frameInfo->chroma_size, 2);

    // decode the next mpeg-frame
    frameInfo = decoder->decodeMPEG2Frame( formatYV12 );    
  }
  //qDebug( "%s------------------------------------------------",c_name );
  
  delete [] ref_data;

  return frame_count;  
}
Esempio n. 6
0
int main_loop(void *data)
{
	int ret=0;
	int i,j,k,l,m,n,o;
	unsigned int YUVMacroPix;
	unsigned char *pix8 = (unsigned char *)&YUVMacroPix;
	Pix *pix2;
	char *pix;
	if ((pix2= malloc(sizeof(Pix)))==NULL) {
		printf("couldn't allocate memory for: pix2\n");
		ret=1;
		return(ret);
	}
	//fprintf(stderr,"Thread started...\n");
	/*
		ImageSurf=SDL_CreateRGBSurface(SDL_SWSURFACE, overlay->w,
		   overlay->h, 24, 0x00ff0000,0x0000ff00,0x000000ff,0);
	*/
	while (videoIn->signalquit) {
	 currtime = SDL_GetTicks();
	  if (currtime - lasttime > 0) {
		frmrate = 1000/(currtime - lasttime);
	 }
	 lasttime = currtime;
	
	// sprintf(capt,"Frame Rate: %d",frmrate);
	// SDL_WM_SetCaption(capt, NULL);
	
	 if (uvcGrab(videoIn) < 0) {
	    printf("Error grabbing=> Frame Rate is %d\n",frmrate);
	    videoIn->signalquit=0;
		ret = 2;
	 }
	
	 SDL_LockYUVOverlay(overlay);
	 memcpy(p, videoIn->framebuffer,
	       videoIn->width * (videoIn->height) * 2);
	 SDL_UnlockYUVOverlay(overlay);
	 SDL_DisplayYUVOverlay(overlay, &drect);
	
	 /*capture Image*/
	 if (videoIn->capImage){

		if((pim= malloc((pscreen->w)*(pscreen->h)*3))==NULL){/*24 bits -> 3bytes 32 bits ->4 bytes*/
		 	printf("Couldn't allocate memory for: pim\n");
	     	videoIn->signalquit=0;
			ret = 3;
		
		}
		
		//char *ppmheader = "P6\n# Generated by guvcview\n320 240\n255\n";
		//FILE * out = fopen("Yimage.ppm", "wb"); //saving as ppm
		//fprintf(out, ppmheader);
		
		k=overlay->h;
		//printf("overlay->h is %i\n",overlay->h);
		//printf("and pitches[0] is %i\n",overlay->pitches[0]);
	
			
		for(j=0;j<(overlay->h);j++){

			l=j*overlay->pitches[0];/*must add lines already writen=*/
						/*pitches is the overlay number */
						/*off bytes in a line (2*width) */
						
			m=(k*3*overlay->pitches[0])>>1;/*must add lines already writen=   */
						      /*for this case (rgb) every pixel   */
						      /*as 3 bytes (3*width=3*pitches/2)  */
						      /* >>1 = (/2) divide by 2 (?faster?)*/
			for (i=0;i<((overlay->pitches[0])>>2);i++){ /*>>2 = (/4)*/
				/*iterate every 4 bytes (32 bits)*/
				/*Y-U-V-Y1 =>2 pixel (4 bytes)   */
				
				n=i<<2;/*<<2 = (*4) multiply by 4 (?faster?)*/					
				pix8[0] = p[n+l];
				pix8[1] = p[n+1+l];
				pix8[2] = p[n+2+l];
				pix8[3] = p[n+3+l];
			
				/*get RGB data*/
				pix2=yuv2rgb(YUVMacroPix,0,pix2);
			
				/*In BitMaps lines are upside down and*/
				/*pixel format is bgr                 */
				
				o=i*6;				
			
				/*first pixel*/
				pim[o+m]=pix2->b;
				pim[o+1+m]=pix2->g;
				pim[o+2+m]=pix2->r;
				/*second pixel*/
				pim[o+3+m]=pix2->b1;
				pim[o+4+m]=pix2->g1;
				pim[o+5+m]=pix2->r1;	
		  	}
			k--;
	    	}
       /* SDL_LockSurface(ImageSurf);	
		memcpy(pix, pim,(pscreen->w)*(pscreen->h)*3); //24 bits -> 3bytes 32 bits ->4 bytes
		SDL_UnlockSurface(ImageSurf);*/
	

	    if(SaveBPM(videoIn->ImageFName, width, height, 24, pim)) {
	      fprintf (stderr,"Error: Couldn't capture Image to %s \n",
			     videoIn->ImageFName);
	    } 
	    else {	  
          printf ("Capture Image to %s \n",videoIn->ImageFName);
        }
		free(pim);
	    videoIn->capImage=FALSE;	
	  }
	  
	  /*capture AVI */
	  if (videoIn->capAVI && videoIn->signalquit){
	   long framesize;		
	   switch (AVIFormat) {
		case 1:
	  	   framesize=(pscreen->w)*(pscreen->h)*2; /*YUY2 -> 2 bytes per pixel */
	           if (AVI_write_frame (AviOut,
			       p, framesize) < 0)
	                printf ("write error on avi out \n");
		   break;
		case 2:
		    framesize=(pscreen->w)*(pscreen->h)*3; /*DIB 24/32 -> 3/4 bytes per pixel*/ 
		    if((pim= malloc(framesize))==NULL){
				printf("Couldn't allocate memory for: pim\n");
	     		videoIn->signalquit=0;
				ret = 4;
			}
		    k=overlay->h;
					
		for(j=0;j<(overlay->h);j++){

			l=j*overlay->pitches[0];/*must add lines already writen=*/
						/*pitches is the overlay number */
						/*off bytes in a line (2*width) */
						
			m=(k*3*overlay->pitches[0])>>1;/*must add lines already writen=   */
						      /*for this case (rgb) every pixel   */
						      /*as 3 bytes (3*width=3*pitches/2)  */
						      /* >>1 = (/2) divide by 2 (?faster?)*/
			for (i=0;i<((overlay->pitches[0])>>2);i++){ /*>>2 = (/4)*/
				/*iterate every 4 bytes (32 bits)*/
				/*Y-U-V-Y1 =>2 pixel (4 bytes)   */
				
				n=i<<2;/*<<2 = (*4) multiply by 4 (?faster?)*/					
				pix8[0] = p[n+l];
				pix8[1] = p[n+1+l];
				pix8[2] = p[n+2+l];
				pix8[3] = p[n+3+l];
			
				/*get RGB data*/
				pix2=yuv2rgb(YUVMacroPix,0,pix2);
			
				/*In BitMaps lines are upside down and*/
				/*pixel format is bgr                 */
				
				o=i*6;				
			
				/*first pixel*/
				pim[o+m]=pix2->b;
				pim[o+1+m]=pix2->g;
				pim[o+2+m]=pix2->r;
				/*second pixel*/
				pim[o+3+m]=pix2->b1;
				pim[o+4+m]=pix2->g1;
				pim[o+5+m]=pix2->r1;	
		  	}
			k--;
	    	}
		     
		     if (AVI_write_frame (AviOut,
			       pim, framesize) < 0)
	                printf ("write error on avi out \n");
		     free(pim);
		     break;


		} 
	   framecount++;	   
		  
	  } 
	  SDL_Delay(SDL_WAIT_TIME);
	
  }
Esempio n. 7
0
static int merger(avi_t *out, char *file)
{
    avi_t *in;
    long frames, n, bytes;
    int key, j, aud_tracks;
    static int init = 0;
    static int vid_chunks = 0;

    double fps;
    static double vid_ms;
    static double aud_ms[AVI_MAX_TRACKS];
    int have_printed=0;
    int do_drop_video=0;

    if (!init) {
	for (j=0; j<AVI_MAX_TRACKS; j++)
	    aud_ms[j] = 0.0;
	vid_ms = 0;
	vid_chunks = 0;
	init = 1;
    }

    if(indexfile)  {
	if (NULL == (in = AVI_open_input_indexfile(file, 0, indexfile))) {
	    AVI_print_error("AVI open with indexfile");
	    return(-1);
	}
    }
    else if(NULL == (in = AVI_open_input_file(file,1))) {
	AVI_print_error("AVI open");
	return(-1);
    }

    AVI_seek_start(in);
    fps    =  AVI_frame_rate(in);
    frames =  AVI_video_frames(in);
    aud_tracks = AVI_audio_tracks(in);

    for (n=0; n<frames; ++n) {

      ++vid_chunks;
      vid_ms = vid_chunks*1000.0/fps;

      // audio
      for(j=0; j<aud_tracks; ++j) {

	  int ret;
	  double old_ms = aud_ms[j];

	  AVI_set_audio_track(in, j);
	  AVI_set_audio_track(out, j);

	  ret = sync_audio_video_avi2avi (vid_ms, &aud_ms[j], in, out);
	  if (ret<0) {
	      if (ret==-2) {
		  if (aud_ms[j] == old_ms) {
		      do_drop_video = 1;
		      if (!have_printed) {
			  fprintf(stderr, "\nNo audiodata left for track %d->%d (%.2f=%.2f) %s ..\n",
			      AVI_get_audio_track(in), AVI_get_audio_track(out),
			      old_ms, aud_ms[j], (do_drop_video && drop_video)?"breaking (-c)":"continuing");
			  have_printed++;
		      }
		  }
	      } else {
		  fprintf(stderr, "\nAn error happend at frame %ld track %d\n", n, j);
	      }
	  }

      }

      if (do_drop_video && drop_video) {
	  fprintf(stderr, "\n[avimerge] Dropping %ld frames\n", frames-n-1);
	  goto out;
      }

      // video
      bytes = AVI_read_frame(in, data, &key);

      if(bytes < 0) {
	AVI_print_error("AVI read video frame");
	return(-1);
      }

      if(AVI_write_frame(out, data, bytes, key)<0) {
	AVI_print_error("AVI write video frame");
	return(-1);
      }

      // progress
      fprintf(stderr, "[%s] (%06ld-%06ld) (%.2f <-> %.2f)\r", file, sum_frames, sum_frames + n, vid_ms, aud_ms[0]);
    }
out:
    fprintf(stderr, "\n");

    AVI_close(in);

    sum_frames += n;

    return(0);
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
  avi_t *avifile, *avifile1, *avifile2;

  char *outfile=NULL, *infile=NULL, *audfile=NULL;

  long rate, mp3rate;

  int j, ch, cc=0, track_num=0, out_track_num=-1;
  int width, height, format=0, format_add, chan, bits, aud_error=0;

  double fps;

  char *codec;

  long offset, frames, n, bytes, aud_offset=0;

  int key;

  int aud_tracks;

  // for mp3 audio
  FILE *f=NULL;
  int len, headlen, chan_i, rate_i, mp3rate_i;
  unsigned long vid_chunks=0;
  char head[8];
  off_t pos;
  double aud_ms = 0.0, vid_ms = 0.0;
  double aud_ms_w[AVI_MAX_TRACKS];

  ac_init(AC_ALL);

  if(argc==1) usage(EXIT_FAILURE);

  while ((ch = getopt(argc, argv, "A:a:b:ci:o:p:f:x:?hv")) != -1) {

    switch (ch) {

    case 'i':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      infile = optarg;

      break;

    case 'A':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      out_track_num = atoi(optarg);

      if(out_track_num<-1) usage(EXIT_FAILURE);

      break;

    case 'a':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      track_num = atoi(optarg);

      if(track_num<0) usage(EXIT_FAILURE);

      break;

    case 'b':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      is_vbr = atoi(optarg);

      if(is_vbr<0) usage(EXIT_FAILURE);

      break;

    case 'c':

      drop_video = 1;

      break;

    case 'o':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      outfile = optarg;

      break;

    case 'p':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      audfile = optarg;

      break;

    case 'f':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      comfile = optarg;

      break;


    case 'x':

      if(optarg[0]=='-') usage(EXIT_FAILURE);
      indexfile = optarg;

      break;

    case 'v':
      version();
      exit(EXIT_SUCCESS);
    case 'h':
      usage(EXIT_SUCCESS);
    default:
      usage(EXIT_FAILURE);
    }
  }

  if(outfile == NULL || infile == NULL) usage(EXIT_FAILURE);

  printf("scanning file %s for video/audio parameter\n", infile);

  // open first file for video/audio info read only
  if(indexfile) {
      if (NULL == (avifile1 = AVI_open_input_indexfile(infile,0,indexfile))) {
	  AVI_print_error("AVI open with index file");
      }
  }
  else if(NULL == (avifile1 = AVI_open_input_file(infile,1))) {
      AVI_print_error("AVI open");
      exit(1);
  }

  AVI_info(avifile1);

  // safety checks

  if(strcmp(infile, outfile)==0) {
    printf("error: output filename conflicts with input filename\n");
    exit(1);
  }

  ch = optind;

  while (ch < argc) {

    if(tc_file_check(argv[ch]) != 0) {
      printf("error: file not found\n");
      exit(1);
    }

    if(strcmp(argv[ch++], outfile)==0) {
      printf("error: output filename conflicts with input filename\n");
      exit(1);
    }
  }

  // open output file
  if(NULL == (avifile = AVI_open_output_file(outfile))) {
    AVI_print_error("AVI open");
    exit(1);
  }


  // read video info;

  width  =  AVI_video_width(avifile1);
  height =  AVI_video_height(avifile1);

  fps    =  AVI_frame_rate(avifile1);
  codec  =  AVI_video_compressor(avifile1);

  //set video in outputfile
  AVI_set_video(avifile, width, height, fps, codec);

  if (comfile!=NULL)
    AVI_set_comment_fd(avifile, open(comfile, O_RDONLY));

  //multi audio tracks?
  aud_tracks = AVI_audio_tracks(avifile1);
  if (out_track_num < 0) out_track_num = aud_tracks;

  for(j=0; j<aud_tracks; ++j) {

      if (out_track_num == j) continue;
      AVI_set_audio_track(avifile1, j);

      rate   =  AVI_audio_rate(avifile1);
      chan   =  AVI_audio_channels(avifile1);
      bits   =  AVI_audio_bits(avifile1);

      format =  AVI_audio_format(avifile1);
      mp3rate=  AVI_audio_mp3rate(avifile1);
      //printf("TRACK %d MP3RATE %ld VBR %ld\n", j, mp3rate, AVI_get_audio_vbr(avifile1));

      //set next track of output file
      AVI_set_audio_track(avifile, j);
      AVI_set_audio(avifile, chan, rate, bits, format, mp3rate);
      AVI_set_audio_vbr(avifile, AVI_get_audio_vbr(avifile1));
  }

  if(audfile!=NULL) goto audio_merge;

  // close reopen in merger function
  AVI_close(avifile1);

  //-------------------------------------------------------------

  printf("merging multiple AVI-files (concatenating) ...\n");

  // extract and write to new files

  printf ("file %02d %s\n", ++cc, infile);
  merger(avifile, infile);

  while (optind < argc) {

    printf ("file %02d %s\n", ++cc, argv[optind]);
    merger(avifile, argv[optind++]);
  }

  // close new AVI file

  AVI_close(avifile);

  printf("... done merging %d file(s) in %s\n", cc, outfile);

  // reopen file for video/audio info
  if(NULL == (avifile = AVI_open_input_file(outfile,1))) {
    AVI_print_error("AVI open");
    exit(1);
  }
  AVI_info(avifile);

  return(0);

  //-------------------------------------------------------------


// *************************************************
// Merge the audio track of an additional AVI file
// *************************************************

 audio_merge:

  printf("merging audio %s track %d (multiplexing) into %d ...\n", audfile, track_num, out_track_num);

  // open audio file read only
  if(NULL == (avifile2 = AVI_open_input_file(audfile,1))) {
    int f=open(audfile, O_RDONLY), ret=0;
    char head[1024], *c;
    c = head;
    if (f>0 && (1024 == read(f, head, 1024)) ) {
      while ((c-head<1024-8) && (ret = tc_probe_audio_header(c, 8))<=0 ) {
	c++;
      }
      close(f);

      if (ret > 0) {
	aud_offset = c-head;
	//printf("found atrack 0x%x off=%ld\n", ret, aud_offset);
	goto merge_mp3;
      }
    }

    AVI_print_error("AVI open");
    exit(1);
  }

  AVI_info(avifile2);

  //switch to requested track

  if(AVI_set_audio_track(avifile2, track_num)<0) {
    fprintf(stderr, "invalid audio track\n");
  }

  rate   =  AVI_audio_rate(avifile2);
  chan   =  AVI_audio_channels(avifile2);
  bits   =  AVI_audio_bits(avifile2);

  format =  AVI_audio_format(avifile2);
  mp3rate=  AVI_audio_mp3rate(avifile2);

  //set next track
  AVI_set_audio_track(avifile, out_track_num);
  AVI_set_audio(avifile, chan, rate, bits, format, mp3rate);
  AVI_set_audio_vbr(avifile, AVI_get_audio_vbr(avifile2));

  AVI_seek_start(avifile1);
  frames =  AVI_video_frames(avifile1);
  offset = 0;

  printf ("file %02d %s\n", ++cc, infile);

  for (n=0; n<AVI_MAX_TRACKS; n++)
    aud_ms_w[n] = 0.0;
  vid_chunks=0;

  for (n=0; n<frames; ++n) {

    // video
    bytes = AVI_read_frame(avifile1, data, &key);

    if(bytes < 0) {
      AVI_print_error("AVI read video frame");
      return(-1);
    }

    if(AVI_write_frame(avifile, data, bytes, key)<0) {
      AVI_print_error("AVI write video frame");
      return(-1);
    }
    ++vid_chunks;
    vid_ms = vid_chunks*1000.0/fps;

    for(j=0; j<aud_tracks; ++j) {

      if (j == out_track_num) continue;
      AVI_set_audio_track(avifile1, j);
      AVI_set_audio_track(avifile, j);
      chan   = AVI_audio_channels(avifile1);

      // audio
      chan = AVI_audio_channels(avifile1);
      if(chan) {
	  sync_audio_video_avi2avi(vid_ms, &aud_ms_w[j], avifile1, avifile);
      }
    }


    // merge additional track

    // audio
    chan = AVI_audio_channels(avifile2);
    AVI_set_audio_track(avifile, out_track_num);

    if(chan) {
	sync_audio_video_avi2avi(vid_ms, &aud_ms, avifile2, avifile);
    }

    // progress
    fprintf(stderr, "[%s] (%06ld-%06ld)\r", outfile, offset, offset + n);

  }

  fprintf(stderr,"\n");

  offset = frames;

  //more files to merge?

  AVI_close(avifile1);

  while (optind < argc) {

    printf ("file %02d %s\n", ++cc, argv[optind]);

    if(NULL == ( avifile1 = AVI_open_input_file(argv[optind++],1))) {
      AVI_print_error("AVI open");
      goto finish;
    }

    AVI_seek_start(avifile1);
    frames =  AVI_video_frames(avifile1);

    for (n=0; n<frames; ++n) {

      // video
      bytes = AVI_read_frame(avifile1, data, &key);

      if(bytes < 0) {
	AVI_print_error("AVI read video frame");
	return(-1);
      }

      if(AVI_write_frame(avifile, data, bytes, key)<0) {
	AVI_print_error("AVI write video frame");
	return(-1);
      }

      ++vid_chunks;
      vid_ms = vid_chunks*1000.0/fps;

      // audio
      for(j=0; j<aud_tracks; ++j) {

	if (j == out_track_num) continue;
	AVI_set_audio_track(avifile1, j);
	AVI_set_audio_track(avifile, j);

	chan   = AVI_audio_channels(avifile1);

	if(chan) {
	  sync_audio_video_avi2avi(vid_ms, &aud_ms_w[j], avifile1, avifile);
	}
      }

      // merge additional track

      chan   = AVI_audio_channels(avifile2);
      AVI_set_audio_track(avifile, out_track_num);

      if(chan) {
	  sync_audio_video_avi2avi(vid_ms, &aud_ms, avifile2, avifile);
      } // chan

      // progress
      fprintf(stderr, "[%s] (%06ld-%06ld)\r", outfile, offset, offset + n);
    }

    fprintf(stderr, "\n");

    offset += frames;
    AVI_close(avifile1);
  }

 finish:

  // close new AVI file

  printf("... done multiplexing in %s\n", outfile);

  AVI_info(avifile);
  AVI_close(avifile);

  return(0);


// *************************************************
// Merge a raw audio file which is either MP3 or AC3
// *************************************************

merge_mp3:

  f = fopen(audfile,"rb");
  if (!f) { perror ("fopen"); exit(1); }

  fseek(f, aud_offset, SEEK_SET);
  len = fread(head, 1, 8, f);
  format_add  = tc_probe_audio_header(head, len);
  headlen = tc_get_audio_header(head, len, format_add, &chan_i, &rate_i, &mp3rate_i);
  fprintf(stderr, "... this looks like a %s track ...\n", (format_add==0x55)?"MP3":"AC3");

  fseek(f, aud_offset, SEEK_SET);

  //set next track
  AVI_set_audio_track(avifile, out_track_num);
  AVI_set_audio(avifile, chan_i, rate_i, 16, format_add, mp3rate_i);
  AVI_set_audio_vbr(avifile, is_vbr);

  AVI_seek_start(avifile1);
  frames =  AVI_video_frames(avifile1);
  offset = 0;

  for (n=0; n<AVI_MAX_TRACKS; ++n)
      aud_ms_w[n] = 0.0;

  for (n=0; n<frames; ++n) {

    // video
    bytes = AVI_read_frame(avifile1, data, &key);

    if(bytes < 0) {
      AVI_print_error("AVI read video frame");
      return(-1);
    }

    if(AVI_write_frame(avifile, data, bytes, key)<0) {
      AVI_print_error("AVI write video frame");
      return(-1);
    }

    vid_chunks++;
    vid_ms = vid_chunks*1000.0/fps;

    for(j=0; j<aud_tracks; ++j) {

      if (j == out_track_num) continue;
      AVI_set_audio_track(avifile1, j);
      AVI_set_audio_track(avifile, j);
      chan   = AVI_audio_channels(avifile1);

      if(chan) {
	sync_audio_video_avi2avi(vid_ms, &aud_ms_w[j], avifile1, avifile);
      }
    }


    // merge additional track

    if(headlen>4 && !aud_error) {
      while (aud_ms < vid_ms) {
	//printf("reading Audio Chunk ch(%ld) vms(%lf) ams(%lf)\n", vid_chunks, vid_ms, aud_ms);
	pos = ftell(f);

	len = fread (head, 1, 8, f);
	if (len<=0) { //eof
	  fprintf(stderr, "EOF in %s; continuing ..\n", audfile);
	  aud_error=1;
	  break;
	}

	if ( (headlen = tc_get_audio_header(head, len, format_add, NULL, NULL, &mp3rate_i))<0) {
	  fprintf(stderr, "Broken %s track #(%d)? skipping\n", (format_add==0x55?"MP3":"AC3"), aud_tracks);
	  aud_ms = vid_ms;
	  aud_error=1;
	} else { // look in import/tcscan.c for explanation
	  aud_ms += (headlen*8.0)/(mp3rate_i);
	}

	fseek (f, pos, SEEK_SET);

	len = fread (data, headlen, 1, f);
	if (len<=0) { //eof
	  fprintf(stderr, "EOF in %s; continuing ..\n", audfile);
	  aud_error=1;
	  break;
	}

	AVI_set_audio_track(avifile, out_track_num);

	if(AVI_write_audio(avifile, data, headlen)<0) {
	  AVI_print_error("AVI write audio frame");
	  return(-1);
	}

      }
    }

    // progress
    fprintf(stderr, "[%s] (%06ld-%06ld)\r", outfile, offset, offset + n);

  }

  fprintf(stderr,"\n");
  offset = frames;

  // more files?
  while (optind < argc) {

    printf ("file %02d %s\n", ++cc, argv[optind]);

    if(NULL == ( avifile1 = AVI_open_input_file(argv[optind++],1))) {
      AVI_print_error("AVI open");
      goto finish;
    }

    AVI_seek_start(avifile1);
    frames =  AVI_video_frames(avifile1);

    for (n=0; n<frames; ++n) {

      // video
      bytes = AVI_read_frame(avifile1, data, &key);

      if(bytes < 0) {
	AVI_print_error("AVI read video frame");
	return(-1);
      }

      if(AVI_write_frame(avifile, data, bytes, key)<0) {
	AVI_print_error("AVI write video frame");
	return(-1);
      }

      vid_chunks++;
      vid_ms = vid_chunks*1000.0/fps;

      for(j=0; j<aud_tracks; ++j) {

	if (j == out_track_num) continue;
	AVI_set_audio_track(avifile1, j);
	AVI_set_audio_track(avifile, j);
	chan   = AVI_audio_channels(avifile1);

	if(chan) {
	  sync_audio_video_avi2avi(vid_ms, &aud_ms_w[j], avifile1, avifile);
	}
      }

      // merge additional track
      // audio

      if(headlen>4 && !aud_error) {
	while (aud_ms < vid_ms) {
	  //printf("reading Audio Chunk ch(%ld) vms(%lf) ams(%lf)\n", vid_chunks, vid_ms, aud_ms);
	  pos = ftell(f);

	  len = fread (head, 8, 1, f);
	  if (len<=0) { //eof
	    fprintf(stderr, "EOF in %s; continuing ..\n", audfile);
	    aud_error=1; break;
	  }

	  if ( (headlen = tc_get_audio_header(head, len, format_add, NULL, NULL, &mp3rate_i))<0) {
	    fprintf(stderr, "Broken %s track #(%d)?\n", (format_add==0x55?"MP3":"AC3"), aud_tracks);
	    aud_ms = vid_ms;
	    aud_error=1;
	  } else { // look in import/tcscan.c for explanation
	    aud_ms += (headlen*8.0)/(mp3rate_i);
	  }

	  fseek (f, pos, SEEK_SET);

	  len = fread (data, headlen, 1, f);
	  if (len<=0) { //eof
	    fprintf(stderr, "EOF in %s; continuing ..\n", audfile);
	    aud_error=1; break;
	  }

	  AVI_set_audio_track(avifile, out_track_num);

	  if(AVI_write_audio(avifile, data, headlen)<0) {
	    AVI_print_error("AVI write audio frame");
	    return(-1);
	  }

	}
      }

      // progress
      fprintf(stderr, "[%s] (%06ld-%06ld)\r", outfile, offset, offset + n);
    }

    fprintf(stderr, "\n");

    offset += frames;
    AVI_close(avifile1);
  }


  if (f) fclose(f);

  printf("... done multiplexing in %s\n", outfile);

  AVI_close(avifile);

  return(0);
}
Esempio n. 9
0
Revel_Error Revel_XvidEncoder::EncodeFrame(const Revel_VideoFrame& frame,
                                      int *frameSize)
{
    Revel_Error revError = Revel_BaseEncoder::EncodeFrame(frame, frameSize);
    if (revError != REVEL_ERR_NONE)
        return revError;

	// Version for the frame and the stats
	xvid_enc_frame_t xvid_enc_frame;
	memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
	xvid_enc_frame.version = XVID_VERSION;

	xvid_enc_stats_t xvid_enc_stats;
	memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
	xvid_enc_stats.version = XVID_VERSION;

	// Bind output buffer
	xvid_enc_frame.bitstream = m_encodedFrame;
	xvid_enc_frame.length = -1;

	// Initialize input image fields
	if (frame.pixels != NULL) {
		xvid_enc_frame.input.plane[0] = frame.pixels;
		xvid_enc_frame.input.csp = GetXvidPixelFormat(frame.pixelFormat);
		// XviD expects the origin in the upper left.  If the user specified it in the lower
		// left, pass a flag to flip the frame before encoding.
		if (m_params.origin == REVEL_ORIGIN_LOWER_LEFT)
			xvid_enc_frame.input.csp |= XVID_CSP_VFLIP;
		xvid_enc_frame.input.stride[0] = frame.width * frame.bytesPerPixel;
	} else {
		xvid_enc_frame.input.csp = XVID_CSP_NULL;
	}

	// Set up core's general features
	xvid_enc_frame.vol_flags = 0;

	// Set up core's general features
    int quality = GetXvidQuality(m_params.quality);
	xvid_enc_frame.vop_flags = vop_presets[quality];

	// Frame type -- let core decide for us
	xvid_enc_frame.type = XVID_TYPE_AUTO;

	// Force the right quantizer -- It is internally managed by RC plugins
	xvid_enc_frame.quant = 0;

	// Set up motion estimation flags
	xvid_enc_frame.motion = motion_presets[quality];

	// We don't use special matrices
	xvid_enc_frame.quant_intra_matrix = NULL;
	xvid_enc_frame.quant_inter_matrix = NULL;

	// Encode the frame
	int frameBytes = xvid_encore(m_xvidEncoderHandle, XVID_ENC_ENCODE,
        &xvid_enc_frame, &xvid_enc_stats);

    // Write the frame to the output stream.
    int aviErr = AVI_write_frame(m_outFile, m_encodedFrame, frameBytes);
    if (aviErr != 0)
        return REVEL_ERR_FILE;

    m_totalOutBytes += frameBytes;
    if (frameSize != NULL)
        *frameSize = frameBytes;

	return REVEL_ERR_NONE;
}
Esempio n. 10
0
/**
 * This thread sends the frame to TS mux
 * \param Parameter The GF_AVRedirect pointer
 */
static Bool video_encoding_thread_run(void *param)
{
    GF_AVRedirect * avr = (GF_AVRedirect*) param;
    u64 currentFrameTimeProcessed = 0;
    u32 lastEncodedFrameTime = 0;
    AVCodecContext * ctx = NULL;
    assert( avr );
    gf_sc_add_video_listener ( avr->term->compositor, &avr->video_listen );
    while (avr->is_running && (!ctx || !avr->swsContext)) {
        ctx = ts_get_video_codec_context(avr->ts_implementation);
        gf_sleep(16);
    }
    if (!ctx) {
        goto exit;
    }
    printf("******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start);
    while (avr->is_running) {
        {
            gf_mx_p(avr->frameMutex);
            while (!avr->frameTime || currentFrameTimeProcessed == avr->frameTime) {
                gf_mx_v(avr->frameMutex);
                if (!avr->is_running) {
                    goto exit;
                }
                gf_mx_p(avr->frameMutex);
				gf_sleep(1);
            }
            assert( currentFrameTimeProcessed != avr->frameTime);
            currentFrameTimeProcessed = avr->frameTime;
            {
                avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight );
                assert( avr->swsContext );
                sws_scale ( avr->swsContext,
#ifdef USE_AVCODEC2
                            ( const uint8_t * const * )
#else
                            ( uint8_t ** )
#endif /* USE_AVCODEC2 */
                            avr->RGBpicture->data, avr->RGBpicture->linesize,
                            0, avr->srcHeight,
                            avr->YUVpicture->data, avr->YUVpicture->linesize );
#ifdef AVR_DUMP_RAW_AVI
                if ( AVI_write_frame ( avr->avi_out, avr->frame, avr->size, 1 ) <0 )
                {
                    GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error writing video frame\n" ) );
                }
#endif /* AVR_DUMP_RAW_AVI */
                gf_mx_v(avr->frameMutex);
                if (avr->encode)
                {
                    int written;
                    //u32 sysclock = gf_sys_clock();
                    avr->YUVpicture->pts = currentFrameTimeProcessed;
                    //printf("Encoding frame PTS="LLU", frameNum=%u, time=%u...", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed);
                    written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture );
                    //ctx->coded_frame->pts = currentFrameTimeProcessed;
                    if ( written < 0 )
                    {
                        GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while encoding video frame =%d\n", written ) );
                    } else
                        if ( written > 0 )
                        {
                            ts_encode_video_frame(avr->ts_implementation, avr->videoOutbuf, written);
                        }
                    lastEncodedFrameTime = currentFrameTimeProcessed;
                }
            }
        }
        avr->frameTimeEncoded = currentFrameTimeProcessed;
		gf_sleep(1);
    } /* End of main loop */
exit:
    GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending video encoding thread...\n"));
    if (avr->term)
        gf_sc_remove_video_listener ( avr->term->compositor, &avr->video_listen );
    return 0;
}
Esempio n. 11
0
int evid_enc_frame(evid_handler_t *evid_handler, pixel_t *frame) {
  xvid_enc_frame_t xvid_enc_frame;
  handler_t *handler=(handler_t *)evid_handler;
  static const int vop_presets[] = {
    0,
    0,
    XVID_VOP_HALFPEL,
    XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
    XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
    XVID_VOP_HALFPEL | XVID_VOP_INTER4V | XVID_VOP_TRELLISQUANT,
    XVID_VOP_HALFPEL | XVID_VOP_INTER4V | XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED,
  };
  static const int motion_presets[] = {
    0,
    XVID_ME_ADVANCEDDIAMOND16,
    XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16,
    XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8,
    XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
    XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
    XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 | XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
  };
  int frame_size;

  // XviD
  memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
  xvid_enc_frame.version=XVID_VERSION;
  xvid_enc_frame.vol_flags=0;
  xvid_enc_frame.vol_flags|=XVID_VOL_INTERLACING;
  xvid_enc_frame.quant_intra_matrix=NULL;
  xvid_enc_frame.quant_inter_matrix=NULL;
  xvid_enc_frame.par=XVID_PAR_11_VGA;
  xvid_enc_frame.par_width=1;
  xvid_enc_frame.par_height=1;
  xvid_enc_frame.fincr=0;
  xvid_enc_frame.vop_flags=vop_presets[handler->evid_xvidpar.quality];
  if(handler->evid_xvidpar.gray)
    xvid_enc_frame.vop_flags|=XVID_VOP_GREYSCALE;
  xvid_enc_frame.motion=motion_presets[handler->evid_xvidpar.quality];
  xvid_enc_frame.input.csp=XVID_CSP_YUY2;
  xvid_enc_frame.input.plane[0]=frame;
  xvid_enc_frame.input.stride[0]=handler->frame_par.width*PALETTE_DEPTH;
  xvid_enc_frame.type=XVID_TYPE_AUTO;
  xvid_enc_frame.quant=handler->evid_xvidpar.quant;
  xvid_enc_frame.bitstream=handler->xvid.bitstream;
  xvid_enc_frame.length=-1;

  frame_size=xvid_encore(handler->xvid.handle, XVID_ENC_ENCODE, &xvid_enc_frame, NULL);

  // avilib
  if(AVI_write_frame(handler->avilib.avi, (char *)handler->xvid.bitstream, (long)frame_size, ((xvid_enc_frame.out_flags&XVID_KEYFRAME)?1:0))) {
    free(handler->errstr);
    switch(AVI_errno) {
      case AVI_ERR_SIZELIM:
        return 1;
        break;
      default:
        x_asprintf(&handler->errstr, "Error writing encoded frame to AVI file: %s.\n", AVI_strerror());
        break;
    }
    return 1;
  }
  // update header
  if(AVI_make_header(handler->avilib.avi)) {
    free(handler->errstr);
    x_asprintf(&handler->errstr, "Error writing encoded frame to AVI file: %s.\n", AVI_strerror());
    return 1;
  }
  return 0;
}
Esempio n. 12
0
static void index_rebuild_fallback(struct anim * anim,
                                   IMB_Timecode_Type UNUSED(tcs_in_use),
                                   IMB_Proxy_Size proxy_sizes_in_use,
                                   int quality,
                                   short *stop, short *do_update,
                                   float *progress)
{
    int cnt = IMB_anim_get_duration(anim, IMB_TC_NONE);
    int i, pos;
    AviMovie * proxy_ctx[IMB_PROXY_MAX_SLOT];
    char fname[FILE_MAXDIR+FILE_MAXFILE];
    char fname_tmp[FILE_MAXDIR+FILE_MAXFILE];

    memset(proxy_ctx, 0, sizeof(proxy_ctx));

    /* since timecode indices only work with ffmpeg right now,
       don't know a sensible fallback here...

       so no proxies, no game to play...
    */
    if (proxy_sizes_in_use == IMB_PROXY_NONE) {
        return;
    }

    for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
        if (proxy_sizes_in_use & proxy_sizes[i]) {
            char fname[FILE_MAXDIR+FILE_MAXFILE];

            get_proxy_filename(anim, proxy_sizes[i], fname, TRUE);
            BLI_make_existing_file(fname);

            proxy_ctx[i] = alloc_proxy_output_avi(
                               anim, fname,
                               anim->x * proxy_fac[i],
                               anim->y * proxy_fac[i],
                               quality);
        }
    }

    for (pos = 0; pos < cnt; pos++) {
        struct ImBuf * ibuf = IMB_anim_absolute(
                                  anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
        int next_progress = (int) ((double) pos / (double) cnt);

        if (*progress != next_progress) {
            *progress = next_progress;
            *do_update = 1;
        }

        if (*stop) {
            break;
        }

        IMB_flipy(ibuf);

        for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
            if (proxy_sizes_in_use & proxy_sizes[i]) {
                int x = anim->x * proxy_fac[i];
                int y = anim->y * proxy_fac[i];

                struct ImBuf * s_ibuf = IMB_scalefastImBuf(
                                            ibuf, x, y);

                IMB_convert_rgba_to_abgr(s_ibuf);

                AVI_write_frame (proxy_ctx[i], pos,
                                 AVI_FORMAT_RGB32,
                                 s_ibuf->rect, x * y * 4);

                /* note that libavi free's the buffer... */
                s_ibuf->rect = 0;

                IMB_freeImBuf(s_ibuf);
            }
        }
    }

    for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
        if (proxy_sizes_in_use & proxy_sizes[i]) {
            AVI_close_compress (proxy_ctx[i]);
            MEM_freeN (proxy_ctx[i]);

            get_proxy_filename(anim, proxy_sizes[i],
                               fname_tmp, TRUE);
            get_proxy_filename(anim, proxy_sizes[i],
                               fname, FALSE);

            if (*stop) {
                unlink(fname_tmp);
            } else {
                rename(fname_tmp, fname);
            }
        }
    }
}
Esempio n. 13
0
File: main.c Progetto: Enlik/mlt
int main(int argc, char *argv[]) {

    int opt_shutter_angle = 0;
    int opt_mjpeg_quality = 100;

    int nf, i, nc, nr;
    int tfs, fps;

    vc *pos_i, *pos_h, *pos_y;

    es_ctx *es;
    rs_ctx *rs;

    opterr = 0;

    while ((i = getopt(argc, argv, "r:q:")) != -1) {

        switch (i) {

            case 'r':
                opt_shutter_angle = atoi(optarg);
                break;

            case 'q':
                opt_mjpeg_quality = atoi(optarg);
                break;

            default:
                print_help(argv);
        }
    }

    if (argc < optind + 2)
        print_help(argv);

    if (AVI_open_movie(argv[optind], &mv_in) != AVI_ERROR_NONE) {

        printf("error: can't read from %s\n", argv[optind]);
        return EXIT_FAILURE;
    }

    if (mv_in.header->Streams < 1 || mv_in.streams[0].sh.Type != AVIST_VIDEO) {

        printf("error: video stream not found on %s\n", argv[optind]);
        return EXIT_FAILURE;
    }

    if (AVI_open_compress(argv[optind + 1], &mv_out, 1, AVI_FORMAT_MJPEG) != AVI_ERROR_NONE) {

        printf("error: can't write to %s\n", argv[optind + 1]);
        return EXIT_FAILURE;
    }

    printf("status: setup\n");

    prepare_lanc_kernels();

	nc = mv_in.header->Width;
	nr = mv_in.header->Height;

    tfs = mv_in.header->TotalFrames;
    fps = 1000000 / mv_in.header->MicroSecPerFrame;

    pos_i = (vc *)malloc(tfs * sizeof(vc));
    pos_h = (vc *)malloc(tfs * sizeof(vc));

    pos_y = (vc *)malloc(nr * sizeof(vc));
    
    AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &nc);
    AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &nr);
    AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &fps);
    AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &opt_mjpeg_quality);

    es = es_init(nc, nr);
    rs = rs_init(nc, nr);

    printf("status: estimating\n");

    for (nf = 0; nf < tfs; nf ++) {

        unsigned char *fr = (unsigned char *)AVI_read_frame(&mv_in, AVI_FORMAT_RGB24, nf, 0);

        pos_i[nf] = vc_add(
            nf > 0 ? pos_i[nf - 1] : vc_set(0.0, 0.0),
            es_estimate(es, fr)
            );
        
        free(fr);

        if ((nf + 1) % 10 == 0) {

            printf(".");
            fflush(stdout);
        }
    }

    printf("\nstatus: filtering\n");

    hipass(pos_i, pos_h, tfs, fps / 2);

    printf("status: resampling\n");

    for (nf = 0; nf < tfs; nf ++) {

        unsigned char *fr = (unsigned char *)AVI_read_frame(&mv_in, AVI_FORMAT_RGB24, nf, 0);

        for (i = 0; i < nr; i ++) {

            pos_y[i] = interp(
                pos_h, tfs,
                nf + (i - nr / 2.0) * opt_shutter_angle / (nr * 360.0)
                );
        }

        rs_resample(rs, fr, pos_y);

        AVI_write_frame(&mv_out, nf, AVI_FORMAT_RGB24, fr, nc * nr * 3 * sizeof(unsigned char));

        if ((nf + 1) % 10 == 0) {

            printf(".");
            fflush(stdout);
        }
    }
        
    printf("\nstatus: closing\n");

    es_free(es);
    rs_free(rs);

    free_lanc_kernels();

    AVI_close(&mv_in);
    AVI_close_compress(&mv_out);

    return EXIT_SUCCESS;
}
Esempio n. 14
0
int main(int argc, char *argv[])
{

  avi_t *avifile1=NULL;
  avi_t *avifile2=NULL;
  avi_t *avifile3=NULL;

  char *in_file=NULL, *out_file=NULL;

  long frames, bytes;

  double fps;

  char *codec;

  int track_num=0, aud_tracks;
  int encode_null=0;

  int i, j, n, key, shift=0;

  int ch, preload=0;

  long rate, mp3rate;

  int width, height, format, chan, bits;

  int be_quiet = 0;
  FILE *status_fd = stderr;

  /* for null frame encoding */
  char nulls[32000];
  long nullbytes=0;
  char tmp0[] = "/tmp/nullfile.00.avi"; /* XXX: use mktemp*() */

  buffer_list_t *ptr;

  double vid_ms = 0.0, shift_ms = 0.0, one_vid_ms = 0.0;
  double aud_ms [ AVI_MAX_TRACKS ];
  int aud_bitrate = 0;
  int aud_chunks = 0;

  ac_init(AC_ALL);

  if(argc==1) usage(EXIT_FAILURE);

  while ((ch = getopt(argc, argv, "a:b:vi:o:n:Nq?h")) != -1)
    {

	switch (ch) {

	case 'i':

	     if(optarg[0]=='-') usage(EXIT_FAILURE);
	    in_file=optarg;

	    break;

	case 'a':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  track_num = atoi(optarg);

	  if(track_num<0) usage(EXIT_FAILURE);

	  break;

	case 'b':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  is_vbr = atoi(optarg);

	  if(is_vbr<0) usage(EXIT_FAILURE);

	  break;

	case 'o':

	    if(optarg[0]=='-') usage(EXIT_FAILURE);
	    out_file=optarg;

	    break;

	case 'f':

	    if(optarg[0]=='-') usage(EXIT_FAILURE);
	    comfile = optarg;

	    break;

	case 'n':

	    if(sscanf(optarg,"%d", &shift)!=1) {
		fprintf(stderr, "invalid parameter for option -n\n");
		usage(EXIT_FAILURE);
	    }
	    break;

	case 'N':
	    encode_null=1;
	    break;
	case 'q':
	    be_quiet = 1;
	    break;
	case 'v':
	    version();
	    exit(0);
	    break;
      case 'h':
	usage(EXIT_SUCCESS);
      default:
	usage(EXIT_FAILURE);
      }
    }

  // check
  if(in_file==NULL || out_file == NULL) usage(EXIT_FAILURE);

  if(shift == 0) fprintf(stderr, "no sync requested - exit");

  memset (nulls, 0, sizeof(nulls));


  // open file
  if(NULL == (avifile1 = AVI_open_input_file(in_file,1))) {
      AVI_print_error("AVI open");
      exit(1);
  }

  if(strcmp(in_file, out_file)==0) {
      printf("error: output filename conflicts with input filename\n");
      exit(1);
  }

  if(NULL == (avifile2 = AVI_open_output_file(out_file))) {
    AVI_print_error("AVI open");
    exit(1);
  }

  if (be_quiet) {
    if (!(status_fd = fopen("/dev/null", "w"))) {
      fprintf(stderr, "Can't open /dev/null\n");
      exit(1);
    }
  }

  // read video info;

  AVI_info(avifile1);

  // read video info;

  frames =  AVI_video_frames(avifile1);
   width =  AVI_video_width(avifile1);
  height =  AVI_video_height(avifile1);

  fps    =  AVI_frame_rate(avifile1);
  codec  =  AVI_video_compressor(avifile1);

  //set video in outputfile
  AVI_set_video(avifile2, width, height, fps, codec);

  if (comfile!=NULL)
    AVI_set_comment_fd(avifile2, open(comfile, O_RDONLY));

  aud_tracks = AVI_audio_tracks(avifile1);

  for(j=0; j<aud_tracks; ++j) {

    AVI_set_audio_track(avifile1, j);

    rate   =  AVI_audio_rate(avifile1);
    chan   =  AVI_audio_channels(avifile1);
    bits   =  AVI_audio_bits(avifile1);

    format =  AVI_audio_format(avifile1);
    mp3rate=  AVI_audio_mp3rate(avifile1);

    //set next track of output file
    AVI_set_audio_track(avifile2, j);
    AVI_set_audio(avifile2, chan, rate, bits, format, mp3rate);
    AVI_set_audio_vbr(avifile2, is_vbr);
  }

  //switch to requested audio_channel

  if(AVI_set_audio_track(avifile1, track_num)<0) {
    fprintf(stderr, "invalid auto track\n");
  }

  AVI_set_audio_track(avifile2, track_num);

  if (encode_null) {
      char cmd[1024];

      rate   =  AVI_audio_rate(avifile2);
      chan   =  AVI_audio_channels(avifile2);
      bits   =  AVI_audio_bits(avifile2);
      format =  AVI_audio_format(avifile2);
      mp3rate=  AVI_audio_mp3rate(avifile2);

      if (bits==0) bits=16;
      if (mp3rate%2) mp3rate++;

      fprintf(status_fd, "Creating silent mp3 frame with current parameter\n");
      memset (cmd, 0, sizeof(cmd));
      tc_snprintf(cmd, sizeof(cmd), "transcode -i /dev/zero -o %s -x raw,raw"
	      " -n 0x1 -g 16x16 -y raw,raw -c 0-5 -e %ld,%d,%d -b %ld -q0",
	      tmp0, rate,bits,chan, mp3rate);

      printf(cmd);
      system(cmd);

      if(NULL == (avifile3 = AVI_open_input_file(tmp0,1))) {
	  AVI_print_error("AVI open");
	  exit(1);
      }

      nullbytes = AVI_audio_size(avifile3, 3);

      /* just read a few frames */
      if(AVI_read_audio(avifile3, nulls, nullbytes) < 0) {
	  AVI_print_error("AVI audio read frame");
	  return(-1);
      }
      memset (nulls, 0, sizeof(nulls));
      if(AVI_read_audio(avifile3, nulls, nullbytes) < 0) {
	  AVI_print_error("AVI audio read frame");
	  return(-1);
      }
      memset (nulls, 0, sizeof(nulls));
      if(AVI_read_audio(avifile3, nulls, nullbytes) < 0) {
	  AVI_print_error("AVI audio read frame");
	  return(-1);
      }


      /*
      printf("\nBytes (%ld): \n", nullbytes);
      {
	  int asd=0;
	  for (asd=0; asd<nullbytes; asd++){
	      printf("%x ",(unsigned char)nulls[asd]);
	  }
	  printf("\n");
      }
      */



  }

  vid_ms   = 0.0;
  shift_ms = 0.0;
  for (n=0; n<AVI_MAX_TRACKS; ++n)
      aud_ms[n] = 0.0;

  // ---------------------------------------------------------------------

  for (n=0; n<frames; ++n) {

    // video unchanged
    bytes = AVI_read_frame(avifile1, data, &key);

    if(bytes < 0) {
      AVI_print_error("AVI read video frame");
      return(-1);
    }

    if(AVI_write_frame(avifile2, data, bytes, key)<0) {
      AVI_print_error("AVI write video frame");
      return(-1);
    }

    vid_ms = (n+1)*1000.0/fps;


    // Pass-through all other audio tracks.
    for(j=0; j<aud_tracks; ++j) {

	// skip track we want to modify
	if (j == track_num) continue;

	// switch to track
	AVI_set_audio_track(avifile1, j);
	AVI_set_audio_track(avifile2, j);
	sync_audio_video_avi2avi(vid_ms, &aud_ms[j], avifile1, avifile2);
    }

    //switch to requested audio_channel
    if(AVI_set_audio_track(avifile1, track_num)<0) {
	fprintf(stderr, "invalid auto track\n");
    }
    AVI_set_audio_track(avifile2, track_num);
    shift_ms = (double)shift*1000.0/fps;
    one_vid_ms = 1000.0/fps;
    format = AVI_audio_format(avifile1);
    rate   = AVI_audio_rate(avifile1);
    chan   = AVI_audio_channels(avifile1);
    bits   = AVI_audio_bits(avifile1);
    bits   = bits==0?16:bits;
    mp3rate= AVI_audio_mp3rate(avifile1);


    if(shift>0) {

      // for n < shift, shift audio frames are discarded

      if(!preload) {

	if (tc_format_ms_supported(format)) {
	  for(i=0;i<shift;++i) {
	      //fprintf (stderr, "shift (%d) i (%d) n (%d) a (%d)\n", shift, i, n, aud_chunks);
	    while (aud_ms[track_num] < vid_ms + one_vid_ms*(double)i) {

		aud_bitrate = (format==0x1||format==0x2000)?1:0;
		aud_chunks++;
		if( (bytes = AVI_read_audio_chunk(avifile1, data)) <= 0) {
		    aud_ms[track_num] = vid_ms + one_vid_ms*i;
		    if (bytes == 0) continue;
		    AVI_print_error("AVI 2 audio read frame");
		    break;
		}

		if ( !aud_bitrate && tc_get_audio_header(data, bytes, format, NULL, NULL, &aud_bitrate)<0) {
		    // if this is the last frame of the file, slurp in audio chunks
		    if (n == frames-1) continue;
		    aud_ms[track_num] = vid_ms + one_vid_ms*i;
		} else
		    aud_ms[track_num] += (bytes*8.0)/(format==0x1?((double)(rate*chan*bits)/1000.0):
				       (format==0x2000?(double)(mp3rate):aud_bitrate));
	    }
	  }

	} else { // fallback
	    bytes=0;
	    for(i=0;i<shift;++i) {
		do {
		    if( (bytes = AVI_read_audio_chunk(avifile1, data)) < 0) {
			AVI_print_error("AVI audio read frame");
			return(-1);
		    }
		} while (AVI_can_read_audio(avifile1));
	    }
	}
	preload=1;
      }


      // copy rest of the track
      if(n<frames-shift) {
	if (tc_format_ms_supported(format)) {

	    while (aud_ms[track_num] < vid_ms + shift_ms) {

		aud_chunks++;
		aud_bitrate = (format==0x1||format==0x2000)?1:0;

		if( (bytes = AVI_read_audio_chunk(avifile1, data)) < 0) {
		    aud_ms[track_num] = vid_ms + shift_ms;
		    AVI_print_error("AVI 3 audio read frame");
		    break;
		}

		if(AVI_write_audio(avifile2, data, bytes) < 0) {
		    AVI_print_error("AVI 3 write audio frame");
		    return(-1);
		}

		fprintf(status_fd, "V [%05d][%08.2f] | A [%05d][%08.2f] [%05ld]\r", n, vid_ms, aud_chunks, aud_ms[track_num], bytes);

		if (bytes == 0) {
		    aud_ms[track_num] = vid_ms + shift_ms;
		    continue;
		}

		if(n>=frames-2*shift) {

		    // save audio frame for later
		    ptr = buffer_register(n);

		    if(ptr==NULL) {
			fprintf(stderr,"buffer allocation failed\n");
			break;
		    }

		    ac_memcpy(ptr->data, data, bytes);
		    ptr->size = bytes;
		    ptr->status = BUFFER_READY;
		}


		if ( !aud_bitrate && tc_get_audio_header(data, bytes, format, NULL, NULL, &aud_bitrate)<0) {
		    if (n == frames-1) continue;
		    aud_ms[track_num] = vid_ms + shift_ms;
		} else
		    aud_ms[track_num] += (bytes*8.0)/(format==0x1?((double)(rate*chan*bits)/1000.0):
				       (format==0x2000?(double)(mp3rate):aud_bitrate));
	    }

	} else { // fallback
	bytes = AVI_audio_size(avifile1, n+shift-1);

	do {
	    if( (bytes = AVI_read_audio_chunk(avifile1, data)) < 0) {
		AVI_print_error("AVI audio read frame");
		return(-1);
	    }

	    if(AVI_write_audio(avifile2, data, bytes) < 0) {
		AVI_print_error("AVI write audio frame");
		return(-1);
	    }

	    fprintf(status_fd, "V [%05d] | A [%05d] [%05ld]\r", n, n+shift, bytes);

	    if(n>=frames-2*shift) {

		// save audio frame for later
		ptr = buffer_register(n);

		if(ptr==NULL) {
		    fprintf(stderr,"buffer allocation failed\n");
		    break;
		}

		ac_memcpy(ptr->data, data, bytes);
		ptr->size = bytes;
		ptr->status = BUFFER_READY;
	    }
	} while (AVI_can_read_audio(avifile1));
	}
      }

      // padding at the end
      if(n>=frames-shift) {

	if (!ptrlen) {
	    ptr = buffer_retrieve();
	    ac_memcpy (ptrdata, ptr->data, ptr->size);
	    ptrlen = ptr->size;
	}

	if (tc_format_ms_supported(format)) {

	    while (aud_ms[track_num] < vid_ms + shift_ms) {

		aud_bitrate = (format==0x1||format==0x2000)?1:0;

		// mute this -- check if can mute (valid A header)!
		if (tc_probe_audio_header(ptrdata, ptrlen) > 0)
		    tc_format_mute(ptrdata, ptrlen, format);

		if(AVI_write_audio(avifile2, ptrdata, ptrlen) < 0) {
		    AVI_print_error("AVI write audio frame");
		    return(-1);
		}

		fprintf(status_fd, " V [%05d][%08.2f] | A [%05d][%08.2f] [%05ld]\r", n, vid_ms, n+shift, aud_ms[track_num], bytes);

		if ( !aud_bitrate && tc_get_audio_header(ptrdata, ptrlen, format, NULL, NULL, &aud_bitrate)<0) {
		    //if (n == frames-1) continue;
		    aud_ms[track_num] = vid_ms + shift_ms;
		} else
		    aud_ms[track_num] += (ptrlen*8.0)/(format==0x1?((double)(rate*chan*bits)/1000.0):
				       (format==0x2000?(double)(mp3rate):aud_bitrate));
	    }

	} else { // fallback

	// get next audio frame
	ptr = buffer_retrieve();

	while (1) {
	    printf("ptr->id (%d) ptr->size (%d)\n", ptr->id, ptr->size);

	    if(ptr==NULL) {
		fprintf(stderr,"no buffer found\n");
		break;
	    }

	    if (encode_null) {
		if(AVI_write_audio(avifile2, nulls, nullbytes)<0) {
		    AVI_print_error("AVI write audio frame");
		    return(-1);
		}
	    } else {
		// simple keep old frames to force exact time delay
		if(AVI_write_audio(avifile2, ptr->data, ptr->size)<0) {
		    AVI_print_error("AVI write audio frame");
		    return(-1);
		}
	    }

	    fprintf(status_fd, "V [%05d] | padding\r", n);

	    if (ptr->next && ptr->next->id == ptr->id) {
		buffer_remove(ptr);
		ptr = buffer_retrieve();
		continue;
	    }

	    buffer_remove(ptr);
	    break;
	}  // 1
      }
      }


// *************************************
// negative shift (pad audio at start)
// *************************************

    } else {

      if (tc_format_ms_supported(format)) {
	/*
	fprintf(status_fd, "n(%d) -shift(%d) shift_ms (%.2lf) vid_ms(%.2lf) aud_ms[%d](%.2lf) v-s(%.2lf)\n",
	    n, -shift, shift_ms, vid_ms, track_num, aud_ms[track_num], vid_ms + shift_ms);
	    */

	// shift<0 -> shift_ms<0 !
	while (aud_ms[track_num] < vid_ms) {
	    /*
	  fprintf(stderr, " 1 (%02d) %s frame_read len=%4ld (A/V) (%8.2f/%8.2f)\n",
	      n, format==0x55?"MP3":"AC3", bytes, aud_ms[track_num], vid_ms);
	      */

	  aud_bitrate = (format==0x1||format==0x2000)?1:0;

	  if( (bytes = AVI_read_audio_chunk(avifile1, data)) < 0) {
	    AVI_print_error("AVI 2 audio read frame");
	    aud_ms[track_num] = vid_ms;
	    break;
	    //return(-1);
	  }

	  // save audio frame for later
	  ptr = buffer_register(n);

	  if(ptr==NULL) {
	    fprintf(stderr,"buffer allocation failed\n");
	    break;
	  }

	  ac_memcpy(ptr->data, data, bytes);
	  ptr->size = bytes;
	  ptr->status = BUFFER_READY;

	  if(n<-shift) {

	    // mute this -- check if can mute!
	    if (tc_probe_audio_header(data, bytes) > 0)
		tc_format_mute(data, bytes, format);

	    // simple keep old frames to force exact time delay
	    if(AVI_write_audio(avifile2, data, bytes)<0) {
	      AVI_print_error("AVI write audio frame");
	      return(-1);
	    }

	    fprintf(status_fd, "V [%05d] | padding\r", n);

	  } else {
	    if (n==-shift)
		fprintf(status_fd, "\n");

	    // get next audio frame
	    ptr = buffer_retrieve();

	    if(ptr==NULL) {
	      fprintf(stderr,"no buffer found\n");
	      break;
	    }

	    if(AVI_write_audio(avifile2, ptr->data, ptr->size)<0) {
	      AVI_print_error("AVI write audio frame");
	      return(-1);
	    }
	    bytes = ptr->size;
	    ac_memcpy (data, ptr->data, bytes);

	    fprintf(status_fd, "V [%05d] | A [%05d]\r", n, ptr->id);

	    buffer_remove(ptr);
	  }

	  if ( !aud_bitrate && tc_get_audio_header(data, bytes, format, NULL, NULL, &aud_bitrate)<0) {
	    if (n == frames-1) continue;
	    aud_ms[track_num] = vid_ms;
	  } else
	    aud_ms[track_num] += (bytes*8.0)/(format==0x1?((double)(rate*chan*bits)/1000.0):
				       (format==0x2000?(double)(mp3rate):aud_bitrate));

	  /*
	  fprintf(stderr, " 1 (%02d) %s frame_read len=%4ld (A/V) (%8.2f/%8.2f)\n",
	      n, format==0x55?"MP3":"AC3", bytes, aud_ms[track_num], vid_ms);
	      */

	}








      } else { // no supported format

      bytes = AVI_audio_size(avifile1, n);


      if(bytes > SIZE_RGB_FRAME) {
	fprintf(stderr, "invalid frame size\n");
	return(-1);
      }

      if(AVI_read_audio(avifile1, data, bytes) < 0) {
	AVI_print_error("AVI audio read frame");
	return(-1);
      }

      // save audio frame for later
      ptr = buffer_register(n);

      if(ptr==NULL) {
	fprintf(stderr,"buffer allocation failed\n");
	break;
      }

      ac_memcpy(ptr->data, data, bytes);
      ptr->size = bytes;
      ptr->status = BUFFER_READY;


      if(n<-shift) {

	if (encode_null) {
	    if(AVI_write_audio(avifile2, nulls, nullbytes)<0) {
		AVI_print_error("AVI write audio frame");
		return(-1);
	    }
	} else {
	// simple keep old frames to force exact time delay
	    if(AVI_write_audio(avifile2, data, bytes)<0) {
		AVI_print_error("AVI write audio frame");
		return(-1);
	    }
	}

	fprintf(status_fd, "V [%05d] | padding\r", n);

      } else {

	// get next audio frame
	ptr = buffer_retrieve();

	if(ptr==NULL) {
	  fprintf(stderr,"no buffer found\n");
	  break;
	}

	if(AVI_write_audio(avifile2, ptr->data, ptr->size)<0) {
	  AVI_print_error("AVI write audio frame");
	  return(-1);
	}

	fprintf(status_fd, "V [%05d] | A [%05d]\r", n, ptr->id);

	buffer_remove(ptr);
      }
    }
    }
  }

  fprintf(status_fd, "\n");

  if (be_quiet) {
    fclose(status_fd);
  }

  AVI_close(avifile1);
  AVI_close(avifile2);

  if (avifile3) {
      memset(nulls, 0, sizeof(nulls));
      tc_snprintf(nulls, sizeof(nulls), "rm -f %s", tmp0);
      system(nulls);
      AVI_close(avifile3);
  }

  return(0);
}