我最近尝试从基带编码帧时遇到了问题。分段故障发生在Avcodec_encode_video2调用上,但我不知道为什么。
这是我初始化avcodeccontext的功能:
void
create_codec_context(
Header *hdr,
AVCodecContext *cc,
AVStream *st,
AVCodec *codec)
{
switch (hdr->stream_info)
{
case (Line1080i60):
cc->time_base.num = 1;
cc->time_base.den = 30;
break;
case (Line1080i5994):
cc->time_base.num = 1001;
cc->time_base.den = 30000;
break;
case (Line1080i50):
cc->time_base.num = 1;
cc->time_base.den = 25;
break;
case (Line720p60):
cc->time_base.num = 1;
cc->time_base.den = 60;
break;
case (Line1080p60):
cc->time_base.num = 1;
cc->time_base.den = 60;
break;
case (Line720p5994):
cc->time_base.num = 1001;
cc->time_base.den = 60000;
break;
case (Line1080p5994):
cc->time_base.num = 1001;
cc->time_base.den = 60000;
break;
case (Line720p50):
cc->time_base.num = 1;
cc->time_base.den = 50;
case (Line1080p50):
cc->time_base.num = 1;
cc->time_base.den = 50;
break;
default:
syslog(LOG_ERR, "Unknown local socket header stream info (VidStd): %d", hdr->stream_info);
exit(EXIT_FAILURE);
break;
}
cc->width = hdr->width;
cc->height = hdr->height;
st->r_frame_rate.num = cc->time_base.den;
st->r_frame_rate.den = cc->time_base.num;
cc->codec_type = AVMEDIA_TYPE_VIDEO;
cc->codec_id = codec->id;
cc->bit_rate = (int64_t)cc->width * (cc->height >> !!hdr->interlaced) * 2 * 8 * cc->time_base.den / cc->time_base.num;
cc->pix_fmt = hdr->pix_fmt;
st->time_base.num = 1;
st->time_base.den = 90000;
if (cc->codec_id == AV_CODEC_ID_RAWVIDEO)
{
cc->codec_tag = get_raw_pix_fmt_tag(cc->pix_fmt);
if (cc->codec_tag == 0)
{
syslog(LOG_ERR, "Failed to get codec tag for raw video pix fmt: %d", cc->pix_fmt);
exit(EXIT_FAILURE);
}
}
cc->max_b_frames = 0;
cc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
}
这是我的每个帧的过程循环:
size_t
process_bb_data(
uint8_t *src,
uint8_t *dst)
{
Header *src_hdr = (Header *)src;
uint8_t *src_y = src + sizeof(Header);
uint8_t *src_u = src_y + (src_hdr->Y_linesize * src_hdr->height);
uint8_t *src_v = src_u + (src_hdr->U_linesize * src_hdr->height);
Header *dst_hdr = (Header *)dst;
uint8_t *dst_y = dst + sizeof(Header);
uint8_t *dst_u = dst_y + (dst_hdr->Y_linesize * dst_hdr->height);
uint8_t *dst_v = dst_u + (dst_hdr->U_linesize * dst_hdr->height);
memcpy(dst_hdr, src_hdr, sizeof(Header));
memcpy(dst_y, src_y, dst_hdr->Y_linesize * dst_hdr->height);
memcpy(dst_u, src_u, dst_hdr->U_linesize * dst_hdr->height);
memcpy(dst_v, src_v, dst_hdr->V_linesize * dst_hdr->height);
av_register_all();
avcodec_register_all();
AVCodec *codec = avcodec_find_encoder_by_name("mpeg2video");
AVCodecContext *cc = avcodec_alloc_context3(codec);
avcodec_get_context_defaults3(cc, codec)
AVFormatContext *fmt_ctx = avformat_alloc_context();
AVStream *st = avformat_new_stream(fmt_ctx, NULL);
/* My function from above */
create_codec_context(dst_hdr, cc, st, codec);
AVFrame *frame = av_frame_alloc();
frame->width = dst_hdr->width;
frame->height = dst_hdr->height;
frame->format = dst_hdr->pix_fmt;
frame->data[0] = dst_y;
frame->data[1] = dst_u;
frame->data[2] = dst_v;
frame->linesize[0] = dst_hdr->Y_linesize;
frame->linesize[1] = dst_hdr->U_linesize;
frame->linesize[2] = dst_hdr->V_linesize;
int ret;
int got_packet = 0;
AVPacket pkt = {0};
av_init_packet(&pkt);
pkt.data = NULL; //dst_y;
pkt.size = 0; //(dst_hdr->Y_linesize + dst_hdr->U_linesize + dst_hdr->V_linesize) * dst_hdr->height;
/* SEGMENTATION FAULT HERE */
ret = avcodec_encode_video2(cc, &pkt, frame, &got_packet);
if (got_packet)
{
ret = av_write_frame(fmt_ctx, &pkt);
av_packet_unref(&pkt);
}
else
{
ret = 0;
}
if (ret < 0)
{
exit(EXIT_FAILURE);
}
return (sizeof(Header) + dst_hdr->data_size);
}
我在这里错过了真正愚蠢的东西吗?
哇,刚刚发现问题...别忘了您的 avcodec_open2(CC,CODEC,NULL)呼叫,女士和绅士。