继续操作前请注册或者登录。
胡斌

support the video size of student being 240x240

... ... @@ -23,10 +23,12 @@ _nOutputWidth(320),
_cur_out_v_ts(0),
_cur_out_a_ts(0),
_max_audio(1),
_swsCtx(NULL),
_swsCtxPortrait(NULL),
_scaledFrame(NULL),
_scaledPortraitFrame(NULL),
_swsCtx_320_240(NULL),
_swsCtx_240_320(NULL),
_swsCtx_240_240(NULL),
_scaledFrame_320_240(NULL),
_scaledFrame_240_320(NULL),
_scaledFrame_240_240(NULL),
_last_videos_got(-1),
_teacherFrame(NULL),
_studentFrame(NULL)
... ... @@ -37,34 +39,10 @@ _studentFrame(NULL)
}
else {
_nOutputHeight = 240;
_swsCtx = sws_getContext(SRC_W, SRC_H, AV_PIX_FMT_YUV420P,
SCALED_W, SCALED_H, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
NULL, NULL, NULL);
_swsCtxPortrait = sws_getContext(SRC_H, SRC_W, AV_PIX_FMT_YUV420P,
SCALED_H, SCALED_W, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
NULL, NULL, NULL);
_scaledFrame = av_frame_alloc();
_scaledFrame->format = AV_PIX_FMT_YUV420P;
_scaledFrame->width = SCALED_W;
_scaledFrame->height = SCALED_H;
_scaledFrame->pts = 0;
_scaledPortraitFrame = av_frame_alloc();
_scaledPortraitFrame->format = AV_PIX_FMT_YUV420P;
_scaledPortraitFrame->width = SCALED_H;
_scaledPortraitFrame->height = SCALED_W;
_scaledPortraitFrame->pts = 0;
int ret = av_frame_get_buffer(_scaledFrame, 32);
if (ret != 0)
{
printf("Error alloc frame buffer for scaling video frame");
}
ret = av_frame_get_buffer(_scaledPortraitFrame, 32);
if (ret != 0)
{
printf("Error alloc frame buffer for scaling portrait video frame");
}
init_scale_context(&_swsCtx_320_240, &_scaledFrame_320_240, SRC_W, SRC_H, SCALED_W, SCALED_H);
init_scale_context(&_swsCtx_240_320, &_scaledFrame_240_320, SRC_H, SRC_W, SCALED_H, SCALED_W);
init_scale_context(&_swsCtx_240_240, &_scaledFrame_240_240, SRC_H, SRC_H, SCALED_H, SCALED_H);
}
RGB2YUV(blank_r, blank_g, blank_b, &_blank_y, &_blank_u, &_blank_v);
}
... ... @@ -151,21 +129,10 @@ int CAVTranscoder::close()
flush_encoder(1);
av_write_trailer(_ofmt_ctx);
if (_swsCtx) {
sws_freeContext(_swsCtx);
_swsCtx = NULL;
}
if (_swsCtxPortrait){
sws_freeContext(_swsCtxPortrait);
_swsCtxPortrait = NULL;
}
if (_scaledFrame) {
av_frame_free(&_scaledFrame);
}
if (_scaledPortraitFrame) {
av_frame_free(&_scaledPortraitFrame);
}
free_scale_context(&_swsCtx_320_240, &_scaledFrame_320_240);
free_scale_context(&_swsCtx_240_320, &_scaledFrame_240_320);
free_scale_context(&_swsCtx_240_240, &_scaledFrame_240_240);
#if USE_H264BSF
av_bitstream_filter_close(h264bsfc);
... ... @@ -401,26 +368,36 @@ int CAVTranscoder::open_output_file(const char *filename)
}
int h = 0;
if (pFrame->width == SRC_W && pFrame->height == SRC_H) {
h = sws_scale(_swsCtx, pFrame->data, pFrame->linesize, 0, pFrame->height,
_scaledFrame->data, _scaledFrame->linesize);
h = sws_scale(_swsCtx_320_240, pFrame->data, pFrame->linesize, 0, pFrame->height,
_scaledFrame_320_240->data, _scaledFrame_320_240->linesize);
if (h <= 0){
printf("\nscale output result:%d?,ignored", h);
continue;
}
_scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
fillDestFrame(pDstFrame, _scaledFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3);
_scaledFrame_320_240->pkt_dts = pFrame->pkt_dts;//pass rotation
fillDestFrame(pDstFrame, _scaledFrame_320_240, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3);
}
else if (pFrame->width == SRC_H && pFrame->height == SRC_W) {
h = sws_scale(_swsCtxPortrait, pFrame->data, pFrame->linesize, 0, pFrame->height,
_scaledPortraitFrame->data, _scaledPortraitFrame->linesize);
h = sws_scale(_swsCtx_240_320, pFrame->data, pFrame->linesize, 0, pFrame->height,
_scaledFrame_240_320->data, _scaledFrame_240_320->linesize);
if (h <= 0){
printf("\nscale output result:%d?,ignored", h);
continue;
}
_scaledPortraitFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
fillDestFrame(pDstFrame, _scaledPortraitFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, (SCALED_W - SCALED_H) / 2, SCALED_H - 3, SCALED_H - 3);
_scaledFrame_240_320->pkt_dts = pFrame->pkt_dts;//pass rotation
fillDestFrame(pDstFrame, _scaledFrame_240_320, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, (SCALED_W - SCALED_H) / 2, SCALED_H - 3, SCALED_H - 3);
}
else if (pFrame->width == SRC_H && pFrame->height == SRC_H) {
h = sws_scale(_swsCtx_240_240, pFrame->data, pFrame->linesize, 0, pFrame->height,
_scaledFrame_240_240->data, _scaledFrame_240_240->linesize);
if (h <= 0){
printf("\nscale output result:%d?,ignored", h);
continue;
}
_scaledFrame_240_240->pkt_dts = pFrame->pkt_dts;//pass rotation
fillDestFrame(pDstFrame, _scaledFrame_240_240, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 1)*(imageIdx / 4), 0, 0, SCALED_H - 3, SCALED_H - 3);
}
else {
printf("\nthe frame resolution %dx%d is unexpected! ignored!", pFrame->width, pFrame->height);
continue;
... ... @@ -454,12 +431,12 @@ int CAVTranscoder::open_output_file(const char *filename)
if (pSrcFrame->pkt_dts == 0) {
for (int i = 0; i < pSrcFrame->height; i++) {
memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + i * pSrcFrame->linesize[0], pSrcFrame->linesize[0] > 0 ? pSrcFrame->linesize[0] : -pSrcFrame->linesize[0]);
memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + i * pSrcFrame->linesize[0], pSrcFrame->width);
}
for (int i = 0; i < pSrcFrame->height / 2; i++){
memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + i * pSrcFrame->linesize[1], pSrcFrame->linesize[1] > 0 ? pSrcFrame->linesize[1] : -pSrcFrame->linesize[1]);
memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + i * pSrcFrame->linesize[2], pSrcFrame->linesize[2] > 0 ? pSrcFrame->linesize[2] : -pSrcFrame->linesize[2]);
memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + i * pSrcFrame->linesize[1], pSrcFrame->width/2);
memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + i * pSrcFrame->linesize[2], pSrcFrame->width/2);
}
}
else if (pSrcFrame->pkt_dts == 180) {
... ... @@ -467,7 +444,7 @@ int CAVTranscoder::open_output_file(const char *filename)
for (int i = 0; i < pSrcFrame->height; i++) {
unsigned char * psrc = startSrcY - i * pSrcFrame->linesize[0];
unsigned char * pdst = pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x;
unsigned char * pdst_end = pdst + pSrcFrame->linesize[0];
unsigned char * pdst_end = pdst + pSrcFrame->width;
for (; pdst < pdst_end; psrc--, pdst++) {
*pdst = *psrc;
}
... ... @@ -477,13 +454,13 @@ int CAVTranscoder::open_output_file(const char *filename)
for (int i = 0; i < pSrcFrame->height / 2; i++){
unsigned char * psrc = startSrcU - i * pSrcFrame->linesize[1];
unsigned char * pdst = pDstFrame->data[1] + (y/2 + i)*pDstFrame->linesize[1] + x/2;
unsigned char * pdst_end = pdst + pSrcFrame->linesize[1];
unsigned char * pdst_end = pdst + pSrcFrame->width /2;
for (; pdst < pdst_end; psrc--, pdst++) {
*pdst = *psrc;
}
psrc = startSrcV - i * pSrcFrame->linesize[2];
pdst = pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2;
pdst_end = pdst + pSrcFrame->linesize[2];
pdst_end = pdst + pSrcFrame->width /2;
for (; pdst < pdst_end; psrc--, pdst++) {
*pdst = *psrc;
}
... ... @@ -493,7 +470,7 @@ int CAVTranscoder::open_output_file(const char *filename)
for (int i = 0; i < pSrcFrame->height; i++) {
unsigned char * psrc = pSrcFrame->data[0] + i * pSrcFrame->linesize[0];
unsigned char * psrc_end = psrc + pSrcFrame->width;
unsigned char * pdst = pDstFrame->data[0] + y * pDstFrame->linesize[0] + pSrcFrame->height -1 - i;
unsigned char * pdst = pDstFrame->data[0] + y * pDstFrame->linesize[0] + x + pSrcFrame->height -1 - i;
for (; psrc < psrc_end; psrc++ ,pdst += pDstFrame->linesize[0]) {
*pdst = *psrc;
}
... ... @@ -502,13 +479,13 @@ int CAVTranscoder::open_output_file(const char *filename)
for (int i = 0; i < pSrcFrame->height/2; i++) {
unsigned char * psrc = pSrcFrame->data[1] + i * pSrcFrame->linesize[1];
unsigned char * psrc_end = psrc + pSrcFrame->width/2;
unsigned char * pdst = pDstFrame->data[1] + y /2 * pDstFrame->linesize[1] + pSrcFrame->height/2 -1 - i;
unsigned char * pdst = pDstFrame->data[1] + y /2 * pDstFrame->linesize[1] + x/2 + pSrcFrame->height/2 -1 - i;
for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[1]) {
*pdst = *psrc;
}
psrc = pSrcFrame->data[2] + i * pSrcFrame->linesize[2];
psrc_end = psrc + pSrcFrame->width / 2;
pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + pSrcFrame->height / 2 - 1 - i;
pdst = pDstFrame->data[2] + y / 2 * pDstFrame->linesize[2] + x/2 + pSrcFrame->height / 2 - 1 - i;
for (; psrc < psrc_end; psrc++, pdst += pDstFrame->linesize[2]) {
*pdst = *psrc;
}
... ... @@ -654,7 +631,7 @@ int CAVTranscoder::open_output_file(const char *filename)
}
}
else if (_studentFrame) {
if (_studentFrame->width == SRC_W) {
if (_studentFrame->width == SRC_W && _studentFrame->height == SRC_H) {
if (_studentFrame->pkt_dts != 90){
fillDestFrame(pDstFrame, _studentFrame, 0, 0);
}
... ... @@ -662,11 +639,19 @@ int CAVTranscoder::open_output_file(const char *filename)
fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, (SRC_W - SRC_H) / 2, 0, SRC_W, SRC_H);
}
}
else if (_studentFrame->pkt_dts == 90){
fillDestFrame(pDstFrame, _studentFrame, 0, 0);
else if (_studentFrame->width == SRC_H && _studentFrame->height == SRC_W) {
if (_studentFrame->pkt_dts == 90){
fillDestFrame(pDstFrame, _studentFrame, 0, 0);
}
else {
fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, 0, (SRC_W - SRC_H) / 2, SRC_W, SRC_H);
}
}
else if (_studentFrame->width == SRC_H && _studentFrame->height == SRC_H) {
fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0);
}
else {
fillDestFrame(pDstFrame, _studentFrame, (SRC_W - SRC_H) / 2, 0, 0, (SRC_W - SRC_H) / 2, SRC_W, SRC_H);
printf("\nresolution: %dx%d unexpected!", _studentFrame->width, _studentFrame->height);
}
}
... ... @@ -767,6 +752,39 @@ int CAVTranscoder::flush_encoder(unsigned int stream_index)
return ret;
}
int CAVTranscoder::init_scale_context(SwsContext ** ctx, AVFrame ** frame, int src_w, int src_h, int dest_w, int dest_h)
{
*ctx = sws_getContext(src_w, src_h, AV_PIX_FMT_YUV420P,
dest_w, dest_h, AV_PIX_FMT_YUV420P, SWS_BILINEAR,
NULL, NULL, NULL);
*frame = av_frame_alloc();
(*frame)->format = AV_PIX_FMT_YUV420P;
(*frame)->width = dest_w;
(*frame)->height = dest_h;
(*frame)->pts = 0;
int ret = av_frame_get_buffer(*frame, 32);
if (ret != 0)
{
printf("Error alloc frame buffer for scaling video frame");
}
return ret;
}
int CAVTranscoder::free_scale_context(SwsContext ** ctx, AVFrame ** frame)
{
if (*ctx){
sws_freeContext(*ctx);
*ctx = NULL;
}
if (*frame) {
av_frame_free(frame);
}
return 0;
}
void CAVTranscoder::set_max_audio(int max_audio)
{
_max_audio = max_audio;
... ...
... ... @@ -39,12 +39,17 @@ private:
int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame);
int flush_encoder(unsigned int stream_index);
int init_scale_context(struct SwsContext ** ctx, AVFrame ** frame, int src_w, int src_h, int dest_w, int dest_h);
int free_scale_context(struct SwsContext ** ctx, AVFrame ** frame);
void * _a_frame_pool;
int _max_audio;
struct SwsContext * _swsCtx;
struct SwsContext * _swsCtxPortrait;
AVFrame * _scaledFrame;
AVFrame * _scaledPortraitFrame;
struct SwsContext * _swsCtx_320_240;
struct SwsContext * _swsCtx_240_320;
struct SwsContext * _swsCtx_240_240;
AVFrame * _scaledFrame_320_240;
AVFrame * _scaledFrame_240_320;
AVFrame * _scaledFrame_240_240;
int _last_videos_got;
AVFrame * _teacherFrame;
AVFrame * _studentFrame; // for one2one,keep the last frame
... ...