#include #include #include #include #include #include #include #include #include #include "ffmpeg.h" int decode(AVCodecContext *avctx, AVFrame *frame, uint8_t *data, int size, int *got_frame) { int ret; struct AVPacket pkt = {.data = data, .size = size}; *got_frame = 0; printf("avctx: %p\n", avctx); printf("avctx->internal: %p->%p\n", avctx, avctx->internal); ret = avcodec_send_packet(avctx, &pkt); av_packet_unref(&pkt); if (ret < 0) return ret == AVERROR_EOF ? 0 : ret; ret = avcodec_receive_frame(avctx, frame); if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) return ret; if (ret >= 0) *got_frame = 1; return 0; } int encode(AVCodecContext *avctx, AVPacket *pkt, int *got_packet, AVFrame *frame) { int ret; *got_packet = 0; ret = avcodec_send_frame(avctx, frame); if (ret < 0) return ret; ret = avcodec_receive_packet(avctx, pkt); if (!ret) *got_packet = 1; if (ret == AVERROR(EAGAIN)) return 0; return ret; } int avcodec_encode_jpeg(AVCodecContext *pCodecCtx, AVFrame *pFrame,AVPacket *packet) { AVCodec *jpegCodec = avcodec_find_encoder(AV_CODEC_ID_MJPEG); int ret = -1; if (!jpegCodec) { return ret; } AVCodecContext *jpegContext = avcodec_alloc_context3(jpegCodec); if (!jpegContext) { jpegCodec = NULL; return ret; } jpegContext->pix_fmt = AV_PIX_FMT_YUVJ420P; jpegContext->height = pFrame->height; jpegContext->width = pFrame->width; jpegContext->time_base= (AVRational){1,25}; ret = avcodec_open2(jpegContext, jpegCodec, NULL); if (ret < 0) { goto error; } int gotFrame; ret = encode(jpegContext, packet, &gotFrame, pFrame); if (ret < 0) { goto error; } error: avcodec_close(jpegContext); avcodec_free_context(&jpegContext); jpegCodec = NULL; return ret; } uint8_t *convert(AVCodecContext *pCodecCtx,AVFrame *pFrame,AVFrame *nFrame,int *size, int format) { struct SwsContext *img_convert_ctx = sws_getCachedContext( NULL, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pFrame->width, pFrame->height, format, SWS_BICUBIC, NULL, NULL, NULL ); nFrame->format = format; nFrame->width = pFrame->width; nFrame->height = pFrame->height; *size = av_image_get_buffer_size( format, pFrame->width, pFrame->height, 1); uint8_t *tmp_picture_buf = (uint8_t *)malloc(*size); av_image_fill_arrays(nFrame->data, nFrame->linesize, tmp_picture_buf, format, pFrame->width, pFrame->height, 1); sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, nFrame->height, nFrame->data, nFrame->linesize); sws_freeContext(img_convert_ctx); return tmp_picture_buf; } int avcodec_encode_jpeg_nv12(AVCodecContext *pCodecCtx, AVFrame *pFrame,AVFrame *nFrame,AVPacket *packet) { int size = 0; uint8_t * data = convert(pCodecCtx, pFrame, nFrame, &size, AV_PIX_FMT_YUV420P); int ret = avcodec_encode_jpeg(pCodecCtx,nFrame,packet); free(data); return ret; }