📄 lav_io.c
字号:
/* 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 + -