📄 dvenc.c
字号:
if (((long)(buf-frame)/(c->sys->frame_size/(c->sys->difseg_size*c->sys->n_difchan))%c->sys->difseg_size) > 5) { /* FIXME: is this really needed ? */ dv_write_pack(dv_video_recdate, c, &buf[j+14]); dv_write_pack(dv_video_rectime, c, &buf[j+22]); dv_write_pack(dv_video_recdate, c, &buf[j+38]); dv_write_pack(dv_video_rectime, c, &buf[j+46]); } } /* DV VAUX: 4th, 5th and 6th 3DIFs */ for (j = 80*3 + 3; j < 80*6; j += 80) { dv_write_pack(dv_video_recdate, c, &buf[j+5*2]); dv_write_pack(dv_video_rectime, c, &buf[j+5*3]); dv_write_pack(dv_video_recdate, c, &buf[j+5*11]); dv_write_pack(dv_video_rectime, c, &buf[j+5*12]); } }}/* * The following 3 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){ int i, reqasize; *frame = &c->frame_buf[0]; reqasize = 4 * dv_audio_frame_size(c->sys, c->frames); switch (st->codec->codec_type) { case CODEC_TYPE_VIDEO: /* FIXME: we have to have more sensible approach than this one */ if (c->has_video) av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames); memcpy(*frame, data, c->sys->frame_size); c->has_video = 1; break; case CODEC_TYPE_AUDIO: for (i = 0; i < c->n_ast && st != c->ast[i]; i++); /* FIXME: we have to have more sensible approach than this one */ if (av_fifo_size(&c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);#ifdef __CW32__ av_fifo_generic_write(&c->audio_data[i], (void*)data, data_size, NULL);#else av_fifo_generic_write(&c->audio_data[i], data, data_size, NULL);#endif /* Lets see if we've got enough audio for one DV frame */ c->has_audio |= ((reqasize <= av_fifo_size(&c->audio_data[i])) << i); break; default: break; } /* Lets see if we have enough data to construct one DV frame */ if (c->has_video == 1 && c->has_audio + 1 == 1<<c->n_ast) { dv_inject_metadata(c, *frame); c->has_audio = 0; for (i=0; i<c->n_ast; i++) { dv_inject_audio(c, i, *frame); av_fifo_drain(&c->audio_data[i], reqasize); c->has_audio |= ((reqasize <= av_fifo_size(&c->audio_data[i])) << i); } c->has_video = 0; c->frames++; return c->sys->frame_size; } return 0;}DVMuxContext* dv_init_mux(AVFormatContext* s){ DVMuxContext *c = s->priv_data; AVStream *vst = NULL; int i; /* we support at most 1 video and 2 audio streams */ if (s->nb_streams > 3) return NULL; c->n_ast = 0; c->ast[0] = c->ast[1] = NULL; /* We have to sort out where audio and where video stream is */ for (i=0; i<s->nb_streams; i++) { switch (s->streams[i]->codec->codec_type) { case CODEC_TYPE_VIDEO: if (vst) return NULL; vst = s->streams[i]; break; case CODEC_TYPE_AUDIO: if (c->n_ast > 1) return NULL; c->ast[c->n_ast++] = s->streams[i]; break; default: goto bail_out; } } /* Some checks -- DV format is very picky about its incoming streams */ if (!vst || vst->codec->codec_id != CODEC_ID_DVVIDEO) goto bail_out; for (i=0; i<c->n_ast; i++) { if (c->ast[i] && (c->ast[i]->codec->codec_id != CODEC_ID_PCM_S16LE || c->ast[i]->codec->sample_rate != 48000 || c->ast[i]->codec->channels != 2)) goto bail_out; } c->sys = dv_codec_profile(vst->codec); if (!c->sys) goto bail_out; if((c->n_ast > 1) && (c->sys->n_difchan < 2)) { /* only 1 stereo pair is allowed in 25Mbps mode */ goto bail_out; } /* Ok, everything seems to be in working order */ c->frames = 0; c->has_audio = 0; c->has_video = 0; c->start_time = (time_t)s->timestamp; for (i=0; i<c->n_ast; i++) { if (c->ast[i] && av_fifo_init(&c->audio_data[i], 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0) { while (i>0) { i--; av_fifo_free(&c->audio_data[i]); } goto bail_out; } } return c;bail_out: return NULL;}void dv_delete_mux(DVMuxContext *c){ int i; for (i=0; i < c->n_ast; i++) av_fifo_free(&c->audio_data[i]);}#ifdef CONFIG_MUXERSstatic int dv_write_header(AVFormatContext *s){ if (!dv_init_mux(s)) { av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n" "Make sure that you supply exactly two streams:\n" " video: 25fps or 29.97fps, audio: 2ch/48Khz/PCM\n" " (50Mbps allows an optional second audio stream)\n"); return -1; } return 0;}static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt){ uint8_t* frame; int fsize; fsize = dv_assemble_frame(s->priv_data, s->streams[pkt->stream_index], pkt->data, pkt->size, &frame); if (fsize > 0) { put_buffer(s->pb, frame, fsize); put_flush_packet(s->pb); } return 0;}/* * We might end up with some extra A/V data without matching counterpart. * E.g. video data without enough audio to write the complete frame. * Currently we simply drop the last frame. I don't know whether this * is the best strategy of all */static int dv_write_trailer(struct AVFormatContext *s){ dv_delete_mux(s->priv_data); return 0;}#endif /* CONFIG_MUXERS */#ifdef CONFIG_DV_MUXERAVOutputFormat dv_muxer = { "dv", NULL_IF_CONFIG_SMALL("DV video format"), NULL, "dv", sizeof(DVMuxContext), CODEC_ID_PCM_S16LE, CODEC_ID_DVVIDEO, dv_write_header, dv_write_packet, dv_write_trailer,};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -