Improve _get_first_good_video_frame complexity 44/278544/5
authorminje.ahn <minje.ahn@samsung.com>
Fri, 22 Jul 2022 00:07:21 +0000 (09:07 +0900)
committerMinje ahn <minje.ahn@samsung.com>
Mon, 8 Aug 2022 23:11:33 +0000 (23:11 +0000)
Change-Id: Ib6b0cf9337fe958a416b5703104557735679ed38
Signed-off-by: minje.ahn <minje.ahn@samsung.com>
formats/ffmpeg/mm_file_format_ffmpeg.c
packaging/libmm-fileinfo.spec

index bc0976cb73ab7b6751f7b48d6d1b98710d2abbdf..1795971998e99cadf4cf640571d61390f8036c0b 100644 (file)
@@ -977,7 +977,7 @@ static unsigned int _diff_memory(const void *s1, const void *s2, unsigned int n)
 /**
  * compare with center line.
  */
-static int __is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize)
+static bool __is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize)
 {
 #define _MM_CHUNK_NUM                  8                                               /*FIXME*/
 #define _MM_CHUNK_LIMIT                        (_MM_CHUNK_NUM / 2)
@@ -1000,31 +1000,32 @@ static int __is_good_pgm(unsigned char *buf, int wrap, int xsize, int ysize)
 
        /*if too small, always ok return.*/
        if (ysize < _MM_CHUNK_NUM)
-               return 1;
+               return true;
 
        for (point = 0, sum_diff = 0, i = step; i < ysize; i += step) {
-               if (i != cnt_offset) {
-
-                       /*binary compare*/
-                       is_different = _diff_memory(cnt, buf + i * wrap, xsize);
-                       point += (is_different == 0 ? 0 : 1);
-                       sum_diff += is_different;
-
-                       debug_msg(RELEASE, "check %04d line. %s [%d]", i, (is_different == 0 ? "same" : "different"), is_different);
-
-                       if (point >= _MM_CHUNK_LIMIT) {
-                               if (sum_diff > _MM_CHUNK_DIFF_LIMIT) {
-                                       debug_msg(RELEASE, "Good :-)");
-                                       return 1;
-                               } else {
-                                       debug_msg(RELEASE, "Bad :-(");
-                                       return 0;
-                               }
-                       }
+               if (i == cnt_offset)
+                       continue;
+
+               /*binary compare*/
+               is_different = _diff_memory(cnt, buf + i * wrap, xsize);
+               point += (is_different == 0 ? 0 : 1);
+               sum_diff += is_different;
+
+               debug_msg(RELEASE, "check %04d line. %s [%d]", i, (is_different == 0 ? "same" : "different"), is_different);
+
+               if (point < _MM_CHUNK_LIMIT)
+                       continue;
+
+               if (sum_diff <= _MM_CHUNK_DIFF_LIMIT) {
+                       debug_msg(RELEASE, "Bad :-(");
+                       return false;
                }
 
+               debug_msg(RELEASE, "Good :-)");
+               return true;
        }
-       return 0;
+
+       return false;
 }
 
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
@@ -1059,11 +1060,12 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
        AVFrame *tmp_frame = NULL;
        AVFrame *first_frame = NULL;
 
-       int ret;
        int found = 0;
-       int i, v, len;
+       int i = 0;
+       int v = 0;
+       int ret;
        int retry = 0;
-       int key_detected;
+       bool key_detected = false;
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
        char pgm_name[256] = {0, };
 #endif
@@ -1075,10 +1077,8 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
 
        if (!first_frame || !tmp_frame) {
                debug_error(DEBUG, "failed to alloc frame.");
-               if (first_frame)
-                       av_frame_free(&first_frame);
-               if (tmp_frame)
-                       av_frame_free(&tmp_frame);
+               av_frame_free(&first_frame);
+               av_frame_free(&tmp_frame);
 
                return MMFILE_FORMAT_FAIL;
        }
@@ -1086,84 +1086,85 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
        debug_msg(RELEASE, "frame: 1. %p, 2. %p", first_frame, tmp_frame);
 
        pCodecCtx->skip_frame = AVDISCARD_BIDIR;
+       frame = first_frame;
 
-       for (i = 0, v = 0, key_detected = 0, frame = first_frame; i < key_search_limit && v < frame_search_limit;) {
+       while (i < key_search_limit && v < frame_search_limit) {
                pkt = av_packet_alloc();
                if (!pkt) {
                        debug_error(DEBUG, "packet allocation failed.");
                        break;
                }
 
-               ret = av_read_frame(pFormatCtx, pkt);
-               if (ret < 0) {
+               if (av_read_frame(pFormatCtx, pkt) < 0) {
                        debug_error(DEBUG, "read failed. (maybe EOF or broken)");
                        break;
                }
 
-               if (avcodec_get_type(pFormatCtx->streams[pkt->stream_index]->codecpar->codec_id) == AVMEDIA_TYPE_VIDEO) {
-                       v++;
-                       if ((pkt->flags & AV_PKT_FLAG_KEY) || (key_detected == 1)) {
-                               debug_msg(RELEASE, "video frame: %d, %d, %d", retry, i, v);
-#ifdef __MMFILE_TEST_MODE__
-                               _dump_av_packet(pkt);
-#endif
-                               i++;
-                               key_detected = 0;
+               if (avcodec_get_type(pFormatCtx->streams[pkt->stream_index]->codecpar->codec_id) != AVMEDIA_TYPE_VIDEO)
+                       goto NEXT;
 
-                               len = avcodec_send_packet(pCodecCtx, pkt);
-                               if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
-                                       debug_error(RELEASE, "Error while avcodec_send_packet[%2d]", len);
-                                       break;
-                               }
+               v++;
+               if (!(pkt->flags & AV_PKT_FLAG_KEY) && !key_detected)
+                       goto NEXT;
 
-                               len = avcodec_receive_frame(pCodecCtx, frame);
-                               if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
-                                       debug_warning(DEBUG, "Error while decoding frame %dth", i);
-                               } else if (len >= 0) {
-                                       if (frame->key_frame) {
-                                               debug_msg(RELEASE, "key frame!");
-#ifdef MMFILE_FORMAT_DEBUG_DUMP
-                                               memset(pgm_name, 0x00, sizeof(pgm_name));
-                                               snprintf(pgm_name, sizeof(pgm_name), "./key_%d_%d_%d.pgm", retry, i, v);
-                                               _save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
+               debug_msg(RELEASE, "video frame: %d, %d, %d", retry, i, v);
+#ifdef __MMFILE_TEST_MODE__
+               _dump_av_packet(pkt);
 #endif
+               i++;
+               key_detected = false;
 
-                                               found++;
-
-                                               ret = __is_good_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height);
-                                               if (ret != 0) {
-                                                       debug_msg(RELEASE, "is good frame.");
-                                                       break;
-                                               }
-
-                                               /*reset video frame count & retry searching*/
-                                               debug_warning(RELEASE, "not good fame. retry scanning.");
-                                               i = 0;
-                                               v = 0;
-                                               retry++;
+               ret = avcodec_send_packet(pCodecCtx, pkt);
+               if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
+                       debug_error(RELEASE, "Error while avcodec_send_packet[%2d]", ret);
+                       break;
+               }
 
-                                               /*set buffer frame*/
-                                               frame = tmp_frame;
+               ret = avcodec_receive_frame(pCodecCtx, frame);
+               if (ret < 0) {
+                       if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+                               debug_msg(RELEASE, "decode not completed.");
+                               key_detected = true;
+                               goto NEXT;
+                       }
+                       debug_warning(DEBUG, "Error while decoding frame %dth", i);
+                       goto NEXT;
+               }
 
-                                               /*limit of retry.*/
-                                               if (retry > _RETRY_SEARCH_LIMIT)
-                                                       break;
+               if (!frame->key_frame) {
+                       debug_msg(RELEASE, "skip (not key frame).");
+#ifdef MMFILE_FORMAT_DEBUG_DUMP
+                       memset(pgm_name, 0x00, sizeof(pgm_name));
+                       snprintf(pgm_name, sizeof(pgm_name), "./not_key_%d_%d_%d.pgm", retry, i, v);
+                       _save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
+#endif
+                       goto NEXT;
+               }
 
-                                       } else {
-                                               debug_msg(RELEASE, "skip (not key frame).");
+               debug_msg(RELEASE, "key frame!");
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
-                                               memset(pgm_name, 0x00, sizeof(pgm_name));
-                                               snprintf(pgm_name, sizeof(pgm_name), "./not_key_%d_%d_%d.pgm", retry, i, v);
-                                               _save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
+               memset(pgm_name, 0x00, sizeof(pgm_name));
+               snprintf(pgm_name, sizeof(pgm_name), "./key_%d_%d_%d.pgm", retry, i, v);
+               _save_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height, pgm_name);
 #endif
-                                       }
-                               } else {
-                                       debug_msg(RELEASE, "decode not completed.");
-                                       key_detected = 1;
-                               }
-                       }
+               found++;
+
+               if (__is_good_pgm(frame->data[0], frame->linesize[0], pCodecCtx->width, pCodecCtx->height)) {
+                       debug_msg(RELEASE, "is good frame.");
+                       break;
                }
 
+               debug_warning(RELEASE, "not good fame. retry scanning.");
+               i = 0;
+               v = 0;
+               retry++;
+
+               /*set buffer frame*/
+               frame = tmp_frame;
+
+               if (retry > _RETRY_SEARCH_LIMIT)
+                       break;
+NEXT:
                av_packet_free(&pkt);
        }
 
@@ -1174,27 +1175,21 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
 
        /*set decode frame to output*/
        if (found > 0) {
-               ret = MMFILE_FORMAT_SUCCESS;
                if (retry == 0 || found == retry) {
                        *pFrame = first_frame;
-                       if (tmp_frame)
-                               av_frame_free(&tmp_frame);
+                       av_frame_free(&tmp_frame);
                } else {
                        *pFrame = tmp_frame;
-                       if (first_frame)
-                               av_frame_free(&first_frame);
+                       av_frame_free(&first_frame);
                }
        } else {
-               ret = MMFILE_FORMAT_FAIL;
-               if (first_frame)
-                       av_frame_free(&first_frame);
-               if (tmp_frame)
-                       av_frame_free(&tmp_frame);
+               av_frame_free(&first_frame);
+               av_frame_free(&tmp_frame);
        }
 
        debug_msg(RELEASE, "out frame: %p", *pFrame);
 
        pCodecCtx->skip_frame = AVDISCARD_NONE;
 
-       return ret;
+       return (found > 0) ? MMFILE_FORMAT_SUCCESS : MMFILE_FORMAT_FAIL;
 }
index a8a8eae77bf6ece269d65399f3321936fe6b380f..2508b690e79c3f6a61196ecc43ff8958916a8f23 100644 (file)
@@ -1,6 +1,6 @@
 Name:      libmm-fileinfo
 Summary:    Media Fileinfo
-Version:    1.0.9
+Version:    1.0.10
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0