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);

LibAV がどのように機能するかについて少し知っている人が SO にいることを願っています。例を見て、その使用方法に関するさまざまな「記事」を読みました。だから、ええ、私は今のところ立ち往生しています。

ありがとう。

4

1 に答える 1

1

ここで現在行っているのは、各ビデオ パケットの生のコンテンツを出力ファイルに書き込んでおり、コンテナやフレーミングは一切行われていません。AVFormatContextこれは、いくつかの特殊なフォーマット (MPEG1 ビデオや MP3 オーディオ ストリームなど) では機能しますが、一般的には機能しません。 ( を使用してavformat_write_header)を開き、av_interleaved_write_frame(またはav_write_frameストリームがすでに適切にインターリーブされている場合)、 を使用してすべてのルーズエンドを結び付けますav_write_trailer

于 2012-09-26T17:09:32.943 に答える