You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.3 KiB
C
121 lines
3.3 KiB
C
#include <libavformat/avformat.h>
|
|
#include <libavcodec/avcodec.h>
|
|
#include <libavutil/avutil.h>
|
|
#include <libavutil/imgutils.h>
|
|
#include <libswresample/swresample.h>
|
|
#include <libavutil/opt.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <libswscale/swscale.h>
|
|
#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, data: %p, size: %d\n", avctx, data, size);
|
|
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;
|
|
}
|
|
|