胡斌

keep last frame in same av segment,need improved

save output info
... ... @@ -16,6 +16,8 @@ _media_role(mr_student)
CAVDecoder::~CAVDecoder()
{
free_cur_v_frame();
free_cur_a_frame();
}
int CAVDecoder::add(media_info &info)
... ... @@ -59,9 +61,13 @@ bool CAVDecoder::get_one_v_frame()
int64_t ts;
int ret = -1;
if (_video_info.size()) {
ret = _video_decoder.get_one_frame(&_cur_v_frame, ts);
AVFrame * pFrame = NULL;
ret = _video_decoder.get_one_frame(&pFrame, ts);
if (ret == 0) {
//_cur_v_ts_ms = _v_start_time_ms + ts;
if (pFrame){
free_cur_v_frame();
_cur_v_frame = pFrame;
}
_cur_v_ts_ms += VFRAME_DURATION_MS;
}
else {
... ... @@ -77,23 +83,30 @@ bool CAVDecoder::get_one_v_frame()
if (_cur_v_ts_ms < _end_time_ms) {//should have as video frame
_cur_v_ts_ms += VFRAME_DURATION_MS;//return last v frame
ret = 0;
if (!_cur_v_frame) {
_cur_v_frame = get_blank_frame();
}
}
}
return ret == 0;
}
AVFrame * CAVDecoder::get_blank_frame()
std::string CAVDecoder::get_cur_vfile()
{
return NULL;
if (_video_info.size()){
return _video_info.front().name;
}
else {
return "";
}
}
AVFrame * CAVDecoder::get_silence_frame()
std::string CAVDecoder::get_cur_afile()
{
return NULL;
if (_audio_info.size()){
return _audio_info.front().name;
}
else {
return "";
}
}
void CAVDecoder::free_cur_a_frame()
... ... @@ -114,6 +127,7 @@ bool CAVDecoder::get_one_a_frame()
{
int64_t ts;
int ret = -1;
free_cur_a_frame();
if (_audio_info.size()) {
ret = _audio_decoder.get_one_frame(&_cur_a_frame, ts);
if (ret == 0) {
... ... @@ -132,9 +146,6 @@ bool CAVDecoder::get_one_a_frame()
if (_cur_a_ts_ms < _end_time_ms) {//should have a audio frame
_cur_a_ts_ms += AFRAME_DURATION_MS;//return last a frame
ret = 0;
if (!_cur_a_frame) {
_cur_a_frame = get_silence_frame();
}
}
}
... ...
... ... @@ -13,6 +13,8 @@ public:
unsigned int getuid();
bool get_one_a_frame();
bool get_one_v_frame();
std::string get_cur_vfile();
std::string get_cur_afile();
double _cur_a_ts_ms;
int64_t _cur_v_ts_ms;
media_role _media_role;
... ... @@ -31,11 +33,9 @@ protected:
int64_t _end_time_ms;
unsigned int _uid;
private:
AVFrame * get_blank_frame();
AVFrame * get_silence_frame();
public:
void free_cur_a_frame();
protected:
void free_cur_v_frame();
void free_cur_a_frame();
};
... ...
... ... @@ -19,7 +19,8 @@ _cur_out_v_ts(0),
_cur_out_a_ts(0),
_max_audio(1),
_swsCtx(NULL),
_scaledFrame(NULL)
_scaledFrame(NULL),
_last_videos_got(-1)
{
_one2one = bOne2One;
if (_one2one) {
... ... @@ -237,7 +238,7 @@ int CAVTranscoder::open_output_file(const char *filename)
/* Third parameter can be used to pass settings to encoder */
ret = avcodec_open2(enc_ctx, encoder, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
av_log(NULL, AV_LOG_ERROR, "Cannot open audio encoder for stream #%u\n", i);
return ret;
}
}
... ... @@ -299,7 +300,6 @@ int CAVTranscoder::open_output_file(const char *filename)
for (int i = 0; i < 1024; i++,pdst++,psrc++) {
*pdst += (*psrc/_max_audio);
}
(*it)->free_cur_a_frame();
}
}
... ... @@ -339,7 +339,6 @@ int CAVTranscoder::open_output_file(const char *filename)
if (pFrame) {
fillDestFrame(pDstFrame, pFrame, 0, 0);
fill_pure_color = false;
pDecoder->free_cur_v_frame();
}
}
if(fill_pure_color){//fill with pure color
... ... @@ -364,8 +363,7 @@ int CAVTranscoder::open_output_file(const char *filename)
}
//copy each frame to the dest frame
fillDestFrame(pDstFrame, _scaledFrame, SRC_W - SCALED_H - ((imageIdx % 4) * SCALED_H), SRC_H - SCALED_H - (SCALED_H + 8)*imageIdx / 4, (SCALED_W - SCALED_H) / 2, 0, SCALED_H, SCALED_H);
pDecoder->free_cur_v_frame();
fillDestFrame(pDstFrame, _scaledFrame, SRC_W - SCALED_H - 10 - (imageIdx % 4) * (SCALED_H + 10), SRC_H - SCALED_H - (SCALED_H + 8)*(imageIdx / 4), (SCALED_W - SCALED_H) / 2, 0, SCALED_H, SCALED_H);
imageIdx++;
}
}
... ... @@ -427,21 +425,35 @@ int CAVTranscoder::open_output_file(const char *filename)
memset(dstbuf, 0x80, nDstSize);
if (decoders_got_frame.size() == 2){
if (_last_videos_got != 2) {
_last_videos_got = 2;
printf("\n--get 2 video:%"PRIu64", %s, %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str(), decoders_got_frame[1]->get_cur_vfile().c_str());
}
fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, decoders_got_frame[0]->_media_role == mr_teacher ? 0 : 240);
decoders_got_frame[0]->free_cur_v_frame();
fillDestFrame(pDstFrame, decoders_got_frame[1]->_cur_v_frame, 0, decoders_got_frame[1]->_media_role == mr_teacher ? 0 : 240);
decoders_got_frame[1]->free_cur_v_frame();
}
else if (decoders_got_frame.size() == 1)
{
if (_last_videos_got != 1) {
_last_videos_got = 1;
printf("\n--get 1 video:%"PRIu64", %s\n", _cur_out_v_ts, decoders_got_frame[0]->get_cur_vfile().c_str());
}
fillDestFrame(pDstFrame, decoders_got_frame[0]->_cur_v_frame, 0, 0);
decoders_got_frame[0]->free_cur_v_frame();
//todo: fill the bottom half image with pure color
}
else {
if (_last_videos_got != 0) {
_last_videos_got = 0;
printf("\n--get 0 video:%"PRIu64"\n", _cur_out_v_ts);
}
//fill with last image?
}
#if 0
if (_cur_out_v_ts > (26 * 60 + 57) *(1000 /50)) {
printf("\n--get %d video:%"PRIu64"\n", decoders_got_frame.size(), _cur_out_v_ts);
}
#endif
//fill the timestamp of dest frame
pDstFrame->pts = _cur_out_v_ts;
... ...
... ... @@ -43,6 +43,7 @@ private:
int _max_audio;
struct SwsContext * _swsCtx;
AVFrame * _scaledFrame;
int _last_videos_got;
public:
void set_max_audio(int max_audio);
};
... ...
... ... @@ -23,6 +23,15 @@ int CVideoDecoder::add(media_info &info)
_info.push_back(info);
_rotate = info.rotate;
if (_info.size() > 1) {
if (_is_finished == false) {
printf("add file:%s ,but the last file, %s, is not finished?", info.name.c_str(), _info[_info.size() - 2].name.c_str());
}
else {
printf("add file:%s ,after the last file, %s", info.name.c_str(), _info[_info.size() - 2].name.c_str());
}
}
int ret;
do{
... ...
... ... @@ -731,11 +731,15 @@ int get_output_file_name(const char * filename, const char * prefix,char * outpu
}
void save_out_info(float start_time, char * outputfile)
void save_out_info(double duration,const char * mediafile)
{
if (!fp_out_info) {
fp_out_info = fopen(out_info_file, "wt");
}
if (fp_out_info) {
float duration = get_file_duration(outputfile, false);
fprintf(fp_out_info, "%.3f %.3f %s\n", start_time, duration, outputfile);
fprintf(fp_out_info, "%.3f %.3lf %s\n", 0.0f, duration, mediafile);
fclose(fp_out_info);
fp_out_info = NULL;
}
}
... ... @@ -955,8 +959,12 @@ int load_record_info(char * record_info)
#define MIN_TIME_INTERVAL 25
int process_av_files()
int process_av_files(char * record_info)
{
load_record_info(record_info);
get_outinfo_file_name(record_info);
av_register_all();
avfilter_register_all();
... ... @@ -964,18 +972,19 @@ int process_av_files()
videoTranscoder.set_max_audio(max_audio);
int64_t cur_time = 0;
bool has_file = sorted_media.size();
bool has_file = sorted_media.size()!=0;
std::string out_media_file;
if (has_file) {
media_info info = sorted_media.front();
std::string m = get_outmedia_file_name(info.name.c_str());
printf("open output file:%s\n", m.c_str());
int ret = videoTranscoder.open_output_file(m.c_str());
out_media_file = get_outmedia_file_name(info.name.c_str());
printf("open output file:%s\n", out_media_file.c_str());
int ret = videoTranscoder.open_output_file(out_media_file.c_str());
if (ret) {
printf("open output file:%s fail!\n", m.c_str());
printf("open output file:%s fail!\n", out_media_file.c_str());
return ret;
}
else {
printf("open output file:%s success!\n", m.c_str());
printf("open output file:%s success!\n", out_media_file.c_str());
}
}
... ... @@ -991,7 +1000,7 @@ int process_av_files()
else {
break;
}
has_file = sorted_media.size();
has_file = sorted_media.size()!=0;
}
cur_time = videoTranscoder.transcode();
... ... @@ -1003,6 +1012,8 @@ int process_av_files()
videoTranscoder.close();
save_out_info(((double)cur_time)/1000.0, out_media_file.c_str());
return 0;
}
... ... @@ -1026,7 +1037,5 @@ int main(int argc, char * argv[])
}
}
load_record_info(argv[1]);
process_av_files();
return process_av_files(argv[1]);
}
... ...