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

📄 dv.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    return 5;}static inline int dv_write_dif_id(enum dv_section_type t, uint8_t seq_num,                                   uint8_t dif_num, uint8_t* buf){    buf[0] = (uint8_t)t;    /* Section type */    buf[1] = (seq_num<<4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */	     (0 << 3) |     /* FSC: for 50Mb/s 0 - first channel; 1 - second */	     7;             /* reserved -- always 1 */    buf[2] = dif_num;       /* DIF block number Video: 0-134, Audio: 0-8 */    return 3;}static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf){    if (syb_num == 0 || syb_num == 6) {	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */		 (0<<4)  | /* AP3 (Subcode application ID) */		 0x0f;     /* reserved -- always 1 */    }     else if (syb_num == 11) {	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */                 0x7f;     /* reserved -- always 1 */    }    else {	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */                 (0<<4)  | /* APT (Track application ID) */		 0x0f;     /* reserved -- always 1 */    }    buf[1] = 0xf0 |            /* reserved -- always 1 */             (syb_num & 0x0f); /* SSYB number 0 - 11   */    buf[2] = 0xff;             /* reserved -- always 1 */    return 3;}static void dv_format_frame(DVMuxContext *c, uint8_t* buf){    int i, j, k;        for (i = 0; i < c->sys->difseg_size; i++) {       memset(buf, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */              /* DV header: 1DIF */       buf += dv_write_dif_id(dv_sect_header, i, 0, buf);       buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);       buf += 72; /* unused bytes */				          /* DV subcode: 2DIFs */       for (j = 0; j < 2; j++) {          buf += dv_write_dif_id( dv_sect_subcode, i, j, buf);	  for (k = 0; k < 6; k++) {	     buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf);	     buf += dv_write_pack(dv_ssyb_packs_dist[i][k], c, buf);	  }	  buf += 29; /* unused bytes */       }              /* DV VAUX: 3DIFs */       for (j = 0; j < 3; j++) {	  buf += dv_write_dif_id(dv_sect_vaux, i, j, buf);	  for (k = 0; k < 15 ; k++)	     buf += dv_write_pack(dv_vaux_packs_dist[i][k], c, buf);	  buf += 2; /* unused bytes */       }               /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */       for (j = 0; j < 135; j++) {            if (j%15 == 0) {	        buf += dv_write_dif_id(dv_sect_audio, i, j/15, buf);	        buf += dv_write_pack(dv_aaux_packs_dist[i][j/15], c, buf);		buf += 72; /* shuffled PCM audio */	    }	    buf += dv_write_dif_id(dv_sect_video, i, j, buf);	    buf += 77; /* 1 video macro block: 1 bytes control			                       4 * 14 bytes Y 8x8 data			                           10 bytes Cr 8x8 data						   10 bytes Cb 8x8 data */       }    }}static void dv_inject_audio(DVMuxContext *c, const uint8_t* pcm, uint8_t* frame_ptr){    int i, j, d, of;    for (i = 0; i < c->sys->difseg_size; i++) {       frame_ptr += 6 * 80; /* skip DIF segment header */       for (j = 0; j < 9; j++) {          for (d = 8; d < 80; d+=2) {	     of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride;	     frame_ptr[d] = pcm[of*2+1]; // FIXME: may be we have to admit	     frame_ptr[d+1] = pcm[of*2]; //        that DV is a big endian PCM                 }          frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */       }    }}static void dv_inject_video(DVMuxContext *c, const uint8_t* video_data, uint8_t* frame_ptr){    int i, j;    int ptr = 0;    for (i = 0; i < c->sys->difseg_size; i++) {       ptr += 6 * 80; /* skip DIF segment header */       for (j = 0; j < 135; j++) {            if (j%15 == 0)	        ptr += 80; /* skip Audio DIF */	    ptr += 3;	    memcpy(frame_ptr + ptr, video_data + ptr, 77);	    ptr += 77;       }    }}/*  * This is the dumbest implementation of all -- it simply looks at * a fixed offset and if pack isn't there -- fails. We might want * to have a fallback mechanism for complete search of missing packs. */static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t){    int offs;        switch (t) {    case dv_audio_source:          offs = (80*6 + 80*16*3 + 3);	  break;    case dv_audio_control:          offs = (80*6 + 80*16*4 + 3);	  break;    case dv_video_control:          offs = (80*5 + 48 + 5);          break;    default:          return NULL;    }       return (frame[offs] == t ? &frame[offs] : NULL);}/*  * There's a couple of assumptions being made here: * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. *    We can pass them upwards when ffmpeg will be ready to deal with them. * 2. We don't do software emphasis. * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples *    are converted into 16bit linear ones. */static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2){    int size, i, j, d, of, smpls, freq, quant, half_ch;    uint16_t lc, rc;    const DVprofile* sys;    const uint8_t* as_pack;        as_pack = dv_extract_pack(frame, dv_audio_source);    if (!as_pack)    /* No audio ? */	return 0;       sys = dv_frame_profile(frame);    smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */    freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */    quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */        if (quant > 1)	return -1; /* Unsupported quantization */    size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */    half_ch = sys->difseg_size/2;    /* for each DIF segment */    for (i = 0; i < sys->difseg_size; i++) {       frame += 6 * 80; /* skip DIF segment header */       if (quant == 1 && i == half_ch) {           if (!pcm2)               break;           else               pcm = pcm2;       }       for (j = 0; j < 9; j++) {          for (d = 8; d < 80; d += 2) {	     if (quant == 0) {  /* 16bit quantization */		 of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride;                 if (of*2 >= size)		     continue;		 		 pcm[of*2] = frame[d+1]; // FIXME: may be we have to admit		 pcm[of*2+1] = frame[d]; //        that DV is a big endian PCM		 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)		     pcm[of*2+1] = 0;	      } else {           /* 12bit quantization */		 lc = ((uint16_t)frame[d] << 4) | 		      ((uint16_t)frame[d+2] >> 4);		 rc = ((uint16_t)frame[d+1] << 4) |	              ((uint16_t)frame[d+2] & 0x0f);		 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));		 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));		 of = sys->audio_shuffle[i%half_ch][j] + (d - 8)/3 * sys->audio_stride;                 if (of*2 >= size)		     continue;		 pcm[of*2] = lc & 0xff; // FIXME: may be we have to admit		 pcm[of*2+1] = lc >> 8; //        that DV is a big endian PCM		 of = sys->audio_shuffle[i%half_ch+half_ch][j] + 		      (d - 8)/3 * sys->audio_stride;		 pcm[of*2] = rc & 0xff; // FIXME: may be we have to admit		 pcm[of*2+1] = rc >> 8; //        that DV is a big endian PCM		 ++d;	      }	  }			  frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */        }    }    return size;}static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame){    const uint8_t* as_pack;    const DVprofile* sys;    int freq, smpls, quant, i;    sys = dv_frame_profile(frame);    as_pack = dv_extract_pack(frame, dv_audio_source);    if (!as_pack || !sys) {    /* No audio ? */        c->ach = 0;	return -1;    }        smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */    freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */    quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */    c->ach = (quant && freq == 2) ? 2 : 1;    /* The second stereo channel could appear in IEC 61834 stream only */    if (c->ach == 2 && !c->ast[1]) {        c->ast[1] = av_new_stream(c->fctx, 0);	if (c->ast[1]) {	    c->ast[1]->codec.codec_type = CODEC_TYPE_AUDIO;	    c->ast[1]->codec.codec_id = CODEC_ID_PCM_S16LE;	} else	    c->ach = 1;    }    for (i=0; i<c->ach; i++) {       c->ast[i]->codec.sample_rate = dv_audio_frequency[freq];       c->ast[i]->codec.channels = 2;       c->ast[i]->codec.bit_rate = 2 * dv_audio_frequency[freq] * 16;    }        return (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;}static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame){    const DVprofile* sys;     const uint8_t* vsc_pack;    AVCodecContext* avctx;    int apt, is16_9;    int size = 0;        sys = dv_frame_profile(frame);    if (sys) {        avctx = &c->vst->codec;		avctx->frame_rate = sys->frame_rate;        avctx->frame_rate_base = sys->frame_rate_base;        avctx->width = sys->width;        avctx->height = sys->height;        avctx->pix_fmt = sys->pix_fmt;        	vsc_pack = dv_extract_pack(frame, dv_video_control);        apt = frame[4] & 0x07;	is16_9 = (vsc_pack && (vsc_pack[2] & 0x07) == (apt?0x02:0x07));	avctx->sample_aspect_ratio = sys->sar[is16_9];		size = sys->frame_size;    }    return size;}/*  * The following 6 functions constitute our interface to the world */int dv_assemble_frame(DVMuxContext *c, AVStream* st,                      const uint8_t* data, int data_size, uint8_t** frame){    uint8_t pcm[8192];    int fsize, reqasize;       *frame = &c->frame_buf[0];    if (c->has_audio && c->has_video) {  /* must be a stale frame */        dv_format_frame(c, *frame);	c->frames++;	c->has_audio = c->has_video = 0;    }        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {        /* FIXME: we have to have more sensible approach than this one */	if (c->has_video)

⌨️ 快捷键说明

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