FFMpeg 编码解码问题。

jkkj1630 2018-12-27 12:21:44
extern "C"
{
#include <libavutil/imgutils.h>
//引入头文件
#include <libavformat/avformat.h>
//引入时间
#include <libavutil/time.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

int avError(int errNum) {
char buf[1024];
av_strerror(errNum, buf, sizeof(buf));
printf("%s\n",buf);
return -1;
}

int main()
{
av_register_all();
avformat_network_init();
const char *inUrl = "drj.flv";
AVFormatContext *pInputCtx = NULL;
int ret = avformat_open_input(&pInputCtx, inUrl, 0, NULL);
if (ret < 0){
return avError(ret);
}
ret = avformat_find_stream_info(pInputCtx, 0);
if (ret != 0){
return avError(ret);
}
av_dump_format(pInputCtx, 0, inUrl, 0);
AVFormatContext * pOutputCtx = NULL;
ret = avformat_alloc_output_context2(&pOutputCtx, NULL, "flv", "rtmp://192.168.1.9/live/demo3");
if (ret < 0){
return avError(ret);
}
int vStream = -1;
for (int i = 0; i < pInputCtx->nb_streams; i++){
AVStream *out = avformat_new_stream(pOutputCtx, pInputCtx->streams[i]->codec->codec);
if (!out){
return avError(0);
}

if(pInputCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
vStream=i;
}
ret = avcodec_parameters_copy(out->codecpar, pInputCtx->streams[i]->codecpar);
if (ret < 0){
return avError(ret);
}
out->codec->codec_tag = 0;
}
if(vStream==-1){
return -1; // Didn't find a video stream
}
AVCodecContext*pDecodecCtx=pInputCtx->streams[vStream]->codec;
AVCodec*pDeodec=avcodec_find_decoder(pDecodecCtx->codec_id);
if(pDeodec==NULL){
return -1; // Codec not found
}
if(avcodec_open2(pDecodecCtx, pDeodec, 0)<0){
return -1; // Could not open codec
}
av_dump_format(pOutputCtx, 0, "rtmp://192.168.1.9/live/demo3", 1);
ret = avio_open(&pOutputCtx->pb, "rtmp://192.168.1.9/live/demo3", AVIO_FLAG_WRITE);
if (ret < 0){
avError(ret);
}
ret = avformat_write_header(pOutputCtx, 0);
if (ret < 0){
avError(ret);
}
// Allocate an AVFrame structure
AVFrame*pFrame264=av_frame_alloc();
if(pFrame264==NULL){
return -1;
}

AVCodec *pEncodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!pEncodec){
fprintf(stderr, "Codec not found\n");
return -1;
}

AVCodecContext *pEncodecCtx = avcodec_alloc_context3(pEncodec);
if (!pEncodecCtx){
fprintf(stderr, "Codec not found\n");
return -1;
}
pEncodecCtx->bit_rate = pDecodecCtx->bit_rate;// put sample parameters
pEncodecCtx->width =1280;//
pEncodecCtx->height = 550;//
pEncodecCtx->time_base.num = 1;//(AVRational){1,25};
pEncodecCtx->time_base.den = 25;
pEncodecCtx->gop_size = 250; // emit one intra frame every ten frames
pEncodecCtx->max_b_frames=1;
pEncodecCtx->qmin = 10;
pEncodecCtx->qmax = 51;
pEncodecCtx->thread_count = 1;
pEncodecCtx->codec_id = AV_CODEC_ID_H264;
pEncodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pEncodecCtx->pix_fmt = pDecodecCtx->pix_fmt;//PIX_FMT_RGB24;

if (pOutputCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
pEncodecCtx->flags |= AV_CODEC_FLAG_QSCALE;
}

// Open codec
AVDictionary *param = 0;
av_dict_set(¶m, "preset", "fast", 0);
av_dict_set(¶m, "tune", "zerolatency", 0);
if(avcodec_open2(pEncodecCtx, pEncodec, ¶m)<0)
{
avError(ret);
return -1;
}

AVPacket avPacket;
av_init_packet(&avPacket);
AVPacket avOutPacket;
while (true){
long long startTime = av_gettime();
int nRet = av_read_frame(pInputCtx, &avPacket);
if (nRet < 0){
break;
}
if(avPacket.stream_index == vStream){

//从此开始,如果把下面代码去掉,直接 av_interleaved_write_frame(pOutputCtx, &avPacket)就没有任何问题,但如果加上就有问题。
avcodec_send_packet(pDecodecCtx, &avPacket);
avcodec_receive_frame(pDecodecCtx,pFrame264);
av_init_packet(&avOutPacket);
avOutPacket.data = NULL;
avOutPacket.size = 0;
nRet = avcodec_send_frame(pEncodecCtx,pFrame264);
if (nRet < 0){
fprintf(stderr, "avcodec_send_frame - 2 failed [%d]!\n", AVERROR(nRet));
avError(nRet);
return -7;
}
nRet = avcodec_receive_packet(pEncodecCtx,&avOutPacket);
if (nRet < 0){
fprintf(stderr, "avcodec_receive_packet failed [%d]!\n", nRet);
avError(nRet);
return -7;
}
//到此为止

nRet = av_interleaved_write_frame(pOutputCtx, &avOutPacket);
if (nRet < 0){
fprintf(stderr, "av_interleaved_write_frame failed [%d]!\n", nRet);
avError(nRet);
break;
}
}
else{
nRet = av_interleaved_write_frame(pOutputCtx, &avPacket);
if (nRet < 0){
break;
}
}
}
return 0;
}


大神们,上面是我的代码,如果去掉注释的那几行代码,直接写入到rtmp read出来的AVPacket是正常播放,但如果加上那几行发送解码之后再编码的AVPacket就不行,我这显示的问题是avcodec_receive_packet那个函数返回-11,提示错误Resource temporarily unavailable。
...全文
735 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
QQ515311445 2019-07-25
  • 打赏
  • 举报
回复
pEncodecCtx->pix_fmt = pDecodecCtx->pix_fmt;//PIX_FMT_RGB24;
改为
pEncodecCtx->pix_fmt = pEncodec->pix_fmts[0];
djjs280 2019-03-13
  • 打赏
  • 举报
回复
avcodec_send_frame和avcodec_receive_packet这是解码成yuv数据啊,rtmp并不能直接发送yuv数据,只支持h264数据发送
你要用于rtmp根本不需要解码
jkkj1630 2019-01-02
  • 打赏
  • 举报
回复
现在我读取一个H264编码的视频文件,读取到AVPacket,然后再通过avcodec_send_packet和 avcodec_receive_frame转成AVFrame,然后再通过avcodec_send_frame和avcodec_receive_packet转成AVPacket再进行rtmp发送就不行,如果直接从文件读取的AVPacket直接发送就可以。
jkkj1630 2018-12-31
  • 打赏
  • 举报
回复
avcodec_receive_packet() return -11,error:Resource temporarily unavailable

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧