LCOV - code coverage report
Current view: top level - home/magsoft/trunks/SVT-AV1/Source/App/EncApp - EbAppInputy4m.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 189 46.0 %
Date: 2019-11-25 17:38:06 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             : * Copyright(c) 2019 Intel Corporation
       3             : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
       4             : */
       5             : 
       6             : #include "EbAppString.h"
       7             : #include "EbAppInputy4m.h"
       8             : #define YFM_HEADER_MAX 80
       9             : #define YUV4MPEG2_IND_SIZE 9
      10             : #define PRINT_HEADER 0
      11             : #define CHROMA_MAX 4
      12             : 
      13             : /* copy a string until a specified character or a new line is found */
      14          10 : char* copyUntilCharacterOrNewLine(char *src, char *dst, char chr){
      15          10 :     rsize_t count = 0;
      16          10 :     char * src_init = src;
      17             : 
      18          34 :     while (*src != chr && *src != '\n') {
      19          24 :         src++;
      20          24 :         count++;
      21             :     }
      22             : 
      23          10 :     EB_STRNCPY(dst, YFM_HEADER_MAX, src_init, count);
      24             : 
      25          10 :     return src;
      26             : }
      27             : 
      28             : /* reads the y4m header and parses the input parameters */
      29           2 : int32_t read_y4m_header(EbConfig *cfg){
      30             :     FILE *ptr_in;
      31             :     char buffer[YFM_HEADER_MAX];
      32             :     char *fresult, *tokstart, *tokend, format_str[YFM_HEADER_MAX];
      33           2 :     uint32_t bitdepth = 8, width = 0, height = 0, fr_n = 0,
      34           2 :         fr_d = 0, aspect_n, aspect_d;
      35           2 :     char chroma[CHROMA_MAX] = "420", scan_type = 'p';
      36           2 :     EbBool interlaced = EB_TRUE;
      37             : 
      38             :     /* pointer to the input file */
      39           2 :     ptr_in = cfg->input_file;
      40             : 
      41             :     /* get first line after YUV4MPEG2 */
      42           2 :     fresult = fgets(buffer, sizeof(buffer), ptr_in);
      43           2 :     if(fresult==NULL)
      44           0 :         return EB_ErrorBadParameter;
      45             : 
      46             :     /* print header */
      47             :     if(PRINT_HEADER) {
      48             :         printf("y4m header:");
      49             :         fputs(buffer, stdout);
      50             :     }
      51             : 
      52             :     /* read header parameters */
      53           2 :     tokstart = &(buffer[0]);
      54             : 
      55          32 :     while (*tokstart != '\0') {
      56          30 :         if (*tokstart == 0x20) {
      57          14 :             tokstart++;
      58          14 :             continue;
      59             :         }
      60             : 
      61          16 :         switch (*tokstart++) {
      62           2 :         case 'W': /* width, required. */
      63           2 :             width = (uint32_t)strtol(tokstart, &tokend, 10);
      64             :             if(PRINT_HEADER)
      65             :                 printf("width = %d\n", width);
      66           2 :             tokstart = tokend;
      67           2 :             break;
      68           2 :         case 'H': /* height, required. */
      69           2 :             height = (uint32_t)strtol(tokstart, &tokend, 10);
      70             :             if(PRINT_HEADER)
      71             :                 printf("height = %d\n", height);
      72           2 :             tokstart = tokend;
      73           2 :             break;
      74           2 :         case 'I': /* scan type, not required, default: 'p' */
      75           2 :             switch (*tokstart++) {
      76           2 :             case 'p':
      77           2 :                 interlaced = EB_FALSE;
      78           2 :                 scan_type = 'p';
      79           2 :                 break;
      80           0 :             case 't':
      81           0 :                 interlaced = EB_TRUE;
      82           0 :                 scan_type = 't';
      83           0 :                 break;
      84           0 :             case 'b':
      85           0 :                 interlaced = EB_TRUE;
      86           0 :                 scan_type = 'b';
      87           0 :                 break;
      88           0 :             case '?':
      89             :             default:
      90           0 :                 fprintf(cfg->error_log_file, "interlace type not supported\n");
      91           0 :                 return EB_ErrorBadParameter;
      92             :             }
      93             :             if(PRINT_HEADER)
      94             :                 printf("scan_type = %c\n", scan_type);
      95           2 :             break;
      96           2 :         case 'C': /* color space, not required: default "420" */
      97           2 :             tokstart = copyUntilCharacterOrNewLine(tokstart, format_str, 0x20);
      98           2 :             if (EB_STRCMP("420mpeg2", format_str) == 0) {
      99           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     100             :                 // chroma left
     101           0 :                 bitdepth = 8;
     102           2 :             } else if (EB_STRCMP("420paldv", format_str) == 0) {
     103           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     104             :                 // chroma top-left
     105           0 :                 bitdepth = 8;
     106           2 :             }else if (EB_STRCMP("420jpeg", format_str) == 0) {
     107           2 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     108             :                 // chroma center
     109           2 :                 bitdepth = 8;
     110           0 :             } else if (EB_STRCMP("420p16", format_str) == 0) {
     111           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     112           0 :                 bitdepth = 16;
     113           0 :             } else if (EB_STRCMP("422p16", format_str) == 0) {
     114           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     115           0 :                 bitdepth = 16;
     116           0 :             } else if (EB_STRCMP("444p16", format_str) == 0) {
     117           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     118           0 :                 bitdepth = 16;
     119           0 :             } else if (EB_STRCMP("420p14", format_str) == 0) {
     120           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     121           0 :                 bitdepth = 14;
     122           0 :             } else if (EB_STRCMP("422p14", format_str) == 0) {
     123           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     124           0 :                 bitdepth = 14;
     125           0 :             } else if (EB_STRCMP("444p14", format_str) == 0) {
     126           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     127           0 :                 bitdepth = 14;
     128           0 :             } else if (EB_STRCMP("420p12", format_str) == 0) {
     129           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     130           0 :                 bitdepth = 12;
     131           0 :             } else if (EB_STRCMP("422p12", format_str) == 0) {
     132           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     133           0 :                 bitdepth = 12;
     134           0 :             } else if (EB_STRCMP("444p12", format_str) == 0) {
     135           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     136           0 :                 bitdepth = 12;
     137           0 :             } else if (EB_STRCMP("420p10", format_str) == 0) {
     138           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     139           0 :                 bitdepth = 10;
     140           0 :             } else if (EB_STRCMP("422p10", format_str) == 0) {
     141           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     142           0 :                 bitdepth = 10;
     143           0 :             } else if (EB_STRCMP("444p10", format_str) == 0) {
     144           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     145           0 :                 bitdepth = 10;
     146           0 :             } else if (EB_STRCMP("420p9", format_str) == 0) {
     147           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     148           0 :                 bitdepth = 9;
     149           0 :             } else if (EB_STRCMP("422p9", format_str) == 0) {
     150           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     151           0 :                 bitdepth = 9;
     152           0 :             } else if (EB_STRCMP("444p9", format_str) == 0) {
     153           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     154           0 :                 bitdepth = 9;
     155           0 :             } else if (EB_STRCMP("420", format_str) == 0) {
     156           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "420");
     157           0 :                 bitdepth = 8;
     158           0 :             } else if (EB_STRCMP("411", format_str) == 0) {
     159           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "411");
     160           0 :                 bitdepth = 8;
     161           0 :             } else if (EB_STRCMP("422", format_str) == 0) {
     162           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "422");
     163           0 :                 bitdepth = 8;
     164           0 :             } else if (EB_STRCMP("444", format_str) == 0) {
     165           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "444");
     166           0 :                 bitdepth = 8;
     167           0 :             } else if (EB_STRCMP("mono16", format_str) == 0) {
     168           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "400");
     169           0 :                 bitdepth = 16;
     170           0 :             } else if (EB_STRCMP("mono12", format_str) == 0) {
     171           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "400");
     172           0 :                 bitdepth = 12;
     173           0 :             } else if (EB_STRCMP("mono10", format_str) == 0) {
     174           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "400");
     175           0 :                 bitdepth = 10;
     176           0 :             } else if (EB_STRCMP("mono9", format_str) == 0) {
     177           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "400");
     178           0 :                 bitdepth = 9;
     179           0 :             } else if (EB_STRCMP("mono", format_str) == 0) {
     180           0 :                 EB_STRCPY(chroma, CHROMA_MAX, "400");
     181           0 :                 bitdepth = 8;
     182             :             } else {
     183           0 :                 fprintf(cfg->error_log_file, "chroma format not supported\n");
     184           0 :                 return EB_ErrorBadParameter;
     185             :             }
     186             :             if(PRINT_HEADER)
     187             :                 printf("chroma = %s, bitdepth = %d\n", chroma, bitdepth);
     188           2 :             break;
     189           2 :         case 'F': /* frame rate, required */
     190           2 :             tokstart = copyUntilCharacterOrNewLine(tokstart, format_str, ':');
     191           2 :             fr_n = (uint32_t) strtol(format_str, (char **)NULL, 10);
     192           2 :             tokstart++;
     193           2 :             tokstart = copyUntilCharacterOrNewLine(tokstart, format_str, 0x20);
     194           2 :             fr_d = (uint32_t) strtol(format_str, (char **)NULL, 10);
     195             :             if(PRINT_HEADER) {
     196             :                 printf("framerate_n = %d\n", fr_n);
     197             :                 printf("framerate_d = %d\n", fr_d);
     198             :             }
     199           2 :             break;
     200           2 :         case 'A': /* aspect ratio, not required */
     201           2 :             tokstart = copyUntilCharacterOrNewLine(tokstart, format_str, ':');
     202           2 :             aspect_n = (uint32_t) strtol(format_str, (char **)NULL, 10);
     203           2 :             tokstart++;
     204           2 :             tokstart = copyUntilCharacterOrNewLine(tokstart, format_str, 0x20);
     205           2 :             aspect_d = (uint32_t) strtol(format_str, (char **)NULL, 10);
     206             :             if(PRINT_HEADER) {
     207             :                 printf("aspect_n = %d\n", aspect_n);
     208             :                 printf("aspect_d = %d\n", aspect_d);
     209             :             }
     210           2 :             break;
     211           4 :         default:
     212             :             /* Unknown section: skip it */
     213          48 :             while (*tokstart != 0x20 && *tokstart != '\0')
     214          44 :                 tokstart++;
     215           4 :             break;
     216             :         }
     217             :     }
     218             : 
     219             :     /* Check that we did not try to parse further the end of the header string */
     220           2 :     assert(fresult + strlen(fresult) == tokstart);
     221             : 
     222             :     /*check if required parameters were read*/
     223           2 :     if(width == 0) {
     224           0 :         fprintf(cfg->error_log_file, "width not found in y4m header\n");
     225           0 :         return EB_ErrorBadParameter;
     226             :     }
     227           2 :     if(height == 0) {
     228           0 :         fprintf(cfg->error_log_file, "height not found in y4m header\n");
     229           0 :         return EB_ErrorBadParameter;
     230             :     }
     231           2 :     if(fr_n == 0 || fr_d == 0) {
     232           0 :         fprintf(cfg->error_log_file, "frame rate not found in y4m header\n");
     233           0 :         return EB_ErrorBadParameter;
     234             :     }
     235             : 
     236             :     /* Assign parameters to cfg */
     237           2 :     cfg->source_width = width;
     238           2 :     cfg->source_height = height;
     239           2 :     cfg->frame_rate_numerator = fr_n;
     240           2 :     cfg->frame_rate_denominator = fr_d;
     241           2 :     cfg->frame_rate = fr_n/fr_d;
     242           2 :     cfg->encoder_bit_depth = bitdepth;
     243           2 :     cfg->interlaced_video = interlaced;
     244             :     /* TODO: when implemented, need to set input bit depth
     245             :         (instead of the encoder bit depth) and chroma format */
     246             : 
     247           2 :     return EB_ErrorNone;
     248             : }
     249             : 
     250             : /* read next line which contains the "FRAME" delimiter */
     251         120 : int32_t read_y4m_frame_delimiter(EbConfig *cfg){
     252             :     unsigned char bufferY4Mheader[10];
     253             :     char *fresult;
     254             : 
     255         120 :     fresult = fgets((char *)bufferY4Mheader, sizeof(bufferY4Mheader), cfg->input_file);
     256             : 
     257         120 :     if(fresult == NULL){
     258           0 :         assert(feof(cfg->input_file));
     259           0 :         return EB_ErrorNone;
     260             :     }
     261             : 
     262         120 :     if (EB_STRCMP((const char*)bufferY4Mheader, "FRAME\n") != 0) {
     263           0 :         fprintf(cfg->error_log_file, "Failed to read proper y4m frame delimeter. Read broken.\n");
     264           0 :         return EB_ErrorBadParameter;
     265             :     }
     266             : 
     267         120 :     return EB_ErrorNone;
     268             : }
     269             : 
     270             : /* check if the input file is in YUV4MPEG2 (y4m) format */
     271           2 : EbBool check_if_y4m(EbConfig *cfg)
     272             : {
     273             :     size_t len;
     274             :     char buf[YUV4MPEG2_IND_SIZE+1];
     275           2 :     len = fread(buf, YUV4MPEG2_IND_SIZE, 1, cfg->input_file);
     276           2 :     if (len != 1)
     277           0 :         return EB_FALSE;
     278             : 
     279           2 :     if ((cfg->input_file != stdin) && (!cfg->input_file_is_fifo)) {
     280           2 :         fseek(cfg->input_file, 0, SEEK_SET);
     281             :     } else {
     282           0 :         memcpy(cfg->y4m_buf, buf, YUV4MPEG2_IND_SIZE);
     283             :     }
     284             : 
     285           2 :     buf[YUV4MPEG2_IND_SIZE] = 0;
     286           2 :     return (EB_STRCMP(buf, "YUV4MPEG2") == 0);
     287             : }

Generated by: LCOV version 1.14