123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #include <stdio.h>
- #include <unistd.h>
- #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;
- }
|