⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lav_io.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /* Set lav_fd */   lav_fd->avi_fd      = 0;   lav_fd->qt_fd       = 0;   lav_fd->format      = 0;   lav_fd->interlacing = LAV_INTER_UNKNOWN;   lav_fd->sar_w       = 1; /* unknown - assume square pixels */   lav_fd->sar_h       = 1;    lav_fd->has_audio   = 0;   lav_fd->bps         = 0;   lav_fd->MJPG_chroma = CHROMAUNKNOWN;   /* open video file, try AVI first */   lav_fd->avi_fd = AVI_open_input_file(filename,1);   video_format = 'a'; /* for error messages */   if(lav_fd->avi_fd)   {      /* It is an AVI file */      lav_fd->qt_fd  = 0;      lav_fd->format = 'a';      lav_fd->has_audio = (AVI_audio_bits(lav_fd->avi_fd)>0 &&                           AVI_audio_format(lav_fd->avi_fd)==WAVE_FORMAT_PCM);      video_comp = AVI_video_compressor(lav_fd->avi_fd);   }   else if( AVI_errno==AVI_ERR_NO_AVI )   {#ifdef HAVE_LIBQUICKTIME      if(!quicktime_check_sig(filename))#endif	  {	    /* None of the known formats */            char errmsg[1024];	    sprintf(errmsg, "Unable to identify file (not a supported format - avi");#ifdef HAVE_LIBQUICKTIME            strcat(errmsg, ", quicktime");#endif	    strcat(errmsg, ").\n");            fprintf(stderr, errmsg);	    free(lav_fd);	    internal_error = ERROR_FORMAT; /* Format not recognized */	    return 0;	  }#ifdef HAVE_LIBQUICKTIME      else	{	  /* It is a quicktime file */	  lav_fd->qt_fd = quicktime_open(filename,1,0);	  video_format = 'q'; /* for error messages */	  if(!lav_fd->qt_fd) { free(lav_fd); return 0; }	  lav_fd->avi_fd = 0;	  lav_fd->format = 'q';	  video_comp = quicktime_video_compressor(lav_fd->qt_fd,0);	  /* We want at least one video track */	  if(quicktime_video_tracks(lav_fd->qt_fd) < 1)	    {	      lav_close(lav_fd);	      internal_error = ERROR_FORMAT;	      return 0;	    }	  /* Check for audio tracks */	  lav_fd->has_audio = 0;	  if (quicktime_audio_tracks(lav_fd->qt_fd))	     {	     audio_comp = quicktime_audio_compressor(lav_fd->qt_fd,0);	     if (strncasecmp(audio_comp, QUICKTIME_TWOS,4)==0)		lav_fd->has_audio = 1;	      }	 }#endif   }   else   {      /* There should be an error from avilib, just return */      free(lav_fd);      return 0;   }   /* set audio bytes per sample */   lav_fd->bps = (lav_audio_channels(lav_fd)*lav_audio_bits(lav_fd)+7)/8;   if(lav_fd->bps==0) lav_fd->bps=1; /* make it save since we will divide by that value */   /* Check compressor, no further action if not Motion JPEG */   if(strncasecmp(video_comp,"mjpg",4)!=0 &&      strncasecmp(video_comp,"mjpa",4)!=0 &&      strncasecmp(video_comp,"jpeg",4)!=0 )   {#ifdef HAVE_LIBDV   if(strncasecmp(video_comp,"dvsd",4)==0#ifdef HAVE_LIBQUICKTIME      || strncasecmp(video_comp,QUICKTIME_DV,4)==0#endif      || strncasecmp(video_comp,"dv",2)==0) {       ierr = check_DV2_input(lav_fd);#ifdef LIBDV_PAL_YV12       lav_fd->MJPG_chroma = CHROMA420;#else       lav_fd->MJPG_chroma = CHROMA422;#endif       if (ierr) goto ERREXIT;       /* DV is always interlaced, bottom first */       lav_fd->interlacing = LAV_INTER_BOTTOM_FIRST;    }#endif /* HAVE_LIBDV */   if(strncasecmp(video_comp,"yuv",3)==0#ifdef HAVE_LIBQUICKTIME/*    || strncasecmp(video_comp,QUICKTIME_YUV4,4)==0 */      || strncasecmp(video_comp,QUICKTIME_YUV420,4)==0#endif      ) {       ierr = check_YUV420_input(lav_fd);#ifdef HAVE_LIBQUICKTIME       /* check for YUV format if quicktime file */       if (strncasecmp(video_comp,QUICKTIME_YUV420,4)==0)           lav_fd->MJPG_chroma = CHROMA420;       else if (strncasecmp(video_comp,QUICKTIME_YUV4,4)==0)           lav_fd->MJPG_chroma = CHROMA422;#else   lav_fd->MJPG_chroma = CHROMA420;#endif       if (ierr) goto ERREXIT;   }      return lav_fd;   }   /* Make some checks on the video source, we read the first frame for that */   ierr  = 0;   frame = NULL;   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   if ( (len = lav_frame_size(lav_fd,0)) <=0 ) goto ERREXIT;   if ( (frame = (unsigned char*) malloc(len)) == 0 ) { ierr=ERROR_MALLOC; goto ERREXIT; }   if ( lav_read_frame(lav_fd,frame) <= 0 ) goto ERREXIT;   /* reset video position to 0 */   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   if( scan_jpeg(frame, len, 1) ) { ierr=ERROR_JPEG; goto ERREXIT; }   /* We have to look to the JPEG SOF marker for further information      The SOF marker has the following format:      FF      C0      len_hi      len_lo      data_precision      height_hi      height_lo      width_hi      width_lo      num_components      And then 3 bytes for each component:      Component id      H, V sampling factors (as nibbles)      Quantization table number    */   /* Check if the JPEG has the special 4:2:2 format needed for      some HW JPEG decompressors (the Iomega Buz, for example) */   ncomps = frame[jpeg_image_offset + 9];   if(ncomps==3)   {      for(n=0;n<3;n++)      {         hf[n] = frame[jpeg_image_offset + 10 + 3*n + 1]>>4;         vf[n] = frame[jpeg_image_offset + 10 + 3*n + 1]&0xf;      }	  /* Identify chroma sub-sampling format only 420 and 422 supported	   at present...*/	  if( hf[0] == 2*hf[1] && hf[0] == 2*hf[2] )	  {		 if( vf[0] == vf[1] && vf[0] == vf[2] )		 {			 lav_fd->MJPG_chroma = CHROMA422;		 }		 else if( vf[0] == 2*vf[1] && vf[0] == 2*vf[2] )			 lav_fd->MJPG_chroma = CHROMA420;		 else					 lav_fd->MJPG_chroma = CHROMAUNKNOWN;	  }	  else		  lav_fd->MJPG_chroma = CHROMAUNKNOWN;   }   /* Check if video is interlaced */   /* height and width are encoded in the JPEG SOF marker at offsets 5 and 7 */   jpg_height = get_int2(frame + jpeg_image_offset + 5);   jpg_width  = get_int2(frame + jpeg_image_offset + 7);   /* check height */   if( jpg_height == lav_video_height(lav_fd))   {      lav_fd->interlacing = LAV_NOT_INTERLACED;   }   else if ( jpg_height == lav_video_height(lav_fd)/2 )   {      /* Video is interlaced */      switch(lav_fd->format)      {         case 'a':            /* Check the APP0 Marker, if present */            if(jpeg_app0_offset &&                get_int2(frame + jpeg_app0_offset + 2) >= 5 &&               strncasecmp((char*)(frame + jpeg_app0_offset + 4),"AVI1",4)==0 )            {                if (frame[jpeg_app0_offset+8]==1)                   lav_fd->interlacing = LAV_INTER_TOP_FIRST;                else                   lav_fd->interlacing = LAV_INTER_BOTTOM_FIRST;            }            else            {               /* There is no default, it really depends on the                  application which produced the AVI */               lav_fd->interlacing = LAV_INTER_TOP_FIRST;            }            lav_fd->format = lav_fd->interlacing == LAV_INTER_BOTTOM_FIRST ? 'A' : 'a';            break;         case 'q':            lav_fd->interlacing = LAV_INTER_TOP_FIRST;         case 'm':            lav_fd->interlacing = LAV_INTER_TOP_FIRST;      }   }   else   {      ierr=ERROR_JPEG;      goto ERREXIT;   }   free(frame);   return lav_fd;ERREXIT:   lav_close(lav_fd);   if(frame) free(frame);   internal_error = ierr;   return 0;}/* Get size of first field of for a data array containing   (possibly) two jpeg fields */int lav_get_field_size(uint8_t * jpegdata, long jpeglen){   int res;   res = scan_jpeg(jpegdata,jpeglen,0);   if(res<0) return jpeglen; /* Better than nothing */   /* we return jpeg_padded len since this routine is used      for field exchange where alignment might be important */   return jpeg_padded_len;}static char error_string[4096];const char *lav_strerror(void){   switch(internal_error)   {      case ERROR_JPEG:         sprintf(error_string,"Internal: broken JPEG format");         internal_error = 0;         return error_string;      case ERROR_MALLOC:         sprintf(error_string,"Internal: Out of memory");         internal_error = 0;         return error_string;      case ERROR_FORMAT:         sprintf(error_string,"Input file format not recognized");         internal_error = 0;         return error_string;      case ERROR_NOAUDIO:         sprintf(error_string,"Trying to read audio from a video only file");         internal_error = 0;         return error_string;   }   switch(video_format)   {      case 'a':      case 'A':         return AVI_strerror();#ifdef HAVE_LIBQUICKTIME      case 'q':         /* The quicktime documentation doesn't say much about error codes,            we hope that strerror may give some info */         sprintf(error_string,"Quicktime error, possible(!) reason: %s",strerror(errno));         return error_string;#endif      default:         /* No or unknown video format */         if(errno) strerror(errno);         else sprintf(error_string,"No or unknown video format");         return error_string;   }}#ifdef HAVE_LIBDVstatic int check_DV2_input(lav_file_t *lav_fd){   int ierr = 0;   double len = 0;   unsigned char *frame = NULL;   /* Make some checks on the video source, we read the first frame for that */   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   if ( (len = lav_frame_size(lav_fd,0)) <=0 ) goto ERREXIT;   if ( (frame = (unsigned char*) malloc(len)) == 0 ) { ierr=ERROR_MALLOC; goto ERREXIT; }   if ( lav_read_frame(lav_fd,frame) <= 0 ) goto ERREXIT;   {     dv_decoder_t *decoder = dv_decoder_new(0,0,0);     dv_parse_header(decoder, frame);     switch (decoder->system) {     case e_dv_system_525_60:       if (dv_format_wide(decoder)) {	 lav_fd->sar_w = 40;	 lav_fd->sar_h = 33;       } else {	 lav_fd->sar_w = 10;	 lav_fd->sar_h = 11;       }        break;     case e_dv_system_625_50:       if (dv_format_wide(decoder)) {	 lav_fd->sar_w = 118;	 lav_fd->sar_h = 81;       } else {	 lav_fd->sar_w = 59;	 lav_fd->sar_h = 54;       }        break;     default:       lav_fd->sar_w = 0; /* ??? -> unknown */       lav_fd->sar_h = 0;       break;     }     dv_decoder_free(decoder);   }   /* reset video position to 0 */   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   return 0;ERREXIT:   lav_close(lav_fd);   if(frame) free(frame);   if (ierr) internal_error = ierr;   return 1;}#endifstatic int check_YUV420_input(lav_file_t *lav_fd){   int ierr = 0;   double len = 0;   unsigned char *frame = NULL;   /* Make some checks on the video source, we read the first frame for that */   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   if ( (len = lav_frame_size(lav_fd,0)) <=0 ) goto ERREXIT;   if ( (frame = (unsigned char*) malloc(len)) == 0 ) { ierr=ERROR_MALLOC; goto ERREXIT; }   if ( lav_read_frame(lav_fd,frame) <= 0 ) goto ERREXIT;   /* reset video position to 0 */   if ( lav_set_video_position(lav_fd,0) ) goto ERREXIT;   return 0;ERREXIT:   lav_close(lav_fd);   if(frame) free(frame);   if (ierr) internal_error = ierr;   return 1;}int lav_fileno(lav_file_t *lav_file){   int res;   video_format = lav_file->format;    switch(lav_file->format)   {      case 'a':      case 'A':         res = AVI_fileno( lav_file->avi_fd );         break;#ifdef HAVE_LIBQUICKTIME      case 'q':         res = fileno(((quicktime_t *)lav_file->qt_fd)->stream);         break;#endif      default:         res = -1;   }   return res;}/* We need this to reorder the 32 bit values for big endian systems */uint32_t reorder_32(uint32_t todo, int big_endian){  unsigned char b0, b1, b2, b3;  unsigned long reversed;   if( big_endian )  {    b0 = (todo & 0x000000FF);    b1 = (todo & 0x0000FF00) >> 8;    b2 = (todo & 0x00FF0000) >> 16;    b3 = (todo & 0xFF000000) >> 24;    reversed = (b0 << 24) + (b1 << 16) + (b2 << 8) +b3;    return reversed;  }  else  {    return todo;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -