Skip to content

Commit 39409d0

Browse files
committed
change the dependency dump and decoding from multiple files, each gop one file for each dependency
1 parent 9ccb6ba commit 39409d0

File tree

3 files changed

+183
-172
lines changed

3 files changed

+183
-172
lines changed

dependency.c

Lines changed: 118 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ static int videoIndexCmp(const int *a, const int *b) {
1414
/*parsing the video file, done by parse thread*/
1515
void get_video_info(char **p_videoFilenameList, int p_debug) {
1616
AVCodec *lVideoCodec;
17-
char l_depGopRecFileName[100], l_depIntraFileName[100], l_depInterFileName[100], l_depMbPosFileName[100], l_depDcpFileName[100];
1817
int lError;
1918
int l_dumpDep;
2019
int l_i;
@@ -57,60 +56,43 @@ void get_video_info(char **p_videoFilenameList, int p_debug) {
5756
}
5857
for (l_i = 0; l_i < gNumOfVideoFiles; ++l_i) {
5958
#if (defined SELECTIVE_DECODING) || (defined NORM_DECODE_DEBUG)
60-
/*check if the dependency files exist, if not, we'll need to dump the dependencies*/
61-
sprintf(l_depGopRecFileName, "./%s_goprec.txt", p_videoFilenameList[l_i]);
62-
sprintf(l_depIntraFileName, "./%s_intra.txt", p_videoFilenameList[l_i]);
63-
sprintf(l_depInterFileName, "./%s_inter.txt", p_videoFilenameList[l_i]);
64-
sprintf(l_depMbPosFileName, "./%s_mbpos.txt", p_videoFilenameList[l_i]);
65-
sprintf(l_depDcpFileName, "./%s_dcp.txt", p_videoFilenameList[l_i]);
66-
#ifdef CLEAR_DEP_BEFORE_START
67-
remove(l_depGopRecFileName);
68-
remove(l_depIntraFileName);
69-
remove(l_depInterFileName);
70-
remove(l_depMbPosFileName);
71-
remove(l_depDcpFileName);
72-
#endif
73-
if ((!if_file_exists(l_depGopRecFileName)) || (!if_file_exists(l_depIntraFileName)) || (!if_file_exists(l_depInterFileName)) || (!if_file_exists(l_depMbPosFileName)) || (!if_file_exists(l_depDcpFileName))) {
74-
l_dumpDep = 1;
75-
} else {
76-
l_dumpDep = 0;
77-
}
78-
LOGI(10, "l_dumpDep=%d", l_dumpDep);
79-
#else
80-
l_dumpDep = 0;
81-
#endif
59+
/***
60+
The following section are initialization for dumping dependencies
61+
**/
8262
/*open the video file*/
83-
if (l_dumpDep) {
84-
if ((lError = av_open_input_file(&gFormatCtxDepList[l_i], p_videoFilenameList[l_i], NULL, 0, NULL)) !=0 ) {
85-
LOGE(1, "Error open video file: %d", lError);
86-
return; //open file failed
87-
}
88-
/*retrieve stream information*/
89-
if ((lError = av_find_stream_info(gFormatCtxDepList[l_i])) < 0) {
90-
LOGE(1, "Error find stream information: %d", lError);
91-
return;
92-
}
93-
/*find the video stream and its decoder*/
94-
gVideoStreamIndexList[l_i] = av_find_best_stream(gFormatCtxDepList[l_i], AVMEDIA_TYPE_VIDEO, -1, -1, &lVideoCodec, 0);
95-
if (gVideoStreamIndexList[l_i] == AVERROR_STREAM_NOT_FOUND) {
96-
LOGE(1, "Error: cannot find a video stream");
97-
return;
98-
} else {
99-
LOGI(10, "video codec: %s; stream index: %d", lVideoCodec->name, gVideoStreamIndexList[l_i]);
100-
}
101-
if (gVideoStreamIndexList[l_i] == AVERROR_DECODER_NOT_FOUND) {
102-
LOGE(1, "Error: video stream found, but no decoder is found!");
103-
return;
104-
}
105-
/*open the codec*/
106-
gVideoCodecCtxDepList[l_i] = gFormatCtxDepList[l_i]->streams[gVideoStreamIndexList[l_i]]->codec;
107-
LOGI(10, "open codec for dumping dep: (%d, %d)", gVideoCodecCtxDepList[l_i]->height, gVideoCodecCtxDepList[l_i]->width);
108-
if (avcodec_open(gVideoCodecCtxDepList[l_i], lVideoCodec) < 0) {
109-
LOGE(1, "Error: cannot open the video codec!");
110-
return;
111-
}
112-
gVideoCodecCtxDepList[l_i]->dump_dependency = l_dumpDep;
113-
}
63+
if ((lError = av_open_input_file(&gFormatCtxDepList[l_i], p_videoFilenameList[l_i], NULL, 0, NULL)) !=0 ) {
64+
LOGE(1, "Error open video file: %d", lError);
65+
return; //open file failed
66+
}
67+
/*retrieve stream information*/
68+
if ((lError = av_find_stream_info(gFormatCtxDepList[l_i])) < 0) {
69+
LOGE(1, "Error find stream information: %d", lError);
70+
return;
71+
}
72+
/*find the video stream and its decoder*/
73+
gVideoStreamIndexList[l_i] = av_find_best_stream(gFormatCtxDepList[l_i], AVMEDIA_TYPE_VIDEO, -1, -1, &lVideoCodec, 0);
74+
if (gVideoStreamIndexList[l_i] == AVERROR_STREAM_NOT_FOUND) {
75+
LOGE(1, "Error: cannot find a video stream");
76+
return;
77+
} else {
78+
LOGI(10, "video codec: %s; stream index: %d", lVideoCodec->name, gVideoStreamIndexList[l_i]);
79+
}
80+
if (gVideoStreamIndexList[l_i] == AVERROR_DECODER_NOT_FOUND) {
81+
LOGE(1, "Error: video stream found, but no decoder is found!");
82+
return;
83+
}
84+
/*open the codec*/
85+
gVideoCodecCtxDepList[l_i] = gFormatCtxDepList[l_i]->streams[gVideoStreamIndexList[l_i]]->codec;
86+
LOGI(10, "open codec for dumping dep: (%d, %d)", gVideoCodecCtxDepList[l_i]->height, gVideoCodecCtxDepList[l_i]->width);
87+
if (avcodec_open(gVideoCodecCtxDepList[l_i], lVideoCodec) < 0) {
88+
LOGE(1, "Error: cannot open the video codec!");
89+
return;
90+
}
91+
gVideoCodecCtxDepList[l_i]->dump_dependency = 1;
92+
#endif
93+
/***
94+
The following section are initialization for decoding
95+
**/
11496
if ((lError = av_open_input_file(&gFormatCtxList[l_i], p_videoFilenameList[l_i], NULL, 0, NULL)) !=0 ) {
11597
LOGE(1, "Error open video file: %d", lError);
11698
return; //open file failed
@@ -148,24 +130,7 @@ void get_video_info(char **p_videoFilenameList, int p_debug) {
148130
LOGI(10, "SELECTIVE_DECODING is disabled");
149131
gVideoCodecCtxList[l_i]->allow_selective_decoding = 0;
150132
#endif
151-
152-
gVideoCodecCtxList[l_i]->dump_dependency = l_dumpDep;
153-
#if (defined SELECTIVE_DECODING) || (defined NORM_DECODE_DEBUG)
154-
/*open all the dependency files*/
155-
if (l_dumpDep) {
156-
packet_queue_init(&gVideoPacketQueueList[l_i]); //initialize the packet queue
157-
gVideoCodecCtxDepList[l_i]->g_gopF = fopen(l_depGopRecFileName, "a");
158-
gVideoCodecCtxDepList[l_i]->g_mbPosF = fopen(l_depMbPosFileName, "a");
159-
gVideoCodecCtxDepList[l_i]->g_dcPredF = fopen(l_depDcpFileName, "a");
160-
gVideoCodecCtxDepList[l_i]->g_intraDepF = fopen(l_depIntraFileName, "a");
161-
gVideoCodecCtxDepList[l_i]->g_interDepF = fopen(l_depInterFileName, "a");
162-
}
163-
gVideoCodecCtxList[l_i]->g_gopF = fopen(l_depGopRecFileName, "r");
164-
gVideoCodecCtxList[l_i]->g_mbPosF = fopen(l_depMbPosFileName, "r");
165-
gVideoCodecCtxList[l_i]->g_dcPredF = fopen(l_depDcpFileName, "r");
166-
gVideoCodecCtxList[l_i]->g_intraDepF = fopen(l_depIntraFileName, "r");
167-
gVideoCodecCtxList[l_i]->g_interDepF = fopen(l_depInterFileName, "r");
168-
#endif
133+
gVideoCodecCtxList[l_i]->dump_dependency = 0;
169134
/*set the debug option*/
170135
gVideoCodecCtxList[l_i]->debug_selective = p_debug;
171136
if (gVideoCodecCtxList[l_i]->debug_selective == 1) {
@@ -611,46 +576,79 @@ static void compute_mb_mask_from_inter_frame_dependency(int _stFrame, int _edFra
611576
}
612577

613578
void dep_decode_a_video_packet(int p_videoFileIndex) {
579+
char l_depGopRecFileName[100], l_depIntraFileName[100], l_depInterFileName[100], l_depMbPosFileName[100], l_depDcpFileName[100];
614580
AVFrame *l_videoFrame = avcodec_alloc_frame();
615581
int l_numOfDecodedFrames, l_frameType;
616582
//LOGI(10, "dep_decode_a_video_packet for video: %d", p_videoFileIndex);
617583
while (av_read_frame(gFormatCtxDepList[p_videoFileIndex], &gVideoPacketDepList[p_videoFileIndex]) >= 0) {
618-
if (gVideoPacketDepList[p_videoFileIndex].stream_index == gVideoStreamIndexList[p_videoFileIndex]) {
619-
//LOGI(10, "got a video packet, dump dependency: %d", p_videoFileIndex);
620-
++gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num;
621-
/*put the video packet into the packet queue, for the decoding thread to access*/
622-
//LOGI(10, "put a video packet into queue: %d", p_videoFileIndex);
623-
packet_queue_put(&gVideoPacketQueueList[p_videoFileIndex], &gVideoPacketDepList[p_videoFileIndex]);
624-
/*update the gop information if it's an I-frame*/
625-
l_frameType = (gVideoPacketDepList[p_videoFileIndex].data[4] & 0xC0);
626-
if (l_frameType == 0x00) { //an I frame packet
627-
if (gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num == 1) {
628-
fprintf(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF, "1:"); //if it's first video packet
584+
if (gVideoPacketDepList[p_videoFileIndex].stream_index == gVideoStreamIndexList[p_videoFileIndex]) {
585+
//LOGI(10, "got a video packet, dump dependency: %d", p_videoFileIndex);
586+
++gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num;
587+
/*put the video packet into the packet queue, for the decoding thread to access*/
588+
//LOGI(10, "put a video packet into queue: %d", p_videoFileIndex);
589+
packet_queue_put(&gVideoPacketQueueList[p_videoFileIndex], &gVideoPacketDepList[p_videoFileIndex]);
590+
/*update the gop information if it's an I-frame
591+
update: for every GOP, we generate a set of dependency files. It has the following advantages:
592+
0. It avoids the overhead, and memory issue caused by opearting on big files
593+
1. It makes it easy to delete some of the files that is already used if we're having a space constraints
594+
or we never use the dependency files again (in live streaming)
595+
*/
596+
l_frameType = (gVideoPacketDepList[p_videoFileIndex].data[4] & 0xC0);
597+
if (l_frameType == 0x00) { //an I frame packet
598+
if (gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num == 1) {
599+
//if it's first frame, no action is needed
600+
} else {
601+
//print the end frame number of previoius gop
602+
fprintf(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF, "%d:\n", gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num - 1);
603+
++gVideoPacketQueueList[p_videoFileIndex].dep_gop_num;
604+
//TODO: fflush all the dependency files for previous gop, may not be necessary since we're closing these files
605+
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF);
606+
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_mbPosF);
607+
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_dcPredF);
608+
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_intraDepF);
609+
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_interDepF);
610+
//close all dependency files for this GOP
611+
fclose(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF);
612+
fclose(gVideoCodecCtxDepList[p_videoFileIndex]->g_mbPosF);
613+
fclose(gVideoCodecCtxDepList[p_videoFileIndex]->g_dcPredF);
614+
fclose(gVideoCodecCtxDepList[p_videoFileIndex]->g_intraDepF);
615+
fclose(gVideoCodecCtxDepList[p_videoFileIndex]->g_interDepF);
616+
}
617+
/*check if the dependency files exist, if not, we'll need to dump the dependencies*/
618+
sprintf(l_depGopRecFileName, "./%s_goprec_gop%d.txt", gVideoFileNameList[p_videoFileIndex], gVideoPacketQueueList[p_videoFileIndex].dep_gop_num);
619+
sprintf(l_depIntraFileName, "./%s_intra_gop%d.txt", gVideoFileNameList[p_videoFileIndex], gVideoPacketQueueList[p_videoFileIndex].dep_gop_num);
620+
sprintf(l_depInterFileName, "./%s_inter_gop%d.txt", gVideoFileNameList[p_videoFileIndex], gVideoPacketQueueList[p_videoFileIndex].dep_gop_num);
621+
sprintf(l_depMbPosFileName, "./%s_mbpos_gop%d.txt", gVideoFileNameList[p_videoFileIndex], gVideoPacketQueueList[p_videoFileIndex].dep_gop_num);
622+
sprintf(l_depDcpFileName, "./%s_dcp_gop%d.txt", gVideoFileNameList[p_videoFileIndex], gVideoPacketQueueList[p_videoFileIndex].dep_gop_num);
623+
#ifdef CLEAR_DEP_BEFORE_START
624+
remove(l_depGopRecFileName);
625+
remove(l_depIntraFileName);
626+
remove(l_depInterFileName);
627+
remove(l_depMbPosFileName);
628+
remove(l_depDcpFileName);
629+
#endif
630+
if ((!if_file_exists(l_depGopRecFileName)) || (!if_file_exists(l_depIntraFileName)) || (!if_file_exists(l_depInterFileName)) || (!if_file_exists(l_depMbPosFileName)) || (!if_file_exists(l_depDcpFileName))) {
631+
//TODO: we should also check l_depGopRecFileName file content, see if it actually contains both GOP start and end frame
632+
//if any of the dependency files are missing, we still do dumping
633+
packet_queue_init(&gVideoPacketQueueList[p_videoFileIndex]); //initialize the packet queue
634+
gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF = fopen(l_depGopRecFileName, "w");
635+
gVideoCodecCtxDepList[p_videoFileIndex]->g_mbPosF = fopen(l_depMbPosFileName, "w");
636+
gVideoCodecCtxDepList[p_videoFileIndex]->g_dcPredF = fopen(l_depDcpFileName, "w");
637+
gVideoCodecCtxDepList[p_videoFileIndex]->g_intraDepF = fopen(l_depIntraFileName, "w");
638+
gVideoCodecCtxDepList[p_videoFileIndex]->g_interDepF = fopen(l_depInterFileName, "w");
639+
}
640+
//dump the start frame number for the new gop
641+
fprintf(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF, "%d:", gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num);
642+
}
643+
/*dump the dependency info*/
644+
avcodec_decode_video2_dep(gVideoCodecCtxDepList[p_videoFileIndex], l_videoFrame, &l_numOfDecodedFrames, &gVideoPacketDepList[p_videoFileIndex]);
645+
//av_free_packet(&gVideoPacketDepList[p_videoFileIndex]);
646+
break;
629647
} else {
630-
/*this will cause the end of the goprect.txt has an additional line. But we stick to this method
631-
for speed purpose */
632-
fprintf(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF, "%d:\n%d:", gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num - 1, gVideoCodecCtxDepList[p_videoFileIndex]->dep_video_packet_num);
633-
++gVideoPacketQueueList[p_videoFileIndex].dep_gop_num;
634-
/*fflush all the dependency files*/
635-
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_gopF);
636-
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_mbPosF);
637-
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_dcPredF);
638-
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_intraDepF);
639-
fflush(gVideoCodecCtxDepList[p_videoFileIndex]->g_interDepF);
640-
//pthread_cond_signal(&gVideoPacketQueue.cond);
641-
//LOGI(10, "signal gVideoPacketQueue.cond: %d", gVideoPacketQueue.dep_gop_num);
648+
//it's not a video packet
649+
//LOGI(10, "%d != %d: it's not a video packet, continue reading!", gVideoPacketDep.stream_index, gVideoStreamIndex);
650+
av_free_packet(&gVideoPacketDepList[p_videoFileIndex]);
642651
}
643-
}
644-
//fprintf(g_gopF, "%d: 0x%x\n", g_dep_videoPacketNum, l_frameType); //[DEBUG PRINT]
645-
/*dump the dependency info*/
646-
avcodec_decode_video2_dep(gVideoCodecCtxDepList[p_videoFileIndex], l_videoFrame, &l_numOfDecodedFrames, &gVideoPacketDepList[p_videoFileIndex]);
647-
//av_free_packet(&gVideoPacketDepList[p_videoFileIndex]);
648-
break;
649-
} else {
650-
//it's not a video packet
651-
//LOGI(10, "%d != %d: it's not a video packet, continue reading!", gVideoPacketDep.stream_index, gVideoStreamIndex);
652-
av_free_packet(&gVideoPacketDepList[p_videoFileIndex]);
653-
}
654652
}
655653
av_free(l_videoFrame);
656654
}
@@ -893,25 +891,20 @@ void load_gop_info(int p_videoFileIndex, FILE* p_gopRecFile) {
893891
char l_gopRecLine[50];
894892
char *l_aToken;
895893
int l_stFrame = 0, l_edFrame = 0;
896-
LOGI(10, "load gop info starts: %d, %d, %d", gVideoCodecCtxList[p_videoFileIndex]->dump_dependency, gVideoPacketQueueList[p_videoFileIndex].dep_gop_num, gNumOfGop);
897-
while ((!gVideoCodecCtxList[p_videoFileIndex]->dump_dependency) || (gVideoPacketQueueList[p_videoFileIndex].dep_gop_num > gNumOfGop)) {
898-
LOGI(10, "load gop info in progress: %d", gNumOfVideoFiles);
899-
if (fgets(l_gopRecLine, 50, p_gopRecFile) == NULL)
900-
break;
901-
if ((l_aToken = strtok(l_gopRecLine, ":")) != NULL)
902-
l_stFrame = atoi(l_aToken);
903-
else
904-
break;
905-
if ((l_aToken = strtok(NULL, ":")) != NULL)
906-
l_edFrame = atoi(l_aToken);
907-
else
908-
break;
909-
gGopStart[gNumOfGop] = l_stFrame;
910-
gGopEnd[gNumOfGop] = l_edFrame;
911-
gNumOfGop += 1;
912-
}
913-
//fclose(p_gopRecFile);
914-
LOGI(10, "load gop info ends: %d", gNumOfVideoFiles);
894+
LOGI(10, "load gop info starts: %d, %d", gVideoPacketQueueList[p_videoFileIndex].dep_gop_num, g_decode_gop_num);
895+
if (fgets(l_gopRecLine, 50, p_gopRecFile) == NULL)
896+
return;
897+
if ((l_aToken = strtok(l_gopRecLine, ":")) != NULL)
898+
l_stFrame = atoi(l_aToken);
899+
else
900+
return;
901+
if ((l_aToken = strtok(NULL, ":")) != NULL)
902+
l_edFrame = atoi(l_aToken);
903+
else
904+
return;
905+
gGopStart = l_stFrame;
906+
gGopEnd = l_edFrame;
907+
LOGI(10, "load gop info ends: %d", p_videoFileIndex);
915908
}
916909

917910
/*load the pre computation for a gop and also compute the inter frame dependency for a gop*/

dependency.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ AVFormatContext **gFormatCtxList;
7070
AVFormatContext **gFormatCtxDepList;
7171
int gNumOfVideoFiles;
7272
int gCurrentDecodingVideoFileIndex;
73-
//char *gFileName; //the file name of the video
73+
char **gVideoFileNameList; //the list of video file names
7474
int *gVideoStreamIndexList; //video stream index
7575
int gStFrame;
7676

7777
int gVideoPacketNum; //the current frame number
78-
int g_dep_videoPacketNum; //the current frame number when dumping dependency
78+
//int g_dep_videoPacketNum; //the current frame number when dumping dependency
7979

8080
AVPacket *gVideoPacketDepList; //the video packet for dumping dependency
8181
AVPacket gVideoPacket; //the original video packet
@@ -90,8 +90,8 @@ FILE *g_interDepF;
9090
FILE *g_dcPredF;
9191
FILE *g_gopF;*/
9292

93-
int gGopStart[MAX_NUM_OF_GOP];
94-
int gGopEnd[MAX_NUM_OF_GOP];
93+
int gGopStart;
94+
int gGopEnd;
9595
int gNumOfGop;
9696

9797
int *gZoomLevelToVideoIndex;

0 commit comments

Comments
 (0)