239 lines
No EOL
6.3 KiB
C++
239 lines
No EOL
6.3 KiB
C++
#ifdef _OPENLIB
|
|
|
|
#include "SCENE.h"
|
|
|
|
extern "C" {
|
|
#include "avformat.h"
|
|
#include "avcodec.h"
|
|
#include "avutil.h"
|
|
}
|
|
|
|
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
|
#define STREAM_PIX_FMT PIX_FMT_YUV420P //PIX_FMT_YUV420P /* default pix_fmt *///PIX_FMT_YUV420P //PIX_FMT_RGB24 //
|
|
#define PICTURE_PIX_FMT PIX_FMT_RGB32
|
|
|
|
static AVCodec *codecEnc = NULL;
|
|
static AVCodec *codecDec = NULL;
|
|
|
|
|
|
typedef struct _VideoData
|
|
{
|
|
AVCodecContext *c;
|
|
AVFrame *pict;
|
|
SwsContext
|
|
} VideoData;
|
|
|
|
void AVCodec_Init()
|
|
{
|
|
av_register_all();
|
|
|
|
if (!codecEnc)
|
|
codecEnc= avcodec_find_encoder(CODEC_ID_FLV1);
|
|
if (!codecDec)
|
|
codecDec= avcodec_find_decoder(CODEC_ID_FLV1); //CODEC_ID_H263
|
|
}
|
|
|
|
//void *Encode_INIT(MAP *PPicture)
|
|
//u32 Encode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH)
|
|
//void Encode_CLOSE(void *H)
|
|
/*
|
|
|
|
if (!fmt)
|
|
fmt = guess_format("mpeg", NULL, NULL);
|
|
|
|
AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id);
|
|
AVCodecContext *c= avcodec_alloc_context();
|
|
AVFrame input[FF_MAX_B_FRAMES+2];
|
|
const int scale= s->avctx->brd_scale;
|
|
int i, j, out_size;
|
|
int outbuf_size= s->width * s->height; //FIXME
|
|
uint8_t *outbuf= av_malloc(outbuf_size);
|
|
ImgReSampleContext *resample;
|
|
int64_t best_rd= INT64_MAX;
|
|
int best_b_count= -1;
|
|
const int lambda2= s->lambda2;
|
|
|
|
c->width = s->width >> scale;
|
|
c->height= s->height>> scale;
|
|
c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED;
|
|
c->flags|= s->avctx->flags & CODEC_FLAG_QPEL;
|
|
c->mb_decision= s->avctx->mb_decision;
|
|
c->me_cmp= s->avctx->me_cmp;
|
|
c->mb_cmp= s->avctx->mb_cmp;
|
|
c->me_sub_cmp= s->avctx->me_sub_cmp;
|
|
c->pix_fmt = PIX_FMT_YUV420P;
|
|
c->time_base= s->avctx->time_base;
|
|
c->max_b_frames= s->max_b_frames;
|
|
*/
|
|
|
|
void *AVCodec_Encode_INIT(MAP *PPicture)
|
|
{
|
|
AVCodec_Init();
|
|
VideoData *vd = (VideoData *)CC_malloc(sizeof(VideoData));
|
|
|
|
vd->c = (AVCodecContext *) avcodec_alloc_context();
|
|
vd->c->codec_id = codecEnc->id;
|
|
vd->c->codec_type = CODEC_TYPE_VIDEO;
|
|
|
|
/* put sample parameters */
|
|
vd->c->bit_rate = 400000;
|
|
/* resolution must be a multiple of two */
|
|
vd->c->width = PPicture->SX;
|
|
vd->c->height = PPicture->SY;
|
|
/* time base: this is the fundamental unit of time (in seconds) in terms
|
|
of which frame timestamps are represented. for fixed-fps content,
|
|
timebase should be 1/framerate and timestamp increments should be
|
|
identically 1. */
|
|
vd->c->time_base.den = STREAM_FRAME_RATE;
|
|
vd->c->time_base.num = 1;
|
|
//vd->c->gosize = 12; /* emit one intra frame every twelve frames at most */
|
|
vd->c->pix_fmt = STREAM_PIX_FMT;
|
|
if (vd->c->codec_id == CODEC_ID_MPEG2VIDEO) {
|
|
/* just for testing, we also add B frames */
|
|
vd->c->max_b_frames = 2;
|
|
}
|
|
if (vd->c->codec_id == CODEC_ID_MPEG1VIDEO){
|
|
/* Needed to avoid using macroblocks in which some coeffs overflow.
|
|
This does not happen with normal video, it just happens here as
|
|
the motion of the chroma plane does not match the luma plane. */
|
|
vd->c->mb_decision = 2;
|
|
}
|
|
/* some formats want stream headers to be separate */
|
|
// vd->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
|
|
|
if (avcodec_open(vd->c, codecEnc) < 0)
|
|
{
|
|
CC_free(vd->c);
|
|
CC_free(vd);
|
|
return NULL;
|
|
}
|
|
|
|
int size;
|
|
uint8_t *picture_buf;
|
|
|
|
vd->pict = avcodec_alloc_frame();
|
|
if (!vd->pict)
|
|
return NULL;
|
|
|
|
size = avpicture_get_size(PICTURE_PIX_FMT, PPicture->SX, PPicture->SY);
|
|
picture_buf = av_malloc(size);
|
|
|
|
if (!picture_buf)
|
|
{
|
|
CC_free(vd->pict);
|
|
return NULL;
|
|
}
|
|
avpicture_fill((AVPicture *)vd->pict, picture_buf, PICTURE_PIX_FMT, PPicture->SX, PPicture->SY);
|
|
return vd;
|
|
}
|
|
|
|
u32 AVCodec_Encode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH)
|
|
{
|
|
int encodedSize;
|
|
VideoData *vd = (VideoData *)H;
|
|
|
|
if (!H) return 0;
|
|
|
|
|
|
encodedSize = avcodec_encode_video(vd->c, (uint8_t *)Buffer + 4, DATA_MAX-4, vd->pict);
|
|
*((int *)Buffer) = encodedSize;
|
|
return encodedSize;
|
|
}
|
|
|
|
void AVCodec_Encode_CLOSE(void *H)
|
|
{
|
|
if (H)
|
|
av_free(H);
|
|
}
|
|
|
|
|
|
void *AVCodec_Decode_INIT(MAP *PPicture)
|
|
{
|
|
AVCodec_Init();
|
|
AVCodecContext *c = (AVCodecContext *) avcodec_alloc_context();
|
|
|
|
c->codec_id = codecDec->id;
|
|
c->codec_type = CODEC_TYPE_VIDEO;
|
|
|
|
/* put sample parameters */
|
|
c->bit_rate = 400000;
|
|
/* resolution must be a multiple of two */
|
|
c->width = PPicture->SX;
|
|
c->height = PPicture->SY;
|
|
/* time base: this is the fundamental unit of time (in seconds) in terms
|
|
of which frame timestamps are represented. for fixed-fps content,
|
|
timebase should be 1/framerate and timestamp increments should be
|
|
identically 1. */
|
|
c->time_base.den = STREAM_FRAME_RATE;
|
|
c->time_base.num = 1;
|
|
//c->gosize = 12; /* emit one intra frame every twelve frames at most */
|
|
c->pix_fmt = STREAM_PIX_FMT;
|
|
if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
|
|
/* just for testing, we also add B frames */
|
|
c->max_b_frames = 2;
|
|
}
|
|
if (c->codec_id == CODEC_ID_MPEG1VIDEO){
|
|
/* Needed to avoid using macroblocks in which some coeffs overflow.
|
|
This does not happen with normal video, it just happens here as
|
|
the motion of the chroma plane does not match the luma plane. */
|
|
c->mb_decision = 2;
|
|
}
|
|
// some formats want stream headers to be separate
|
|
// c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
|
|
|
return c;
|
|
}
|
|
|
|
u32 AVCodec_Decode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH)
|
|
{
|
|
AVFrame pict;
|
|
int got_picture_ptr = FROMSCRATCH;
|
|
int encodedSize = *((int *)Buffer);
|
|
|
|
if (encodedSize > 0)
|
|
{
|
|
avpicture_fill((AVPicture *)&pict, (uint8_t *)PPicture->BASE, PICTURE_PIX_FMT, PPicture->SX, PPicture->SY);
|
|
return avcodec_decode_video((AVCodecContext *)H, &pict, &got_picture_ptr, (uint8_t *)Buffer+4, encodedSize);
|
|
} else
|
|
return 0;
|
|
}
|
|
|
|
void AVCodec_Decode_CLOSE(void *H)
|
|
{
|
|
if (H)
|
|
av_free(H);
|
|
}
|
|
|
|
|
|
|
|
void *Encode_INIT(MAP *PPicture)
|
|
{
|
|
return AVCodec_Encode_INIT(PPicture);
|
|
}
|
|
|
|
u32 Encode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH, u32 Q, u32 R)
|
|
{
|
|
return AVCodec_Encode_FRAME(H, PPicture, Buffer, FROMSCRATCH);
|
|
}
|
|
|
|
void Encode_CLOSE(void *H)
|
|
{
|
|
AVCodec_Encode_CLOSE(H);
|
|
}
|
|
|
|
void *Decode_INIT(MAP *PPicture)
|
|
{
|
|
return AVCodec_Decode_INIT(PPicture);
|
|
}
|
|
|
|
u32 Decode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH)
|
|
{
|
|
return AVCodec_Decode_FRAME(H, PPicture, Buffer, FROMSCRATCH);
|
|
}
|
|
|
|
void Decode_CLOSE(void *H)
|
|
{
|
|
AVCodec_Decode_CLOSE(H);
|
|
}
|
|
|
|
#endif |