胡斌

improve one2many, keep still image of teacher, rotate and copy cliped image frame of pip

... ... @@ -46,7 +46,7 @@ int CAVDecoder::add(media_info &info)
_end_time_ms = info.end_time_ms;
}
av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %"PRIu64", %"PRIu64"\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms);
av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %"PRIu64", %"PRIu64", %.3f\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms, info.duration);
return 0;
}
... ...
... ... @@ -341,20 +341,25 @@ int CAVTranscoder::open_output_file(const char *filename)
uint8_t *dstbuf = new uint8_t[nDstSize];
avpicture_fill((AVPicture*)pDstFrame, dstbuf, AV_PIX_FMT_YUV420P, _nOutputWidth, _nOutputHeight);
bool fill_pure_color = true;
if (idxTeacher != -1) {
//copy teacher frame to dest frame
CAVDecoder * pDecoder = decoders_got_frame[idxTeacher];
AVFrame * pFrame = pDecoder->_cur_v_frame;
if (pFrame) {
fillDestFrame(pDstFrame, pFrame, 0, 0);
fill_pure_color = false;
av_frame_free(&_teacherFrame);
_teacherFrame = pFrame;
pDecoder->_cur_v_frame = NULL;
}
}
if(fill_pure_color){//fill with pure color
memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
memset(pDstFrame->data[1], _blank_u, _nOutputWidth *_nOutputHeight / 4);
memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
if (_teacherFrame) {
fillDestFrame(pDstFrame, _teacherFrame, 0, 0);
}
else
{//fill with pure color
memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
memset(pDstFrame->data[1], _blank_u, _nOutputWidth *_nOutputHeight / 4);
memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
}
int imageIdx = 0;
... ... @@ -371,9 +376,11 @@ int CAVTranscoder::open_output_file(const char *filename)
if (h <= 0){
printf("scale output 0?");
}
_scaledFrame->pkt_dts = pFrame->pkt_dts;//pass rotation
//copy each frame to the dest frame
fillDestFrame(pDstFrame, _scaledFrame, SRC_W - 3 - (imageIdx % 4) * (SCALED_H + 5), SRC_H - SCALED_H - (SCALED_H + 2)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H-1, SCALED_H-1);
fillDestFrame(pDstFrame, _scaledFrame, SRC_W - (imageIdx % 4 + 1) * (SCALED_H + 5) + 4, SRC_H - SCALED_H + 3 - (SCALED_H + 4)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H - 3, SCALED_H - 3);
imageIdx++;
}
}
... ... @@ -401,9 +408,8 @@ int CAVTranscoder::open_output_file(const char *filename)
return 0;
}
if (pSrcFrame->pkt_dts == 180) {
unsigned char * startSrcY = pSrcFrame->data[0] + (pSrcFrame->height) * pSrcFrame->linesize[0] - 1;
unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height- 1 ) * pSrcFrame->linesize[0];
for (int i = 0; i < pSrcFrame->height; i++) {
//memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, startSrcY - i * pSrcFrame->linesize[0], pSrcFrame->linesize[0]);
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];
... ... @@ -411,11 +417,9 @@ int CAVTranscoder::open_output_file(const char *filename)
*pdst = *psrc;
}
}
unsigned char * startSrcU = pSrcFrame->data[1] + (pSrcFrame->height/2 ) * pSrcFrame->linesize[1] -1;
unsigned char * startSrcV = pSrcFrame->data[2] + (pSrcFrame->height/2) * pSrcFrame->linesize[2] -1;
unsigned char * startSrcU = pSrcFrame->data[1] + pSrcFrame->width/2 + (pSrcFrame->height/2 -1) * pSrcFrame->linesize[1];
unsigned char * startSrcV = pSrcFrame->data[2] + pSrcFrame->width/2 + (pSrcFrame->height/2 -1) * pSrcFrame->linesize[2];
for (int i = 0; i < pSrcFrame->height / 2; i++){
//memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, startSrcU - i * pSrcFrame->linesize[1], pSrcFrame->linesize[1]);
//memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, startSrcV - i * pSrcFrame->linesize[2], pSrcFrame->linesize[2]);
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];
... ... @@ -445,13 +449,42 @@ int CAVTranscoder::open_output_file(const char *filename)
int CAVTranscoder::fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y, int srcx, int srcy, int w, int h)
{
for (int i = 0; i < h; i++) {
memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + (i+srcy) * pSrcFrame->linesize[0] + srcx, pSrcFrame->linesize[0] > 0 ? w : -w);
if (pSrcFrame->pkt_dts == 180) {
unsigned char * startSrcY = pSrcFrame->data[0] + pSrcFrame->width + (pSrcFrame->height - srcy - 1) * pSrcFrame->linesize[0] - srcx;
for (int i = 0; i < h; 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 + w;
for (; pdst < pdst_end; psrc--, pdst++) {
*pdst = *psrc;
}
}
unsigned char * startSrcU = pSrcFrame->data[1] + pSrcFrame->width / 2 + ((pSrcFrame->height - srcy -1)/ 2) * pSrcFrame->linesize[1] - srcx / 2;
unsigned char * startSrcV = pSrcFrame->data[2] + pSrcFrame->width / 2 + ((pSrcFrame->height - srcy -1)/ 2) * pSrcFrame->linesize[2] - srcx / 2;
for (int i = 0; i < h / 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 + w/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 + w/2;
for (; pdst < pdst_end; psrc--, pdst++) {
*pdst = *psrc;
}
}
}
else {
for (int i = 0; i < h; i++) {
memcpy(pDstFrame->data[0] + (y + i)*pDstFrame->linesize[0] + x, pSrcFrame->data[0] + (i + srcy) * pSrcFrame->linesize[0] + srcx, w);
}
for (int i = 0; i < h / 2; i++){
memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + (i + srcy/2) * pSrcFrame->linesize[1], pSrcFrame->linesize[1] > 0 ? w/2 : -w/2);
memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + (i + srcy/2) * pSrcFrame->linesize[2], pSrcFrame->linesize[2] > 0 ? w/2 : -w/2);
for (int i = 0; i < h / 2; i++){
memcpy(pDstFrame->data[1] + (y / 2 + i)*pDstFrame->linesize[1] + x / 2, pSrcFrame->data[1] + (i + srcy / 2) * pSrcFrame->linesize[1], w / 2);
memcpy(pDstFrame->data[2] + (y / 2 + i)*pDstFrame->linesize[2] + x / 2, pSrcFrame->data[2] + (i + srcy / 2) * pSrcFrame->linesize[2], w / 2);
}
}
return 0;
}
... ... @@ -483,7 +516,7 @@ int CAVTranscoder::open_output_file(const char *filename)
}
}
if (!_teacherFrame && !_studentFrame) {
if (!_teacherFrame || !_studentFrame) {
memset(pDstFrame->data[0], _blank_y, _nOutputWidth * _nOutputHeight);
memset(pDstFrame->data[1], _blank_u, _nOutputWidth * _nOutputHeight / 4);
memset(pDstFrame->data[2], _blank_v, _nOutputWidth * _nOutputHeight / 4);
... ...
... ... @@ -32,7 +32,8 @@ public:
int rotate;
float duration;
int index;
int index;//index in record info file
int sorted_index;//index according to start time
unsigned int uid;
media_type m_type;
media_role m_role;
... ...
... ... @@ -466,8 +466,8 @@ void check_audio_duration()
list <media_info> sorted_media;
deque<media_info> sorted_infos;
list <media_info> sorted_media; //sorted media files only by start
list <media_info> sorted_media_with_end; //sorted media files with end in sort
vector<media_info> media_infos;
vector<string > merged_files;
vector<string> tmp_files;
... ... @@ -566,6 +566,7 @@ void get_video_last_frame_jpeg(const char * video, const char * destfile) {
}
}
void add_media_info(media_info m)
{
list<media_info>::iterator it = sorted_media.begin();
... ... @@ -574,9 +575,20 @@ void add_media_info(media_info m)
break;
}
}
sorted_media.insert(it, m);
}
void add_media_info_with_end(media_info m)
{
list<media_info>::iterator it = sorted_media_with_end.begin();
for (; it != sorted_media_with_end.end(); it++){
if (it->type_time > m.type_time){
break;
}
}
sorted_media_with_end.insert(it, m);
}
list<media_info> audio_files;
... ... @@ -619,35 +631,40 @@ void add_media_infos()
m.start_time_ms = f.start_time * 1000;
m.end_time_ms = f.end_time * 1000;
add_media_info(m);
}
list<media_info>::iterator it = sorted_media.begin();
int index = 0;
for (; it != sorted_media.end(); it++,index++){
it->sorted_index = index;
}
sorted_media_with_end = sorted_media;
it = sorted_media.begin();
for (; it != sorted_media.end(); it++){
media_info m = *it;
m.t_type = tt_end;
m.type_time = m.end_time;
add_media_info(m);
add_media_info_with_end(m);
if (it->m_type == mt_audio) {
audio_files.push_back(*it);
}
}
list<media_info> audio_type_files;
list<media_info>::iterator it = sorted_media.begin();
for (; it != sorted_media.end(); it++){
it = sorted_media_with_end.begin();
for (; it != sorted_media_with_end.end(); it++){
if (it->m_type == mt_audio) {
if (it->t_type == tt_start) {
audio_files.push_back(*it);
}
audio_type_files.push_back(*it);
}
}
printf("\nsorted file info:");
it = sorted_media.begin();
for (; it != sorted_media.end();){
printf("\n%.3f %s %s", it->type_time, it->name.c_str(), it->t_type == tt_start ? "start" : "end");
if (it->t_type == tt_end) {
it = sorted_media.erase(it);
}
else
{
it++;
}
it = sorted_media_with_end.begin();
for (; it != sorted_media_with_end.end();it++){
printf("\n%2d %8.3f %s %s", it->sorted_index, it->type_time, it->name.c_str(), it->t_type == tt_start ? "start" : "end");
}
printf("\n-------------------------\n");
... ... @@ -733,13 +750,13 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu
}
void save_out_info(double duration,const char * mediafile)
void save_out_info(const char * out_mediafile, const char * firstfile,double duration)
{
if (!fp_out_info) {
fp_out_info = fopen(out_info_file, "wt");
}
if (fp_out_info) {
fprintf(fp_out_info, "%.3f %.3lf %s\n", 0.0f, duration, mediafile);
fprintf(fp_out_info, "%s %s %.3lf\n", out_mediafile, firstfile, duration);
fclose(fp_out_info);
fp_out_info = NULL;
}
... ... @@ -984,10 +1001,11 @@ int process_av_files(char * record_info)
int64_t cur_time = 0;
bool has_file = sorted_media.size()!=0;
std::string out_media_file;
std::string out_media_file,first_media_file;
if (has_file) {
media_info info = sorted_media.front();
out_media_file = get_outmedia_file_name(info.name.c_str());
first_media_file = info.name;
out_media_file = get_outmedia_file_name(record_info);
printf("open output file:%s\n", out_media_file.c_str());
int ret = videoTranscoder.open_output_file(out_media_file.c_str());
if (ret) {
... ... @@ -1023,7 +1041,7 @@ int process_av_files(char * record_info)
videoTranscoder.close();
save_out_info(((double)cur_time)/1000.0, out_media_file.c_str());
save_out_info( out_media_file.c_str(), first_media_file.c_str(),((double)cur_time)/1000.0);
time(&end);
... ...