demuxer.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,287 行 · 第 1/3 页
C
1,287 行
} if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); break; } //F("1\n"); if(!demux_fill_buffer(demux,ds)){ //F("5\n"); mp_dbg(MSGT_DEMUXER,MSGL_DBG2,"ds_fill_buffer()->demux_fill_buffer() failed\n"); break; // EOF } } ds->buffer_pos=ds->buffer_size=0; ds->buffer=NULL; ds->current=NULL; mp_msg(MSGT_DEMUXER,MSGL_V,"ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video"); ds->eof=1; return 0;}int demux_read_data(demux_stream_t *ds,unsigned char* mem,int len){int x;int bytes=0;while(len>0){ x=ds->buffer_size-ds->buffer_pos; if(x==0){ if(!ds_fill_buffer(ds)) return bytes; } else { if(x>len) x=len; if(mem) fast_memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); bytes+=x;len-=x;ds->buffer_pos+=x; }}return bytes;}int demux_read_data_pack(demux_stream_t *ds,unsigned char* mem,int len){int x;int bytes=0;while(len>0){ x=ds->buffer_size-ds->buffer_pos; if(x==0){ if(!ds_fill_buffer(ds)) return bytes; } else { if(x>len) x=len; if(mem) fast_memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); bytes+=x;len-=x;ds->buffer_pos+=x; return bytes; // stop at end of package! (for correct timestamping) }}return bytes;}/** * \brief read data until the given 3-byte pattern is encountered, up to maxlen * \param mem memory to read data into, may be NULL to discard data * \param maxlen maximum number of bytes to read * \param read number of bytes actually read * \param pattern pattern to search for (lowest 8 bits are ignored) * \return whether pattern was found */int demux_pattern_3(demux_stream_t *ds, unsigned char *mem, int maxlen, int *read, uint32_t pattern) { register uint32_t head = 0xffffff00; register uint32_t pat = pattern & 0xffffff00; int total_len = 0; do { register unsigned char *ds_buf = &ds->buffer[ds->buffer_size]; int len = ds->buffer_size - ds->buffer_pos; register long pos = -len; if (unlikely(pos >= 0)) { // buffer is empty ds_fill_buffer(ds); continue; } do { head |= ds_buf[pos]; head <<= 8; } while (++pos && head != pat); len += pos; if (total_len + len > maxlen) len = maxlen - total_len; len = demux_read_data(ds, mem ? &mem[total_len] : NULL, len); total_len += len; } while ((head != pat || total_len < 3) && total_len < maxlen && !ds->eof); if (read) *read = total_len; return total_len >= 3 && head == pat;}void ds_free_packs(demux_stream_t *ds){ demux_packet_t *dp=ds->first; while(dp){ demux_packet_t *dn=dp->next; free_demux_packet(dp); dp=dn; } if(ds->asf_packet){ // free unfinished .asf fragments: free(ds->asf_packet->buffer); free(ds->asf_packet); ds->asf_packet=NULL; } ds->first=ds->last=NULL; ds->packs=0; // !!!!! ds->bytes=0; if(ds->current) free_demux_packet(ds->current); ds->current=NULL; ds->buffer=NULL; ds->buffer_pos=ds->buffer_size; ds->pts=0; ds->pts_bytes=0;}int ds_get_packet(demux_stream_t *ds,unsigned char **start){ while(1){ int len; if(ds->buffer_pos>=ds->buffer_size){ if(!ds_fill_buffer(ds)){ // EOF *start = NULL; return -1; } } len=ds->buffer_size-ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos+=len; return len; }}int ds_get_packet_pts(demux_stream_t *ds,unsigned char **start, double *pts){ int len; *pts = MP_NOPTS_VALUE; if(ds->buffer_pos>=ds->buffer_size){ if (!ds_fill_buffer(ds)) { // EOF *start = NULL; return -1; } } // Should use MP_NOPTS_VALUE for "unknown pts" in the packets too // Return pts unless this read starts from the middle of a packet if (!ds->buffer_pos && (correct_pts || ds->current->pts)) *pts = ds->current->pts; len=ds->buffer_size-ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos+=len; return len;}int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start){ while(1){ int len; if(ds->buffer_pos>=ds->buffer_size){ *start = NULL; if(!ds->packs) return -1; // no sub if(!ds_fill_buffer(ds)) return -1; // EOF } len=ds->buffer_size-ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos+=len; return len; }}double ds_get_next_pts(demux_stream_t *ds){ demuxer_t* demux = ds->demuxer; while(!ds->first) { if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); return MP_NOPTS_VALUE; } if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); return MP_NOPTS_VALUE; } if(!demux_fill_buffer(demux,ds)) return MP_NOPTS_VALUE; } return ds->first->pts;}// ====================================================================void demuxer_help(void){ int i; mp_msg(MSGT_DEMUXER, MSGL_INFO, "Available demuxers:\n"); mp_msg(MSGT_DEMUXER, MSGL_INFO, " demuxer: type info: (comment)\n"); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DEMUXERS\n"); for (i = 0; demuxer_list[i]; i++) { if (demuxer_list[i]->type > DEMUXER_TYPE_MAX) // Don't display special demuxers continue; if (demuxer_list[i]->comment && strlen(demuxer_list[i]->comment)) mp_msg(MSGT_DEMUXER, MSGL_INFO, "%10s %2d %s (%s)\n", demuxer_list[i]->name, demuxer_list[i]->type, demuxer_list[i]->info, demuxer_list[i]->comment); else mp_msg(MSGT_DEMUXER, MSGL_INFO, "%10s %2d %s\n", demuxer_list[i]->name, demuxer_list[i]->type, demuxer_list[i]->info); }}/** * Get demuxer type for a given demuxer name * * @param demuxer_name string with demuxer name of demuxer number * @param force will be set if demuxer should be forced. * May be NULL. * @return DEMUXER_TYPE_xxx, -1 if error or not found */int get_demuxer_type_from_name(char *demuxer_name, int *force){ int i; long type_int; char *endptr; if (!demuxer_name || !demuxer_name[0]) return DEMUXER_TYPE_UNKNOWN; if (force) *force = demuxer_name[0] == '+'; if (demuxer_name[0] == '+') demuxer_name = &demuxer_name[1]; for (i = 0; demuxer_list[i]; i++) { if (demuxer_list[i]->type > DEMUXER_TYPE_MAX) // Can't select special demuxers from commandline continue; if (strcmp(demuxer_name, demuxer_list[i]->name) == 0) return demuxer_list[i]->type; } // No match found, try to parse name as an integer (demuxer number) type_int = strtol(demuxer_name, &endptr, 0); if (*endptr) // Conversion failed return -1; if ((type_int > 0) && (type_int <= DEMUXER_TYPE_MAX)) return (int)type_int; return -1;}int extension_parsing=1; // 0=off 1=mixed (used only for unstable formats)int correct_pts=0;/* NOTE : Several demuxers may be opened at the same time so demuxers should NEVER rely on an external var to enable them self. If a demuxer can't do any autodection it should only use file_format. The user can explictly set file_format with the -demuxer option so there is really no need for another extra var. For conivence an option can be added to set file_format directly to the right type (ex: rawaudio,rawvideo). Also the stream can override the file_format so a demuxer wich rely on a special stream type can set file_format at the stream level (ex: tv,mf).*/static demuxer_t* demux_open_stream(stream_t *stream, int file_format, int force, int audio_id, int video_id, int dvdsub_id, char* filename) {//int file_format=(*file_format_ptr);demuxer_t *demuxer=NULL;sh_video_t *sh_video=NULL;demuxer_desc_t *demuxer_desc;int fformat = 0;int i;//printf("demux_open(%p,%d,%d,%d,%d) \n",stream,file_format,audio_id,video_id,dvdsub_id);//F("demux_open(%p,%d,%d,%d,%d %s) \n",stream,file_format,audio_id,video_id,dvdsub_id,filename);// If somebody requested a demuxer check itif (file_format) {//F("1\n") if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) {//F("2\n") demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);//F("3\n") if (demuxer_desc->check_file) fformat = demuxer_desc->check_file(demuxer);//F("4\n") if (force || !demuxer_desc->check_file) fformat = demuxer_desc->type; if (fformat != 0) { if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; // Move messages to demuxer detection code? mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc); file_format = demuxer_desc->type = fformat; if (!demuxer->desc->open || (demux2 = demuxer->desc->open(demuxer))) { demuxer = demux2; goto dmx_open; } } else { // Format changed after check, recurse //F("5\n") free_demuxer(demuxer); //F("6\n") return demux_open_stream(stream, fformat, force, audio_id, video_id, dvdsub_id, filename); } } // Check failed for forced demuxer, quit free_demuxer(demuxer); return NULL; }}#if 0// Test demuxers with safe file checksfor (i = 0; (demuxer_desc = demuxer_list[i]); i++) { //F("%d",i); if (demuxer_desc->safe_check) { //F("new demuxer\n"); demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename); //F("new demuxer\n"); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { // F("8\n"); if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open || (demux2 = demuxer->desc->open(demuxer))) { demuxer = demux2; goto dmx_open; } } else { if (fformat == DEMUXER_TYPE_PLAYLIST) return demuxer; // handled in mplayer.c // Format changed after check, recurse // F("4\n"); free_demuxer(demuxer); // F("5\n"); demuxer=demux_open_stream(stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if(demuxer) return demuxer; // done! file_format = DEMUXER_TYPE_UNKNOWN; } } free_demuxer(demuxer); demuxer = NULL; }}#endif// If no forced demuxer perform file extension based detection// Ok. We're over the stable detectable fileformats, the next ones are a bit// fuzzy. So by default (extension_parsing==1) try extension-based detection// first:if(file_format==DEMUXER_TYPE_UNKNOWN && filename && extension_parsing==1){ file_format=demuxer_type_by_filename(filename); if(file_format!=DEMUXER_TYPE_UNKNOWN){ // we like recursion :) demuxer=demux_open_stream(stream, file_format, force, audio_id, video_id, dvdsub_id, filename); if(demuxer) return demuxer; // done! file_format=DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing... mp_msg(MSGT_DEMUXER,MSGL_V,"demuxer: continue fuzzy content-based format guessing...\n"); }}#if 1// Test demuxers with safe file checksfor (i = 0; (demuxer_desc = demuxer_list[i]); i++) { //F("%d",i); if (demuxer_desc->safe_check) { //F("new demuxer\n"); demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename); //F("new demuxer\n"); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { // F("8\n"); if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open || (demux2 = demuxer->desc->open(demuxer))) { demuxer = demux2; goto dmx_open; } } else { if (fformat == DEMUXER_TYPE_PLAYLIST) return demuxer; // handled in mplayer.c // Format changed after check, recurse // F("4\n"); free_demuxer(demuxer); // F("5\n"); demuxer=demux_open_stream(stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if(demuxer) return demuxer; // done! file_format = DEMUXER_TYPE_UNKNOWN; } } free_demuxer(demuxer); demuxer = NULL; }}#endif// Try detection for all other demuxersfor (i = 0; (demuxer_desc = demuxer_list[i]); i++) { if (!demuxer_desc->safe_check && demuxer_desc->check_file) { demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open || (demux2 = demuxer->desc->open(demuxer))) { demuxer = demux2; goto dmx_open; } } else { if (fformat == DEMUXER_TYPE_PLAYLIST) return demuxer; // handled in mplayer.c // Format changed after check, recurse free_demuxer(demuxer); demuxer=demux_open_stream(stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if(demuxer) return demuxer; // done! file_format = DEMUXER_TYPE_UNKNOWN; } } free_demuxer(demuxer); demuxer = NULL; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?