Example #1
0
static void encode_2pass_prepare(struct encode_lavc_context *ctx,
                                 AVDictionary **dictp,
                                 AVStream *stream,
                                 AVCodecContext *codec,
                                 struct stream **bytebuf,
                                 const char *prefix)
{
    if (!*bytebuf) {
        char buf[sizeof(ctx->avc->filename) + 12];
        AVDictionaryEntry *de = av_dict_get(ctx->voptions, "flags", NULL, 0);

        snprintf(buf, sizeof(buf), "%s-%s-pass1.log", ctx->avc->filename,
                 prefix);
        buf[sizeof(buf) - 1] = 0;

        if (value_has_flag(de ? de->value : "", "pass2")) {
            if (!(*bytebuf = stream_open(buf, ctx->global))) {
                MP_WARN(ctx, "%s: could not open '%s', "
                       "disabling 2-pass encoding at pass 2\n", prefix, buf);
                codec->flags &= ~AV_CODEC_FLAG_PASS2;
                set_to_avdictionary(ctx, dictp, "flags", "-pass2");
            } else {
                struct bstr content = stream_read_complete(*bytebuf, NULL,
                                                           1000000000);
                if (content.start == NULL) {
                    MP_WARN(ctx, "%s: could not read '%s', "
                           "disabling 2-pass encoding at pass 1\n",
                           prefix, ctx->avc->filename);
                } else {
                    content.start[content.len] = 0;
                    codec->stats_in = content.start;
                }
                free_stream(*bytebuf);
                *bytebuf = NULL;
            }
        }

        if (value_has_flag(de ? de->value : "", "pass1")) {
            if (!(*bytebuf = open_output_stream(buf, ctx->global))) {
                MP_WARN(ctx,
                    "%s: could not open '%s', disabling "
                    "2-pass encoding at pass 1\n",
                    prefix, ctx->avc->filename);
                set_to_avdictionary(ctx, dictp, "flags", "-pass1");
            }
        }
    }
}
Example #2
0
static bool open_this_file(int i,char *outfilename,progress_info *proginfo)
{
  unsigned char header[CANONICAL_HEADER_SIZE];

  create_output_filename(files[i]->filename,files[i]->input_format->extension,outfilename);

  proginfo->filename1 = files[i]->filename;
  proginfo->filedesc1 = files[i]->m_ss;
  proginfo->filename2 = outfilename;

  if (NULL == (files[i]->output = open_output_stream(outfilename,&files[i]->output_proc))) {
    prog_error(proginfo);
    st_error("could not open output file: [%s]",outfilename);
  }

  make_canonical_header(header,files[i]);

  if ((numfiles - 1 == i) && pad)
    put_data_size(header,CANONICAL_HEADER_SIZE,files[i]->new_data_size+pad_bytes);
  else {
    put_data_size(header,CANONICAL_HEADER_SIZE,files[i]->new_data_size);
    if (files[i]->new_data_size & 1)
      put_chunk_size(header,(files[i]->new_data_size + 1) + CANONICAL_HEADER_SIZE - 8);
  }

  if (write_n_bytes(files[i]->output,header,CANONICAL_HEADER_SIZE,proginfo) != CANONICAL_HEADER_SIZE) {
    prog_error(proginfo);
    st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE);
    return FALSE;
  }

  proginfo->filename2 = outfilename;
  proginfo->bytes_total = files[i]->new_data_size + CANONICAL_HEADER_SIZE;

  return TRUE;
}
Example #3
0
static bool do_join()
{
  int i,bytes_to_skip,bytes_to_xfer;
  proc_info output_proc;
  char outfilename[FILENAME_SIZE];
  wlong total=0;
  unsigned char header[CANONICAL_HEADER_SIZE];
  FILE *output;
  wave_info *joined_info;
  bool success;
  progress_info proginfo;

  success = FALSE;

  create_output_filename("","",outfilename);

  for (i=0;i<numfiles;i++)
    total += files[i]->data_size;

  if (all_files_cd_quality && (total % CD_BLOCK_SIZE) != 0) {
    pad_bytes = CD_BLOCK_SIZE - (total % CD_BLOCK_SIZE);
    if (JOIN_NOPAD != pad_type)
      total += pad_bytes;
  }

  if (NULL == (joined_info = new_wave_info(NULL))) {
    st_error("could not allocate memory for joined file information");
  }

  joined_info->chunk_size = total + CANONICAL_HEADER_SIZE - 8;
  joined_info->channels = files[0]->channels;
  joined_info->samples_per_sec = files[0]->samples_per_sec;
  joined_info->avg_bytes_per_sec = files[0]->avg_bytes_per_sec;
  joined_info->rate = files[0]->rate;
  joined_info->block_align = files[0]->block_align;
  joined_info->bits_per_sample = files[0]->bits_per_sample;
  joined_info->data_size = total;
  joined_info->wave_format = files[0]->wave_format;
  joined_info->problems = (files[0]->problems & PROBLEM_NOT_CD_QUALITY);

  if (PROB_ODD_SIZED_DATA(joined_info))
    joined_info->chunk_size++;

  joined_info->total_size = joined_info->chunk_size + 8;
  joined_info->length = joined_info->data_size / joined_info->rate;
  joined_info->exact_length = (double)joined_info->data_size / (double)joined_info->rate;

  length_to_str(joined_info);

  proginfo.initialized = FALSE;
  proginfo.prefix = "Joining";
  proginfo.clause = "-->";
  proginfo.filename1 = files[0]->filename;
  proginfo.filedesc1 = files[0]->m_ss;
  proginfo.filename2 = outfilename;
  proginfo.filedesc2 = joined_info->m_ss;
  proginfo.bytes_total = files[0]->total_size;

  prog_update(&proginfo);

  if (NULL == (output = open_output_stream(outfilename,&output_proc))) {
    st_error("could not open output file");
  }

  make_canonical_header(header,joined_info);

  if (write_n_bytes(output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) {
    prog_error(&proginfo);
    st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE);
    goto cleanup;
  }

  if (all_files_cd_quality && (JOIN_PREPAD == pad_type) && pad_bytes) {
    if (pad_bytes != write_padding(output,pad_bytes,&proginfo)) {
      prog_error(&proginfo);
      st_warning("error while pre-padding with %d zero-bytes",pad_bytes);
      goto cleanup;
    }
  }

  for (i=0;i<numfiles;i++) {
    proginfo.bytes_total = files[i]->total_size;
    proginfo.filename1 = files[i]->filename;
    proginfo.filedesc1 = files[i]->m_ss;
    prog_update(&proginfo);

    if (!open_input_stream(files[i])) {
      prog_error(&proginfo);
      st_warning("could not reopen input file");
      goto cleanup;
    }

    bytes_to_skip = files[i]->header_size;

    while (bytes_to_skip > 0) {
      bytes_to_xfer = min(bytes_to_skip,CANONICAL_HEADER_SIZE);
      if (read_n_bytes(files[i]->input,header,bytes_to_xfer,NULL) != bytes_to_xfer) {
        prog_error(&proginfo);
        st_warning("error while reading %d bytes of data",bytes_to_xfer);
        goto cleanup;
      }
      bytes_to_skip -= bytes_to_xfer;
    }

    if (transfer_n_bytes(files[i]->input,output,files[i]->data_size,&proginfo) != files[i]->data_size) {
      prog_error(&proginfo);
      st_warning("error while transferring %lu bytes of data",files[i]->data_size);
      goto cleanup;
    }

    prog_success(&proginfo);

    close_input_stream(files[i]);
  }

  if (all_files_cd_quality && JOIN_POSTPAD == pad_type && pad_bytes) {
    if (pad_bytes != write_padding(output,pad_bytes,NULL)) {
      prog_error(&proginfo);
      st_warning("error while post-padding with %d zero-bytes",pad_bytes);
      goto cleanup;
    }
  }

  if ((JOIN_NOPAD == pad_type) && PROB_ODD_SIZED_DATA(joined_info) && (1 != write_padding(output,1,NULL))) {
    prog_error(&proginfo);
    st_warning("error while NULL-padding odd-sized data chunk");
    goto cleanup;
  }

  if (all_files_cd_quality) {
    if (JOIN_NOPAD != pad_type) {
      if (pad_bytes)
        st_info("%s-padded output file with %d zero-bytes.\n",((JOIN_PREPAD == pad_type)?"Pre":"Post"),pad_bytes);
      else
        st_info("No padding needed.\n");
    }
    else {
      st_info("Output file was not padded, ");
      if (pad_bytes)
        st_info("though it needs %d bytes of padding.\n",pad_bytes);
      else
        st_info("nor was it needed.\n");
    }
  }

  success = TRUE;

cleanup:
  if ((CLOSE_CHILD_ERROR_OUTPUT == close_output(output,output_proc)) || !success) {
    success = FALSE;
    remove_file(outfilename);
    st_error("failed to join files");
  }

  return success;
}
static bool split_file(wave_info *info)
{
  unsigned char header[CANONICAL_HEADER_SIZE];
  char outfilename[FILENAME_SIZE],filenum[FILENAME_SIZE];
  int current;
  wint discard,bytes;
  bool success;
  wlong leadin_bytes, leadout_bytes, bytes_to_xfer;
  progress_info proginfo;
 
  // uwe
  double start_time, end_time, last_end_time;	
  
	
  success = FALSE;

  proginfo.initialized = FALSE;
  proginfo.prefix = "Splitting";
  proginfo.clause = "-->";
  proginfo.filename1 = info->filename;
  proginfo.filedesc1 = info->m_ss;
  proginfo.filename2 = NULL;
  proginfo.filedesc2 = NULL;
  proginfo.bytes_total = 0;

  if (!open_input_stream(info)) {
    prog_error(&proginfo);
    st_error("could not reopen input file: [%s]",info->filename);
  }

  discard = info->header_size;
  while (discard > 0) {
    bytes = min(discard,CANONICAL_HEADER_SIZE);
    if (read_n_bytes(info->input,header,bytes,NULL) != bytes) {
      prog_error(&proginfo);
      st_error("error while discarding %d-byte WAVE header",info->header_size);
    }
    discard -= bytes;
  }

  leadin_bytes = (leadin) ? smrt_parse((unsigned char *)leadin,info) : 0;
  leadout_bytes = (leadout) ? smrt_parse((unsigned char *)leadout,info) : 0;
  adjust_for_leadinout(leadin_bytes,leadout_bytes);

  // uwe transcription
  st_output("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
  st_output("<Trans version=\"2\">\n\n");
  start_time = end_time = last_end_time = 0;
	
  for (current=0;current<numfiles;current++) {
    if (SPLIT_INPUT_CUE == input_type && cueinfo.format) {
      create_output_filename(cueinfo.filenames[current],"",outfilename);
    }
    else {
      st_snprintf(filenum,8,num_format,current+offset);
      create_output_filename(filenum,"",outfilename);
    }

    files[current]->chunk_size = files[current]->data_size + CANONICAL_HEADER_SIZE - 8;
    files[current]->channels = info->channels;
    files[current]->samples_per_sec = info->samples_per_sec;
    files[current]->avg_bytes_per_sec = info->avg_bytes_per_sec;
    files[current]->block_align = info->block_align;
    files[current]->bits_per_sample = info->bits_per_sample;
    files[current]->wave_format = info->wave_format;
    files[current]->rate = info->rate;
    files[current]->length = files[current]->data_size / (wlong)info->rate;
    files[current]->exact_length = (double)files[current]->data_size / (double)info->rate;
    files[current]->total_size = files[current]->chunk_size + 8;

    length_to_str(files[current]);

    proginfo.filedesc2 = files[current]->m_ss;
    proginfo.bytes_total = files[current]->total_size;

    if (extract_track[current]) {
      proginfo.prefix = "Splitting";
      proginfo.filename2 = outfilename;

	  // uwe transcription
	  start_time += last_end_time;
	  end_time += files[current]->data_size / (wlong)info->rate;
	  last_end_time = end_time;
		
	  printf("<Turn startTime=\"%.2f\"", start_time); // %.2f
	  st_output(" endTime=\"%.2f\"", end_time);
	  st_output(" splitFilename=\"%s\"", outfilename);
	  st_output(" speaker=\"spk1\">\n");
	  st_output("<Sync time=\"%.2f\"/>\n", start_time);
	  st_output("***Include transcript words here***\n");
	  st_output("</Turn>\n");
		
      if (NULL == (files[current]->output = open_output_stream(outfilename,&files[current]->output_proc))) {
        prog_error(&proginfo);
        st_error("could not open output file");
      }
    }
    else {
      proginfo.prefix = "Skipping ";
      proginfo.filename2 = NULLDEVICE;

      if (NULL == (files[current]->output = open_output(NULLDEVICE))) {
        prog_error(&proginfo);
        st_error("while skipping track %d: could not open output file: [%s]",current+1,NULLDEVICE);
      }

      files[current]->output_proc.pid = NO_CHILD_PID;
    }

    if (PROB_ODD_SIZED_DATA(files[current]))
      files[current]->chunk_size++;

    make_canonical_header(header,files[current]);

	// uwe disable
    //prog_update(&proginfo);

    if (write_n_bytes(files[current]->output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) {
      prog_error(&proginfo);
      st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE);
      goto cleanup;
    }

    /* if this is not the first file, finish up writing previous file, and simultaneously start writing to current file */
    if (0 != current) {
      /* write overlapping lead-in/lead-out data to both previous and current files */
      if (transfer_n_bytes2(info->input,files[current]->output,files[current-1]->output,leadin_bytes+leadout_bytes,&proginfo) != leadin_bytes+leadout_bytes) {
        prog_error(&proginfo);
        st_warning("error while transferring %ld bytes of lead-in/lead-out",leadin_bytes+leadout_bytes);
        goto cleanup;
      }

      /* pad and close previous file */
      if (PROB_ODD_SIZED_DATA(files[current-1]) && (1 != write_padding(files[current-1]->output,1,&proginfo))) {
        prog_error(&proginfo);
        st_warning("error while NULL-padding odd-sized data chunk");
        goto cleanup;
      }

      close_output(files[current-1]->output,files[current-1]->output_proc);
    }

    /* transfer unique non-overlapping data from input file to current file */
    bytes_to_xfer = files[current]->new_data_size;
    if (0 != current)
      bytes_to_xfer -= leadout_bytes;
    if (numfiles - 1 != current)
      bytes_to_xfer -= leadin_bytes;

    if (transfer_n_bytes(info->input,files[current]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) {
      prog_error(&proginfo);
      st_warning("error while transferring %ld bytes of data",bytes_to_xfer);
      goto cleanup;
    }

    /* if this is the last file, close it */
    if (numfiles - 1 == current) {
      /* pad and close current file */
      if (PROB_ODD_SIZED_DATA(files[current]) && (1 != write_padding(files[current]->output,1,&proginfo))) {
        prog_error(&proginfo);
        st_warning("error while NULL-padding odd-sized data chunk");
        goto cleanup;
      }

      close_output(files[current]->output,files[current]->output_proc);

      // uwe transcription  
      st_output("</Trans>\n");

    }

	// uwe disable 
    // prog_success(&proginfo);
 
  }

  close_input_stream(info);

  success = TRUE;

cleanup:
  if (!success) {
    close_output(files[current]->output,files[current]->output_proc);
    remove_file(outfilename);
    st_error("failed to split file");
  }

  return success;
}
Example #5
0
SCM make_ffmpeg_output(SCM scm_file_name,
                       SCM scm_format_name,
                       SCM scm_video_parameters,
                       SCM scm_have_video,
                       SCM scm_audio_parameters,
                       SCM scm_have_audio,
                       SCM scm_debug)
{
  SCM retval;
  struct ffmpeg_t *self;
  scm_dynwind_begin(0);
  const char *file_name = scm_to_locale_string(scm_file_name);
  scm_dynwind_free(file_name);
  self = (struct ffmpeg_t *)scm_gc_calloc(sizeof(struct ffmpeg_t), "ffmpeg");
  self->video_stream_idx = -1;
  self->audio_stream_idx = -1;
  SCM_NEWSMOB(retval, ffmpeg_tag, self);

  int err;
  const char *format_name = NULL;
  if (!scm_is_false(scm_format_name)) {
    format_name = scm_to_locale_string(scm_symbol_to_string(scm_format_name));
    scm_dynwind_free(format_name);
  };
#ifdef HAVE_AVFORMAT_ALLOC_OUTPUT_CONTEXT2
  err = avformat_alloc_output_context2(&self->fmt_ctx, NULL, format_name, file_name);
  if (!self->fmt_ctx) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-output", "Error initializing output format for file '~a': ~a",
                   scm_list_2(scm_file_name, get_error_text(err)));
  };
#else
  AVOutputFormat *format;
  if (format_name)
    format = av_guess_format(format_name, NULL, NULL);
  else
    format = av_guess_format(NULL, file_name, NULL);
  if (!format) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-output", "Unable to determine file format for file '~a'",
                   scm_list_1(scm_file_name));
  };
  self->fmt_ctx = avformat_alloc_context();
  if (!self->fmt_ctx) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-output", "Error initializing output format for file '~a'",
                   scm_list_1(scm_file_name));
  };
  self->fmt_ctx->oformat = format;
  strncpy(self->fmt_ctx->filename, file_name, sizeof(self->fmt_ctx->filename));
#endif

  char have_video = scm_is_true(scm_have_video);
  if (have_video) {
    // Open codec and video stream
    enum AVCodecID video_codec_id = self->fmt_ctx->oformat->video_codec;
    AVCodec *video_encoder = find_encoder(retval, video_codec_id, "video");
    AVStream *video_stream = open_output_stream(retval, video_encoder, &self->video_stream_idx, "video", scm_file_name);

    // Get video parameters
    SCM scm_shape          = scm_car(scm_video_parameters);
    SCM scm_frame_rate     = scm_cadr(scm_video_parameters);
    SCM scm_video_bit_rate = scm_caddr(scm_video_parameters);
    SCM scm_aspect_ratio   = scm_cadddr(scm_video_parameters);

    // Configure the output video codec
    self->video_codec_ctx =
      configure_output_video_codec(video_stream, video_codec_id, scm_video_bit_rate, scm_shape, scm_frame_rate, scm_aspect_ratio);

    // Some formats want stream headers to be separate.
    if (self->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
        self->video_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

    // Open output video codec
    open_codec(retval, self->video_codec_ctx, video_encoder, "video", scm_file_name);

    // Allocate frame
    self->video_target_frame = allocate_output_video_frame(retval, self->video_codec_ctx);
  };

  char have_audio = scm_is_true(scm_have_audio);
  if (have_audio) {
    // Open audio codec and stream
    enum AVCodecID audio_codec_id = self->fmt_ctx->oformat->audio_codec;
    AVCodec *audio_encoder = find_encoder(retval, audio_codec_id, "audio");
    AVStream *audio_stream = open_output_stream(retval, audio_encoder, &self->audio_stream_idx, "audio", scm_file_name);

    // Get audio parameters
    SCM scm_select_rate    = scm_car(scm_audio_parameters);
    SCM scm_channels       = scm_cadr(scm_audio_parameters);
    SCM scm_audio_bit_rate = scm_caddr(scm_audio_parameters);
    SCM scm_select_format  = scm_cadddr(scm_audio_parameters);

    // Configure the output audio codec
    self->audio_codec_ctx =
      configure_output_audio_codec(retval, audio_stream, audio_codec_id,
                                   scm_select_rate, scm_channels, scm_audio_bit_rate, scm_select_format);

    // Some formats want stream headers to be separate.
    if (self->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
        self->audio_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

    // Open output audio codec
    open_codec(retval, self->audio_codec_ctx, audio_encoder, "audio", scm_file_name);

    // Allocate audio frame
    self->audio_target_frame =
      allocate_output_audio_frame(retval, self->audio_codec_ctx, self->audio_codec_ctx->sample_fmt);
    self->audio_packed_frame =
      allocate_output_audio_frame(retval, self->audio_codec_ctx, av_get_packed_sample_fmt(self->audio_codec_ctx->sample_fmt));

    // Initialise audio buffer
    ringbuffer_init(&self->audio_buffer, 1024);
  };

  if (scm_is_true(scm_debug)) av_dump_format(self->fmt_ctx, 0, file_name, 1);

  // Open the output file if needed
  if (!(self->fmt_ctx->oformat->flags & AVFMT_NOFILE)) {
    int err = avio_open(&self->fmt_ctx->pb, file_name, AVIO_FLAG_WRITE);
    if (err < 0) {
      ffmpeg_destroy(retval);
      scm_misc_error("make-ffmpeg-output", "Could not open '~a': ~a",
                     scm_list_2(scm_file_name, get_error_text(err)));
    }
    self->output_file = 1;
  }

  // Write video file header
  err = avformat_write_header(self->fmt_ctx, NULL);
  if (err < 0) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-output", "Error writing header of video '~a': ~a",
                   scm_list_2(scm_file_name, get_error_text(err)));
  };
  self->header_written = 1;

  scm_dynwind_end();
  return retval;
}