2024年1月3日发(作者:)

//av_opt_set(c->priv_data, /*"preset"*/"et", /*"slow"*/NULL, 0);

//打开编码器

if (avcodec_open2(c, pCodecH264, NULL)<0) printf("不能打开编码库"); int size = c->width * c->height; rtmp_tool->yuv_buff = (uint8_t *)malloc((size * 3) / 2); // size for YUV 420

//图象编码

rtmp_tool->outbuf = (uint8_t*)malloc(outbuf_size); int u_size = 0;

const char * filename = "0_Data.h264"; rtmp_tool->f = fopen(filename, "wb"); if (!rtmp_tool->f) { printf("could not open %sn", filename); exit(1); } //初始化SwsContext

rtmp_tool->scxt = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR24, c->width, c->height, AV_PIX_FMT_YUV420P, SWS_POINT, NULL, NULL, NULL); rtmp_tool->c = c; return rtmp_tool;}char* push_rtsp(int* plus1,int len,void* vp) { Rtmp_tool *rtmp_tool =(Rtmp_tool *) vp; for (int i = 0; i < len; i++) { plus1[i] = (uint8_t)plus1[i]; }

AVCodecContext *c = rtmp_tool->c;// (AVCodecContext*)vp; printf("2 %d %dn", c->width, c->height); //--------------- AVPacket avpkt; AVFrame *m_pRGBFrame = rtmp_tool->m_pRGBFrame; AVFrame *m_pYUVFrame = rtmp_tool->m_pYUVFrame; /*unsigned char *pBmpBuf; pBmpBuf = new unsigned char[len];*/

//memcpy(rgb_buff, (uint8_t*)plus1, nDataLen); // avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)plus1, AV_PIX_FMT_RGB24, rtmp_tool->nWidth, rtmp_tool->nHeight); m_pRGBFrame->linesize[0] = c->width * 3; m_pRGBFrame->linesize[1] =0; m_pRGBFrame->linesize[2] =0; m_pRGBFrame->linesize[3] =0; m_pRGBFrame->format = AV_PIX_FMT_RGB24; m_pRGBFrame->width = rtmp_tool->nWidth; m_pRGBFrame->height = rtmp_tool->nHeight; uint8_t *p = m_pRGBFrame->data[0]; int y = 0, x = 0; for (y = 0; y < rtmp_tool->nHeight; y++) { for (x = 0; x < rtmp_tool->nWidth; x++) { *p++ = (uint8_t)plus1[(y*rtmp_tool->nWidth + x) * 3]; // R *p++ = (uint8_t)plus1[(y*rtmp_tool->nWidth + x) * 3 +1]; // G *p++ = (uint8_t)plus1[(y*rtmp_tool->nWidth + x) * 3 +2] ; // B } } printf("1 %d %d n", rtmp_tool->nWidth, rtmp_tool->nHeight); //将YUV buffer 填充YUV Frame

avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)rtmp_tool->yuv_buff, AV_PIX_FMT_YUV420P, rtmp_tool->nWidth, rtmp_tool->nHeight); // 翻转RGB图像

//m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (rtmp_tool->nHeight - 1); //m_pRGBFrame->linesize[0] *= -1; //m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (rtmp_tool->nHeight / 2 - 1); //m_pRGBFrame->linesize[1] *= -1; //m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (rtmp_tool->nHeight / 2 - 1); //m_pRGBFrame->linesize[2] *= -1; //将RGB转化为YUV

sws_scale(rtmp_tool->scxt, m_pRGBFrame->data, m_pRGBFrame->linesize, 0, c->height, m_pYUVFrame->data, m_pYUVFrame->linesize);

pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL) { printf("%d Codec not found n", cam_no); goto restart_stream; //return -1; } if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("%d Could not open codec.n", cam_no); goto restart_stream; continue; //return -1; } if (pCodecCtx->width <= 0 || pCodecCtx->height <= 0 || pCodecCtx->height >2000 || pCodecCtx->width >3000) { printf("cam %d pCodecCtx error 1 width %d height %d ", cam_no, pCodecCtx->width, pCodecCtx->height); goto restart_stream; } goto ok; restart_stream: printf("%d restart 1 ", cam_no); avformat_free_context(pFormatCtx); printf("restart 2 "); //avformat_close_input(&pFormatCtx); pFormatCtx = NULL; pFormatCtx = avformat_alloc_context(); printf("restart 3 "); //av_freep(aviobuffer); //printf("restart 4"); aviobuffer = (unsigned char *)av_malloc(1512); printf("restart 4 "); AVIOContext *avio2 = avio_alloc_context(aviobuffer, 1512, 0, &deviceInfo, read_buffer, NULL, NULL); pFormatCtx->pb = avio2; pFormatCtx->probesize = 1000 * 1024; pFormatCtx->max_analyze_duration = 10 * AV_TIME_BASE; if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0) { printf("2Couldn't open input stream %dn", cam_no); //return -1; } printf("restart 5n"); pCodec = NULL; continue; ok: break; } printf("camno:%d code name :%s width %d height %dn",cam_no, pCodec->name, pCodecCtx->width, pCodecCtx->height); AVFrame *pFrame, *pFrameYUV; pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc(); int ret, got_picture; if (g_errorcall) { char* cc; int length = strlen(pCodec->name); cc = new char[length + 1]; strcpy(cc, pCodec->name); g_errorcall(0, cam_no, pCodecCtx->width, pCodecCtx->height, cc, 11); } AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket)); struct SwsContext *img_convert_ctx; img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); uint8_t *out_buffer; printf("cam %d ready decode 2", cam_no); out_buffer = new uint8_t[avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height)]; avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); //av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1); printf("cam %d ready decode 3", cam_no); int dec_error_count = 0; int tmp_test = 0; while (av_read_frame(pFormatCtx, packet) >= 0) { if (packet->stream_index == videoindex) { //tmp_test++; if (packet->size < 50) { av_free_packet(packet); //printf("cam:%d packet is too small %dn", cam_no, packet->size); Sleep(3); continue; } if (g_errorcall != 0) g_errorcall(2, _no, 1, 2, "start decode",3); char str_decode[40]; sprintf(str_decode, "cam %d start decode", cam_no); SLOG1(str_decode); ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) { dec_error_count++; char str3[80]; sprintf(str3, "%d%s decode_error:%d error_count %d", cam_no, " Decode Error", ret, dec_error_count); SLOG1(str3); if (g_errorcall != 0) g_errorcall(1, _no, 0, 2, str3, 80); printf("cam:%d Decode Error got_picture %d decode_error_num %dn", cam_no, got_picture, dec_error_count); if (dec_error_count > 2) { dec_error_count = 0; // restart ffmpeg av_free_packet(packet);

Sleep(50); sws_freeContext(img_convert_ctx); img_convert_ctx = NULL; printf("cam %d sws_freeContext 1n", cam_no); //av_free(out_buffer);

//av_free(pFrameYUV); avcodec_close(pCodecCtx); //pCodecCtx = NULL; if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) { printf("Could not open codec.n"); return -1; } /*pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc();*/ //packet = (AVPacket *)av_malloc(sizeof(AVPacket)); printf("cam_no %d avcodec_open2 ok width:%d height:%dn", cam_no, pCodecCtx->width, pCodecCtx->height); img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

char str3[40]; sprintf(str3, "ffmpeg restart cam %d ", cam_no); SLOG1(str3); continue; } } if (got_picture) { if (g_errorcall != 0) g_errorcall(2, _no, 1, 2, "got_picture",4); char str3[40]; sprintf(str3, "cam %d got_picture", cam_no); SLOG1(str3); sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); /*fwrite(pFrameYUV->data[0], (pCodecCtx->width)*(pCodecCtx->height) * 3, 1, output);*/ tcallback((char*)pFrameYUV->data[0], pCodecCtx->height * pCodecCtx->width * 3, cam_no, pCodecCtx->height, pCodecCtx->width); } } av_free_packet(packet); Sleep(10); } sws_freeContext(img_convert_ctx); //av_free(out_buffer);

av_free(pFrameYUV); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0;}int tcp_init(char* ip, int port) { int res = tcpInit(ip, port); //printf("conn servert%dn", res); return res;}int ffmpeg_recv(int cam_no, FrameFunc tcallback(char* a, int size, int cam_no, int height, int width)){ av_register_all(); unsigned version = avcodec_version(); printf("FFmpeg version: %dn", version); AVFormatContext *pFormatCtx; int i, videoindex; AVCodecContext *pCodecCtx; AVCodec *pCodec; char filepath[] = "video.264"; avformat_network_init(); pFormatCtx = avformat_alloc_context(); //string patha = "C:Userssbd01Videosvideo.264"; //fp_open = fopen(patha.c_str(), "rb+"); unsigned char *aviobuffer = (unsigned char *)av_malloc(1512); AVIOContext *avio = avio_alloc_context(aviobuffer, 1512, 0, &cam_no, read_buffer, NULL, NULL); pFormatCtx->pb = avio; if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0) { printf("Couldn't open input stream.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; inb_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; } if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) { printf("Could not open codec.n"); return -1; } AVFrame *pFrame, *pFrameYUV; pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc(); int ret, got_picture; AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket)); struct SwsContext *img_convert_ctx; img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); uint8_t *out_buffer; out_buffer = new uint8_t[avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height)]; avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); while (av_read_frame(pFormatCtx, packet) >= 0) { if (packet->stream_index == videoindex) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) { printf("Decode Error.n"); return -1; } if (got_picture) { sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); /*fwrite(pFrameYUV->data[0], (pCodecCtx->width)*(pCodecCtx->height) * 3, 1, output);*/ tcallback((char*)pFrameYUV->data[0], pCodecCtx->height * pCodecCtx->width * 3, cam_no, pCodecCtx->height, pCodecCtx->width); } } av_free_packet(packet); } sws_freeContext(img_convert_ctx); //fclose(fp_open); //SDL_Quit(); //av_free(out_buffer);

av_free(pFrameYUV); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0;}//Callback

int file_buffer(void *opaque, uint8_t *buf, int buf_size) { FILE *fp_open = (FILE *)opaque; if (!feof(fp_open)) { int true_size = fread(buf, 1, buf_size, fp_open); return true_size; } else { return -1; }}int play_file(char* file_name, FrameFunc tcallback(char* a, int size,int num, int height, int width)){ av_register_all(); unsigned version = avcodec_version();

printf("FFmpeg version: %dn", version); AVFormatContext *pFormatCtx; int i, videoindex; AVCodecContext *pCodecCtx; AVCodec *pCodec; char filepath[] = "video.264"; //av_register_all(); avformat_network_init(); pFormatCtx = avformat_alloc_context(); string patha = "C:Userssbd01Videosvideo.264"; //patha = "C:"; FILE *fp_open = fopen(file_name, "rb+"); unsigned char *aviobuffer = (unsigned char *)av_malloc(32768); //printf("avio_alloc_context %dn", cam_no); AVIOContext *avio = avio_alloc_context(aviobuffer, 32768, 0, (void*)fp_open, file_buffer, NULL, NULL); pFormatCtx->pb = avio; //if (avformat_open_input(&pFormatCtx, patha.c_str(), NULL, NULL) != 0) { if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0) { printf("Couldn't open input stream.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; inb_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; } if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) { printf("Could not open codec.n"); return -1; } AVFrame *pFrame, *pFrameYUV; pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc(); /*if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf("Could not initialize SDL - %sn", SDL_GetError()); return -1; }*/ /*int screen_w = 0, screen_h = 0; SDL_Surface *screen; screen_w = pCodecCtx->width; screen_h = pCodecCtx->height; screen = SDL_SetVideoMode(screen_w, screen_h, 0, 0); if (!screen) { printf("SDL: could not set video mode - exiting:%sn", SDL_GetError()); return -1; } SDL_Overlay *bmp; bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen); SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = screen_w; rect.h = screen_h;*/ //SDL End------------------------

int ret, got_picture; AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket)); struct SwsContext *img_convert_ctx; img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); uint8_t *out_buffer; out_buffer = new uint8_t[avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height)]; avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); while (av_read_frame(pFormatCtx, packet) >= 0) { if (packet->stream_index == videoindex) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) {