📄 x264.c
字号:
}}static int open_file_avis( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ){ AVISTREAMINFO info; PAVISTREAM p_avi = NULL; int i; *p_handle = NULL; AVIFileInit(); if( AVIStreamOpenFromFile( &p_avi, psz_filename, streamtypeVIDEO, 0, OF_READ, NULL ) ) { AVIFileExit(); return -1; } if( AVIStreamInfo(p_avi, &info, sizeof(AVISTREAMINFO)) ) { AVIStreamRelease(p_avi); AVIFileExit(); return -1; } // check input format if (info.fccHandler != MAKEFOURCC('Y', 'V', '1', '2')) { fprintf( stderr, "avis [error]: unsupported input format (%c%c%c%c)\n", (char)(info.fccHandler & 0xff), (char)((info.fccHandler >> 8) & 0xff), (char)((info.fccHandler >> 16) & 0xff), (char)((info.fccHandler >> 24)) ); AVIStreamRelease(p_avi); AVIFileExit(); return -1; } p_param->i_width = info.rcFrame.right - info.rcFrame.left; p_param->i_height = info.rcFrame.bottom - info.rcFrame.top; i = gcd(info.dwRate, info.dwScale); p_param->i_fps_den = info.dwScale / i; p_param->i_fps_num = info.dwRate / i; fprintf( stderr, "avis [info]: %dx%d @ %.2f fps (%d frames)\n", p_param->i_width, p_param->i_height, (double)p_param->i_fps_num / (double)p_param->i_fps_den, (int)info.dwLength ); *p_handle = (hnd_t)p_avi; return 0;}static int get_frame_total_avis( hnd_t handle, int i_width, int i_height ){ PAVISTREAM p_avi = (PAVISTREAM)handle; AVISTREAMINFO info; if( AVIStreamInfo(p_avi, &info, sizeof(AVISTREAMINFO)) ) return -1; return info.dwLength;}static int read_frame_avis( x264_picture_t *p_pic, hnd_t handle, int i_frame, int i_width, int i_height ){ PAVISTREAM p_avi = (PAVISTREAM)handle; p_pic->img.i_csp = X264_CSP_YV12; if( AVIStreamRead(p_avi, i_frame, 1, p_pic->img.plane[0], i_width * i_height * 3 / 2, NULL, NULL ) ) return -1; return 0;}static int close_file_avis( hnd_t handle ){ PAVISTREAM p_avi = (PAVISTREAM)handle; AVIStreamRelease(p_avi); AVIFileExit(); return 0;}#endifstatic int open_file_bsf( char *psz_filename, hnd_t *p_handle ){ if ((*p_handle = fopen(psz_filename, "w+b")) == NULL) return -1; return 0;}static int set_param_bsf( hnd_t handle, x264_param_t *p_param ){ return 0;}static int write_nalu_bsf( hnd_t handle, uint8_t *p_nalu, int i_size ){ if (fwrite(p_nalu, i_size, 1, (FILE *)handle) > 0) return i_size; return -1;}static int set_eop_bsf( hnd_t handle, x264_picture_t *p_picture ){ return 0;}static int close_file_bsf( hnd_t handle ){ if ((handle == NULL) || (handle == stdout)) return 0; return fclose((FILE *)handle);}/* -- mp4 muxing support ------------------------------------------------- */#ifdef MP4_OUTPUTtypedef struct{ M4File *p_file; AVCConfig *p_config; M4Sample *p_sample; int i_track; int i_descidx; int i_time_inc; int i_time_res; int i_numframe; int i_init_delay; uint8_t b_sps; uint8_t b_pps;} mp4_t;static void recompute_bitrate_mp4(M4File *p_file, int i_track){ u32 i, count, di, timescale, time_wnd, rate; u64 offset; Double br; ESDescriptor *esd; esd = M4_GetStreamDescriptor(p_file, i_track, 1); if (!esd) return; esd->decoderConfig->avgBitrate = 0; esd->decoderConfig->maxBitrate = 0; rate = time_wnd = 0; timescale = M4_GetMediaTimeScale(p_file, i_track); count = M4_GetSampleCount(p_file, i_track); for (i=0; i<count; i++) { M4Sample *samp = M4_GetSampleInfo(p_file, i_track, i+1, &di, &offset); if (samp->dataLength>esd->decoderConfig->bufferSizeDB) esd->decoderConfig->bufferSizeDB = samp->dataLength; if (esd->decoderConfig->bufferSizeDB < samp->dataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength; esd->decoderConfig->avgBitrate += samp->dataLength; rate += samp->dataLength; if (samp->DTS > time_wnd + timescale) { if (rate > esd->decoderConfig->maxBitrate) esd->decoderConfig->maxBitrate = rate; time_wnd = samp->DTS; rate = 0; } M4_DeleteSample(&samp); } br = (Double) (s64) M4_GetMediaDuration(p_file, i_track); br /= timescale; esd->decoderConfig->avgBitrate = (u32) (esd->decoderConfig->avgBitrate / br); /*move to bps*/ esd->decoderConfig->avgBitrate *= 8; esd->decoderConfig->maxBitrate *= 8; M4_ChangeStreamDescriptor(p_file, i_track, 1, esd); OD_DeleteDescriptor((Descriptor **)&esd);}static int close_file_mp4( hnd_t handle ){ mp4_t *p_mp4 = (mp4_t *)handle; if (p_mp4 == NULL) return 0; if (p_mp4->p_config) AVC_DeleteConfig(p_mp4->p_config); if (p_mp4->p_sample) { if (p_mp4->p_sample->data) free(p_mp4->p_sample->data); M4_DeleteSample(&p_mp4->p_sample); } if (p_mp4->p_file) { recompute_bitrate_mp4(p_mp4->p_file, p_mp4->i_track); M4_SetMoviePLIndication(p_mp4->p_file, M4_PL_VISUAL, 0x15); M4_SetStorageMode(p_mp4->p_file, M4_FLAT); M4_MovieClose(p_mp4->p_file); } free(p_mp4); return 0;}static int open_file_mp4( char *psz_filename, hnd_t *p_handle ){ mp4_t *p_mp4; *p_handle = NULL; if ((p_mp4 = (mp4_t *)malloc(sizeof(mp4_t))) == NULL) return -1; memset(p_mp4, 0, sizeof(mp4_t)); p_mp4->p_file = M4_MovieOpen(psz_filename, M4_OPEN_WRITE); if ((p_mp4->p_sample = M4_NewSample()) == NULL) { close_file_mp4( p_mp4 ); return -1; } M4_SetMovieVersionInfo(p_mp4->p_file, H264_AVC_File, 0); *p_handle = p_mp4; return 0;}static int set_param_mp4( hnd_t handle, x264_param_t *p_param ){ mp4_t *p_mp4 = (mp4_t *)handle; p_mp4->i_track = M4_NewTrack(p_mp4->p_file, 0, M4_VisualMediaType, p_param->i_fps_num); p_mp4->p_config = AVC_NewConfig(); M4_AVC_NewStreamConfig(p_mp4->p_file, p_mp4->i_track, p_mp4->p_config, NULL, NULL, &p_mp4->i_descidx); M4_SetVisualEntrySize(p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_param->i_width, p_param->i_height); p_mp4->p_sample->data = (char *)malloc(p_param->i_width * p_param->i_height * 3 / 2); if (p_mp4->p_sample->data == NULL) return -1; p_mp4->i_time_res = p_param->i_fps_num; p_mp4->i_time_inc = p_param->i_fps_den; p_mp4->i_init_delay = p_param->i_bframe ? (p_param->b_bframe_pyramid ? 2 : 1) : 0; p_mp4->i_init_delay *= p_mp4->i_time_inc; fprintf(stderr, "mp4 [info]: initial delay %d (scale %d)\n", p_mp4->i_init_delay, p_mp4->i_time_res); return 0;}static int write_nalu_mp4( hnd_t handle, uint8_t *p_nalu, int i_size ){ mp4_t *p_mp4 = (mp4_t *)handle; AVCConfigSlot *p_slot; uint8_t type = p_nalu[4] & 0x1f; int psize; switch(type) { // sps case 0x07: if (!p_mp4->b_sps) { p_mp4->p_config->configurationVersion = 1; p_mp4->p_config->AVCProfileIndication = p_nalu[5]; p_mp4->p_config->profile_compatibility = p_nalu[6]; p_mp4->p_config->AVCLevelIndication = p_nalu[7]; p_slot = (AVCConfigSlot *)malloc(sizeof(AVCConfigSlot)); p_slot->size = i_size - 4; p_slot->data = (char *)malloc(p_slot->size); memcpy(p_slot->data, p_nalu + 4, i_size - 4); ChainAddEntry(p_mp4->p_config->sequenceParameterSets, p_slot); p_slot = NULL; p_mp4->b_sps = 1; } break; // pps case 0x08: if (!p_mp4->b_pps) { p_slot = (AVCConfigSlot *)malloc(sizeof(AVCConfigSlot)); p_slot->size = i_size - 4; p_slot->data = (char *)malloc(p_slot->size); memcpy(p_slot->data, p_nalu + 4, i_size - 4); ChainAddEntry(p_mp4->p_config->pictureParameterSets, p_slot); p_slot = NULL; p_mp4->b_pps = 1; if (p_mp4->b_sps) M4_AVC_UpdateStreamConfig(p_mp4->p_file, p_mp4->i_track, 1, p_mp4->p_config); } break; // slice, sei case 0x1: case 0x5: case 0x6: psize = i_size - 4 ; memcpy(p_mp4->p_sample->data + p_mp4->p_sample->dataLength, p_nalu, i_size); p_mp4->p_sample->data[p_mp4->p_sample->dataLength + 0] = (psize >> 24) & 0xff; p_mp4->p_sample->data[p_mp4->p_sample->dataLength + 1] = (psize >> 16) & 0xff; p_mp4->p_sample->data[p_mp4->p_sample->dataLength + 2] = (psize >> 8) & 0xff; p_mp4->p_sample->data[p_mp4->p_sample->dataLength + 3] = (psize >> 0) & 0xff; p_mp4->p_sample->dataLength += i_size; break; } return i_size;}static int set_eop_mp4( hnd_t handle, x264_picture_t *p_picture ){ mp4_t *p_mp4 = (mp4_t *)handle; uint32_t dts = p_mp4->i_numframe * p_mp4->i_time_inc; uint32_t pts = p_picture->i_pts; int offset = p_mp4->i_init_delay + pts - dts; p_mp4->p_sample->IsRAP = p_picture->i_type == X264_TYPE_IDR ? 1 : 0; p_mp4->p_sample->DTS = dts; p_mp4->p_sample->CTS_Offset = offset; M4_AddSample(p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_mp4->p_sample); p_mp4->p_sample->dataLength = 0; p_mp4->i_numframe++; return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -