使用FFmpeg avcodec_receive_frame解码h264视频流出现延时?
 ret = avcodec_send_packet(avctx, pkt);
    if (ret < 0) {
        return -1;
    }
    while (ret >= 0){
        ret = avcodec_receive_frame(avctx, frame);
        }

解码网络H264数据 在网络出现中断丢失帧的时候有几率出现解码延时
重置解码器后又恢复正常,有什么方法可以不用重置解码器吗?

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
ffmpeg avcodec_receive_frame 解码效率慢

``` if (pPacket->stream_index == videoIndex) { Uint32 pretimer = SDL_GetTicks(); /* ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, pPacket); if (ret < 0) { printf("解帧失败!\n"); return -1; } */ ret = avcodec_send_packet(pCodecCtx, pPacket); if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) return -1; ret = avcodec_receive_frame(pCodecCtx, pFrame); if (ret < 0 && ret != AVERROR_EOF) { //fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret)); continue; } Uint32 a = SDL_GetTicks() - pretimer; cout << "avcodec_receive_frame" << a << endl; } ``` ffmpeg 我是用3.4版本 解码时,使用函数avcodec_send_packet avcodec_receive_frame 获取一帧4K高清视频,30ms左右 使用2.8老版本时 avcodec_decode_video2 获取一帧4K高清视频 10ms左右,请问这种情况如何解决。为什么新版本的解码速度反倒是变慢了。

ffmpeg 硬编码时avcodec_encode_video2返回错误码-11(Resource temporarily unavailable)

用ffmpeg将bmp文件序列编码为h264,使用软编码器AV_CODEC_ID_H264时 程序可以正常运行,换成硬编码器h264_nvenc后,程序有时可以正常运行,但有时会报错,错误现象为: 编码生成的h264文件大小为0KB,avcodec_encode_video2()函数返回错误码-11,使用av_strerror显示错误码映射为“Resource temporarily unavailable”。 换成新的API(avcodec_send_frame和avcodec_receive_packet)后,已经返回-11。程序如下: ``` #include<stdio.h> #include<iostream> #include<afx.h> using namespace std; extern"C" { #include <libavcodec\avcodec.h> #include <libavformat\avformat.h> #include <libswscale\swscale.h> #include <libavutil\pixfmt.h> #include <libavutil\imgutils.h> #include <libavutil/opt.h> #include "libavutil/time.h" } #define bmpImagePath "F:/laboratory/holiday/bmp2H264/image_bmp1/%03d.bmp" //bmp图像路径 #define H264FilePath "F:/laboratory/holiday/bmp2H264/h264/text.h264" //H264文件输出路径 const int image_number = 100; //bmp图片数量 int main() { CFile file[image_number + 1000]; BYTE *szTxt[image_number + 1000]; int nWidth = 0; int nHeight = 0; int nDataLen = 0; int nLen; CString csFileName; for (int fileI = 1; fileI <= image_number; fileI++) { csFileName.Format(bmpImagePath, fileI); file[fileI - 1].Open(csFileName, CFile::modeRead | CFile::typeBinary); nLen = file[fileI - 1].GetLength(); szTxt[fileI - 1] = new BYTE[nLen]; file[fileI - 1].Read(szTxt[fileI - 1], nLen); file[fileI - 1].Close(); BITMAPFILEHEADER bmpFHeader; BITMAPINFOHEADER bmpIHeader; memcpy(&bmpFHeader, szTxt[fileI - 1], sizeof(BITMAPFILEHEADER)); int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER); memcpy(&bmpIHeader, szTxt[fileI - 1] + sizeof(BITMAPFILEHEADER), nHeadLen); nWidth = bmpIHeader.biWidth; nHeight = bmpIHeader.biHeight; szTxt[fileI - 1] += bmpFHeader.bfOffBits; nDataLen = nLen - bmpFHeader.bfOffBits; cout << "fileI:" << fileI << endl; } av_register_all(); avcodec_register_all(); AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB帧数据 AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV帧数据 AVCodecContext *c = NULL; //AVCodecContext *in_c = NULL; AVCodec *pCodecH264 = NULL; //编码器 uint8_t * yuv_buff = NULL;// //查找h264编码器 //pCodecH264 = avcodec_find_encoder(AV_CODEC_ID_H264); //软编码器 pCodecH264 = avcodec_find_encoder_by_name("h264_nvenc"); //硬编码器 if (!pCodecH264) { fprintf(stderr, "h264 codec not found\n"); exit(1); } c = avcodec_alloc_context3(pCodecH264); if (!c) { throw exception("avcodec_alloc_context3 failed!"); } c->bit_rate = 3000000;// put sample parameters //c->bit_rate = 2500000;// put sample parameters c->width = nWidth; c->height = nHeight; AVRational rate; rate.num = 1; rate.den = 25; c->time_base = rate;//(AVRational){1,25}; c->gop_size = 10; // emit one intra frame every ten frames c->max_b_frames = 1; c->thread_count = 1; c->pix_fmt = AV_PIX_FMT_YUV420P;//PIX_FMT_RGB24; if (avcodec_open2(c, pCodecH264, NULL)<0) //打开编码器 TRACE("不能打开编码库"); int size = c->width * c->height; yuv_buff = (uint8_t *)malloc((size * 3) / 2); // size for YUV 420 uint8_t * rgb_buff = new uint8_t[nDataLen]; //将rgb图像数据填充rgb帧 //图象编码 //int outbuf_size = 100000000; int outbuf_size = nWidth * nHeight * 3; uint8_t * outbuf = (uint8_t*)malloc(outbuf_size); int u_size = 0; FILE *f = NULL; char * filename = H264FilePath; f = fopen(filename, "wb"); if (!f) { TRACE("could not open %s\n", filename); exit(1); } //初始化SwsContext SwsContext * scxt = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR24, c->width, c->height, AV_PIX_FMT_YUV420P, SWS_POINT, NULL, NULL, NULL); AVPacket avpkt; //AVFrame *pTFrame=new AVFrame int num = 0; long long int vpts = 0; for (int i = 0; i< image_number; ++i) { int index = i; memcpy(rgb_buff, szTxt[index], nDataLen); avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, AV_PIX_FMT_RGB24, nWidth, nHeight); //将YUV buffer 填充YUV Frame avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, AV_PIX_FMT_YUV420P, nWidth, nHeight); // 翻转RGB图像 m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1); m_pRGBFrame->linesize[0] *= -1; m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1); m_pRGBFrame->linesize[1] *= -1; m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1); m_pRGBFrame->linesize[2] *= -1; //将RGB转化为YUV sws_scale(scxt, m_pRGBFrame->data, m_pRGBFrame->linesize, 0, c->height, m_pYUVFrame->data, m_pYUVFrame->linesize); int got_packet_ptr = 0; av_init_packet(&avpkt); avpkt.data = outbuf; avpkt.size = outbuf_size; //m_pYUVFrame->pts = vpts; /*u_size = avcodec_send_frame(c, m_pYUVFrame); if (u_size != 0) { char errorbuf[1024] = { 0 }; av_strerror(u_size, errorbuf, sizeof(errorbuf)); cout << "error number:" << u_size << "avcodec_send_frame error:" << errorbuf << endl; } u_size = avcodec_receive_packet(c, &avpkt); if (u_size != 0) { char errorbuf[1024] = { 0 }; av_strerror(u_size, errorbuf, sizeof(errorbuf)); cout << "error number:"<< u_size << " avcodec_receive_packet error:" << errorbuf << endl; }*/ u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr); if (u_size != 0) { char errorbuf[1024] = { 0 }; av_strerror(u_size, errorbuf, sizeof(errorbuf)); cout << "error number:" << u_size << "avcodec_encode_video2 error:" << errorbuf << endl; } m_pYUVFrame->pts++; //cout << "encode frame" << index + 1 << " successfully!" << endl; cout << "u_size:" << u_size << endl; if (u_size == 0) { cout << "encode frame" << index + 1 << " successfully!" << endl; cout << "*************" << ++num << "************" << endl; fwrite(avpkt.data, 1, avpkt.size, f); } //vpts++; else { avcodec_send_packet(c, &avpkt); } } cout << "nWidth" << nWidth << endl; cout << "nHeight" << nHeight << endl; fclose(f); delete[]m_pRGBFrame; delete[]m_pYUVFrame; delete[]rgb_buff; free(outbuf); free(yuv_buff); avcodec_close(c); av_free(c); //avcodec_free_context(&c); system("pause"); return 0; } ``` 错误结果截图如下: ![图片说明](https://img-ask.csdn.net/upload/202004/19/1587275773_301317.png)

FFmpeg中的avcodec_find_encoder_by_name("libx264")内幕是怎样的呢?

为什么我在win7、vs2015中可以得到一个AVCodec,而在win10、vs2017中却返回NULL呢? 新线索: 在win10、vs2017中,debug模式下此函数返回空,在release模式下不为空;

FFmpeg:avcodec_find_encoder_by_name("libx264")返回空,是怎么回事呢?

FFmpeg编译时的参数:./configure --enable-shared --enable-static --enable-pic --enable-gpl --enable-avresample --enable-sdl --enable-libx264 cmd中使用ffmpeg -encoders ![图片说明](https://img-ask.csdn.net/upload/201912/15/1576374486_153947.jpg) 新线索: 在win7、vs2015中此函数不为空,在win10、vs2017中为空; 在win10、vs2017中的debug模式下,此函数返回空,release模式下不为空;

使用ffmpeg方法avcodec_encode_video2 编码参数问题!

雷博的代码! 此处文件格式为YUV420P 使用ffmpeg编码h.264 ![图片说明](https://img-ask.csdn.net/upload/201801/11/1515659805_828534.png) 讲解一下这里的pFrame->data为什么要这样赋值? 代码链接:http://blog.csdn.net/leixiaohua1020/article/details/25430425 假如原始帧格式为YUYV422P的时候 data又该怎么赋值?

ffmpeg的avcodec_find_decoder(AV_CODEC_ID_BMP)返回空是怎么回事呢?

if (!avcodec_find_decoder(AV_CODEC_ID_BMP)) { exit(__LINE__); }

ffmpeg编解码异常,Resource temporarily unavailable

修改ffplay官方代码,使用ffmpeg实现从新编码保存mp4功能。调用avcodec_receive_packet返回-1,提示Resource temporarily unavailable,保存出来的文件没有I帧。 完整代码: https://github.com/hrdzkj/ffplay/tree/ffplayOpengl (注意是在ffplayOpengl分支) 关键代码: int ffp_start_record(FFPlayer *ffp, const char *file_name) { assert(ffp); VideoState *is = ffp->is; if (!file_name || !strlen(file_name)) { // 没有路径 av_log(ffp, AV_LOG_ERROR, "filename is invalid"); goto end; } if (!is || !is->ic || is->paused || is->abort_request) { // 没有上下文,或者上下文已经停止 av_log(ffp, AV_LOG_ERROR, "is,is->ic,is->paused is invalid"); goto end; } if (ffp->is_record) { // 已经在录制 av_log(ffp, AV_LOG_ERROR, "recording has started"); goto end; } ffp->m_ofmt_ctx = NULL; ffp->is_record = 0; ffp->record_error = 0; // todo avformat_new_stream,avcodec_copy_context/avcodec_parameters_from_context 等api函数的作用,初始化了什么东西 // 初始化一个用于输出的AVFormatContext结构体 avformat_alloc_output_context2(&ffp->m_ofmt_ctx, NULL, "mp4", file_name); if (!ffp->m_ofmt_ctx) { av_log(ffp, AV_LOG_ERROR, "Could not create output context filename is %s\n", file_name); goto end; } stream_ctx = av_mallocz_array(is->ic->nb_streams, sizeof(*stream_ctx)); if (!stream_ctx) { goto end; } for (int i = 0; i < is->ic->nb_streams; i++) { int ret; AVCodec *encoder; AVCodecContext *enc_ctx; AVCodecContext *dec_ctx = is->ic->streams[i]->codec; if (dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO && dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) { continue; } //对照输入流创建输出流通道 AVStream *in_stream = is->ic->streams[i]; AVStream *out_stream = avformat_new_stream(ffp->m_ofmt_ctx, NULL); if (!out_stream) { av_log(ffp, AV_LOG_ERROR, "Failed allocating output stream\n"); goto end; } //查找编码器、创建编码器上下文、设置编码器参数,然后打开编码器 encoder = avcodec_find_encoder(dec_ctx->codec_id); if (!encoder) { av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n"); goto end; } enc_ctx = avcodec_alloc_context3(encoder); if (!enc_ctx) { av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n"); goto end; } //不是帧率的问题,是I P B帧的区别导致的问题了 ret = avcodec_parameters_to_context(enc_ctx, in_stream->codecpar); if (ret < 0) { printf("Failed to copy context input to output stream codec context\n"); goto end; } if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) { //enc_ctx->height = dec_ctx->height; //enc_ctx->width = dec_ctx->width; //enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio; //enc_ctx->gop_size = 10; //enc_ctx->max_b_frames = 0; //if (encoder->pix_fmts) //enc_ctx->pix_fmt = encoder->pix_fmts[0]; //else // enc_ctx->pix_fmt = dec_ctx->pix_fmt; enc_ctx->time_base = av_inv_q(dec_ctx->framerate); //enc_ctx->time_base = //(AVRational) { 1, 30 }; //enc_ctx->framerate = //(AVRational) { 30, 1 }; } else { //enc_ctx->sample_rate = dec_ctx->sample_rate; //enc_ctx->channel_layout = dec_ctx->channel_layout; //enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout); //enc_ctx->sample_fmt = encoder->sample_fmts[0]; enc_ctx->time_base = (AVRational) { 1, dec_ctx->sample_rate }; } if (ffp->m_ofmt_ctx->flags & AVFMT_GLOBALHEADER) { enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } ret = avcodec_open2(enc_ctx, encoder, NULL); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i); goto end; } ret = avcodec_copy_context(out_stream->codec, in_stream->codec); //ret = avcodec_parameters_to_context(out_stream->codec, in_stream->codecpar); //ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i); goto end; } out_stream->time_base = enc_ctx->time_base; stream_ctx[i].enc_ctx = enc_ctx; } av_dump_format(ffp->m_ofmt_ctx, 0, file_name, 1); // 打开输出文件 if (!(ffp->m_ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { if (avio_open(&ffp->m_ofmt_ctx->pb, file_name, AVIO_FLAG_WRITE) < 0) { av_log(ffp, AV_LOG_ERROR, "Could not open output file '%s'", file_name); goto end; } } // 写视频文件头 if (avformat_write_header(ffp->m_ofmt_ctx, NULL) < 0) { av_log(ffp, AV_LOG_ERROR, "Error occurred when opening output file\n"); goto end; } ffp->is_first = 0; ffp->is_record = 1; ffp->record_error = 0; return 0; end: ffp->record_error = 1; return -1; } static void encode(FFPlayer *ffp,AVCodecContext *enc_ctx, AVFrame *frame) { int ret; int got_frame;// malloc(sizeof(int)); AVPacket pkt = { 0 }; av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; int stream_index=getMediaTypeStreamIndex(ffp,AVMEDIA_TYPE_VIDEO); /* send the frame to the encoder */ if (frame) printf("Send frame %3"PRId64"\n", frame->pts); /* //旧的api ret= avcodec_encode_video2(enc_ctx, &pkt,frame, &got_frame); if (ret < 0) return ret; if (!(got_frame)) { fprintf(stderr, "avcodec_encode_video2 fail \n"); return ; } ffp_record_file(ffp, &pkt); av_packet_unref(&pkt); */ //新的api ret = avcodec_send_frame(enc_ctx, frame); if (ret < 0) { fprintf(stderr, "Error sending a frame for encoding\n"); return -1; } while (1) { ret = avcodec_receive_packet(enc_ctx, &pkt); if (ret) { fprintf(stderr, "Error encoding ret= %d,%s \n", ret,av_err2str(ret)); break; } fprintf(stdout, " -----> encoding success!\n"); pkt.stream_index = stream_index; ffp_record_file(ffp,&pkt); av_packet_unref(&pkt); } } 提示Resource temporarily unavailable的截图 ![图片说明](https://img-ask.csdn.net/upload/201911/14/1573714996_774759.jpg) 生成的mp4文件无I帧截图 ![图片说明](https://img-ask.csdn.net/upload/201911/14/1573715130_904969.png)

ffmpeg avcodec_open2问题

AVCodecContext *c; c->bit_rate = 400000; c->width = width; c->height = height; c->time_base = avRate; c->lmin = 1; c->lmax = 1000; c->me_method = 8; c->me_range = 16; c->me_subpel_quality = 7; c->qmin = 10; c->qmax = 51; c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->pix_fmt = PIX_FMT_YUV420P; if (c->codec_id == CODEC_ID_MPEG2VIDEO) { c->max_b_frames = 2; } if (c->codec_id == CODEC_ID_MPEG1VIDEO){ c->mb_decision=2; avcodec_open2宽度和高度不同时有时打开成功,有时失败,如1366*768打开成功,1365*767打开失败

FFmpeg C++ 的 avcodec_encode_video2 返回 -40

我想通過avcodec_encode_video2 覆蓋packet中的memory來達到刷新我做過特殊渲染的影像,但avcodec_encode_video2 的返回值是不成功-40問題: 我正常撥放輸出都沒問題 就是沒辦法蓋過圖層,是不是哪邊memory寫法不正確呢? 代碼如下: AVOutputFormat* ofmt = NULL; //Input AVFormatContext and Output AVFormatContext AVFormatContext* i_pFormatCtx = NULL, * out_pFormatCtx = NULL; AVCodecContext* pCodecCtx;//視頻解碼器 AVCodecContext* pCodecCtxAudio;//音頻解碼器 AVCodec* pCodec; AVCodec* pCodecAudio; AVPacket packet; string in_filename; string out_filename; int ret, i; int videoindex = -1; int audioindex = -1; int frame_index = 0; int64_t start_time = 0; uint8_t* buffer; AVFrame* pFrame; AVFrame* pFrameRGB; int frameFinished; int frameAudioFinished; int numBytes; AVStream* in_stream, * out_stream; vector<AVPacket> BIGpacket; in_filename = "D:/yolo/data_movie/f1.mp4"; out_filename = "rtmp://localhost:1935/live/home";//怀堤 URLㄗOutput URLㄘ[RTMP] //================ // 註冊: av_register_all(); //================ //Network avformat_network_init(); //======================= //Input if ((ret = avformat_open_input(&i_pFormatCtx, in_filename.c_str(), 0, 0)) < 0) { //printf("Could not open input file."); goto end; } if ((ret = avformat_find_stream_info(i_pFormatCtx, 0)) < 0) { //printf("Failed to retrieve input stream information"); goto end; } for (i = 0; i < i_pFormatCtx->nb_streams; i++) { if (i_pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoindex = i; } if (i_pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { audioindex = i; } } av_dump_format(i_pFormatCtx, 0, in_filename.c_str(), 0); //Output avformat_alloc_output_context2(&out_pFormatCtx, NULL, "flv", out_filename.c_str()); //RTMP if (!out_pFormatCtx) { //printf("Could not create output context\n"); ret = AVERROR_UNKNOWN; goto end; } ofmt = out_pFormatCtx->oformat; for (i = 0; i < i_pFormatCtx->nb_streams; i++) { //Create output AVStream according to input AVStream AVStream* in_stream = i_pFormatCtx->streams[i]; AVStream* out_stream = avformat_new_stream(out_pFormatCtx, in_stream->codec->codec); if (!out_stream) { AfxMessageBox(L"Failed allocating output stream"); //printf("Failed allocating output stream\n"); ret = AVERROR_UNKNOWN; goto end; } //Copy the settings of AVCodecContext ret = avcodec_copy_context(out_stream->codec, in_stream->codec); if (ret < 0) { //printf("Failed to copy context from input to output stream codec context\n"); goto end; } out_stream->codec->codec_tag = 0; if (out_pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } //====================================================================== // 打开視頻解码器 pCodecCtx = i_pFormatCtx->streams[videoindex]->codec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (avcodec_open2(pCodecCtx, pCodec, 0) < 0) { DbgPrint("Could not open codec"); return; } //====================================================================== // 打开音頻解码器 pCodecCtxAudio= i_pFormatCtx->streams[audioindex]->codec; pCodecAudio= avcodec_find_decoder(pCodecCtxAudio->codec_id); if (avcodec_open2(pCodecCtxAudio, pCodecAudio, 0) < 0) { DbgPrint("Could not open codec"); return; } #if OUTPUT_PCM pFile = fopen("output.pcm", "wb"); #endif** packet = *(AVPacket*)av_malloc(sizeof(AVPacket)); av_init_packet(&packet); //===================================================================== // 破解視頻某些编解码器可能生成的错误帧速率 if (pCodecCtx->time_base.num > 1000 && pCodecCtx->time_base.den == 1) { pCodecCtx->time_base.den = 1000; } // 分配视频帧 pFrame = av_frame_alloc(); // Allocate an AVFrame structure pFrameRGB = av_frame_alloc(); if (pFrameRGB == NULL) return; numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);// Determine required buffer size and allocate buffer buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t)); avpicture_fill((AVPicture*)pFrameRGB, buffer, AV_PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);// Assign appropriate parts of buffer to image planes in pFrameRGB long prepts = 0; //Dump Format------------------ av_dump_format(out_pFormatCtx, 0, out_filename.c_str(), 1); //Open output URL if (!(ofmt->flags & AVFMT_NOFILE)) { ret = avio_open(&out_pFormatCtx->pb, out_filename.c_str(), AVIO_FLAG_WRITE); if (ret < 0) { AfxMessageBox(L"Could not open output URL"); //printf("Could not open output URL '%s'", out_filename); goto end; } } //Write file header ret = avformat_write_header(out_pFormatCtx, NULL); if (ret < 0) { //printf("Error occurred when opening output URL\n"); goto end; } start_time = av_gettime(); while (1) { //Get an AVPacket ret = av_read_frame(i_pFormatCtx, &packet); if (ret < 0) { break; } if (G_PAUSE) { break; } /* if (packet.stream_index == audioindex) { //聲音: ret = avcodec_decode_audio4(pCodecCtx, pFrame, &frameAudioFinished,&packet); } */ //Important:Delay if (packet.stream_index == videoindex) { //==================================================================================== //幀解碼器: int a=avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);// Decode video frame //ret = avcodec_encode_video2(pCodecCtx, &packet, pFrameRGB, &frameFinished); if (frameFinished) { static struct SwsContext* img_convert_ctx; if (img_convert_ctx == NULL) { int w = pCodecCtx->width; int h = pCodecCtx->height; img_convert_ctx = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h, AV_PIX_FMT_RGB24, 4, NULL, NULL, NULL); if (img_convert_ctx == NULL) { fprintf(stderr, "Cannot initialize the conversion context!\n"); exit(1); } } int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); if (ret == 0) { fprintf(stderr, "SWS_Scale failed [%d]!\n", ret); continue; } // Save the frame to disk if (i++ <= 5) { SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); } CopyDate(pFrameRGB, pCodecCtx->width, pCodecCtx->height, packet.pts - prepts); ret =avcodec_encode_video2(pCodecCtx, &packet, pFrameRGB, &frameFinished); if (ret < 0) { AfxMessageBox(L"Encoding失敗"); } prepts = packet.pts; } //============================================================================================== AVRational time_base = i_pFormatCtx->streams[videoindex]->time_base; AVRational time_base_q = { 1,AV_TIME_BASE }; int64_t pts_time = av_rescale_q(packet.dts, time_base, time_base_q); int64_t now_time = av_gettime() - start_time; if (pts_time > now_time) { av_usleep(pts_time - now_time); } } //Simple Write PTS if (packet.pts == AV_NOPTS_VALUE) { //Write PTS AVRational time_base1 = i_pFormatCtx->streams[videoindex]->time_base; //Duration between 2 frames (us) int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(i_pFormatCtx->streams[videoindex]->r_frame_rate); //Parameters packet.pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE); packet.dts = packet.pts; packet.duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE); } in_stream = i_pFormatCtx->streams[packet.stream_index]; out_stream = out_pFormatCtx->streams[packet.stream_index]; /* copy packet */ //Convert PTS/DTS packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base); packet.pos = -1; //Print to Screen if (packet.stream_index == videoindex) { //printf("Send %8d video frames to output URL\n", frame_index); frame_index++; //ret = av_interleaved_write_frame(out_pFormatCtx, &packet); } //ret = av_write_frame(ofmt_ctx, &pkt); ret = av_interleaved_write_frame(out_pFormatCtx, &packet); if (ret < 0) { //printf("Error muxing packet\n"); break; } av_free_packet(&packet); } //Write file trailer av_write_trailer(out_pFormatCtx); end: AfxMessageBox(L"Stream is closed"); avformat_close_input(&i_pFormatCtx); /* close output */ if (out_pFormatCtx && !(ofmt->flags & AVFMT_NOFILE)) avio_close(out_pFormatCtx->pb); avformat_free_context(out_pFormatCtx); if (ret < 0 && ret != AVERROR_EOF) { //printf("Error occurred.\n"); return ; } return;

FFmpeg 编码 avcodec_open2 x264 memory leak

开发平台 : Mac OS X EI Capitan 10.11.4 Xcode Version 7.3 iOS 9.3 代码 : // x264 参数 double crf = 23; int qmin = 12;// 最小的量化因子。取值范围0-69。 int qmax = 18;// 最大的量化因子。取值范围13-69。 int keyint = 16; int scenecut = 0; // slow // ultrafast // superfast av_opt_set(codec_ctx->priv_data, "preset", "ultrafast", 0); // zerolatency // stillimage,fastdecode,zerolatency av_opt_set(codec_ctx->priv_data, "tune", "stillimage,fastdecode,zerolatency", 0); av_opt_set(codec_ctx->priv_data, "profile", "baseline", 0); char x264opts[512] = { 0 }; sprintf(x264opts, "crf=%f:scenecut=%d", crf, scenecut); av_opt_set(codec_ctx->priv_data, "x264opts", x264opts, 0); codec_ctx->codec_id = codec_id; codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; codec_ctx->pix_fmt = PIX_FMT_YUV420P; codec_ctx->width = in_width; codec_ctx->height = in_height; codec_ctx->bit_rate = bit_rate;// 比特率 codec_ctx->time_base = (AVRational){ 1, in_frames_per_secs }; codec_ctx->qcompress = 1;// x264 参数 qcomp codec_ctx->qblur = 1; codec_ctx->qmin = qmin;// 最小量化系数 codec_ctx->qmax = qmax;// 最大量化系数 codec_ctx->keyint_min = 2;// 关键帧的最小间隔帧数 codec_ctx->gop_size = keyint;// 关键帧的最大间隔帧数,x264 参数 keyint codec_ctx->scenechange_threshold = scenecut;// 场景变化检测阈值 codec_ctx->max_b_frames = 0;// optional param 可选参数,禁用B帧,,设置 x264 参数 profile 值为 baseline 时,此参数失效 codec_ctx->thread_count = 1; codec_ctx->ticks_per_frame = 2; /* codec_ctx->rc_max_rate = 700;// 最大码流,x264单位kbps,ffmpeg单位bps,x264 参数 vbv-maxrate codec_ctx->rc_min_rate = 300;// 最小码流 codec_ctx->rc_buffer_size = codec_ctx->rc_max_rate + codec_ctx->rc_min_rate;// x264 参数 vbv-bufsize */ codec_ctx->max_qdiff = 6;// 固定量化器因子允许的最大偏差,取值范围0-69,x264 参数 qpstep codec_ctx->me_range = 5; codec_ctx->refs = 3;// 运动补偿,x264 参数 ref codec_ctx->rc_strategy = FF_RC_STRATEGY_XVID;// 码率控制策略,宏定义,查API codec_ctx->dct_algo = FF_DCT_AUTO; codec_ctx->idct_algo = FF_IDCT_AUTO; codec_ctx->profile = FF_PROFILE_H264_BASELINE; codec_ctx->codec_tag = 0; } if(oformat->flags & AVFMT_GLOBALHEADER) { codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; } av_error = avcodec_open2(codec_ctx, codec, NULL); if (0 != av_error) { goto fail_label; } g_out_fmt_ctx = fmt_ctx; g_video_codec_ctx = codec_ctx; video_stream_index = fmt_ctx->nb_streams - 1; ret = 0; fail_label: if (0 != ret) { printf("%s", "fail"); if (codec_ctx) { avcodec_close(codec_ctx); codec_ctx = NULL; } if (fmt_ctx) { avformat_free_context(fmt_ctx); fmt_ctx = NULL; } } else { printf("%s", "success"); } codec_ctx = NULL; stream = NULL; codec = NULL; } void test_release_mw_recorder_controller() { video_stream_index = -1; if (g_video_codec_ctx) { avcodec_close(g_video_codec_ctx); g_video_codec_ctx = NULL; } if (g_out_fmt_ctx) { avformat_free_context(g_out_fmt_ctx); g_out_fmt_ctx = NULL; } } - (void)click_init_h264:(id)sender { NSString *format_name = @"flv";// flv、aac NSArray *doc_paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *doc_path = [doc_paths objectAtIndex:0]; NSString *filename = [doc_path stringByAppendingPathComponent:[NSString stringWithFormat:@"test_ffmpeg_encoder.%@", format_name]]; const char *format_name_str = format_name.UTF8String; const char *filename_str = filename.UTF8String; test_init_mw_recorder_controller(format_name_str, filename_str); } - (void)click_release_h264:(id)sender { test_release_mw_recorder_controller(); } 使用 Instruments 进行内存 leak 检测时,在调用 click_init_h264 方法后,就会出现 7个x264_malloc方法调用的memory leak的情况。 Instruments截图--->>>![图片说明](https://img-ask.csdn.net/upload/201605/26/1464240798_520440.png) 所以想请求各位有使用FFmpeg进行视频编码的高手,这是什么问题。是我的设置参数有问题,还是步骤有问题。请指点一下小弟。(小弟刚学FFmpeg,想写个iOS录制视频的例子,使用x264库进行视频编码,aac进行音频编码。现在可以正常编码,录制的视频也可以播。现在就差这个memory leak一直找不到解决办法)。 FFmpeg打印x264配置信息 : [libx264 @ 0x110060800] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2 [libx264 @ 0x110060800] profile Constrained Baseline, level 2.2 [libx264 @ 0x110060800] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=0 ref=3 deblock=0:-3:-3 analyse=0:0 me=dia subme=0 psy=1 psy_rd=2.00:0.70 mixed_ref=0 me_range=5 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=5 lookahead_threads=5 sliced_threads=1 slices=5 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=6 keyint_min=2 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=1.00 qpmin=12 qpmax=18 qpstep=8 ip_ratio=1.40 aq=0 我自己找到了一些规律,不懂是否正确。 已找到泄露的调用 av_error = avcodec_open2(codec_ctx, codec, NULL); 这句一调用就有x264_malloc memory leak 出来了。 而且是泄露的个数是可以计算出来,是codec_ctx->qmax - codec_ctx->qmin + 1个泄露。所以在想是不是x264设置参数的问题导致。 求大神。

ffmpeg 无法定位程序输入点avcodec_alloc_context3

从zeranoe 下载的开发库 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <libavcodec/avcodec.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> #pragma comment(lib, "avcodec.lib") #pragma comment(lib,"avutil.lib") int main(int argc, char **argv) { const char *filename, *codec_name; const AVCodec *codec; AVCodecContext *c = NULL; int i, ret, x, y; FILE *f; AVFrame *frame; AVPacket *pkt; uint8_t endcode[] = { 0, 0, 1, 0xb7 }; if (argc <= 2) { fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]); exit(0); } filename = argv[1]; codec_name = argv[2]; avcodec_register_all(); /* find the mpeg1video encoder */ codec = avcodec_find_encoder_by_name(codec_name); if (!codec) { fprintf(stderr, "Codec '%s' not found\n", codec_name); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } av_opt_set(c->priv_data, "turn", "zerolatency", 0); return 0; } 只要加上av_opt_set(c->priv_data, "turn", "zerolatency", 0); 就会出现无法定位输入点 ```

调用ffmpeg接口解码H264数据流,无法解码非关键帧

调用ffmpeg的avcodec_decode_video2接口解码H264数据帧,为什么只能解码关键帧,非关键帧都解码不到呢,代码如下: AVCodec *codec; AVPacket packet; AVFrame *pFrame; AVCodecContext *pcodec; av_init_packet(&packet); av_register_all(); codec = avcodec_find_decoder(AV_CODEC_ID_H264); if(!codec) { fprintf(stderr, "Codec not found\n"); return 0; } pcodec = avcodec_alloc_context3(codec); if (!pcodec) { fprintf(stderr, "Could not allocate audio codec context\n"); return 0; } pcodec->extradata =(uint8_t *)malloc(51); pcodec->extradata_size = 51; memcpy(pcodec->extradata, sps,43); memcpy(pcodec->extradata+43, pps,8); if(avcodec_open2(pcodec, codec,NULL) >= 0) pFrame = avcodec_alloc_frame();// Allocate video frame else return -1; int got_picture; packet.data = pBuffer;//这里填入一个指向完整H264数据帧的指针 packet.size = dwBufsize;//这个填入H264数据帧的大小 //printf("size of packet=%d\n",sizeof(packet)); printf("packet->size=%d\n",packet.size); int DecodeRet=avcodec_decode_video2(pcodec, pFrame, &got_picture, &packet); if (DecodeRet < 0) { printf("Decode Error.\n"); return DecodeRet; }

avcodec_decode_video2()解码不成功

调用ffmpeg的库从文件中读出视频流信息,利用av_read_frame提取帧,最后调用avcodec_decode_video2接口对帧进行解码,代码如下: AVFormatContext *pFormatCtx; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame2; AVPacket packet2; int H264GetStream() { int i, videoindex; char filepath[]="sample.mp4"; av_register_all(); pFormatCtx = avformat_alloc_context(); if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){ printf("无法打开文件\n"); return -1; } if(avformat_find_stream_info(pFormatCtx,NULL)<0) { printf("Couldn't find stream information.\n"); return -1; } videoindex=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoindex=i; break; } if(videoindex==-1) { printf("Didn't find a video stream.\n"); return -1; } pCodecCtx=pFormatCtx->streams[videoindex]->codec; pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { printf("Codec not found.\n"); return -1; } printf("pCodec=%d\n",pCodec->id); if(avcodec_open2(pCodecCtx, pCodec,NULL)<0) { printf("Could not open codec.\n"); return -1; } pFrame2=avcodec_alloc_frame(); int ret, got_picture; int y_size = pCodecCtx->width * pCodecCtx->height; //packet2=(AVPacket *)malloc(sizeof(AVPacket)); //av_new_packet(packet2, y_size); av_init_packet(&packet2); char filepath_out[]="bigbuckbunny_1920x1080.yuv"; fp_out = fopen(filepath_out, "wb"); if (!fp_out) { printf("Could not open output YUV file\n"); return -1; } //输出一下信息----------------------------- printf("文件信息-----------------------------------------\n"); av_dump_format(pFormatCtx,0,filepath,0); printf("-------------------------------------------------\n"); //------------------------------ while(av_read_frame(pFormatCtx, &packet2)>=0) { printf("packet2->stream_index=%d\n",packet2.stream_index); printf("videoindex=%d\n",videoindex); if(packet2.stream_index==videoindex) { printf("decode start!"); //packet->data[0]=0;packet->data[1]=0;packet->data[2]=0;packet->data[3]=1; // packet->size-=4; printf("packet2->data=%d %d %d %d\n",packet2.data[0],packet2.data[1],packet2.data[2],packet2.data[3]); printf("packet2->size=%d\n",packet2.size); ret = avcodec_decode_video2(pCodecCtx, pFrame2, &got_picture, &packet2); printf("got_picture=%x\n",got_picture); if(ret < 0) { printf("decode error!\n"); return -1; } if(got_picture) { printf("got_picture=%x\n",got_picture); //Y, U, V int i; for(i=0;i<pFrame->height;i++) { fwrite(pFrame->data[0]+pFrame->linesize[0]*i,1,pFrame->width,fp_out); } for(i=0;i<pFrame->height/2;i++) { fwrite(pFrame->data[1]+pFrame->linesize[1]*i,1,pFrame->width/2,fp_out); } for(i=0;i<pFrame->height/2;i++) { fwrite(pFrame->data[2]+pFrame->linesize[2]*i,1,pFrame->width/2,fp_out); } printf("Succeed to decode 1 frame!\n"); } } av_free_packet(&packet2); } //av_free(pFrameYUV); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; } 每次运行到ret = avcodec_decode_video2(pCodecCtx, pFrame2, &got_picture, &packet2)这一步程序就不再运行下去了,也没有任何返回值。 在这里打印信息检查了一下 while(av_read_frame(pFormatCtx, &packet2)>=0) { printf("packet2->stream_index=%d\n",packet2.stream_index); printf("videoindex=%d\n",videoindex); 发现packet2.stream_index的值一直不变,按道理应该还有一路音频流。 程序是在linux平台下运行的,求问哪里出错了!

ffmpeg解码MediaCodec的h264编码问题

安卓下用MediaCodec的h264编码: ``` boolean eof = false; MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); ByteBuffer[] outputBuffers = null; boolean sendKeyFrame = false; while (!eof) { int bufIndex = codec.dequeueOutputBuffer(bufferInfo, -1); eof = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; try { if (bufIndex >= 0) { if (outputBuffers == null) { outputBuffers = codec.getOutputBuffers(); } ByteBuffer codecBuffer = outputBuffers[bufIndex]; codecBuffer.position(bufferInfo.offset); codecBuffer.limit(bufferInfo.offset + bufferInfo.size); byte[] buf = new byte[bufferInfo.size]; codecBuffer.get(buf, 0, bufferInfo.size); Socket.sendVideo(buf); // 发送数据 } else if (bufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { outputBuffers = null; } else if (bufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { MediaFormat outputFormat = codec.getOutputFormat(); } } finally { if (bufIndex >= 0) { codec.releaseOutputBuffer(bufIndex, false); } } } ``` PC下vc使用ffmpeg参考网上的解码h264流 https://blog.csdn.net/xushan239/article/details/79028111 https://www.cnblogs.com/lidabo/p/3326502.html 参考各种等等, 错误: avcodec_decode_video2或者avcodec_send_packet返回AVERROR_INVALIDD(-1094995529) 要不就是在avformat_open_input里无限循环read_packet 问: 哪里出问题? 本人对ffmpeg、MediaCodec都不熟悉,谁能帮忙解决一下?

ffmpeg解码h264视频流的问题

先上代码: int VideoDecoder_Decode(X264_H dwHandle, uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int nOutSize, int *nWidth, int *nHeight)//nOutSize { X264_Decoder_Handle *pHandle; //*i_frame_size = 0; if (dwHandle == 0) { return -1; } pHandle = (X264_Decoder_Handle *)dwHandle; //pHandle->inbuf_ptr = pDataIn; //pHandle->inSize = nInSize; pHandle->avpkt.size = nInSize; pHandle->avpkt.data = pDataIn; while (pHandle->avpkt.size > 0) { //LOGI("avcodec_decode_video2\n"); //pHandle->outSize = avcodec_decode_video2(pHandle->c, pHandle->picture, &pHandle->got_picture, // pHandle->inbuf_ptr, pHandle->inSize); pHandle->comsumedSize = avcodec_decode_video2(pHandle->c, pHandle->picture, &pHandle->got_picture, &(pHandle->avpkt)); if (pHandle->comsumedSize < 0) { //LOGE("Error while decoding frame InSize = %d comsumedSize = %d\n", pHandle->avpkt.size,pHandle->comsumedSize); //exit(1); printf("222222222222222222222222222222222222222222222222222222222222222"); return -1; } if (pHandle->got_picture) { //printf("saving frame %3d\n", pHandle->frame); fflush(stdout); /* the picture is allocated by the decoder. no need to free it */ *nWidth = pHandle->c->width; *nHeight = pHandle->c->height; if(nOutSize >= (pHandle->c->width)*(pHandle->c->height)*3/2) { pgm_save2(pHandle->picture->data[0], pHandle->picture->linesize[0],pHandle->c->width, pHandle->c->height,pDataOut); pgm_save2(pHandle->picture->data[1], pHandle->picture->linesize[1],pHandle->c->width/2, pHandle->c->height/2,pDataOut +pHandle->c->width * pHandle->c->height); pgm_save2(pHandle->picture->data[2], pHandle->picture->linesize[2],pHandle->c->width/2, pHandle->c->height/2,pDataOut +pHandle->c->width * pHandle->c->height*5/4); } pHandle->frame_count++; } if (pHandle->avpkt.data) { pHandle->avpkt.size -= pHandle->comsumedSize; pHandle->avpkt.data += pHandle->comsumedSize; } } printf("nOutSize: %d (pHandle->c->width)*(pHandle->c->height)*3/2: %d",nOutSize,(pHandle->c->width)*(pHandle->c->height)*3/2); if(nOutSize < (pHandle->c->width)*(pHandle->c->height)*3/2) { printf("33333333333333333333333333333333333333333333333333333333333333"); // printf("nOutSize: %d (pHandle->c->width)*(pHandle->c->height)*3/2: %d",nOutSize,(pHandle->c->width)*(pHandle->c->height)*3/2); return -1; } return 0; } 用ffmpeg支持64的解码库解码时,这段解码代码在iphone5及以下(32位设备)解码时没问题,但在iphone5以上设备(64位设备)上解码时在以下代码处崩溃了,有人说是地址不匹配: pHandle->avpkt.size = nInSize; pHandle->avpkt.data = pDataIn; 崩溃信息如下: ![图片说明](https://img-ask.csdn.net/upload/201508/05/1438745263_605799.png) 到底是什么原因呢,又该怎么解决,哪位大神能够帮忙解答一下,不胜感激....

FFMPEG实时解码RTP传输的H264流视频花屏

自己用QT写的程序,在PC上采集视频编码RTP打包发送。如果发送给自己,然后用VLC播放的话是可以正常显示的(尽管延迟会不断增大,这个问题再待解决),但是用自己编的软件确无法正常显示,能看到一瞬间有部分画面正常,然后一会画面就糊掉了。 同样的代码, 我在树莓派上,用OPENMAX硬件加速编码,然后同样的打包方式发送,发送给树莓派自己或者给PC,都能正常地显示。 不知道这个是哪部分出了原因?到底是FFMPEG编码部分出问题,还是接收的代码有问题?? 结果如图。。。![图片说明](https://img-ask.csdn.net/upload/201510/25/1445754428_146815.jpg) 然后程序会不断报类似如下错误 [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1000 DC, 1000 AC, 1000 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1000 DC, 1000 AC, 1000 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment [h264 @ 17653080] concealing 1040 DC, 1040 AC, 1040 MV errors in P frame [h264 @ 17653080] Cannot use next picture in error concealment

ffmpeg用rtmp做音视频推流同步问题

最近在研究ffmpeg,想做个视频聊天demo. 研究了雷博的博客,视频单独推流没问题,音频单独推流也没得问题。但是同步的时候问题来了。也不知道自己错在哪里 新手,没有C币 只能厚颜向大家提问了。 ``` while (1) { //Wait SDL_WaitEvent(&event); if (event.type == SFM_REFRESH_EVENT) { av_init_packet(dec_packet); //Get an AVPacket if (av_compare_ts(cur_pts_v, ifmt_ctx_video->streams[in_videoindex]->time_base, cur_pts_a, ifmt_ctx_audio->streams[in_audioindex]->time_base) < 0) { got_frame = -1; got_packet = -1; if (av_read_frame(ifmt_ctx_video, dec_packet) >= 0) { if (dec_packet->stream_index == in_videoindex) { pFrame_vedio = av_frame_alloc(); if (!pFrame_vedio) { printf("alloc pFrame Failed.\n"); return -1; } //ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); ret = avcodec_send_packet(inCodecCtx_v, dec_packet); got_frame = avcodec_receive_frame(inCodecCtx_v, pFrame_vedio); if (ret < 0) { av_frame_free(&pFrame_vedio); printf("Decode Error.\n"); return -1; } if (got_frame == 0) { //转码成YUV格式 sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame_vedio->data, pFrame_vedio->linesize, 0, inCodecCtx_v->height, pFrameYUV->data, pFrameYUV->linesize); sws_scale(img_convert_ctx_SDL, (const unsigned char* const*)pFrame_vedio->data, pFrame_vedio->linesize, 0, inCodecCtx_v->height, pFrameYUV_SDL->data, pFrameYUV_SDL->linesize); //初始化封装包 enc_packet.data = NULL; enc_packet.size = 0; av_init_packet(&enc_packet); //编码 //ret = avcodec_encode_video2(oCodecCtx, &enc_packet, pFrameYUV, &got_encpicture); ret = avcodec_send_frame(outCodecCtx_v, pFrameYUV); //FIX : non-strictly-monotonic PTS AVRational time_base_in = { 1, AV_TIME_BASE }; //{ 1, 1000000 }; AVRational time_base_conert = outCodecCtx_v->time_base;//{ 1, 1000 }; pFrameYUV->pts = av_rescale_q(dec_packet->pts, time_base_in, time_base_conert); if (ret < 0) { av_frame_free(&pFrame_vedio); printf("Encode Error.\n"); return -1; } got_packet = avcodec_receive_packet(outCodecCtx_v, &enc_packet); if (got_packet == 0) { enc_packet.stream_index = out_video_st->index; //FIX:No PTS (Example: Raw H.264) //Simple Write PTS if (enc_packet.pts == AV_NOPTS_VALUE) { //Write PTS AVRational time_base1 = ofmt_ctx->streams[out_videoindex]->time_base; //Duration between 2 frames (us) int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(ofmt_ctx->streams[out_videoindex]->r_frame_rate); //Parameters enc_packet.pts = (double)(frame_index*calc_duration) / (double)(av_q2d(time_base1)*AV_TIME_BASE); enc_packet.dts = enc_packet.pts; enc_packet.duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE); } if (dec_packet->stream_index == in_videoindex) { //Delay AVRational time_base = { 1, AV_TIME_BASE };//{ 1, 1000 }; AVRational time_base_q = ofmt_ctx->streams[out_videoindex]->time_base; int64_t pts_time = av_rescale_q(dec_packet->dts, time_base, time_base_q); int64_t now_time = av_rescale_q(av_gettime(), time_base, time_base_q); if (pts_time > now_time) av_usleep(pts_time - now_time); } //Write PTS AVRational time_base = ofmt_ctx->streams[out_videoindex]->time_base;//{ 1, 1000 }; AVRational r_framerate1 = ifmt_ctx_video->streams[in_videoindex]->r_frame_rate;// { 50, 2 }; AVRational time_base_q = { 1, AV_TIME_BASE }; //Duration between 2 frames (us) int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1)); enc_packet.pts = av_rescale_q(frame_index*calc_duration, time_base_q, time_base); enc_packet.dts = enc_packet.pts; enc_packet.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base)); enc_packet.pos = -1; //Print to Screen if (enc_packet.stream_index == in_videoindex) { frame_index++; printf("%8d Send video frames to output URL\n", frame_index); } cur_pts_v = enc_packet.pts; //写到输出上下文 ret = av_interleaved_write_frame(ofmt_ctx, &enc_packet); } av_packet_unref(&enc_packet); } av_frame_free(&pFrame_vedio); } av_packet_unref(dec_packet); #if USE_SDL //int y_size = iCodecCtx->width * iCodecCtx->height; ////SDL--------------------------- //// 设置纹理数据 //pFrameYUV_SDL->data[0] = out_buffer; // Y //pFrameYUV_SDL->data[1] = out_buffer + y_size; // U //pFrameYUV_SDL->data[2] = out_buffer + y_size * 3 / 2; // V #if 0 SDL_UpdateTexture(sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]); #else SDL_UpdateYUVTexture(sdlTexture, &rect, pFrameYUV_SDL->data[0], pFrameYUV_SDL->linesize[0], pFrameYUV_SDL->data[1], pFrameYUV_SDL->linesize[1], pFrameYUV_SDL->data[2], pFrameYUV_SDL->linesize[2]); #endif // 清理渲染器 SDL_RenderClear(sdlRenderer); // 将纹理数据copy到渲染器 //将sdlRect区域的图像显示到dstsdlRect区域 //SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect ); SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &rect); // 显示 SDL_RenderPresent(sdlRenderer); //SDL End----------------------- #endif } } else { const int output_frame_size = outCodecCtx_a->frame_size; //int finished = 0; av_init_packet(dec_packet); dec_packet->data = NULL; dec_packet->size = 0; got_frame = -1; got_packet = -1; if (av_read_frame(ifmt_ctx_audio, dec_packet) >= 0) { if (dec_packet->stream_index == in_audioindex) { pFrame_audio = av_frame_alloc(); if (!pFrame_audio) { printf("alloc pFrame Failed.\n"); return -1; } if (dec_packet->stream_index >= stream_mapping_size || stream_mapping[dec_packet->stream_index] < 0) { av_packet_unref(dec_packet); continue; } //ret = avcodec_decode_audio4(inCodecCtx_a, pFrame, &got_picture, packet); int ret = avcodec_send_packet(inCodecCtx_a, dec_packet); got_frame = avcodec_receive_frame(inCodecCtx_a, pFrame_audio); if (ret < 0) { av_frame_free(&pFrame_audio); printf("Decode Error.\n"); return -1; } if (got_frame == 0) { //写入fifo while (true) { int fifo_size = av_audio_fifo_size(fifo); if (fifo_size >= output_frame_size) break; uint8_t **converted_input_samples; converted_input_samples = (uint8_t **)calloc(outCodecCtx_a->channels, sizeof(converted_input_samples)); ret = av_samples_alloc(converted_input_samples, NULL, outCodecCtx_a->channels, pFrame_audio->nb_samples, outCodecCtx_a->sample_fmt, 0); //swr_convert(au_convert_ctx, pFrameMP3->data, pFrameMP3->nb_samples, (const uint8_t**)m_ain, pFrame_audio->nb_samples); int conver_num = swr_convert(au_convert_ctx, converted_input_samples, pFrame_audio->nb_samples, (const uint8_t**)pFrame_audio->extended_data, pFrame_audio->nb_samples); ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + pFrame_audio->nb_samples); ret = av_audio_fifo_write(fifo, (void **)converted_input_samples, conver_num); } av_init_packet(&enc_packet); enc_packet.data = NULL; enc_packet.size = 0; float sumlen = av_audio_fifo_size(fifo); int num = 0; //从fifo读出 while (true) { int fifo_size = av_audio_fifo_size(fifo); if (fifo_size < output_frame_size) break; const int frame_size = FFMIN(av_audio_fifo_size(fifo), outCodecCtx_a->frame_size); AVFrame *covert_frame; covert_frame = av_frame_alloc(); covert_frame->nb_samples = output_frame_size; covert_frame->channel_layout = outCodecCtx_a->channel_layout; covert_frame->format = outCodecCtx_a->sample_fmt; covert_frame->sample_rate = outCodecCtx_a->sample_rate; ret = av_frame_get_buffer(covert_frame, 0); ret = av_audio_fifo_read(fifo, (void **)covert_frame->data, frame_size); if (covert_frame) { covert_frame->pts = audio_pts; audio_pts += covert_frame->nb_samples; } ret = avcodec_send_frame(outCodecCtx_a, covert_frame); got_packet = avcodec_receive_packet(outCodecCtx_a, &enc_packet); if (got_packet == 0) { frame_index_a++; AVRational timebase = {1,AV_TIME_BASE }; int64_t cal_duration = AV_TIME_BASE *(float)covert_frame->nb_samples / (float)covert_frame->sample_rate; enc_packet.pts = av_rescale_q_rnd(audio_pts, outCodecCtx_a->time_base, ofmt_ctx->streams[out_audio_st->index]->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); enc_packet.dts = enc_packet.pts; enc_packet.duration = av_rescale_q_rnd(cal_duration, timebase, ofmt_ctx->streams[out_audio_st->index]->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); //int64_t cal_duration = AV_TIME_BASE *(float)covert_frame->nb_samples / (float)covert_frame->sample_rate; //enc_packet.pos = -1; //enc_packet.pts = frame_index_a*cal_duration; //enc_packet.dts = enc_packet.pts; //enc_packet.duration = cal_duration; AVRational time_base = ofmt_ctx->streams[out_audioindex]->time_base;//{ 1, 1000 }; AVRational time_base_q = { 1, AV_TIME_BASE }; //Delay int64_t pts_time = av_rescale_q(enc_packet.pts, time_base, time_base_q); int64_t now_time = av_gettime() - start_time; if (pts_time > now_time) av_usleep(pts_time - now_time); //Print to Screen if (enc_packet.stream_index == in_audioindex) { printf("Send %8d audio frames to output URL\n", frame_index_a); } cur_pts_a = enc_packet.pts; ret = av_interleaved_write_frame(ofmt_ctx, &enc_packet); } av_frame_free(&covert_frame); } av_packet_unref(&enc_packet); av_packet_unref(dec_packet); av_frame_free(&pFrame_audio); } } } av_packet_unref(dec_packet); } } else if (event.type == SDL_QUIT) { thread_exit = 1; } else if(event.type == SFM_BREAK_EVENT) { break; } } ```

为什么海思硬件解码不支持ffmpeg转出的h264视频

我用ffmpeg把MP4文件准换成h264,用海思的示例代码都不能播放,海思自己提供的示例h264视频都可以正常播放,用ffmpeg转出来的h264有什么不同吗?

FFmpeg 解码h265 视频时候怎么 过滤 花屏的那一帧

FFmpeg 解码h265视频时候 当码率过高会出现花屏,请问怎么过滤这一帧呢,找到了在hevc_refs.c文件的 find_ref_idx 函数里面打印出的错误帧信息 4.0.2版本的

技术大佬:我去,你写的 switch 语句也太老土了吧

昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!” 来看看小王写的代码吧,看完不要骂我装逼啊。 private static String createPlayer(PlayerTypes p...

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

CSDN:因博主近期注重写专栏文章(已超过150篇),订阅博主专栏人数在突增,近期很有可能提高专栏价格(已订阅的不受影响),提前声明,敬请理解!

CSDN:因博主近期注重写专栏文章(已超过150篇),订阅博主专栏人数在突增,近期很有可能提高专栏价格(已订阅的不受影响),提前声明,敬请理解! 目录 博客声明 大数据了解博主粉丝 博主的粉丝群体画像 粉丝群体性别比例、年龄分布 粉丝群体学历分布、职业分布、行业分布 国内、国外粉丝群体地域分布 博主的近期访问每日增量、粉丝每日增量 博客声明 因近期博主写专栏的文章越来越多,也越来越精细,逐步优化文章。因此,最近一段时间,订阅博主专栏的人数增长也非常快,并且专栏价

我说我不会算法,阿里把我挂了。

不说了,字节跳动也反手把我挂了。

培训班出来的人后来都怎么样了?(二)

接着上回说,培训班学习生涯结束了。后面每天就是无休止的背面试题,不是没有头脑的背,培训公司还是有方法的,现在回想当时背的面试题好像都用上了,也被问到了。回头找找面试题,当时都是打印下来天天看,天天背。 不理解呢也要背,面试造飞机,上班拧螺丝。班里的同学开始四处投简历面试了,很快就有面试成功的,刚开始一个,然后越来越多。不知道是什么原因,尝到胜利果实的童鞋,不满足于自己通过的公司,嫌薪水要少了,选择...

面试了一个 31 岁程序员,让我有所触动,30岁以上的程序员该何去何从?

最近面试了一个31岁8年经验的程序猿,让我有点感慨,大龄程序猿该何去何从。

大三实习生,字节跳动面经分享,已拿Offer

说实话,自己的算法,我一个不会,太难了吧

程序员垃圾简历长什么样?

已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份 这篇文章会用实例告诉你,什么是差的程序员简历! 疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。 就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》 一石激起千层浪,三天收到两百多封简历。 花光了两个星期的所有空闲时...

工作八年,月薪60K,裸辞两个月,投简历投到怀疑人生!

近日,有网友在某职场社交平台吐槽,自己裸辞两个月了,但是找工作却让自己的心态都要崩溃了,全部无果,不是已查看无回音,就是已查看不符合。 “工作八年,两年一跳,裸辞两个月了,之前月薪60K,最近找工作找的心态崩了!所有招聘工具都用了,全部无果,不是已查看无回音,就是已查看不符合。进头条,滴滴之类的大厂很难吗???!!!投简历投的开始怀疑人生了!希望 可以收到大厂offer” 先来看看网...

97年世界黑客编程大赛冠军作品(大小仅为16KB),惊艳世界的编程巨作

这是世界编程大赛第一名作品(97年Mekka ’97 4K Intro比赛)汇编语言所写。 整个文件只有4095个字节, 大小仅仅为16KB! 不仅实现了3D动画的效果!还有一段震撼人心的背景音乐!!! 内容无法以言语形容,实在太强大! 下面是代码,具体操作看最后! @echo off more +1 %~s0|debug e100 33 f6 bf 0 20 b5 10 f3 a5...

不要再到处使用 === 了

我们知道现在的开发人员都使用 === 来代替 ==,为什么呢?我在网上看到的大多数教程都认为,要预测 JavaScript 强制转换是如何工作这太复杂了,因此建议总是使用===。这些都...

什么是a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站?00后的世界我不懂!

A站 AcFun弹幕视频网,简称“A站”,成立于2007年6月,取意于Anime Comic Fun,是中国大陆第一家弹幕视频网站。A站以视频为载体,逐步发展出基于原生内容二次创作的完整生态,拥有高质量互动弹幕,是中国弹幕文化的发源地;拥有大量超粘性的用户群体,产生输出了金坷垃、鬼畜全明星、我的滑板鞋、小苹果等大量网络流行文化,也是中国二次元文化的发源地。 B站 全称“哔哩哔哩(bilibili...

终于,月薪过5万了!

来看几个问题想不想月薪超过5万?想不想进入公司架构组?想不想成为项目组的负责人?想不想成为spring的高手,超越99%的对手?那么本文内容是你必须要掌握的。本文主要详解bean的生命...

MySQL性能优化(五):为什么查询速度这么慢

前期回顾: MySQL性能优化(一):MySQL架构与核心问题 MySQL性能优化(二):选择优化的数据类型 MySQL性能优化(三):深入理解索引的这点事 MySQL性能优化(四):如何高效正确的使用索引 前面章节我们介绍了如何选择优化的数据类型、如何高效的使用索引,这些对于高性能的MySQL来说是必不可少的。但这些还完全不够,还需要合理的设计查询。如果查询写的很糟糕,即使表结构再合理、索引再...

用了这个 IDE 插件,5分钟解决前后端联调!

点击上方蓝色“程序猿DD”,选择“设为星标”回复“资源”获取独家整理的学习资料!作者 |李海庆我是一个 Web 开发前端工程师,受到疫情影响,今天是我在家办公的第78天。开发了两周,...

大厂的 404 页面都长啥样?最后一个笑了...

每天浏览各大网站,难免会碰到404页面啊。你注意过404页面么?猿妹搜罗来了下面这些知名网站的404页面,以供大家欣赏,看看哪个网站更有创意: 正在上传…重新上传取消 腾讯 正在上传…重新上传取消 网易 淘宝 百度 新浪微博 正在上传…重新上传取消 新浪 京东 优酷 腾讯视频 搜...

【高并发】高并发秒杀系统架构解密,不是所有的秒杀都是秒杀!

网上很多的文章和帖子中在介绍秒杀系统时,说是在下单时使用异步削峰来进行一些限流操作,那都是在扯淡! 因为下单操作在整个秒杀系统的流程中属于比较靠后的操作了,限流操作一定要前置处理,在秒杀业务后面的流程中做限流操作是没啥卵用的。

自从喜欢上了B站这12个UP主,我越来越觉得自己是个废柴了!

不怕告诉你,我自从喜欢上了这12个UP主,哔哩哔哩成为了我手机上最耗电的软件,几乎每天都会看,可是吧,看的越多,我就越觉得自己是个废柴,唉,老天不公啊,不信你看看…… 间接性踌躇满志,持续性混吃等死,都是因为你们……但是,自己的学习力在慢慢变强,这是不容忽视的,推荐给你们! 都说B站是个宝,可是有人不会挖啊,没事,今天咱挖好的送你一箩筐,首先啊,我在B站上最喜欢看这个家伙的视频了,为啥 ,咱撇...

代码注释如此沙雕,会玩还是你们程序员!

某站后端代码被“开源”,同时刷遍全网的,还有代码里的那些神注释。 我们这才知道,原来程序员个个都是段子手;这么多年来,我们也走过了他们的无数套路… 首先,产品经理,是永远永远吐槽不完的!网友的评论也非常扎心,说看这些代码就像在阅读程序员的日记,每一页都写满了对产品经理的恨。 然后,也要发出直击灵魂的质问:你是尊贵的付费大会员吗? 这不禁让人想起之前某音乐app的穷逼Vip,果然,穷逼在哪里都是...

Java14 新特性解读

Java14 已于 2020 年 3 月 17 号发布,官方特性解读在这里:https://openjdk.java.net/projects/jdk/14/以下是个人对于特性的中文式...

爬虫(101)爬点重口味的

小弟最近在学校无聊的很哪,浏览网页突然看到一张图片,都快流鼻血。。。然后小弟冥思苦想,得干一点有趣的事情python 爬虫库安装https://s.taobao.com/api?_ks...

疫情后北上广深租房价格跌了吗? | Alfred数据室

去年3月份我们发布了《北上广深租房图鉴》(点击阅读),细数了北上广深租房的各种因素对租房价格的影响。一年过去了,在面临新冠疫情的后续影响、城市尚未完全恢复正常运转、学校还没开学等情况下...

面试官给我挖坑:a[i][j] 和 a[j][i] 有什么区别?

点击上方“朱小厮的博客”,选择“设为星标”后台回复&#34;1024&#34;领取公众号专属资料本文以一个简单的程序开头——数组赋值:int LEN = 10000; int[][] ...

又一起程序员被抓事件

就在昨天互联网又发生一起让人心酸的程序员犯罪事件,著名的百度不限速下载软件 Pandownload PC 版作者被警方抓获。案件大致是这样的:软件的作者不仅非法盗取用户数据,还在QQ群进...

应聘3万的职位,有必要这么刁难我么。。。沙雕。。。

又一次被面试官带到坑里面了。面试官:springmvc用过么?我:用过啊,经常用呢面试官:springmvc中为什么需要用父子容器?我:嗯。。。没听明白你说的什么。面试官:就是contr...

太狠了,疫情期间面试,一个问题砍了我5000!

疫情期间找工作确实有点难度,想拿到满意的薪资,确实要点实力啊!面试官:Spring中的@Value用过么,介绍一下我:@Value可以标注在字段上面,可以将外部配置文件中的数据,比如可以...

Intellij IDEA 美化指南

经常有人问我,你的 IDEA 配色哪里搞的,我会告诉他我自己改的。作为生产力工具,不但要顺手而且更要顺眼。这样才能快乐编码,甚至降低 BUG 率。上次分享了一些 IDEA 有用的插件,反...

【相亲】96年程序员小哥第一次相亲,还没开始就结束了

颜值有点高,条件有点好

太厉害了,终于有人能把TCP/IP 协议讲的明明白白了

一图看完本文 一、 计算机网络体系结构分层 计算机网络体系结构分层 计算机网络体系结构分层 不难看出,TCP/IP 与 OSI 在分层模块上稍有区别。OSI 参考模型注重“通信协议必要的功能是什么”,而 TCP/IP 则更强调“在计算机上实现协议应该开发哪种程序”。 二、 TCP/IP 基础 1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为...

腾讯面试题: 百度搜索为什么那么快?

我还记得去年面腾讯时,面试官最后一个问题是:百度/google的搜索为什么那么快? 这个问题我懵了,我从来没想过,搜素引擎的原理是什么 然后我回答:百度爬取了各个网站的信息,然后进行排序,当输入关键词的时候进行文档比对……巴拉巴拉 面试官:这不是我想要的答案 我内心 这个问题我一直耿耿于怀,终于今天,我把他写出来,以后再问,我直接把这篇文章甩给他!!! 两个字:倒排,将贯穿整篇文章,也是面试官...

相关热词 c# 局部 截图 页面 c#实现简单的文件管理器 c# where c# 取文件夹路径 c# 对比 当天 c# fir 滤波器 c# 和站 队列 c# txt 去空格 c#移除其他类事件 c# 自动截屏
立即提问