2017-11-29 29 views
0

인코더 (x264)를 사용할 때 ffmpeg에 대해 질문하고 싶습니다. 나는 AVPacket이 프레임에 대한 PTS와 DTS를 수행 할 것으로 기대ffmpeg 인 코드 후, AVPacket pts와 dts는 AV_NOPTS_VALUE입니다.

int 
FFVideoEncoder::init(AVCodecID codecId, int bitrate, int fps, int gopSize, 
        int width, int height, AVPixelFormat format) { 
    release(); 

    const AVCodec *codec = avcodec_find_encoder(codecId); 
    m_pCodecCtx = avcodec_alloc_context3(codec); 
    m_pCodecCtx->width = width; 
    m_pCodecCtx->height = height; 
    m_pCodecCtx->pix_fmt = format; 
    m_pCodecCtx->bit_rate = bitrate; 
    m_pCodecCtx->thread_count = 5; 
    m_pCodecCtx->max_b_frames = 0; 
    m_pCodecCtx->gop_size = gopSize; 

    m_pCodecCtx->time_base.num = 1; 
    m_pCodecCtx->time_base.den = fps; 

    //H.264 
    if (m_pCodecCtx->codec_id == AV_CODEC_ID_H264) { 
//  av_dict_set(&opts, "preset", "slow", 0); 
     av_dict_set(&m_pEncoderOpts, "preset", "superfast", 0); 
     av_dict_set(&m_pEncoderOpts, "tune", "zerolatency", 0); 

     m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; 
     m_pCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; 
    } 
    int ret = avcodec_open2(m_pCodecCtx, m_pCodecCtx->codec, &m_pEncoderOpts); 
    if (ret == 0) { 
     LOGI("open avcodec success!"); 
    } else { 
     LOGE("open avcodec error!"); 
     return -1; 
    } 
    return ret; 
} 

int FFVideoEncoder::encode(const Frame &inFrame, AVPacket *outPacket) { 
    AVFrame *frame = av_frame_alloc(); 
// avpicture_fill((AVPicture *) frame, inFrame.getData(), AV_PIX_FMT_YUV420P, inFrame.getWidth(), 
//     inFrame.getHeight()); 
    av_image_fill_arrays(frame->data, frame->linesize, inFrame.getData(), m_pCodecCtx->pix_fmt, 
         inFrame.getWidth(), inFrame.getHeight(), 1); 

    int ret = 0; 
    ret = avcodec_send_frame(m_pCodecCtx, frame); 
    if (ret != 0) { 
     LOGE("send frame error! %s", av_err2str(ret)); 
    } else { 
     ret = avcodec_receive_packet(m_pCodecCtx, outPacket); 
     LOGI("extract data size = %d", m_pCodecCtx->extradata_size); 
     if (ret != 0) { 
      LOGE("receive packet error! %s", av_err2str(ret)); 
     } 
    }; 
    av_frame_free(&frame); 
    return ret; 
} 

:

이 내 코드입니다.

하지만 실제로는 인코딩 된 프레임 데이터와 크기 만 가져올 수 있습니다.

// ====================================

이 질문을 제외

, 나는 또 다른 질문을 가지고있다 :

x264 docs는 "조정"선택이 영화, 애니메이션 및 기타와 같이 설정 될 수 있다고 말한다. 하지만 "zerolatency"매개 변수를 설정할 때만 일반 비디오를 얻을 수 있습니다. 다른 사람들을 선택하면 비디오의 비트 전송률이 매우 낮습니다.

답장을 보내주세요.

답변

0

작동하는지 간단한 예를 볼 수 있도록 이것은 :

난 당신이 사전에 frame->pts을 설정해야합니다 생각합니다.
이 시도 :
당신이 인코딩을위한 전송 프레임의 간단한 카운터로이 framecount 추가 ret = avcodec_send_frame(m_pCodecCtx, frame)

에 보내기 전에 frame->pts = framecount을 설정합니다. 매번 증가합니다.
도움이 되길 바랍니다.

+0

OMG. 당신의 도움을 주셔서 감사합니다. 사실 모든 프레임의 PTS가 있습니다. pts를 AVFrame으로 설정하면 작동합니다! –