@@ -14,7 +14,6 @@ static int videoIndexCmp(const int *a, const int *b) {
14
14
/*parsing the video file, done by parse thread*/
15
15
void get_video_info (char * * p_videoFilenameList , int p_debug ) {
16
16
AVCodec * lVideoCodec ;
17
- char l_depGopRecFileName [100 ], l_depIntraFileName [100 ], l_depInterFileName [100 ], l_depMbPosFileName [100 ], l_depDcpFileName [100 ];
18
17
int lError ;
19
18
int l_dumpDep ;
20
19
int l_i ;
@@ -57,60 +56,43 @@ void get_video_info(char **p_videoFilenameList, int p_debug) {
57
56
}
58
57
for (l_i = 0 ; l_i < gNumOfVideoFiles ; ++ l_i ) {
59
58
#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
+ **/
82
62
/*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
+ **/
114
96
if ((lError = av_open_input_file (& gFormatCtxList [l_i ], p_videoFilenameList [l_i ], NULL , 0 , NULL )) != 0 ) {
115
97
LOGE (1 , "Error open video file: %d" , lError );
116
98
return ; //open file failed
@@ -148,24 +130,7 @@ void get_video_info(char **p_videoFilenameList, int p_debug) {
148
130
LOGI (10 , "SELECTIVE_DECODING is disabled" );
149
131
gVideoCodecCtxList [l_i ]-> allow_selective_decoding = 0 ;
150
132
#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 ;
169
134
/*set the debug option*/
170
135
gVideoCodecCtxList [l_i ]-> debug_selective = p_debug ;
171
136
if (gVideoCodecCtxList [l_i ]-> debug_selective == 1 ) {
@@ -611,46 +576,79 @@ static void compute_mb_mask_from_inter_frame_dependency(int _stFrame, int _edFra
611
576
}
612
577
613
578
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 ];
614
580
AVFrame * l_videoFrame = avcodec_alloc_frame ();
615
581
int l_numOfDecodedFrames , l_frameType ;
616
582
//LOGI(10, "dep_decode_a_video_packet for video: %d", p_videoFileIndex);
617
583
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 ;
629
647
} 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 ]);
642
651
}
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
- }
654
652
}
655
653
av_free (l_videoFrame );
656
654
}
@@ -893,25 +891,20 @@ void load_gop_info(int p_videoFileIndex, FILE* p_gopRecFile) {
893
891
char l_gopRecLine [50 ];
894
892
char * l_aToken ;
895
893
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 );
915
908
}
916
909
917
910
/*load the pre computation for a gop and also compute the inter frame dependency for a gop*/
0 commit comments