1

我似乎无法从我正在编写的 AVPacket.data 中获得任何有用的信息。它不会生成有效的视频文件,而且它们非常小。4Mb 转换为 ~300Kb。他们没有在玩,VLC 将他们的格式报告为“undf”(缺少标题?)。我被困住了,需要一些帮助继续前进。

这是解码编码片段:

// initialize the output context
ctx_out = avformat_alloc_context();

// guess container format
ctx_out->oformat = av_guess_format(NULL, out_file_name, NULL);
snprintf(ctx_out->filename, sizeof(ctx_out->filename), "%s", out_file_name);

// .. stripped: creates video stream, encoder and its codec

if ((res = avio_open2(&ctx_out->pb, out_file_name, AVIO_FLAG_WRITE, NULL, NULL)) != 0) {
  callback_with_error(options, "Failed to open output file for writing (%s)", res);
  return;
}

if ((res = avformat_write_header(ctx_out, NULL)) != 0) {
  callback_with_error(options, "Failed to write output format header (%s)", res);
  return;
}

av_init_packet(&packet);
while (av_read_frame(ctx_format, &packet) >= 0) {
  frame_finished = 0;
  total_size    += packet.size;

  if (packet.stream_index == video_stream) {
    len = avcodec_decode_video2(decoder_video, frame, &frame_finished, &packet);

    if (len < 0) {
      callback_with_error(options, "Frame #%d video decoding error (%d)", current_frame, len);
      return;
    }

    if (frame_finished) {
      len = avcodec_encode_video2(encoder_video, &packet, frame, &frame_finished);

      if (len < 0) {
        continue; // dropped?
      }

      if (frame_finished) {
        if ((res = av_interleaved_write_frame(ctx_out, &packet)) != 0) {
          callback_with_error(options, "Output write error (%d).", res);
          return;
        }
      }
    }

    if (frame_finished) {
      current_frame++;
    }
  } else if (packet.stream_index == audio_stream) {
    // audio
  }
}
av_free_packet(&packet);
av_write_trailer(ctx_out);

for(i = 0; i < ctx_out->nb_streams; i++) {
  av_freep(&ctx_out->streams[i]->codec);
  av_freep(&ctx_out->streams[i]);
}

if (!(ctx_out->oformat->flags & AVFMT_NOFILE)) {
  avio_close(ctx_out->pb);
}
av_free(ctx_out);

我希望 SO 上有人对 LibAV 的工作原理有一点了解。我查看了示例并阅读了有关如何使用它的各种“文章”。所以,是的,我现在被困住了。

谢谢。

4

1 回答 1

1

您当前在这里所做的是将每个视频数据包的原始内容写入输出文件,而无需任何类型的容器或框架。虽然这适用于一些特殊格式(例如 MPEG1 视频和 MP3 音频流),但它一般不起作用——您需要打开一个AVFormatContext(using ),使用(or avformat_write_header) 将每个数据包写入流如果您的流已经正确交错),则使用.av_interleaved_write_frameav_write_frameav_write_trailer

于 2012-09-26T17:09:32.943 回答