libavcodec/dvdata.c
Go to the documentation of this file.
00001 /*
00002  * Constants for DV codec
00003  * Copyright (c) 2002 Fabrice Bellard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "libavutil/rational.h"
00028 #include "libavutil/intreadwrite.h"
00029 #include "avcodec.h"
00030 #include "dvdata.h"
00031 
00032 static DVwork_chunk work_chunks_dv25pal   [1*12*27];
00033 static DVwork_chunk work_chunks_dv25pal411[1*12*27];
00034 static DVwork_chunk work_chunks_dv25ntsc  [1*10*27];
00035 static DVwork_chunk work_chunks_dv50pal   [2*12*27];
00036 static DVwork_chunk work_chunks_dv50ntsc  [2*10*27];
00037 static DVwork_chunk work_chunks_dv100palp [2*12*27];
00038 static DVwork_chunk work_chunks_dv100ntscp[2*10*27];
00039 static DVwork_chunk work_chunks_dv100pali [4*12*27];
00040 static DVwork_chunk work_chunks_dv100ntsci[4*10*27];
00041 
00042 static uint32_t dv_idct_factor_sd    [2*2*22*64];
00043 static uint32_t dv_idct_factor_hd1080[2*4*16*64];
00044 static uint32_t dv_idct_factor_hd720 [2*4*16*64];
00045 
00046 static const DVprofile dv_profiles[] = {
00047     { .dsf = 0,
00048       .video_stype = 0x0,
00049       .frame_size = 120000,        /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
00050       .difseg_size = 10,
00051       .n_difchan = 1,
00052       .time_base = { 1001, 30000 },
00053       .ltc_divisor = 30,
00054       .height = 480,
00055       .width = 720,
00056       .sar = {{8, 9}, {32, 27}},
00057       .work_chunks = &work_chunks_dv25ntsc[0],
00058       .idct_factor = &dv_idct_factor_sd[0],
00059       .pix_fmt = PIX_FMT_YUV411P,
00060       .bpm = 6,
00061       .block_sizes = block_sizes_dv2550,
00062       .audio_stride = 90,
00063       .audio_min_samples  = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
00064       .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
00065       .audio_shuffle = dv_audio_shuffle525,
00066     },
00067     { .dsf = 1,
00068       .video_stype = 0x0,
00069       .frame_size = 144000,        /* IEC 61834 - 625/50 (PAL) */
00070       .difseg_size = 12,
00071       .n_difchan = 1,
00072       .time_base = { 1, 25 },
00073       .ltc_divisor = 25,
00074       .height = 576,
00075       .width = 720,
00076       .sar = {{16, 15}, {64, 45}},
00077       .work_chunks = &work_chunks_dv25pal[0],
00078       .idct_factor = &dv_idct_factor_sd[0],
00079       .pix_fmt = PIX_FMT_YUV420P,
00080       .bpm = 6,
00081       .block_sizes = block_sizes_dv2550,
00082       .audio_stride = 108,
00083       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00084       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00085       .audio_shuffle = dv_audio_shuffle625,
00086     },
00087     { .dsf = 1,
00088       .video_stype = 0x0,
00089       .frame_size = 144000,        /* SMPTE-314M - 625/50 (PAL) */
00090       .difseg_size = 12,
00091       .n_difchan = 1,
00092       .time_base = { 1, 25 },
00093       .ltc_divisor = 25,
00094       .height = 576,
00095       .width = 720,
00096       .sar = {{16, 15}, {64, 45}},
00097       .work_chunks = &work_chunks_dv25pal411[0],
00098       .idct_factor = &dv_idct_factor_sd[0],
00099       .pix_fmt = PIX_FMT_YUV411P,
00100       .bpm = 6,
00101       .block_sizes = block_sizes_dv2550,
00102       .audio_stride = 108,
00103       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00104       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00105       .audio_shuffle = dv_audio_shuffle625,
00106     },
00107     { .dsf = 0,
00108       .video_stype = 0x4,
00109       .frame_size = 240000,        /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */
00110       .difseg_size = 10,           /* also known as "DVCPRO50" */
00111       .n_difchan = 2,
00112       .time_base = { 1001, 30000 },
00113       .ltc_divisor = 30,
00114       .height = 480,
00115       .width = 720,
00116       .sar = {{8, 9}, {32, 27}},
00117       .work_chunks = &work_chunks_dv50ntsc[0],
00118       .idct_factor = &dv_idct_factor_sd[0],
00119       .pix_fmt = PIX_FMT_YUV422P,
00120       .bpm = 6,
00121       .block_sizes = block_sizes_dv2550,
00122       .audio_stride = 90,
00123       .audio_min_samples  = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
00124       .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
00125       .audio_shuffle = dv_audio_shuffle525,
00126     },
00127     { .dsf = 1,
00128       .video_stype = 0x4,
00129       .frame_size = 288000,        /* SMPTE-314M - 625/50 (PAL) 50 Mbps */
00130       .difseg_size = 12,           /* also known as "DVCPRO50" */
00131       .n_difchan = 2,
00132       .time_base = { 1, 25 },
00133       .ltc_divisor = 25,
00134       .height = 576,
00135       .width = 720,
00136       .sar = {{16, 15}, {64, 45}},
00137       .work_chunks = &work_chunks_dv50pal[0],
00138       .idct_factor = &dv_idct_factor_sd[0],
00139       .pix_fmt = PIX_FMT_YUV422P,
00140       .bpm = 6,
00141       .block_sizes = block_sizes_dv2550,
00142       .audio_stride = 108,
00143       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00144       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00145       .audio_shuffle = dv_audio_shuffle625,
00146     },
00147     { .dsf = 0,
00148       .video_stype = 0x14,
00149       .frame_size = 480000,        /* SMPTE-370M - 1080i60 100 Mbps */
00150       .difseg_size = 10,           /* also known as "DVCPRO HD" */
00151       .n_difchan = 4,
00152       .time_base = { 1001, 30000 },
00153       .ltc_divisor = 30,
00154       .height = 1080,
00155       .width = 1280,
00156       .sar = {{1, 1}, {3, 2}},
00157       .work_chunks = &work_chunks_dv100ntsci[0],
00158       .idct_factor = &dv_idct_factor_hd1080[0],
00159       .pix_fmt = PIX_FMT_YUV422P,
00160       .bpm = 8,
00161       .block_sizes = block_sizes_dv100,
00162       .audio_stride = 90,
00163       .audio_min_samples  = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
00164       .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
00165       .audio_shuffle = dv_audio_shuffle525,
00166     },
00167     { .dsf = 1,
00168       .video_stype = 0x14,
00169       .frame_size = 576000,        /* SMPTE-370M - 1080i50 100 Mbps */
00170       .difseg_size = 12,           /* also known as "DVCPRO HD" */
00171       .n_difchan = 4,
00172       .time_base = { 1, 25 },
00173       .ltc_divisor = 25,
00174       .height = 1080,
00175       .width = 1440,
00176       .sar = {{1, 1}, {4, 3}},
00177       .work_chunks = &work_chunks_dv100pali[0],
00178       .idct_factor = &dv_idct_factor_hd1080[0],
00179       .pix_fmt = PIX_FMT_YUV422P,
00180       .bpm = 8,
00181       .block_sizes = block_sizes_dv100,
00182       .audio_stride = 108,
00183       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00184       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00185       .audio_shuffle = dv_audio_shuffle625,
00186     },
00187     { .dsf = 0,
00188       .video_stype = 0x18,
00189       .frame_size = 240000,        /* SMPTE-370M - 720p60 100 Mbps */
00190       .difseg_size = 10,           /* also known as "DVCPRO HD" */
00191       .n_difchan = 2,
00192       .time_base = { 1001, 60000 },
00193       .ltc_divisor = 60,
00194       .height = 720,
00195       .width = 960,
00196       .sar = {{1, 1}, {4, 3}},
00197       .work_chunks = &work_chunks_dv100ntscp[0],
00198       .idct_factor = &dv_idct_factor_hd720[0],
00199       .pix_fmt = PIX_FMT_YUV422P,
00200       .bpm = 8,
00201       .block_sizes = block_sizes_dv100,
00202       .audio_stride = 90,
00203       .audio_min_samples  = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */
00204       .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */
00205       .audio_shuffle = dv_audio_shuffle525,
00206     },
00207     { .dsf = 1,
00208       .video_stype = 0x18,
00209       .frame_size = 288000,        /* SMPTE-370M - 720p50 100 Mbps */
00210       .difseg_size = 12,           /* also known as "DVCPRO HD" */
00211       .n_difchan = 2,
00212       .time_base = { 1, 50 },
00213       .ltc_divisor = 50,
00214       .height = 720,
00215       .width = 960,
00216       .sar = {{1, 1}, {4, 3}},
00217       .work_chunks = &work_chunks_dv100palp[0],
00218       .idct_factor = &dv_idct_factor_hd720[0],
00219       .pix_fmt = PIX_FMT_YUV422P,
00220       .bpm = 8,
00221       .block_sizes = block_sizes_dv100,
00222       .audio_stride = 90,
00223       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00224       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00225       .audio_shuffle = dv_audio_shuffle625,
00226     },
00227     { .dsf = 1,
00228       .video_stype = 0x1,
00229       .frame_size = 144000,        /* IEC 61883-5 - 625/50 (PAL) */
00230       .difseg_size = 12,
00231       .n_difchan = 1,
00232       .time_base = { 1, 25 },
00233       .ltc_divisor = 25,
00234       .height = 576,
00235       .width = 720,
00236       .sar = {{16, 15}, {64, 45}},
00237       .work_chunks = &work_chunks_dv25pal[0],
00238       .idct_factor = &dv_idct_factor_sd[0],
00239       .pix_fmt = PIX_FMT_YUV420P,
00240       .bpm = 6,
00241       .block_sizes = block_sizes_dv2550,
00242       .audio_stride = 108,
00243       .audio_min_samples  = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */
00244       .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
00245       .audio_shuffle = dv_audio_shuffle625,
00246     }
00247 };
00248 
00249 const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys,
00250                                   const uint8_t* frame, unsigned buf_size)
00251 {
00252    int i, dsf, stype;
00253 
00254    if(buf_size < DV_PROFILE_BYTES)
00255        return NULL;
00256 
00257    dsf = (frame[3] & 0x80) >> 7;
00258    stype = frame[80*5 + 48 + 3] & 0x1f;
00259 
00260    /* 576i50 25Mbps 4:1:1 is a special case */
00261    if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) {
00262        return &dv_profiles[2];
00263    }
00264 
00265    if(codec && codec->codec_tag==AV_RL32("dvsd") &&  codec->width==720 && codec->height==576)
00266        return &dv_profiles[1];
00267 
00268    for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
00269        if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
00270            return &dv_profiles[i];
00271 
00272    /* check if old sys matches and assumes corrupted input */
00273    if (sys && buf_size == sys->frame_size)
00274        return sys;
00275 
00276    return NULL;
00277 }
00278 
00279 const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
00280                                   const uint8_t* frame, unsigned buf_size)
00281 {
00282     return avpriv_dv_frame_profile2(NULL, sys, frame, buf_size);
00283 }
00284 
00285 const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
00286 {
00287     int i;
00288 
00289     for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
00290        if (codec->coded_height == dv_profiles[i].height  &&
00291            codec->pix_fmt      == dv_profiles[i].pix_fmt &&
00292            codec->coded_width  == dv_profiles[i].width)
00293                return &dv_profiles[i];
00294 
00295     return NULL;
00296 }
00297