00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <time.h>
00032 #include "avformat.h"
00033 #include "internal.h"
00034 #include "libavcodec/dvdata.h"
00035 #include "libavutil/intreadwrite.h"
00036 #include "libavutil/mathematics.h"
00037 #include "dv.h"
00038
00039 struct DVDemuxContext {
00040 const DVprofile* sys;
00041 AVFormatContext* fctx;
00042 AVStream* vst;
00043 AVStream* ast[4];
00044 AVPacket audio_pkt[4];
00045 uint8_t audio_buf[4][8192];
00046 int ach;
00047 int frames;
00048 uint64_t abytes;
00049 };
00050
00051 static inline uint16_t dv_audio_12to16(uint16_t sample)
00052 {
00053 uint16_t shift, result;
00054
00055 sample = (sample < 0x800) ? sample : sample | 0xf000;
00056 shift = (sample & 0xf00) >> 8;
00057
00058 if (shift < 0x2 || shift > 0xd) {
00059 result = sample;
00060 } else if (shift < 0x8) {
00061 shift--;
00062 result = (sample - (256 * shift)) << shift;
00063 } else {
00064 shift = 0xe - shift;
00065 result = ((sample + ((256 * shift) + 1)) << shift) - 1;
00066 }
00067
00068 return result;
00069 }
00070
00071
00072
00073
00074
00075
00076 static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
00077 {
00078 int offs;
00079
00080 switch (t) {
00081 case dv_audio_source:
00082 offs = (80*6 + 80*16*3 + 3);
00083 break;
00084 case dv_audio_control:
00085 offs = (80*6 + 80*16*4 + 3);
00086 break;
00087 case dv_video_control:
00088 offs = (80*5 + 48 + 5);
00089 break;
00090 default:
00091 return NULL;
00092 }
00093
00094 return frame[offs] == t ? &frame[offs] : NULL;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
00106 const DVprofile *sys)
00107 {
00108 int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
00109 uint16_t lc, rc;
00110 const uint8_t* as_pack;
00111 uint8_t *pcm, ipcm;
00112
00113 as_pack = dv_extract_pack(frame, dv_audio_source);
00114 if (!as_pack)
00115 return 0;
00116
00117 smpls = as_pack[1] & 0x3f;
00118 freq = (as_pack[4] >> 3) & 0x07;
00119 quant = as_pack[4] & 0x07;
00120
00121 if (quant > 1)
00122 return -1;
00123
00124 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
00125 return AVERROR_INVALIDDATA;
00126
00127 size = (sys->audio_min_samples[freq] + smpls) * 4;
00128 half_ch = sys->difseg_size / 2;
00129
00130
00131
00132 ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
00133
00134
00135 for (chan = 0; chan < sys->n_difchan; chan++) {
00136
00137 pcm = ppcm[ipcm++];
00138 if (!pcm)
00139 break;
00140
00141
00142 for (i = 0; i < sys->difseg_size; i++) {
00143 frame += 6 * 80;
00144 if (quant == 1 && i == half_ch) {
00145
00146 pcm = ppcm[ipcm++];
00147 if (!pcm)
00148 break;
00149 }
00150
00151
00152 for (j = 0; j < 9; j++) {
00153 for (d = 8; d < 80; d += 2) {
00154 if (quant == 0) {
00155 of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
00156 if (of*2 >= size)
00157 continue;
00158
00159 pcm[of*2] = frame[d+1];
00160 pcm[of*2+1] = frame[d];
00161 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
00162 pcm[of*2+1] = 0;
00163 } else {
00164 lc = ((uint16_t)frame[d] << 4) |
00165 ((uint16_t)frame[d+2] >> 4);
00166 rc = ((uint16_t)frame[d+1] << 4) |
00167 ((uint16_t)frame[d+2] & 0x0f);
00168 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
00169 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
00170
00171 of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
00172 if (of*2 >= size)
00173 continue;
00174
00175 pcm[of*2] = lc & 0xff;
00176 pcm[of*2+1] = lc >> 8;
00177 of = sys->audio_shuffle[i%half_ch+half_ch][j] +
00178 (d - 8) / 3 * sys->audio_stride;
00179 pcm[of*2] = rc & 0xff;
00180 pcm[of*2+1] = rc >> 8;
00181 ++d;
00182 }
00183 }
00184
00185 frame += 16 * 80;
00186 }
00187 }
00188 }
00189
00190 return size;
00191 }
00192
00193 static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
00194 {
00195 const uint8_t* as_pack;
00196 int freq, stype, smpls, quant, i, ach;
00197
00198 as_pack = dv_extract_pack(frame, dv_audio_source);
00199 if (!as_pack || !c->sys) {
00200 c->ach = 0;
00201 return 0;
00202 }
00203
00204 smpls = as_pack[1] & 0x3f;
00205 freq = (as_pack[4] >> 3) & 0x07;
00206 stype = (as_pack[3] & 0x1f);
00207 quant = as_pack[4] & 0x07;
00208
00209 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
00210 av_log(c->fctx, AV_LOG_ERROR,
00211 "Unrecognized audio sample rate index (%d)\n", freq);
00212 return 0;
00213 }
00214
00215 if (stype > 3) {
00216 av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype);
00217 c->ach = 0;
00218 return 0;
00219 }
00220
00221
00222 ach = ((int[4]){ 1, 0, 2, 4})[stype];
00223 if (ach == 1 && quant && freq == 2)
00224 ach = 2;
00225
00226
00227 for (i = 0; i < ach; i++) {
00228 if (!c->ast[i]) {
00229 c->ast[i] = avformat_new_stream(c->fctx, NULL);
00230 if (!c->ast[i])
00231 break;
00232 avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
00233 c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00234 c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
00235
00236 av_init_packet(&c->audio_pkt[i]);
00237 c->audio_pkt[i].size = 0;
00238 c->audio_pkt[i].data = c->audio_buf[i];
00239 c->audio_pkt[i].stream_index = c->ast[i]->index;
00240 c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
00241 }
00242 c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
00243 c->ast[i]->codec->channels = 2;
00244 c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
00245 c->ast[i]->start_time = 0;
00246 }
00247 c->ach = i;
00248
00249 return (c->sys->audio_min_samples[freq] + smpls) * 4; ;
00250 }
00251
00252 static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
00253 {
00254 const uint8_t* vsc_pack;
00255 AVCodecContext* avctx;
00256 int apt, is16_9;
00257 int size = 0;
00258
00259 if (c->sys) {
00260 avctx = c->vst->codec;
00261
00262 avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
00263 c->sys->time_base.den);
00264 avctx->time_base= c->sys->time_base;
00265 if (!avctx->width){
00266 avctx->width = c->sys->width;
00267 avctx->height = c->sys->height;
00268 }
00269 avctx->pix_fmt = c->sys->pix_fmt;
00270
00271
00272 vsc_pack = dv_extract_pack(frame, dv_video_control);
00273 apt = frame[4] & 0x07;
00274 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
00275 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
00276 c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
00277 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
00278 c->sys->time_base);
00279 size = c->sys->frame_size;
00280 }
00281 return size;
00282 }
00283
00284
00285
00286
00287
00288 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
00289 {
00290 DVDemuxContext *c;
00291
00292 c = av_mallocz(sizeof(DVDemuxContext));
00293 if (!c)
00294 return NULL;
00295
00296 c->vst = avformat_new_stream(s, NULL);
00297 if (!c->vst) {
00298 av_free(c);
00299 return NULL;
00300 }
00301
00302 c->sys = NULL;
00303 c->fctx = s;
00304 memset(c->ast, 0, sizeof(c->ast));
00305 c->ach = 0;
00306 c->frames = 0;
00307 c->abytes = 0;
00308
00309 c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00310 c->vst->codec->codec_id = CODEC_ID_DVVIDEO;
00311 c->vst->codec->bit_rate = 25000000;
00312 c->vst->start_time = 0;
00313
00314 return c;
00315 }
00316
00317 int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
00318 {
00319 int size = -1;
00320 int i;
00321
00322 for (i = 0; i < c->ach; i++) {
00323 if (c->ast[i] && c->audio_pkt[i].size) {
00324 *pkt = c->audio_pkt[i];
00325 c->audio_pkt[i].size = 0;
00326 size = pkt->size;
00327 break;
00328 }
00329 }
00330
00331 return size;
00332 }
00333
00334 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
00335 uint8_t* buf, int buf_size)
00336 {
00337 int size, i;
00338 uint8_t *ppcm[5] = { 0 };
00339
00340 if (buf_size < DV_PROFILE_BYTES ||
00341 !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
00342 buf_size < c->sys->frame_size) {
00343 return -1;
00344 }
00345
00346
00347
00348 size = dv_extract_audio_info(c, buf);
00349 for (i = 0; i < c->ach; i++) {
00350 c->audio_pkt[i].size = size;
00351 c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
00352 ppcm[i] = c->audio_buf[i];
00353 }
00354 if (c->ach)
00355 dv_extract_audio(buf, ppcm, c->sys);
00356
00357
00358
00359 if (c->sys->height == 720) {
00360 if (buf[1] & 0x0C) {
00361 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00362 } else {
00363 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00364 c->abytes += size;
00365 }
00366 } else {
00367 c->abytes += size;
00368 }
00369
00370
00371 size = dv_extract_video_info(c, buf);
00372 av_init_packet(pkt);
00373 pkt->data = buf;
00374 pkt->size = size;
00375 pkt->flags |= AV_PKT_FLAG_KEY;
00376 pkt->stream_index = c->vst->id;
00377 pkt->pts = c->frames;
00378
00379 c->frames++;
00380
00381 return size;
00382 }
00383
00384 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
00385 int64_t timestamp, int flags)
00386 {
00387
00388 const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
00389 int64_t offset;
00390 int64_t size = avio_size(s->pb) - s->data_offset;
00391 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
00392
00393 offset = sys->frame_size * timestamp;
00394
00395 if (size >= 0 && offset > max_offset) offset = max_offset;
00396 else if (offset < 0) offset = 0;
00397
00398 return offset + s->data_offset;
00399 }
00400
00401 void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
00402 {
00403 c->frames= frame_offset;
00404 if (c->ach)
00405 c->abytes= av_rescale_q(c->frames, c->sys->time_base,
00406 (AVRational){8, c->ast[0]->codec->bit_rate});
00407 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00408 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00409 }
00410
00411
00412
00413
00414
00415 typedef struct RawDVContext {
00416 DVDemuxContext* dv_demux;
00417 uint8_t buf[DV_MAX_FRAME_SIZE];
00418 } RawDVContext;
00419
00420 static int dv_read_header(AVFormatContext *s,
00421 AVFormatParameters *ap)
00422 {
00423 unsigned state, marker_pos = 0;
00424 RawDVContext *c = s->priv_data;
00425
00426 c->dv_demux = avpriv_dv_init_demux(s);
00427 if (!c->dv_demux)
00428 return -1;
00429
00430 state = avio_rb32(s->pb);
00431 while ((state & 0xffffff7f) != 0x1f07003f) {
00432 if (s->pb->eof_reached) {
00433 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
00434 return -1;
00435 }
00436 if (state == 0x003f0700 || state == 0xff3f0700)
00437 marker_pos = avio_tell(s->pb);
00438 if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) {
00439 avio_seek(s->pb, -163, SEEK_CUR);
00440 state = avio_rb32(s->pb);
00441 break;
00442 }
00443 state = (state << 8) | avio_r8(s->pb);
00444 }
00445 AV_WB32(c->buf, state);
00446
00447 if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
00448 avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
00449 return AVERROR(EIO);
00450
00451 c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
00452 if (!c->dv_demux->sys) {
00453 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
00454 return -1;
00455 }
00456
00457 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
00458 c->dv_demux->sys->time_base);
00459
00460 return 0;
00461 }
00462
00463
00464 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
00465 {
00466 int size;
00467 RawDVContext *c = s->priv_data;
00468
00469 size = avpriv_dv_get_packet(c->dv_demux, pkt);
00470
00471 if (size < 0) {
00472 if (!c->dv_demux->sys)
00473 return AVERROR(EIO);
00474 size = c->dv_demux->sys->frame_size;
00475 if (avio_read(s->pb, c->buf, size) <= 0)
00476 return AVERROR(EIO);
00477
00478 size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size);
00479 }
00480
00481 return size;
00482 }
00483
00484 static int dv_read_seek(AVFormatContext *s, int stream_index,
00485 int64_t timestamp, int flags)
00486 {
00487 RawDVContext *r = s->priv_data;
00488 DVDemuxContext *c = r->dv_demux;
00489 int64_t offset = dv_frame_offset(s, c, timestamp, flags);
00490
00491 dv_offset_reset(c, offset / c->sys->frame_size);
00492
00493 offset = avio_seek(s->pb, offset, SEEK_SET);
00494 return (offset < 0) ? offset : 0;
00495 }
00496
00497 static int dv_read_close(AVFormatContext *s)
00498 {
00499 RawDVContext *c = s->priv_data;
00500 av_free(c->dv_demux);
00501 return 0;
00502 }
00503
00504 static int dv_probe(AVProbeData *p)
00505 {
00506 unsigned state, marker_pos = 0;
00507 int i;
00508 int matches = 0;
00509 int secondary_matches = 0;
00510
00511 if (p->buf_size < 5)
00512 return 0;
00513
00514 state = AV_RB32(p->buf);
00515 for (i = 4; i < p->buf_size; i++) {
00516 if ((state & 0xffffff7f) == 0x1f07003f)
00517 matches++;
00518
00519
00520 if ((state & 0xff07ff7f) == 0x1f07003f)
00521 secondary_matches++;
00522 if (state == 0x003f0700 || state == 0xff3f0700)
00523 marker_pos = i;
00524 if (state == 0xff3f0701 && i - marker_pos == 80)
00525 matches++;
00526 state = (state << 8) | p->buf[i];
00527 }
00528
00529 if (matches && p->buf_size / matches < 1024*1024) {
00530 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
00531 return AVPROBE_SCORE_MAX*3/4;
00532 return AVPROBE_SCORE_MAX/4;
00533 }
00534 return 0;
00535 }
00536
00537 #if CONFIG_DV_DEMUXER
00538 AVInputFormat ff_dv_demuxer = {
00539 .name = "dv",
00540 .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
00541 .priv_data_size = sizeof(RawDVContext),
00542 .read_probe = dv_probe,
00543 .read_header = dv_read_header,
00544 .read_packet = dv_read_packet,
00545 .read_close = dv_read_close,
00546 .read_seek = dv_read_seek,
00547 .extensions = "dv,dif",
00548 };
00549 #endif