#include #include #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavutil/imgutils.h" //#include "libswresample/swresample.h" #include "libavcodec/avcodec.h" #include "libavutil/time.h" int rgbSize = 0; typedef unsigned char byte; uint8_t *out_buffer = NULL; AVCodec *videoCodec = NULL; AVFrame *frame = NULL; AVFrame *yuvFrame = NULL; AVCodecContext *videoCodecCtx = NULL; struct SwsContext* m_img_convert_ctx = NULL; void ffmpegLog() { } //打开解码器 int openDecoder(int width, int height) { int ret; int errorCode = 0; uint8_t *out_buffer = NULL; videoCodec = avcodec_find_decoder(AV_CODEC_ID_H264); videoCodecCtx = avcodec_alloc_context3(videoCodec); frame = av_frame_alloc(); yuvFrame = av_frame_alloc(); if ((errorCode = avcodec_open2(videoCodecCtx, videoCodec, NULL)) < 0) { return errorCode; } videoCodecCtx->width = width; videoCodecCtx->height = height; videoCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; rgbSize = videoCodecCtx->width * videoCodecCtx->height * 3 / 2; out_buffer = (unsigned char *)av_malloc(rgbSize); av_image_fill_arrays(yuvFrame->data, yuvFrame->linesize, out_buffer, AV_PIX_FMT_YUV420P, videoCodecCtx->width, videoCodecCtx->height, 1); m_img_convert_ctx = sws_getContext(videoCodecCtx->width, videoCodecCtx->height, videoCodecCtx->pix_fmt, videoCodecCtx->width, videoCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); printf("c 端已经打开编码器, 哈哈\n"); return 0; } void PrintArry(byte*data, size_t size) { printf("打印数组:"); for(size_t i = 0;i < size;i++) { printf("%02X", data[i]); } printf("\n"); } int feedData(byte*data, size_t size, byte* outBuffer) { int ret = -1; int len = videoCodecCtx->width*videoCodecCtx->height; AVPacket *videoPacket = av_packet_alloc(); av_new_packet(videoPacket, size); //printf("准备拷贝\n"); memcpy(videoPacket->data, data, size); //printf("准备解码\n"); uint64_t start = av_gettime(); avcodec_send_packet(videoCodecCtx, videoPacket); ret = avcodec_receive_frame(videoCodecCtx, frame); //PrintArry(data, size); uint64_t cost = av_gettime() - start/1000; printf("解码耗时 %d ms", cost); if(ret == 0) { ret = sws_scale(m_img_convert_ctx, (const uint8_t* const*)frame->data, frame->linesize, 0, videoCodecCtx->height, yuvFrame->data, yuvFrame->linesize); byte *p= outBuffer; memcpy(p, yuvFrame->data[0], len); p = p + len; memcpy(p, yuvFrame->data[1], len / 4); p = p + len / 4; memcpy(p, yuvFrame->data[2], len / 4); } if(ret < 0) { char temp[4096]; av_strerror(ret, temp, 4096); // printf("错误打印 %s \n", temp); } av_packet_free(&videoPacket); return ret; } //关闭解码器 void closeDecoder() { if(out_buffer) { free(out_buffer); } av_frame_unref(frame); av_frame_unref(yuvFrame); av_frame_free(&frame); av_frame_free(&yuvFrame); if (m_img_convert_ctx) { sws_freeContext(m_img_convert_ctx); } if (videoCodecCtx) { avcodec_free_context(&videoCodecCtx); } } int main(int argc, char**argv) { //openDecoder(720, 1280); return 0; }