demux_lavf.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 714 行 · 第 1/2 页

C
714
字号
                sh_audio->audio.dwScale=codec->frame_size;                sh_audio->audio.dwRate= codec->sample_rate;            }else{                sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;                sh_audio->audio.dwRate = codec->bit_rate;            }            g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);            sh_audio->audio.dwScale /= g;            sh_audio->audio.dwRate  /= g;//            printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align);            sh_audio->ds= demuxer->audio;            sh_audio->format= codec->codec_tag;            sh_audio->channels= codec->channels;            sh_audio->samplerate= codec->sample_rate;            sh_audio->i_bps= codec->bit_rate/8;            switch (codec->codec_id) {              case CODEC_ID_PCM_S8:              case CODEC_ID_PCM_U8:                sh_audio->samplesize = 1;                break;              case CODEC_ID_PCM_S16LE:              case CODEC_ID_PCM_S16BE:              case CODEC_ID_PCM_U16LE:              case CODEC_ID_PCM_U16BE:                sh_audio->samplesize = 2;                break;              case CODEC_ID_PCM_ALAW:                sh_audio->format = 0x6;                break;              case CODEC_ID_PCM_MULAW:                sh_audio->format = 0x7;                break;            }            if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);	    if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3))	        || (demuxer->audio->id == i || demuxer->audio->id == -1)	    ) {	        demuxer->audio->id = i;                demuxer->audio->sh= demuxer->a_streams[i];	    }            else                st->discard= AVDISCARD_ALL;            break;}        case CODEC_TYPE_VIDEO:{            sh_video_t* sh_video;            BITMAPINFOHEADER *bih;            if(priv->video_streams >= MAX_V_STREAMS)                break;            sh_video=new_sh_video(demuxer, i);            mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "lavf", i);            if(!sh_video) break;            priv->vstreams[priv->video_streams] = i;            priv->video_streams++;            bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);            if(!codec->codec_tag)                codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);            bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;            bih->biWidth= codec->width;            bih->biHeight= codec->height;            bih->biBitCount= codec->bits_per_sample;            bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;            bih->biCompression= codec->codec_tag;            sh_video->bih= bih;            sh_video->disp_w= codec->width;            sh_video->disp_h= codec->height;            if (st->time_base.den) { /* if container has time_base, use that */                sh_video->video.dwRate= st->time_base.den;                sh_video->video.dwScale= st->time_base.num;            } else {            sh_video->video.dwRate= codec->time_base.den;            sh_video->video.dwScale= codec->time_base.num;            }            sh_video->fps=av_q2d(st->r_frame_rate);            sh_video->frametime=1/av_q2d(st->r_frame_rate);            sh_video->format = bih->biCompression;            sh_video->aspect=   codec->width * codec->sample_aspect_ratio.num                               / (float)(codec->height * codec->sample_aspect_ratio.den);            sh_video->i_bps= codec->bit_rate/8;            mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",                 codec->width, codec->sample_aspect_ratio.num,                codec->height, codec->sample_aspect_ratio.den);            sh_video->ds= demuxer->video;            if(codec->extradata_size)                memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);            if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);/*    short 	biPlanes;    int  	biXPelsPerMeter;    int  	biYPelsPerMeter;    int 	biClrUsed;    int 	biClrImportant;*/            if(demuxer->video->id != i && demuxer->video->id != -1)                st->discard= AVDISCARD_ALL;            else{                demuxer->video->id = i;                demuxer->video->sh= demuxer->v_streams[i];            }            break;}        case CODEC_TYPE_SUBTITLE:{            sh_sub_t* sh_sub;            if(priv->sub_streams >= MAX_S_STREAMS)                break;            /* only support text subtitles for now */            if(codec->codec_id != CODEC_ID_TEXT)                break;            sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);            mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_SubtitleID, "lavf", priv->sub_streams);            if(!sh_sub) break;            priv->sstreams[priv->sub_streams] = i;            sh_sub->type = 't';            demuxer->sub->sh = demuxer->s_streams[priv->sub_streams++];            break;}        default:            st->discard= AVDISCARD_ALL;        }    }        mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);    mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);    if(!priv->audio_streams) demuxer->audio->id=-2;  // nosound//    else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;    if(!priv->video_streams){        if(!priv->audio_streams){	    mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");            return NULL;         }        demuxer->video->id=-2; // audio-only    } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;    return demuxer;}static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){    lavf_priv_t *priv= demux->priv;    AVPacket pkt;    demux_packet_t *dp;    demux_stream_t *ds;    int id;    mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");    demux->filepos=stream_tell(demux->stream);    if(av_read_frame(priv->avfc, &pkt) < 0)        return 0;            id= pkt.stream_index;    if(id==demux->audio->id){        // audio        ds=demux->audio;        if(!ds->sh){            ds->sh=demux->a_streams[id];            mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);        }    } else if(id==demux->video->id){        // video        ds=demux->video;        if(!ds->sh){            ds->sh=demux->v_streams[id];            mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);        }    } else if(id==demux->sub->id){        // subtitle        ds=demux->sub;        sub_utf8=1;    } else {        av_free_packet(&pkt);        return 1;    }            if(0/*pkt.destruct == av_destruct_packet*/){        //ok kids, dont try this at home :)        dp=malloc(sizeof(demux_packet_t));        dp->len=pkt.size;        dp->next=NULL;        dp->refcount=1;        dp->master=NULL;        dp->buffer=pkt.data;        pkt.destruct= NULL;    }else{        dp=new_demux_packet(pkt.size);        memcpy(dp->buffer, pkt.data, pkt.size);        av_free_packet(&pkt);    }    if(pkt.pts != AV_NOPTS_VALUE){        dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);        priv->last_pts= dp->pts * AV_TIME_BASE;        if(pkt.duration)            dp->endpts = dp->pts + pkt.duration * av_q2d(priv->avfc->streams[id]->time_base);    }    dp->pos=demux->filepos;    dp->flags= !!(pkt.flags&PKT_FLAG_KEY);    // append packet to DS stream:    ds_add_packet(ds,dp);    return 1;}static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){    lavf_priv_t *priv = demuxer->priv;    int avsflags = 0;    mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);    if (flags & 1) // absolute seek      priv->last_pts = priv->avfc->start_time;    if (flags & 2) { // percent seek      if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)        return;      priv->last_pts += rel_seek_secs * priv->avfc->duration;    } else {      priv->last_pts += rel_seek_secs * AV_TIME_BASE;      if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;    }    av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);}static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg){    lavf_priv_t *priv = demuxer->priv;        switch (cmd) {        case DEMUXER_CTRL_GET_TIME_LENGTH:	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)	        return DEMUXER_CTRL_DONTKNOW;	    	    *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;	    return DEMUXER_CTRL_OK;	case DEMUXER_CTRL_GET_PERCENT_POS:	    if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)	        return DEMUXER_CTRL_DONTKNOW;	    	    *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);	    return DEMUXER_CTRL_OK;	case DEMUXER_CTRL_SWITCH_AUDIO:	case DEMUXER_CTRL_SWITCH_VIDEO:	{	    int id = *((int*)arg);	    int newid = -2;	    int i, curridx = -2;	    int nstreams, *pstreams;	    demux_stream_t *ds;	    if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)	    {	        ds = demuxer->video;	        nstreams = priv->video_streams;	        pstreams = priv->vstreams;	    }	    else	    {	        ds = demuxer->audio;	        nstreams = priv->audio_streams;	        pstreams = priv->astreams;	    }	    if(ds->id == -2)	        return DEMUXER_CTRL_NOTIMPL;	    for(i = 0; i < nstreams; i++)	    {	        if(pstreams[i] == ds->id) //current stream id	        {	            curridx = i;	            break;	        }	    }	    if(id < 0)	    {	        i = (curridx + 1) % nstreams;	        newid = pstreams[i];	    }	    else	    {	        for(i = 0; i < nstreams; i++)	        {		    if(pstreams[i] == id)		    {		        newid = id;		        break;		    }	        }	    }	    if(newid == -2 || i == curridx)	        return DEMUXER_CTRL_NOTIMPL;	    else	    {	        ds_free_packs(ds);	        priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;	        *((int*)arg) = ds->id = newid;	        priv->avfc->streams[newid]->discard = AVDISCARD_NONE;	        return DEMUXER_CTRL_OK;	    }        }	default:	    return DEMUXER_CTRL_NOTIMPL;    }}/** \brief Get the language code for a subtitle track.  Retrieves the language code for a subtitle track.  \param demuxer The demuxer to work on  \param track_num The subtitle track number to get the language from*/char *demux_lavf_sub_lang(demuxer_t *demuxer, int track_num){    lavf_priv_t *priv = demuxer->priv;    return priv->avfc->streams[priv->sstreams[track_num]]->language;}static void demux_close_lavf(demuxer_t *demuxer){    lavf_priv_t* priv = demuxer->priv;    if (priv){        if(priv->avfc)       {         av_close_input_file(priv->avfc); priv->avfc= NULL;        }        free(priv); demuxer->priv= NULL;    }}demuxer_desc_t demuxer_desc_lavf = {  "libavformat demuxer",  "lavf",  "libavformat",  "Michael Niedermayer",  "supports many formats, requires libavformat",  DEMUXER_TYPE_LAVF,  0, // Check after other demuxer  lavf_check_file,  demux_lavf_fill_buffer,  demux_open_lavf,  demux_close_lavf,  demux_seek_lavf,  demux_lavf_control};demuxer_desc_t demuxer_desc_lavf_preferred = {  "libavformat preferred demuxer",  "lavfpref",  "libavformat",  "Michael Niedermayer",  "supports many formats, requires libavformat",  DEMUXER_TYPE_LAVF_PREFERRED,  1,  lavf_check_preferred_file,  demux_lavf_fill_buffer,  demux_open_lavf,  demux_close_lavf,  demux_seek_lavf,  demux_lavf_control};

⌨️ 快捷键说明

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