1

최근에 기저 대역에서 프레임을 인코딩하는 동안 문제가 발생했습니다. 세분화 오류는 avcodec_encode_video2 호출에서 발생하지만 이유는 알 수 없습니다.기저 대역 (ffmpeg)에서 프레임을 인코딩하는 동안 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); 
} 

내가 여기 정말 바보 같은 뭔가를 놓치고 있습니까?

답변

1

와우는, 당신의 avcodec_open2 (CC, 코덱, NULL) 전화, 신사 숙녀 신사를 잊지 마세요 ... 문제를 발견했다.