Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
Revel_Error Revel_BaseEncoder::EncodeStart(const char *filename)
{
    if (m_isEncoding)
        return REVEL_ERR_BUSY;

	// check params
    if (m_params.width == 0 || m_params.height == 0)
    {
		Reset();
        return REVEL_ERR_PARAMS;
    }

    // Create output file
    m_outFile = AVI_open_output_file( (char*)filename );
    if (m_outFile == NULL)
    {
		Reset();
        return REVEL_ERR_FILE;
    }
    AVI_set_video(m_outFile, m_params.width, m_params.height, m_params.frameRate, "XVID");
    if (m_params.hasAudio == 1)
    {
        // Sanity-check the audio settings first, since there's a good chance
        // the caller will leave all these fields uninitialized when updating
        // from Revel 1.0.x.
        if (m_params.audioBits < 0 || m_params.audioBits > 256 ||
            m_params.audioChannels < 0 || m_params.audioChannels > 256 ||
            m_params.audioRate < 0)
        {
            Reset();
            return REVEL_ERR_PARAMS;
        }
        AVI_set_audio(m_outFile, m_params.audioChannels, m_params.audioRate,
            m_params.audioBits, m_params.audioSampleFormat);
    }
    else
    {
        AVI_set_audio(m_outFile, 0, 44100, 16, WAVE_FORMAT_UNKNOWN);
    }

    // Allocate frame buffer
    m_encodedFrame = new char[m_params.width*m_params.height*4];
    if (m_encodedFrame == NULL)
    {
        Reset();
        return REVEL_ERR_MEMORY;
    }

	m_outFilename = std::string(filename);
	m_totalOutBytes = 0;
    m_isEncoding = true;

    return REVEL_ERR_NONE;
}
Ejemplo n.º 3
0
static void
capture_avi (GtkButton * CapAVIButt, GtkWidget * AVIFNameEntry)
{
	char *filename = gtk_entry_get_text(GTK_ENTRY(AVIFNameEntry));
	char *compression="YUY2";

	switch (AVIFormat) {
	 case 1:
		compression="YUY2";
		break;
	 case 2:
		compression="DIB ";
		break;
	 default:
		compression="YUY2";
	}	
	if(videoIn->capAVI) {
	 printf("stoping AVI capture\n");
	 gtk_button_set_label(CapAVIButt,"Capture");
	 AVIstoptime = ms_time();
	 printf("AVI stop time:%d\n",AVIstoptime);	
	 videoIn->capAVI = FALSE;
	 aviClose();		
	} 
	else {
	 if (!(videoIn->signalquit)) {
		/*thread exited while in AVI capture mode*/
        /* we have to close AVI                  */
     printf("close AVI since thread as exited\n");
	 gtk_button_set_label(CapAVIButt,"Capture");
	 printf("AVI stop time:%d\n",AVIstoptime);	
	 aviClose(); 		 
	 } 
	 else {
	   /* thread is running so start AVI capture*/	 
	   printf("starting AVI capture to %s\n",filename);
	   gtk_button_set_label(CapAVIButt,"Stop");  
	   AviOut = AVI_open_output_file(filename);
	   /*4CC compression "YUY2" (YUV) or "DIB " (RGB24)  or  whathever*/	
	   
	   AVI_set_video(AviOut, videoIn->width, videoIn->height, videoIn->fps,compression);		
	 
	   videoIn->AVIFName = filename;
	   AVIstarttime = ms_time();
       printf("AVI start time:%d\n",AVIstarttime);		
	   videoIn->capAVI = TRUE;
	 }
	}	
}
Ejemplo n.º 4
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;  
}
Ejemplo n.º 5
0
static int initVideoFile(struct ALL_DATA *all_data)
{
	struct GWIDGET *gwidget = all_data->gwidget;
	struct paRecordData *pdata = all_data->pdata;
	struct GLOBAL *global = all_data->global;
	struct vdIn *videoIn = all_data->videoIn;
	struct VideoFormatData *videoF = all_data->videoF;
	
	const char *compression= get_vid4cc(global->VidCodec);
	videoF->vcodec = get_vcodec_id(global->VidCodec);
	videoF->acodec = CODEC_ID_NONE;
	videoF->keyframe = 0;
	int ret = 0;
	
	__LOCK_MUTEX(__VMUTEX);
		gboolean capVid = videoIn->capVid;
	__UNLOCK_MUTEX(__VMUTEX);
	
	/*alloc video ring buffer*/
	alloc_videoBuff(all_data);
	
	switch (global->VidFormat)
	{
		case AVI_FORMAT:
			if(videoF->AviOut != NULL)
			{
				g_free(videoF->AviOut);
				videoF->AviOut = NULL;
			}
			videoF->AviOut = g_new0(struct avi_t, 1);
			
			if(AVI_open_output_file(videoF->AviOut, videoIn->VidFName)<0) 
			{
				g_printerr("Error: Couldn't create Video.\n");
				capVid = FALSE; /*don't start video capture*/
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				return(-1);
			} 
			else 
			{
				AVI_set_video(videoF->AviOut, global->width, global->height, 
					global->fps, compression);
		  
				/* start video capture*/
				capVid = TRUE;
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				
				/* start sound capture*/
				if(global->Sound_enable > 0) 
				{
					/*get channels and sample rate*/
					set_sound(global, pdata);
					/*set audio header for avi*/
					AVI_set_audio(videoF->AviOut, global->Sound_NumChan, 
						global->Sound_SampRate,
						get_aud_bit_rate(get_ind_by4cc(global->Sound_Format)), /*bit rate*/
						get_aud_bits(get_ind_by4cc(global->Sound_Format)),     /*sample size - only used for PCM*/
						global->Sound_Format);
					/* Initialize sound (open stream)*/
					if(init_sound (pdata)) 
					{
						g_printerr("Audio initialization error\n");
						global->Sound_enable=0;
						if(!(global->no_display))
                        {
						    gdk_threads_enter();
						    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gwidget->SndEnable),0);
						    gdk_flush();
						    gdk_threads_leave();
						}
						else
                            capture_vid(NULL, all_data);
					} 
				}
			}
			break;
			
		case MKV_FORMAT:
			if(global->Sound_enable > 0) 
			{
				/*set channels, sample rate and allocate buffers*/
				set_sound(global, pdata);
			}
			if(init_FormatContext((void *) all_data)<0)
			{
				capVid = FALSE;
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				return (-1);
			}
			
			videoF->old_apts = 0;
			videoF->apts = 0;
			videoF->vpts = 0;
			
			/* start video capture*/
			capVid = TRUE;
			__LOCK_MUTEX(__VMUTEX);
				videoIn->capVid = capVid;
			__UNLOCK_MUTEX(__VMUTEX);
			pdata->capVid = capVid;
			
			
			/* start sound capture*/
			if(global->Sound_enable > 0) 
			{
				/* Initialize sound (open stream)*/
				if(init_sound (pdata)) 
				{
					g_printerr("Audio initialization error\n");
					global->Sound_enable=0;
					if(!(global->no_display))
                    {
					    /*will this work with the checkbox disabled?*/
					    gdk_threads_enter();
					    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gwidget->SndEnable),0);
					    gdk_flush();
					    gdk_threads_leave();
					}
					else
					    capture_vid(NULL, all_data);
				}
			}
			break;
//WebM = MKV + WebVTT
//add META data capture
		case WEBM_FORMAT:
                     
			if(global->Sound_enable > 0) 
			{
				/*set channels, sample rate and allocate buffers*/
				set_sound(global, pdata);
			}
			if(init_FormatContext((void *) all_data)<0)
			{
				capVid = FALSE;
				__LOCK_MUTEX(__VMUTEX);
					videoIn->capVid = capVid;
				__UNLOCK_MUTEX(__VMUTEX);
				pdata->capVid = capVid;
				return (-1);
			}
			
			videoF->old_apts = 0;
			videoF->apts = 0;
			videoF->vpts = 0;
			
			/* start video capture*/
			capVid = TRUE;
			__LOCK_MUTEX(__VMUTEX);
				videoIn->capVid = capVid;
			__UNLOCK_MUTEX(__VMUTEX);
			pdata->capVid = capVid;
			
			
			/* start sound capture*/
			if(global->Sound_enable > 0) 
			{
				/* Initialize sound (open stream)*/
				if(init_sound (pdata)) 
				{
					g_printerr("Audio initialization error\n");
					global->Sound_enable=0;
					if(!(global->no_display))
                    {
					    /*will this work with the checkbox disabled?*/
					    gdk_threads_enter();
					    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gwidget->SndEnable),0);
					    gdk_flush();
					    gdk_threads_leave();
					}
					else
					    capture_vid(NULL, all_data);
				}
			}
			break;            
		default:
			
			break;
	}
	
	return (ret);
}
Ejemplo n.º 6
0
void bifs_to_vid(M4File *file, char *szConfigFile, u32 width, u32 height, char *rad_name, u32 dump_type, char *out_dir, Float fps, s32 frameID, s32 dump_time)
{
	M4User client;
	int N;
	BIFSVID b2v;
	u16 es_id;
	Bool first_dump, needs_raw;
	u32 i, j, di, count, timescale, frameNum;
	Float duration, cur_time;
	M4VideoSurface fb;
	M4Err e;
	char old_driv[1024], *test;
	char config_path[M4_MAX_PATH];
	avi_t *avi_out; 
	Bool reset_fps;
	ESDescriptor *esd;
	char comp[5];
	char *conv_buf;

	memset(config_path, 0, M4_MAX_PATH);
	memset(&client, 0, sizeof(M4User));
	if (szConfigFile && strlen(szConfigFile)) {
		client.config = NewIniFile(szConfigFile, GPAC_CFG_FILE);
	} else {
		client.config = loadconfigfile();
	}

	if (!client.config) {
		fprintf(stdout, "Configuration File \"GPAC.cfg\" not found\nPlease enter full path to config file:\n");
		scanf("%s", config_path);
		client.config = NewIniFile(config_path, GPAC_CFG_FILE);
		if (!client.config) {
			fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path);
			return;
		}
	}

	avi_out = NULL;
	conv_buf = NULL;
	needs_raw = 0;
	test = IF_GetKey(client.config, "General", "PluginsDirectory");
	client.plugins = NewPluginManager((const unsigned char *) test, client.config);
	strcpy(old_driv, "raw_out");
	if (!PM_GetPluginsCount(client.plugins)) {
		printf("Error: no plugins found\n");
		goto err_exit;
	}

	/*switch driver to raw_driver*/
	test = IF_GetKey(client.config, "Video", "DriverName");
	if (test) strcpy(old_driv, test);

	test = IF_GetKey(client.config, "Rendering", "RendererName");
	/*since we only support RGB24 for MP42AVI force using RAW out with 2D driver*/
	if (test && strstr(test, "2D")) {
		IF_SetKey(client.config, "Video", "DriverName", "raw_out");
		needs_raw = 1;
	}

	b2v.sr = NewSceneRender(&client, 0, 1, NULL);
	SR_SetOption(b2v.sr, M4O_Visible, 0);

	b2v.sg = NewSceneGraph();
	SG_SetSceneTimeCallback(b2v.sg, get_scene_time, &b2v);
	SG_SetInitCallback(b2v.sg, node_init, &b2v);
	SG_SetModifiedCallback(b2v.sg, node_modif, &b2v);

	/*load config*/
	SR_SetOption(b2v.sr, M4O_ReloadConfig, 1);

	b2v.bifs = BIFS_NewDecoder(b2v.sg, 0);
	BIFS_SetClock(b2v.bifs, get_scene_time, &b2v);

	if (needs_raw) {
		test = IF_GetKey(client.config, "Video", "DriverName");
		if (stricmp(test, "raw_out") && stricmp(test, "Raw Video Output")) {
			printf("couldn't load raw output driver (%s used)\n", test);
			goto err_exit;
		}
	}

	strcpy(config_path, "");
	if (out_dir) {
		strcat(config_path, out_dir);
		if (config_path[strlen(config_path)-1] != '\\') strcat(config_path, "\\");
	}
	strcat(config_path, rad_name);
	strcat(config_path, "_bifs");
	if (!dump_type) {
		strcat(config_path, ".avi");
		avi_out = AVI_open_output_file(config_path);
		comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0;
		if (!avi_out) goto err_exit;
	}


	for (i=0; i<M4_GetTrackCount(file); i++) {
		esd = M4_GetStreamDescriptor(file, i+1, 1);
		if (!esd) continue;
		if (!esd->dependsOnESID && (esd->decoderConfig->streamType == M4ST_SCENE)) break;
		OD_DeleteDescriptor((Descriptor **) &esd);
	}
	if (!esd) {
		printf("no bifs track found\n");
		goto err_exit;
	}

	b2v.duration = (u32) M4_GetMediaDuration(file, i+1);
	timescale = M4_GetMediaTimeScale(file, i+1);
	es_id = (u16) M4_GetTrackID(file, i+1);

	e = BIFS_ConfigureStream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);

	if (e) {
		printf("BIFS init error %s\n", M4ErrToString(e));
		OD_DeleteDescriptor((Descriptor **) &esd);
		goto err_exit;
	}
	if (dump_time>=0) dump_time = dump_time *1000 / timescale;

	SR_SetSceneGraph(b2v.sr, b2v.sg);
	count = M4_GetSampleCount(file, i+1);

	reset_fps = 0;
	if (!fps) { 
		fps = (Float) (count * timescale);
		fps /= b2v.duration;
		printf("Estimated BIFS FrameRate %g\n", fps);
		reset_fps = 1;
	}

	if (!width || !height) {
		SG_GetSizeInfo(b2v.sg, &width, &height);
	}
	/*we work in RGB24, and we must make sure the pitch is %4*/
	if ((width*3)%4) {
		printf("Adjusting width (%d) to have a stride multiple of 4\n", width);
		while ((width*3)%4) width--;
	}

	SR_SetSize(b2v.sr, width, height);

	SR_GetScreenBuffer(b2v.sr, &fb);
	width = fb.width;
	height = fb.height;
	if (avi_out) {
		AVI_set_video(avi_out, width, height, fps, comp);
		conv_buf = malloc(sizeof(char) * width * height * 3);
	}
	printf("Dumping at BIFS resolution %d x %d\n\n", width, height);
	SR_ReleaseScreenBuffer(b2v.sr, &fb);

	cur_time = 0;

	duration = 1 / fps;
	if (reset_fps) fps = 0;

	frameNum = 1;
	first_dump = 1;
	N = 0;
	for (j=0; j<count+N; j++) {
		if(j < count)
		{
			M4Sample *samp = M4_GetSample(file, i+1, j+1, &di);

			b2v.cts = samp->DTS + samp->CTS_Offset;
			/*apply command*/
			BIFS_DecodeAU(b2v.bifs, es_id, samp->data, samp->dataLength);
			M4_DeleteSample(&samp);

			if ((frameID>=0) && (j<(u32)frameID)) continue;
			if ((dump_time>=0) && ((u32) dump_time>b2v.cts)) continue;
		}
		/*render frame*/
		SR_RenderFrame(b2v.sr);
		/*needed for background2D !!*/
		if (first_dump) {
			SR_RenderFrame(b2v.sr);
			first_dump = 0;
		}

		if (fps) {
			Float bifs_time = (Float) b2v.cts;
			bifs_time /= timescale;
			if (cur_time > bifs_time) continue;

			while (1) {
				printf("dumped frame time %g (frame %d - sample %d)\r", cur_time, frameNum, j+1);
				dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, frameNum);
				frameNum++;
				cur_time += duration;
				if (cur_time > bifs_time) break;
			}
		} else {
			dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, (frameID>=0) ? frameID : frameNum);
			if (frameID>=0 || dump_time>=0) break;
			frameNum++;
			printf("dumped frame %d / %d\r", j+1, count);
		}

	}
	OD_DeleteDescriptor((Descriptor **) &esd);

	/*destroy everything*/
	BIFS_DeleteDecoder(b2v.bifs);
	SG_Delete(b2v.sg);
	SR_SetSceneGraph(b2v.sr, NULL);
	SR_Delete(b2v.sr);

err_exit:
	if (avi_out) AVI_close(avi_out);
	if (conv_buf) free(conv_buf);
	if (client.plugins) PM_Delete(client.plugins);
	if (needs_raw) IF_SetKey(client.config, "Video", "DriverName", old_driv);
	IF_Delete(client.config);
}
Ejemplo n.º 7
0
Archivo: main.c Proyecto: Bevara/GPAC
void bifs_to_vid(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, char *rad_name, u32 dump_type, char *out_dir, Double fps, s32 frameID, s32 dump_time)
{
	GF_User user;
	BIFSVID b2v;
	u16 es_id;
	Bool first_dump, needs_raw;
	u32 i, j, di, count, timescale, frameNum;
	u32 duration, cur_time;
	GF_VideoSurface fb;
	GF_Err e;
	char old_driv[1024];
	const char *test;
	char config_path[GF_MAX_PATH];
	avi_t *avi_out;
	Bool reset_fps;
	GF_ESD *esd;
	char comp[5];
	char *conv_buf;

	memset(&user, 0, sizeof(GF_User));
	if (szConfigFile && strlen(szConfigFile)) {
		user.config = gf_cfg_init(config_path, NULL);
	} else {
		user.config = gf_cfg_init(NULL, NULL);
	}

	if (!user.config) {
		fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path);
		return;
	}
	avi_out = NULL;
	conv_buf = NULL;
	esd = NULL;
	needs_raw = 0;
	test = gf_cfg_get_key(user.config, "General", "ModulesDirectory");
	user.modules = gf_modules_new((const unsigned char *) test, user.config);
	strcpy(old_driv, "raw_out");
	if (!gf_modules_get_count(user.modules)) {
		printf("Error: no modules found\n");
		goto err_exit;
	}

	/*switch driver to raw_driver*/
	test = gf_cfg_get_key(user.config, "Video", "DriverName");
	if (test) strcpy(old_driv, test);

	test = gf_cfg_get_key(user.config, "Compositor", "RendererName");
	/*since we only support RGB24 for MP42AVI force using RAW out with 2D driver*/
	if (test && strstr(test, "2D")) {
		gf_cfg_set_key(user.config, "Video", "DriverName", "Raw Video Output");
		needs_raw = 1;
	}

	needs_raw = 0;
	user.init_flags = GF_TERM_NO_AUDIO | GF_TERM_FORCE_3D;
	b2v.sr = gf_sc_new(&user, 0, NULL);
	gf_sc_set_option(b2v.sr, GF_OPT_VISIBLE, 0);

	b2v.sg = gf_sg_new();
	gf_sg_set_scene_time_callback(b2v.sg, get_scene_time, &b2v);
	gf_sg_set_init_callback(b2v.sg, node_init, &b2v);
	gf_sg_set_modified_callback(b2v.sg, node_modif, &b2v);

	/*load config*/
	gf_sc_set_option(b2v.sr, GF_OPT_RELOAD_CONFIG, 1);

	b2v.bifs = gf_bifs_decoder_new(b2v.sg, 0);

	if (needs_raw) {
		test = gf_cfg_get_key(user.config, "Video", "DriverName");
		if (stricmp(test, "raw_out") && stricmp(test, "Raw Video Output")) {
			printf("couldn't load raw output driver (%s used)\n", test);
			goto err_exit;
		}
	}

	strcpy(config_path, "");
	if (out_dir) {
		strcat(config_path, out_dir);
		if (config_path[strlen(config_path)-1] != '\\') strcat(config_path, "\\");
	}
	strcat(config_path, rad_name);
	strcat(config_path, "_bifs");
	if (!dump_type) {
		strcat(config_path, ".avi");
		avi_out = AVI_open_output_file(config_path);
		comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0;
		if (!avi_out) goto err_exit;
	}


	for (i=0; i<gf_isom_get_track_count(file); i++) {
		esd = gf_isom_get_esd(file, i+1, 1);
		if (!esd) continue;
		if (!esd->dependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break;
		gf_odf_desc_del((GF_Descriptor *) esd);
		esd = NULL;
	}
	if (!esd) {
		printf("no bifs track found\n");
		goto err_exit;
	}

	b2v.duration = gf_isom_get_media_duration(file, i+1);
	timescale = gf_isom_get_media_timescale(file, i+1);
	es_id = (u16) gf_isom_get_track_id(file, i+1);
	e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);
	if (e) {
		printf("BIFS init error %s\n", gf_error_to_string(e));
		gf_odf_desc_del((GF_Descriptor *) esd);
		esd = NULL;
		goto err_exit;
	}
	if (dump_time>=0) dump_time = dump_time *1000 / timescale;

	gf_sc_set_scene(b2v.sr, b2v.sg);
	count = gf_isom_get_sample_count(file, i+1);

	reset_fps = 0;
	if (!fps) {
		fps = (Float) (count * timescale);
		fps /= (Double) (s64) b2v.duration;
		printf("Estimated BIFS FrameRate %g\n", fps);
		reset_fps = 1;
	}

	if (!width || !height) {
		gf_sg_get_scene_size_info(b2v.sg, &width, &height);
	}
	/*we work in RGB24, and we must make sure the pitch is %4*/
	if ((width*3)%4) {
		printf("Adjusting width (%d) to have a stride multiple of 4\n", width);
		while ((width*3)%4) width--;
	}

	gf_sc_set_size(b2v.sr, width, height);
	gf_sc_draw_frame(b2v.sr);

	gf_sc_get_screen_buffer(b2v.sr, &fb);
	width = fb.width;
	height = fb.height;
	if (avi_out) {
		AVI_set_video(avi_out, width, height, fps, comp);
		conv_buf = gf_malloc(sizeof(char) * width * height * 3);
	}
	printf("Dumping at BIFS resolution %d x %d\n\n", width, height);
	gf_sc_release_screen_buffer(b2v.sr, &fb);

	cur_time = 0;

	duration = (u32)(timescale / fps);
	if (reset_fps) fps = 0;

	frameNum = 1;
	first_dump = 1;
	for (j=0; j<count; j++) {
		GF_ISOSample *samp = gf_isom_get_sample(file, i+1, j+1, &di);

		b2v.cts = samp->DTS + samp->CTS_Offset;
		/*apply command*/
		gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0);
		gf_isom_sample_del(&samp);

		if ((frameID>=0) && (j<(u32)frameID)) continue;
		if ((dump_time>=0) && ((u32) dump_time>b2v.cts)) continue;
		/*render frame*/
		gf_sc_draw_frame(b2v.sr);
		/*needed for background2D !!*/
		if (first_dump) {
			gf_sc_draw_frame(b2v.sr);
			first_dump = 0;
		}

		if (fps) {
			if (cur_time > b2v.cts) continue;

			while (1) {
				printf("dumped frame time %f (frame %d - sample %d)\r", ((Float)cur_time)/timescale, frameNum, j+1);
				dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, frameNum);
				frameNum++;
				cur_time += duration;
				if (cur_time > b2v.cts) break;
			}
		} else {
			dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, (frameID>=0) ? frameID : frameNum);
			if (frameID>=0 || dump_time>=0) break;
			frameNum++;
			printf("dumped frame %d / %d\r", j+1, count);
		}

	}
	gf_odf_desc_del((GF_Descriptor *) esd);

	/*destroy everything*/
	gf_bifs_decoder_del(b2v.bifs);
	gf_sg_del(b2v.sg);
	gf_sc_set_scene(b2v.sr, NULL);
	gf_sc_del(b2v.sr);

err_exit:
	if (avi_out) AVI_close(avi_out);
	if (conv_buf) gf_free(conv_buf);
	if (user.modules) gf_modules_del(user.modules);
	if (needs_raw) gf_cfg_set_key(user.config, "Video", "DriverName", old_driv);
	gf_cfg_del(user.config);
}
Ejemplo 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);
}
Ejemplo n.º 9
0
static Bool start_if_needed(GF_AVRedirect *avr) {
    enum PixelFormat pxlFormatForCodec = PIX_FMT_YUV420P;
    if (avr->is_open)
        return 0;
    gf_mx_p(avr->frameMutex);
    if (avr->is_open) {
        gf_mx_v(avr->frameMutex);
        return 0;
    }
	if (!avr->srcWidth || !avr->srcHeight
#if REDIRECT_AV_AUDIO_ENABLED
		|| !avr->audioSampleRate || !avr->audioChannels
#endif
		) {
        gf_mx_v(avr->frameMutex);
        return 3;
    }
#ifdef AVR_DUMP_RAW_AVI
    avr->avi_out = AVI_open_output_file ( "dump.avi" );
    if ( !avr->avi_out )
    {
        gf_mx_v(avr->frameMutex);
        GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error opening output AVI file\n" ) );
        return 4;
    }
#endif /* AVR_DUMP_RAW_AVI */
    GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Initializing...\n"));
    if (!avr->pcmAudio)
        avr->pcmAudio = gf_ringbuffer_new(32768);

    /* Setting up the video encoding ... */
    {
        avr->YUVpicture = avr->RGBpicture = NULL;
        avr->videoOutbuf = NULL;
#if REDIRECT_AV_AUDIO_ENABLED
        if ( !avr->audioCodec)
        {
            gf_mx_v(avr->frameMutex);
            GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find audio codec.\n" ) );
            return 1;
        }
#endif

        if ( !avr->videoCodec )
        {
            GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find video codec.\n" ) );
            return 2;
        }

        if (avr->videoCodec->id == CODEC_ID_MJPEG) {
            pxlFormatForCodec = PIX_FMT_YUVJ420P;
        }

        avr->RGBpicture = avcodec_alloc_frame();
        assert ( avr->RGBpicture );
        avr->RGBpicture->data[0] = NULL;
        avr->YUVpicture = avcodec_alloc_frame();
        assert ( avr->YUVpicture );
        {
            u32 sz = sizeof ( uint8_t ) * avpicture_get_size ( pxlFormatForCodec, avr->srcWidth, avr->srcHeight );
            avr->yuv_data = av_malloc ( sz ); /* size for YUV 420 */
            assert ( avr->yuv_data );
            memset ( avr->yuv_data, 0, sz );
            avpicture_fill ( ( AVPicture* ) avr->YUVpicture, avr->yuv_data, pxlFormatForCodec, avr->srcWidth, avr->srcHeight );
            avr->YUVpicture->coded_picture_number = 0;
        }
        avr->videoOutbufSize = avr->srcHeight * avr->srcWidth * 4;
        avr->videoOutbuf = gf_malloc ( avr->videoOutbufSize );
        memset ( avr->videoOutbuf, 0, avr->videoOutbufSize );
    }
#ifdef AVR_DUMP_RAW_AVI
    GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Open output AVI file %s\n", "dump.avi" ) );
#endif /* AVR_DUMP_RAW_AVI */
    /* Setting up the TS mux */
    {
        /*
          GF_Socket * ts_output_udp_sk = gf_sk_new ( GF_SOCK_TYPE_UDP );
          if ( gf_sk_is_multicast_address ( avr->udp_address ) )
          {
              e = gf_sk_setup_multicast ( ts_output_udp_sk, avr->udp_address, avr->udp_port, 0, 0, NULL );
          }
          else
          {
              e = gf_sk_bind ( ts_output_udp_sk, NULL, avr->udp_port, avr->udp_address, avr->udp_port, GF_SOCK_REUSE_PORT );
          }
          gf_sk_set_buffer_size(ts_output_udp_sk, 0, 188 * TS_PACKETS_PER_UDP_PACKET);
          gf_sk_set_block_mode(ts_output_udp_sk, 0);*/
        assert( avr->destination );
        avr->ts_implementation = ts_amux_new(avr, VIDEO_RATE, avr->srcWidth, avr->srcHeight, audioCodecBitrate);
    }
    /*
        if ( e )
        {
            GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while initializing UDP address %s\n", gf_error_to_string ( e ) ) );
            return e;
        }
    */
    avr->is_open = avr->ts_implementation != NULL;
    gf_mx_v(avr->frameMutex);
    return avr->is_open ? 1 : 0;
}
Ejemplo n.º 10
0
evid_handler_t *evid_create_handler(frame_par_t *frame_par, evid_xvidpar_t *evid_xvidpar, double framerate, char *filename, char **errstr) {
  xvid_enc_create_t xvid_enc_create;
  handler_t *handler;

  handler=(handler_t *)x_malloc(sizeof(handler_t));
  // frame_par
  memcpy(&(handler->frame_par), frame_par, sizeof(frame_par_t));
  // xvid_par
  memcpy(&(handler->evid_xvidpar), evid_xvidpar, sizeof(evid_xvidpar_t));
  // sets file name
  handler->filename=(char *)x_malloc(strlen(filename)+1);
  strcpy(handler->filename, filename);

  // avilib
  if((handler->avilib.avi=AVI_open_output_file(filename))==NULL) {
    x_asprintf(errstr, "%s.\n", AVI_strerror());
    free(handler);
    return NULL;
  }

  AVI_set_video(handler->avilib.avi, frame_par->width, frame_par->height, framerate, "xvid");
  AVI_set_audio(handler->avilib.avi, 0, 44100, 16, WAVE_FORMAT_UNKNOWN);

  // xvid encoder
  memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
  xvid_enc_create.profile=XVID_PROFILE_S_L0; // XVID_PROFILE_AS_L4; // do not know abot this...
  xvid_enc_create.version=XVID_VERSION;
  xvid_enc_create.width=frame_par->width;
  xvid_enc_create.height=frame_par->height;
  xvid_enc_create.num_zones=0;
  xvid_enc_create.zones=NULL;
  xvid_enc_create.num_plugins=0;
  xvid_enc_create.plugins=NULL;
  xvid_enc_create.num_threads=0;
  xvid_enc_create.max_bframes=0;
  xvid_enc_create.global=0;
  xvid_enc_create.global|=XVID_GLOBAL_CLOSED_GOP;
  xvid_enc_create.fincr=1000;
  xvid_enc_create.fbase=(int)(framerate*1000);
  xvid_enc_create.max_key_interval=(int)(framerate*10);
  xvid_enc_create.frame_drop_ratio=0;
  xvid_enc_create.bquant_ratio=150;
  xvid_enc_create.bquant_offset=100;
  xvid_enc_create.min_quant[0]=2;
  xvid_enc_create.max_quant[0]=31;

  if(xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL)) {
    x_asprintf(errstr, "Error initializing XviD encore.\n");
    if(AVI_close(handler->avilib.avi)) {
      free((*errstr));
      x_asprintf(errstr, "Error initializing XviD encore / Error closing AVI file: %s.\n", AVI_strerror());
    }
    unlink(filename); // no error checking here
    free(handler);
    return NULL;
  }
  handler->xvid.handle=xvid_enc_create.handle;
  // bitstream
  handler->xvid.bitstream=x_malloc((size_t)(handler->frame_par.width*handler->frame_par.height*PALETTE_DEPTH));

  // errstr
  handler->errstr=NULL;
  return (evid_handler_t *)handler;
}
Ejemplo n.º 11
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);
}