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

📄 read-qt.c

📁 xawtv绝版源码
💻 C
字号:
#include "config.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <pthread.h>#include <quicktime/quicktime.h>#include <quicktime/colormodels.h>#include <quicktime/lqt.h>#include "grab-ng.h"#define AUDIO_SIZE (64*1024)/* ----------------------------------------------------------------------- */static int fmtid_to_cmodel[VIDEO_FMT_COUNT] = {    [ VIDEO_RGB24    ] = BC_RGB888,    [ VIDEO_BGR24    ] = BC_BGR888,    [ VIDEO_YUYV     ] = BC_YUV422,    [ VIDEO_YUV420P  ] = BC_YUV420P,};/* ----------------------------------------------------------------------- */struct qt_handle {    /* libquicktime handle */    quicktime_t *qt;    /* format */    struct ng_video_fmt vfmt;    struct ng_audio_fmt afmt;    /* misc video */    unsigned char **rows;    int rate;    /* misc audio */    int channels;    int16_t *left,*right;    long long bps;};static void* qt_open(char *moviename){    struct qt_handle *h;    char *str;    int i;    if (NULL == (h = malloc(sizeof(*h))))	return NULL;    memset(h,0,sizeof(*h));    /* open file */    h->qt = quicktime_open(moviename,1,0);    if (NULL == h->qt) {	fprintf(stderr,"ERROR: can't open file: %s\n",moviename);	free(h);	return NULL;    }    if (ng_debug) {	/* print misc info */	fprintf(stderr,"quicktime movie %s:\n",moviename);	str = quicktime_get_copyright(h->qt);	if (str)	    fprintf(stderr,"  copyright: %s\n",str);	str = quicktime_get_name(h->qt);	if (str)	    fprintf(stderr,"  name: %s\n",str);	str = quicktime_get_info(h->qt);	if (str)	    fprintf(stderr,"  info: %s\n",str);		/* print video info */	if (quicktime_has_video(h->qt)) {	    fprintf(stderr,"  video: %d track(s)\n",quicktime_video_tracks(h->qt));	    for (i = 0; i < quicktime_video_tracks(h->qt); i++) {		fprintf(stderr,			"    track #%d\n"			"      width : %d\n"			"      height: %d\n"			"      depth : %d bit\n"			"      rate  : %.2f fps\n"			"      codec : %s\n",			i+1,			quicktime_video_width(h->qt,i),			quicktime_video_height(h->qt,i),			quicktime_video_depth(h->qt,i),			quicktime_frame_rate(h->qt,i),			quicktime_video_compressor(h->qt,i));	    }	}		/* print audio info */	if (quicktime_has_audio(h->qt)) {	    fprintf(stderr,"  audio: %d track(s)\n",quicktime_audio_tracks(h->qt));	    for (i = 0; i < quicktime_audio_tracks(h->qt); i++) {		fprintf(stderr,			"    track #%d\n"			"      rate  : %ld Hz\n"			"      bits  : %d\n"			"      chans : %d\n"			"      codec : %s\n",			i+1,			quicktime_sample_rate(h->qt,i),			quicktime_audio_bits(h->qt,i),			quicktime_track_channels(h->qt,i),			quicktime_audio_compressor(h->qt,i));	    }	}    }    /* video format */    if (!quicktime_has_video(h->qt)) {	if (ng_debug)	    fprintf(stderr,"qt: no video stream\n");    } else if (!quicktime_supported_video(h->qt,0)) {	if (ng_debug)	    fprintf(stderr,"qt: unsupported video codec\n");    } else {	h->vfmt.width  = quicktime_video_width(h->qt,0);	h->vfmt.height = quicktime_video_height(h->qt,0);	h->rate = quicktime_frame_rate(h->qt,0);    }    /* audio format */    if (!quicktime_has_audio(h->qt)) {	if (ng_debug)	    fprintf(stderr,"qt: no audio stream\n");    } else if (!quicktime_supported_audio(h->qt,0)) {	if (ng_debug)	    fprintf(stderr,"qt: unsupported audio codec\n");    } else {	h->channels   = quicktime_track_channels(h->qt,0);	h->afmt.fmtid = (h->channels > 1) ?	    AUDIO_S16_NATIVE_STEREO : AUDIO_S16_NATIVE_MONO;	h->afmt.rate = quicktime_sample_rate(h->qt,0);    }    return h;}static struct ng_video_fmt* qt_vfmt(void *handle, int *vfmt, int vn){    struct qt_handle *h = handle;    int i;    for (i = 0; i < vn; i++) {	if (ng_debug)	    fprintf(stderr,"qt: trying: %d [%s]\n",		    vfmt[i],ng_vfmt_to_desc[vfmt[i]]);	if (0 == fmtid_to_cmodel[vfmt[i]])	    continue;	if (!quicktime_reads_cmodel(h->qt,fmtid_to_cmodel[vfmt[i]],0))	    continue;	quicktime_set_cmodel(h->qt, fmtid_to_cmodel[vfmt[i]]);	h->vfmt.fmtid = vfmt[i];	break;    }    h->vfmt.bytesperline = (h->vfmt.width*ng_vfmt_to_depth[h->vfmt.fmtid]) >> 3;    return &h->vfmt;}static struct ng_audio_fmt* qt_afmt(void *handle){    struct qt_handle *h = handle;    return h->afmt.fmtid ? &h->afmt : NULL;}static struct ng_video_buf* qt_vdata(void *handle, unsigned int drop){    struct qt_handle *h = handle;    struct ng_video_buf *buf;    unsigned int i;        if (quicktime_video_position(h->qt,0) >= quicktime_video_length(h->qt,0))	return NULL;    buf = ng_malloc_video_buf(&h->vfmt,h->vfmt.bytesperline*h->vfmt.height);    if (!h->rows)	h->rows = malloc(h->vfmt.height * sizeof(char*));    switch (fmtid_to_cmodel[h->vfmt.fmtid]) {    case BC_RGB888:    case BC_BGR888:	for (i = 0; i < h->vfmt.height; i++)	    h->rows[i] = buf->data + h->vfmt.width * 3 * i;	break;    case BC_YUV422:	for (i = 0; i < h->vfmt.height; i++)	    h->rows[i] = buf->data+ h->vfmt.width * 2 * i;	break;    case BC_YUV420P:	h->rows[0] = buf->data;	h->rows[1] = buf->data + h->vfmt.width*h->vfmt.height;	h->rows[2] = buf->data + h->vfmt.width*h->vfmt.height*5/4;	break;    default:	BUG_ON(1,"unknown cmodel");    }    /* drop frames */    for (i = 0; i < drop; i++)	quicktime_read_frame(h->qt,buf->data,0);            buf->info.seq  = quicktime_video_position(h->qt,0);    buf->info.ts   = (long long) buf->info.seq * 1000000000 / h->rate;    lqt_decode_video(h->qt, h->rows, 0);    return buf;}static struct ng_audio_buf* qt_adata(void *handle){    struct qt_handle *h = handle;    struct ng_audio_buf *buf;    int16_t *dest;    long pos;    int i;        if (quicktime_audio_position(h->qt,0) >= quicktime_audio_length(h->qt,0))	return NULL;    buf = ng_malloc_audio_buf(&h->afmt,AUDIO_SIZE);    dest = (int16_t*)buf->data;    pos = quicktime_audio_position(h->qt,0);    buf->info.ts = (long long) pos * 1000000000 / h->afmt.rate;    if (h->channels > 1) {	/* stereo: two channels => interlaved samples */	if (!h->left)	    h->left = malloc(AUDIO_SIZE/2);	if (!h->right)	    h->right = malloc(AUDIO_SIZE/2);	quicktime_set_audio_position(h->qt,pos,0);	quicktime_decode_audio(h->qt,h->left,NULL,AUDIO_SIZE/4,0);	quicktime_set_audio_position(h->qt,pos,1);	quicktime_decode_audio(h->qt,h->right,NULL,AUDIO_SIZE/4,1);	for (i = 0; i < AUDIO_SIZE/4; i++) {	    dest[2*i+0] = h->left[i];	    dest[2*i+1] = h->right[i];	}    } else {	/* mono */	quicktime_decode_audio(h->qt,dest,NULL,AUDIO_SIZE/2,0);    }    return buf;}static int64_t qt_frame_time(void *handle){    struct qt_handle *h = handle;    return 1000000000 / h->rate;}static int qt_close(void *handle){    struct qt_handle *h = handle;    quicktime_close(h->qt);    if (h->rows)	free(h->rows);    free(h);    return 0;}/* ----------------------------------------------------------------------- */struct ng_reader qt_reader = {    name:       "qt",    desc:       "Apple QuickTime format",    magic:	{ "moov", "mdat" },    moff:       {  4,      4     },    mlen:       {  4,      4     },        rd_open:    qt_open,    rd_vfmt:    qt_vfmt,    rd_afmt:    qt_afmt,    rd_vdata:   qt_vdata,    rd_adata:   qt_adata,    frame_time: qt_frame_time,    rd_close:   qt_close,};extern void ng_plugin_init(void);void ng_plugin_init(void){    ng_reader_register(NG_PLUGIN_MAGIC,__FILE__,&qt_reader);}

⌨️ 快捷键说明

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