Exemplo n.º 1
0
int
rename2 (const char *oldname, const char *newname)
{
  int retval;
  char dir1[FILENAME_MAX], dir2[FILENAME_MAX];
  struct stat fstate;

  dirname2 (oldname, dir1);
  dirname2 (newname, dir2);

  // We should use dirname{2}() in case oldname or newname doesn't exist yet
  if (one_filesystem (dir1, dir2))
    {
      if (access (newname, F_OK) == 0 && !one_file (oldname, newname))
        {
          stat (newname, &fstate);
          chmod (newname, fstate.st_mode | S_IWUSR);
          remove (newname);                     // *try* to remove or rename() will fail
        }
      retval = rename (oldname, newname);
    }
  else
    {
      retval = fcopy_raw (oldname, newname);
      // don't remove unless the file can be copied
      if (retval == 0)
        {
          stat (oldname, &fstate);
          chmod (oldname, fstate.st_mode | S_IWUSR);
          remove (oldname);
        }
    }

  return retval;
}
Exemplo n.º 2
0
char *
mkbak (const char *filename, backup_t type)
{
  static char buf[FILENAME_MAX];

  if (access (filename, R_OK) != 0)
    return (char *) filename;

  strcpy (buf, filename);
  set_suffix (buf, ".bak");
  if (strcmp (filename, buf) != 0)
    {
      remove (buf);                             // *try* to remove or rename() will fail
      if (rename (filename, buf))               // keep file attributes like date, etc.
        {
          fprintf (stderr, "ERROR: Can't rename \"%s\" to \"%s\"\n", filename, buf);
          exit (1);
        }
    }
  else // handle the case where filename has the suffix ".bak".
    {
      char buf2[FILENAME_MAX];

      if (!dirname2 (filename, buf))
        {
          fprintf (stderr, "INTERNAL ERROR: dirname2() returned NULL\n");
          exit (1);
        }
      if (buf[0] != 0)
        if (buf[strlen (buf) - 1] != FILE_SEPARATOR)
          strcat (buf, FILE_SEPARATOR_S);

      strcat (buf, basename2 (tmpnam2 (buf2)));
      if (rename (filename, buf))
        {
          fprintf (stderr, "ERROR: Can't rename \"%s\" to \"%s\"\n", filename, buf);
          exit (1);
        }
    }

  switch (type)
    {
    case BAK_MOVE:
      return buf;

    case BAK_DUPE:
    default:
      if (fcopy (buf, 0, fsizeof (buf), filename, "wb"))
        {
          fprintf (stderr, "ERROR: Can't open \"%s\" for writing\n", filename);
          exit (1);
        }
      sync ();
      return buf;
    }
}
Exemplo n.º 3
0
st_strpath_t *
strpath (st_strpath_t *path, const char *path_s)
{
// TODO: compare this with splitpath()
  if (path_s == NULL)
    return NULL;

  realpath2 (path_s, path->realpath);

#if     defined DJGPP || defined __CYGWIN__ || defined _WIN32
  if (isalpha (path->realpath[0]) &&
      path->realpath[1] == ':' &&
      path->realpath[2] == FILE_SEPARATOR)
    sprintf (path->drive, "%c:\\", toupper (path->realpath[0]));
#else
  strcpy (path->drive, FILE_SEPARATOR_S);
#endif

  dirname2 (path_s, path->dirname);
  strcpy (path->basename, basename2 (path_s));
  strcpy (path->suffix, get_suffix (path_s));

  return path;
}
Exemplo n.º 4
0
static VALUE segmenter_segment(VALUE klass, VALUE input_, VALUE output_prefix_, VALUE duration_ ) {

    const char *input;
    const char *output_prefix;
    int segment_duration;
    long max_tsfiles = 0;
    double prev_segment_time = 0;
    unsigned int output_index = 1;
    AVInputFormat *ifmt;
    AVOutputFormat *ofmt;
    AVFormatContext *ic = NULL;
    AVFormatContext *oc;
    AVStream *video_st;
    AVStream *audio_st;
    AVCodec *codec;
    char *output_filename;
    char *remove_filename;
    int video_index;
    int audio_index;
    unsigned int first_segment = 1;
    unsigned int last_segment = 0;
    int decode_done;
    int ret;
    unsigned int i;
    int remove_file;
    
	bool soundOnly = false;

    VALUE sArray = rb_ary_new();
    av_register_all();
    av_log_set_level(AV_LOG_PANIC);

    input = RSTRING_PTR(input_);
    output_prefix = RSTRING_PTR(output_prefix_);
    segment_duration = (FIX2INT(duration_));
	
    char *folder = dirname2(strdup(input));
    
    remove_filename = malloc(sizeof(char) * (strlen(output_prefix) + 15));
    if (!remove_filename) {
        rb_raise(rb_eNoMemError, "Could not allocate space for remove filenames");
    }
    
    output_filename = malloc(sizeof(char) * (strlen(output_prefix) + strlen(folder) + 15));
    if (!output_filename) {
        rb_raise(rb_eNoMemError, "Could not allocate space for output filenames");
    }
    
        
    ifmt = av_find_input_format("mpegts");
    if (!ifmt) {
        rb_raise(rb_eException, "Could not find MPEG-TS demuxer");
    }
    
    ret = av_open_input_file(&ic, input, ifmt, 0, NULL);
    if (ret != 0) {
        rb_raise(rb_eException, "Could not open input file, make sure it is an mpegts file: %d %s", ret, input);
    }
    
    if (av_find_stream_info(ic) < 0) {
        rb_raise(rb_eException, "Could not read stream information");
    }
    
    ofmt = av_guess_format("mpegts", NULL, NULL);
    if (!ofmt) {
        rb_raise(rb_eException, "Could not find MPEG-TS muxer");
    }
    
    oc = avformat_alloc_context();
    if (!oc) {
        rb_raise(rb_eException, "Could not allocated output context");
    }
    oc->oformat = ofmt;

    ic->flags |= AVFMT_FLAG_IGNDTS;
    
    video_index = -1;
    audio_index = -1;
    
    for (i = 0; i < ic->nb_streams && (video_index < 0 || audio_index < 0); i++) {
        switch (ic->streams[i]->codec->codec_type) {
            case CODEC_TYPE_VIDEO:
                video_index = i;
                ic->streams[i]->discard = AVDISCARD_NONE;
                video_st = add_output_stream(oc, ic->streams[i]);
                break;
            case CODEC_TYPE_AUDIO:
                audio_index = i;
                ic->streams[i]->discard = AVDISCARD_NONE;
                audio_st = add_output_stream(oc, ic->streams[i]);
                break;
            default:
                ic->streams[i]->discard = AVDISCARD_ALL;
                break;
        }
    }

	if(!soundOnly) {
		soundOnly = (video_st != NULL);
	}

    if (av_set_parameters(oc, NULL) < 0) {
        rb_raise(rb_eException, "Invalid output format parameters");
    }
    
    dump_format(oc, 0, output_prefix, 1);



	if (!soundOnly) {
		if(video_st == NULL) {
			fprintf(stderr, "video_st is fail\n");
			rb_raise(rb_eException, "video_st fail");
			exit(1);
		}

		if(video_st->codec == NULL) {
			fprintf(stderr,"codec is fail\n");
			rb_raise(rb_eException, "codec fail");
			exit(1);
		}

		if(video_st->codec->codec_id == NULL) {
			fprintf(stderr, "codec_id is fail\n");
			rb_raise(rb_eException, "codec fail");
			exit(1);
		}

		codec = avcodec_find_decoder(video_st->codec->codec_id);
	    if (!codec) {
	        rb_raise(rb_eException, "Could not find video decoder, key frames will not be honored");
	    }
		
	    if (avcodec_open(video_st->codec, codec) < 0) {
	        rb_raise(rb_eException, "Could not open video decoder, key frames will not be honored");
	    }
    
    
	    if (video_st->codec->ticks_per_frame > 1) {
	        // h264 sets the ticks_per_frame and time_base.den but not time_base.num
	        // since we don't use ticks_per_frame, adjust time_base.num accordingly.
	        video_st->codec->time_base.num *= video_st->codec->ticks_per_frame;
	    }
	}
    
    snprintf(output_filename, strlen(output_prefix) + strlen(folder) + 15, "%s/%s-%u.ts", folder, output_prefix, output_index++);
    if (url_fopen(&oc->pb, output_filename, URL_WRONLY) < 0) {
        rb_raise(rb_eException, "Could not open '%s'", output_filename);
    }
    
    if (av_write_header(oc)) {
        rb_raise(rb_eException, "Could not write mpegts header to first output file");
    }
    
    //write_index = !write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, last_segment, 0, max_tsfiles);
    int64_t initial_audio_pts = -1;
    int64_t initial_video_pts = -1;
	double segment_time;
    do {
		
        AVPacket packet;
        //av_init_packet(&packet);
        decode_done = av_read_frame(ic, &packet);
        if (decode_done < 0) {
            break;
        }
        
        if (av_dup_packet(&packet) < 0) {
            rb_raise(rb_eException, "Could not duplicate packet");
            av_free_packet(&packet);
            break;
        }
		
		if (!soundOnly) {
	        if (packet.stream_index == video_index) {
	            if (initial_video_pts < 0) 
					initial_video_pts = packet.pts;
					
	            packet.pts -= initial_video_pts;
	            packet.dts = packet.pts;
	            if (packet.flags & AV_PKT_FLAG_KEY) {
	                segment_time = (double)packet.pts * video_st->time_base.num / video_st->time_base.den;
	            } else {
	                segment_time = prev_segment_time;            }
	        } else if (packet.stream_index == audio_index) {
	            if (initial_audio_pts < 0) initial_audio_pts = packet.pts;
	            packet.pts -= initial_audio_pts;
	            packet.dts = packet.pts;
	            segment_time = prev_segment_time;
	        } else {
	            segment_time = prev_segment_time;
	            segment_time = prev_segment_time;
	        }			
		} else {

			if (packet.stream_index == audio_index) {
				
	            if (initial_audio_pts < 0) 
					initial_audio_pts = packet.pts;
				
				if (packet.flags & AV_PKT_FLAG_KEY) {
					segment_time = (double)packet.pts * audio_st->time_base.num / audio_st->time_base.den;
				} else {
	            	segment_time = prev_segment_time;	
				}
					
	            packet.pts -= initial_audio_pts;
	            packet.dts = packet.pts;

	        } else {
	            segment_time = prev_segment_time;
	            segment_time = prev_segment_time;
	        }
		
		}



        if (segment_time - prev_segment_time >= segment_duration) {
            put_flush_packet(oc->pb);
            url_fclose(oc->pb);
            
            if (max_tsfiles && (int)(last_segment - first_segment) >= max_tsfiles - 1) {
                remove_file = 1;
                first_segment++;
            }
            else {
                remove_file = 0;
            }
            
            
            // Create Segment object
            VALUE seg = rb_obj_alloc(rb_cAvSegment);            

            rb_obj_call_init(seg, 0, 0);
            rb_iv_set(seg, "@index", INT2FIX(++last_segment));
            rb_iv_set(seg, "@duration",INT2FIX((int)floor((segment_time - prev_segment_time))));
            rb_iv_set(seg, "@filename", rb_str_new2(output_filename));
            
            rb_ary_push(sArray, seg);
            
            if (remove_file) {
                snprintf(remove_filename, strlen(output_prefix) + strlen(folder) + 15, "%s/%s-%u.ts", folder, output_prefix, first_segment - 1);
                //snprintf(remove_filename, strlen(output_prefix) + 15, "%s-%u.ts", output_prefix, first_segment - 1);
                remove(remove_filename);
            }
            
//            snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts", output_prefix, output_index++);
            snprintf(output_filename, strlen(output_prefix) + strlen(folder) + 15, "%s/%s-%u.ts", folder, output_prefix, output_index++);
            if (url_fopen(&oc->pb, output_filename, URL_WRONLY) < 0) {
                fprintf(stderr, "Could not open '%s'\n", output_filename);
                break;
            }
            
            prev_segment_time = segment_time;
        }

        ret = av_interleaved_write_frame(oc, &packet);
        if (ret < 0) {
            fprintf(stderr, "Warning: Could not write frame of stream\n");
        }
        else if (ret > 0) {
            fprintf(stderr, "End of stream requested\n");
            av_free_packet(&packet);
            break;
        }
        
        av_free_packet(&packet);
    } while (!decode_done);

    av_write_trailer(oc);

	if (!soundOnly)
    	avcodec_close(video_st->codec);

    for(i = 0; i < oc->nb_streams; i++) {		
		if(&oc->streams[i]->codec != NULL)
        	av_freep(&oc->streams[i]->codec);

		if (&oc->streams[i] != NULL)
        	av_freep(&oc->streams[i]);
    }

    url_fclose(oc->pb);
    av_free(oc);
    
    if (max_tsfiles && (int)(last_segment - first_segment) >= max_tsfiles - 1) {
        remove_file = 1;
        first_segment++;
    }
    else {
        remove_file = 0;
    }
 
    if (remove_file) {
        snprintf(remove_filename, strlen(output_prefix) + strlen(folder) + 15, "%s/%s-%u.ts", folder, output_prefix, first_segment - 1);
        remove(remove_filename);
    }
    return sArray;
}