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