H264编码时候,将extradata写入输出的AVPacket中时将硬编码的annnex-B转化为mp4格式的代码示例
时间: 2024-06-11 21:04:27 浏览: 19
以下是将硬编码的annex-B格式转换为mp4格式的代码示例:
```c
AVPacket* pkt = av_packet_clone(&input_packet);
if (pkt->data && pkt->size > 4 && pkt->data[0] == 0x00 && pkt->data[1] == 0x00 && pkt->data[2] == 0x00 && pkt->data[3] == 0x01) {
// 如果输入的数据是annex-B格式,需要将extradata写入输出的AVPacket中
pkt->flags |= AV_PKT_FLAG_KEY;
uint8_t* new_data = NULL;
int new_size = 0;
if (ctx->codec_id == AV_CODEC_ID_H264) {
// H264编码需要将SPS和PPS放入extradata中
AVStream* stream = ctx->streams[0];
if (stream->codecpar->extradata_size <= 0) {
av_log(NULL, AV_LOG_ERROR, "No extradata found.\n");
return AVERROR_INVALIDDATA;
}
int sps_pos = -1;
int pps_pos = -1;
for (int i = 0; i < stream->codecpar->extradata_size - 4; i++) {
if (stream->codecpar->extradata[i] == 0x00 && stream->codecpar->extradata[i+1] == 0x00 && stream->codecpar->extradata[i+2] == 0x00 && stream->codecpar->extradata[i+3] == 0x01) {
if (sps_pos < 0) {
sps_pos = i;
} else {
pps_pos = i;
break;
}
}
}
if (sps_pos < 0 || pps_pos < 0) {
av_log(NULL, AV_LOG_ERROR, "SPS or PPS not found in extradata.\n");
return AVERROR_INVALIDDATA;
}
new_data = av_malloc(pkt->size + stream->codecpar->extradata_size - sps_pos);
memcpy(new_data, stream->codecpar->extradata, sps_pos);
memcpy(new_data + sps_pos, pkt->data, pkt->size);
memcpy(new_data + sps_pos + pkt->size, stream->codecpar->extradata + pps_pos, stream->codecpar->extradata_size - pps_pos);
new_size = pkt->size + stream->codecpar->extradata_size - sps_pos;
} else if (ctx->codec_id == AV_CODEC_ID_HEVC) {
// HEVC编码需要将VPS、SPS和PPS放入extradata中
AVStream* stream = ctx->streams[0];
if (stream->codecpar->extradata_size <= 0) {
av_log(NULL, AV_LOG_ERROR, "No extradata found.\n");
return AVERROR_INVALIDDATA;
}
int vps_pos = -1;
int sps_pos = -1;
int pps_pos = -1;
for (int i = 0; i < stream->codecpar->extradata_size - 4; i++) {
if (stream->codecpar->extradata[i] == 0x00 && stream->codecpar->extradata[i+1] == 0x00 && stream->codecpar->extradata[i+2] == 0x00 && stream->codecpar->extradata[i+3] == 0x01) {
if (vps_pos < 0) {
vps_pos = i;
} else if (sps_pos < 0) {
sps_pos = i;
} else {
pps_pos = i;
break;
}
}
}
if (vps_pos < 0 || sps_pos < 0 || pps_pos < 0) {
av_log(NULL, AV_LOG_ERROR, "VPS, SPS or PPS not found in extradata.\n");
return AVERROR_INVALIDDATA;
}
new_data = av_malloc(pkt->size + stream->codecpar->extradata_size - vps_pos);
memcpy(new_data, stream->codecpar->extradata, vps_pos);
memcpy(new_data + vps_pos, pkt->data, pkt->size);
memcpy(new_data + vps_pos + pkt->size, stream->codecpar->extradata + sps_pos, stream->codecpar->extradata_size - sps_pos);
new_size = pkt->size + stream->codecpar->extradata_size - vps_pos;
} else {
av_log(NULL, AV_LOG_ERROR, "Unsupported codec.\n");
return AVERROR_INVALIDDATA;
}
av_packet_unref(pkt);
pkt->data = new_data;
pkt->size = new_size;
}
pkt->pts = av_rescale_q(pkt->pts, ctx->streams[0]->time_base, ostream->time_base);
pkt->dts = av_rescale_q(pkt->dts, ctx->streams[0]->time_base, ostream->time_base);
pkt->duration = av_rescale_q(pkt->duration, ctx->streams[0]->time_base, ostream->time_base);
pkt->stream_index = 0;
pkt->pos = -1;
av_interleaved_write_frame(oc, pkt);
```
以上代码示例中,我们首先克隆了输入的AVPacket,然后判断输入的数据是否是annex-B格式。如果是annex-B格式,我们需要将SPS和PPS(或者VPS、SPS和PPS)放入extradata中,然后将extradata和输入数据合并成新的AVPacket。最后,我们使用av_interleaved_write_frame函数将新的AVPacket写入输出文件中。