h264 转 mp4
在使用 ffmpeg 处理 h264 转 mp4 时,生成的 mp4 无法播放,经排查发现是原始数据包没有时间戳信息。
·
在使用 ffmpeg 处理 h264 转 mp4 时,生成的 mp4 无法播放,经排查发现是原始数据包没有时间戳信息。
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}
int main() {
QString input = QString("input.h264");
QString output = QString("output.mp4");
std::string inputfile = input.toStdString();
std::string outputfile = output.toStdString();
AVFormatContext *input_ctx = nullptr;
AVFormatContext *output_ctx = nullptr;
if (avformat_open_input(&input_ctx, inputfile.c_str(), nullptr, nullptr) < 0) {
return -1;
}
if (avformat_find_stream_info(input_ctx, nullptr) < 0) {
return -1;
}
int video_stream_index = -1;
for (unsigned int i = 0; i < input_ctx->nb_streams; i++) {
if (input_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_index = i;
break;
}
}
if (video_stream_index == -1) {
return -1;
}
avformat_alloc_output_context2(&output_ctx, nullptr, "mp4", outputfile.c_str());
if (!output_ctx) {
return -1;
}
AVStream *out_stream = avformat_new_stream(output_ctx, nullptr);
if (!out_stream) {
return -1;
}
AVStream *in_stream = input_ctx->streams[video_stream_index];
avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
out_stream->codecpar->codec_tag = av_codec_get_tag(
output_ctx->oformat->codec_tag, in_stream->codecpar->codec_id);
if (out_stream->codecpar->codec_tag == 0) {
return -1;
}
out_stream->time_base = in_stream->time_base;
out_stream->r_frame_rate = in_stream->r_frame_rate;
if (!(output_ctx->oformat->flags & AVFMT_NOFILE)) {
if (avio_open(&output_ctx->pb, outputfile.c_str(), AVIO_FLAG_WRITE) < 0) {
return -1;
}
}
if (avformat_write_header(output_ctx, nullptr) < 0) {
return -1;
}
AVPacket* packet = av_packet_alloc();
av_packet_unref(packet);
int64_t next_pts = 0;
AVRational frame_rate = av_guess_frame_rate(input_ctx, in_stream, nullptr);
while (av_read_frame(input_ctx, packet) >= 0) {
// 计算时间戳
if (packet->stream_index == video_stream_index) {
if (packet->pts == AV_NOPTS_VALUE) {
packet->pts = next_pts;
packet->dts = next_pts;
next_pts += av_rescale_q(1, frame_rate.den ? (AVRational){frame_rate.den, frame_rate.num} : (AVRational){1,25}, out_stream->time_base);
}
av_packet_rescale_ts(packet,
in_stream->time_base,
out_stream->time_base);
packet->stream_index = out_stream->index;
if (av_interleaved_write_frame(output_ctx, packet) < 0) {
av_packet_unref(packet);
break;
}
}
av_packet_unref(packet);
}
av_write_trailer(output_ctx);
avformat_close_input(&input_ctx);
if (output_ctx && !(output_ctx->oformat->flags & AVFMT_NOFILE))
avio_closep(&output_ctx->pb);
avformat_free_context(output_ctx);
return 0;
}
[点击并拖拽以移动]
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)