sdk-hwV1.3/external/eyesee-mpp/system/private/rtsp/IPCProgram/encodeH265.c

229 lines
7.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* encode.c
*
* Created on: 2014-8-16
* Author: liu
*/
#include <signal.h>
#include "camer.h"
#include "encode.h"
#include "libavformat/avformat.h"
//static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base,
// AVStream *st, AVPacket *pkt) {
// /* rescale output packet timestamp values from codec to stream timebase */
// pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base,
// AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
// pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base,
// AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
// pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);
// pkt->stream_index = st->index;
// /* Write the compressed frame to the media file. */
//// log_packet(fmt_ctx, pkt);
// return av_interleaved_write_frame(fmt_ctx, pkt);
//}
int flush_encoder(Encode* encode, unsigned int stream_index)
{
int ret;
int got_frame;
AVPacket enc_pkt;
while (1) {
printf("Flushing stream #%u encoder\n", stream_index);
//ret = encode_write_frame(NULL, stream_index, &got_frame);
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = avcodec_encode_video2(encode->pCodecCtx, &enc_pkt, NULL, &got_frame);
av_frame_free(NULL);
if (ret < 0) break;
if (!got_frame) {
printf("缓存数据编码成功1帧\n");
ret = 0;
break;
}
}
return ret;
}
int ffmpeg_init(Encode* encode)
{
int ret = 0;
avcodec_register_all();
encode->pCodec = avcodec_find_encoder(AV_CODEC_ID_H265);
if (!encode->pCodec) {
printf("没有找到合适的编码器!\n");
exit(1);
}
encode->pCodecCtx = avcodec_alloc_context3(encode->pCodec);
encode->pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
encode->pCodecCtx->width = encode->in_w;
encode->pCodecCtx->height = encode->in_h;
encode->pCodecCtx->time_base.num = 1;
encode->pCodecCtx->time_base.den = 10;
printf("encode %dx%d, and the time_base num: %d den: %d\n", encode->in_w, encode->in_h,
encode->pCodecCtx->time_base.num, encode->pCodecCtx->time_base.den);
encode->pCodecCtx->bit_rate = 200000;
encode->pCodecCtx->gop_size = 20;
encode->pCodecCtx->max_b_frames = 0;
//H264
//encode->pCodecCtx->me_range = 16;
//encode->pCodecCtx->max_qdiff = 4;
// encode->pCodecCtx->qmin = 8;
// encode->pCodecCtx->qmax = 31;
//encode->pCodecCtx->qcompress = 0.6;
// av_opt_set(encode->pCodecCtx->priv_data, "preset", "slow", 0);
av_opt_set(encode->pCodecCtx->priv_data, "profile", "baseline", 0);
av_opt_set(encode->pCodecCtx->priv_data, "preset", "superfast", 0);
av_opt_set(encode->pCodecCtx->priv_data, "tune", "zerolatency", 0);
//swscale init
enum AVPixelFormat sws_fmt = AV_PIX_FMT_YUYV422;
encode->sws_ctx =
sws_getContext(encode->pCodecCtx->width, encode->pCodecCtx->height, sws_fmt, encode->pCodecCtx->width,
encode->pCodecCtx->height, encode->pCodecCtx->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL);
if ((encode->src_size = av_image_alloc(encode->src_data, encode->src_linesize, encode->pCodecCtx->width,
encode->pCodecCtx->height, sws_fmt, 1)) < 0) {
fprintf(stderr, "Could not allocate source image\n");
return -1;
}
printf("========== src_size: %d\n", encode->src_size);
printf("========== src_height: %d\n", encode->pCodecCtx->height);
printf("========== src_width: %d\n", encode->pCodecCtx->width);
printf("========== src_linesize[0]: %d\n", encode->src_linesize[0]);
printf("========== src_linesize[1]: %d\n", encode->src_linesize[1]);
printf("========== src_linesize[2]: %d\n", encode->src_linesize[2]);
printf("========== src_linesize[3]: %d\n", encode->src_linesize[3]);
encode->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
if (!encode->bsfc) {
printf("bitstream_filter_init failed!\n");
av_bitstream_filter_close(encode->bsfc);
encode->bsfc = NULL;
}
if (avcodec_open2(encode->pCodecCtx, encode->pCodec, NULL) < 0) {
printf("编码器打开失败!\n");
return -1;
}
encode->picture = av_frame_alloc();
encode->picture->format = encode->pCodecCtx->pix_fmt;
encode->picture->width = encode->pCodecCtx->width;
encode->picture->height = encode->pCodecCtx->height;
ret = av_image_alloc(encode->picture->data, encode->picture->linesize, encode->pCodecCtx->width,
encode->pCodecCtx->height, encode->pCodecCtx->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "could not allow raw picture buffer\n");
exit(1);
}
return 0;
}
int ffmpeg_encode_end(Encode* encode)
{
//Flush Encoder
int ret = flush_encoder(encode, 0);
if (ret < 0) {
printf("Flushing encoder failed\n");
return -1;
}
//编码器相关资源清理
av_bitstream_filter_close(encode->bsfc);
avcodec_close(encode->pCodecCtx);
avcodec_free_context(&(encode->pCodecCtx));
av_free(encode->picture);
// avformat_free_context(encode->pFormatCtx);
//swscale格式转换相关资源释放
av_freep(&encode->src_data[0]);
sws_freeContext(encode->sws_ctx);
return 0;
}
static int is_stop;
static void encode_stop(int signo)
{
printf("\nloops! stop!!!\n");
is_stop = 1;
}
//
//int main(int argc, char* argv[]) {
// int got_picture = 0;
//
// signal(SIGINT, encode_stop);
// Encode ecd, *encode;
// encode = &ecd;
// Camera *camera_s, cam;
// camera_s = &cam;
//
// camera_s = calloc_camera();
// camera_s->width = 640;
// camera_s->height = 480;
// camera_s->type = V4L2_PIX_FMT_YUYV;
//// sleep(1);
// encode->in_w = camera_s->width;
// encode->in_h = camera_s->height; //宽高
// int i;
//// encode->out_file = "src01.h264"; //输出文件路径
//
// captureInit(camera_s);
// ffmpeg_init(encode);
// encode->tmp_file_fd = fopen("tmp", "w");
//
// for (i = 0; !is_stop; i++) {
// av_init_packet(&encode->pkt);
// encode->pkt.data = NULL;
// encode->pkt.size = 0;
// //读入YUV
// usleep(10000);
// while (read_frame(camera_s, encode->src_data[0]))
// ;
// sws_scale(encode->sws_ctx, (const uint8_t * const *) (encode->src_data),
// encode->src_linesize, 0, encode->pCodecCtx->height,
// encode->picture->data, encode->picture->linesize);
// //PTS
// encode->picture->pts = i;
// //编码
// int ret = avcodec_encode_video2(encode->pCodecCtx, &encode->pkt,
// encode->picture, &got_picture);
// if (ret < 0) {
// fprintf(stderr, "编码错误!\n");
// return -1;
// }
// if (got_picture == 1) {
// printf("编码成功1帧\n");
//// fwrite(encode->pkt.data, 1, encode->pkt.size, encode->tmp_file_fd);
// uint8_t *poutbuf;
// int poutbuf_size;
//
// int a = av_bitstream_filter_filter(encode->bsfc, encode->pCodecCtx,
// NULL, &poutbuf, &poutbuf_size, encode->pkt.data, encode->pkt.size,
// 0);
// if (a < 0) {
// fprintf(stderr, "bitstream_filter failed!\n");
// } else {
// fwrite(poutbuf, 1, poutbuf_size, encode->tmp_file_fd);
// }
//
// av_free_packet(&encode->pkt);
// }
// }
//
// ffmpeg_encode_end(encode);
// stop_capturing(camera_s);
// av_bitstream_filter_close(encode->bsfc);
// fclose(encode->tmp_file_fd);
//
// return 0;
//}