fixed playback of dv PAl and NTSC (sampling)

git-svn-id: svn://code.dyne.org/veejay/trunk@653 eb8d1916-c9e9-0310-b8de-cf0c9472ead5
This commit is contained in:
Niels Elburg
2006-10-18 20:44:58 +00:00
parent f94d4b91b9
commit 390d5e6fe8
3 changed files with 122 additions and 107 deletions

View File

@@ -181,36 +181,104 @@ void vj_dv_decoder_get_audio(vj_dv_decoder *d, uint8_t *audio_buf)
}
/*
* Unpack libdv's 4:2:2-packed into our 4:2:0-planar or 4:2:2-planar,
* treating each interlaced field independently
*
*/
static inline void frame_YUV422_to_planar(uint8_t **output, uint8_t *input,
int width, int height, int chroma422)
{
int i, j, w2;
uint8_t *y, *cb, *cr;
w2 = width/2;
y = output[0];
cb = output[1];
cr = output[2];
for (i=0; i<height;) {
/* process two scanlines (one from each field, interleaved) */
/* ...top-field scanline */
for (j=0; j<w2; j++) {
/* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */
*(y++) = *(input++);
*(cb++) = *(input++);
*(y++) = *(input++);
*(cr++) = *(input++);
}
i++;
/* ...bottom-field scanline */
for (j=0; j<w2; j++) {
/* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */
*(y++) = *(input++);
*(cb++) = *(input++);
*(y++) = *(input++);
*(cr++) = *(input++);
}
i++;
if (chroma422)
continue;
/* process next two scanlines (one from each field, interleaved) */
/* ...top-field scanline */
for (j=0; j<w2; j++) {
/* skip every second line for U and V */
*(y++) = *(input++);
input++;
*(y++) = *(input++);
input++;
}
i++;
/* ...bottom-field scanline */
for (j=0; j<w2; j++) {
/* skip every second line for U and V */
*(y++) = *(input++);
input++;
*(y++) = *(input++);
input++;
}
i++;
}
}
int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y,
uint8_t * Cb, uint8_t * Cr, int width, int height, int fmt)
{
int pitches[3];
if (!input_buf)
return 0;
if (dv_parse_header(d->decoder, input_buf) < 0)
{
veejay_msg(0, "Unable to read DV header");
return 0;
}
if( d->decoder->system == e_dv_system_none )
{
veejay_msg(0, "No valid PAL or NTSC video frame detected");
return 0;
}
if( d->decoder->system == e_dv_system_625_50 )
{
d->yuy2 = 0;
}
else
{
d->yuy2 = 1;
}
if (!((d->decoder->num_dif_seqs == 10)
|| (d->decoder->num_dif_seqs == 12)))
{
veejay_msg(0, "Dont know how to handle %d dif seqs",
d->decoder->num_dif_seqs );
return 0;
/*
switch(vj_dv_decoder->sampling) {
case e_dv_sample_411:fprintf(stderr,"sample 411\n"); break;
case e_dv_sample_422:fprintf(stderr,"sample 422\n");break;
case e_dv_sample_420:fprintf(stderr,"sample 420\n");break;
default: fprintf(stderr,"unknown\n");break;
}
*/
/*
if (d->decoder->sampling == e_dv_sample_411 ||
d->decoder->sampling == e_dv_sample_422 ||
d->decoder->sampling == e_dv_sample_420)
if (d->decoder->sampling == e_dv_sample_411 || d->decoder->sampling == e_dv_sample_422)
{
pitches[0] = width * 2;
pitches[1] = 0;
@@ -220,18 +288,10 @@ int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y,
dv_decode_full_frame(d->decoder, input_buf,
e_dv_color_yuv, pixels, pitches);
if(fmt == FMT_420)
yuy2toyv12(Y, Cb, Cr, d->dv_video, width, height);
else
yuy2toyv16(Y, Cb, Cr, d->dv_video, width, height);
frame_YUV422_to_planar( pixels, pixels[0], width, height, fmt );
return 1;
}
*/
pitches[0] = width * 2;
pitches[1] = 0;
pitches[2] = 0;
if( d->decoder->sampling == e_dv_sample_420 )
{
@@ -239,29 +299,17 @@ int vj_dv_decode_frame(vj_dv_decoder *d, uint8_t * input_buf, uint8_t * Y,
pixels[0] = d->dv_video;
pixels[1] = d->dv_video + (width * height);
pixels[2] = d->dv_video + (width * height * 5)/4;
dv_decode_full_frame( d->decoder, input_buf, e_dv_color_yuv,
pixels,pitches);
if(fmt==FMT_422)
yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height );
else
yuy2toyv12( Y,Cb,Cr, d->dv_video, width, height );
pitches[0] = width * 2;
pitches[1] = 0;
pitches[2] = 0;
return 1;
}
if( d->decoder->sampling == e_dv_sample_422 )
{
uint8_t *pixels[3];
pixels[0] = d->dv_video;
pixels[1] = d->dv_video + (width * height);
pixels[2] = d->dv_video + (width * height) + (width * height/2);
dv_decode_full_frame( d->decoder, input_buf, e_dv_color_yuv,
pixels,pitches);
dv_decode_full_frame( d->decoder, input_buf, e_dv_color_yuv, pixels,pitches);
if(fmt==FMT_422)
yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height );
else
yuy2toyv12( Y,Cb,Cr, d->dv_video, width, height );
return 1;
}

View File

@@ -26,6 +26,7 @@ typedef struct
dv_decoder_t *decoder;
uint8_t *dv_video;
int fmt;
int yuy2;
int audio;
int16_t **audio_buffers;
} vj_dv_decoder;

View File

@@ -349,47 +349,31 @@ vj_decoder *_el_new_decoder( int id , int width, int height, float fps, int pixe
return NULL;
memset( d, 0, sizeof(vj_decoder));
int found = 0;
veejay_msg(VEEJAY_MSG_DEBUG, "\tCodec %x (%d) , %d x %d at %f, in=%d, out=%d",
id,id,width,height,fps,pixel_format,out_fmt);
#ifdef SUPPORT_READ_DV2
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420 && id != CODEC_ID_DVVIDEO)
{
#else
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420)
if( id == CODEC_ID_DVVIDEO )
{
dv_decoder_ = vj_dv_decoder_init(
1, width, height, pixel_format );
veejay_msg(VEEJAY_MSG_DEBUG,"\tRAW DV %d x %d, pf %d",
width,height,pixel_format);
found = 1;
}
#endif
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420 && !found)
{
int i;
/* for( i = 0; i < 2; i ++ )
{
d->codec[i] = avcodec_find_decoder( id );
if(!d->codec[i])
{ free(d); return NULL; }
d->codec[i] = avcodec_find_decoder( id );
if(!d->codec[i])
{ free(d); return NULL; }
d->context[i] = avcodec_alloc_context();
d->context[i]->width = width;
d->context[i]->height= height;
#if LIBAVFORMAT_BUILD > 5010
d->context[i]->time_base.den = fps;
d->context[i]->time_base.num = 1;
#else
d->context[i]->frame_rate = fps;
#endif
//@@@ sampling !
d->context[i]->pix_fmt = ( i == 0 ? PIX_FMT_YUV420P : PIX_FMT_YUV422P);
d->frame[i] = avcodec_alloc_frame();
}*/
d->codec = avcodec_find_decoder( id );
d->context = avcodec_alloc_context();
d->context->width = width;
d->context->height = height;
// d->context->time_base.den = fps;
// d->context->time_base.num = 1;
d->context->opaque = d;
d->context->palctrl = NULL;
d->frame = avcodec_alloc_frame();
@@ -421,12 +405,7 @@ vj_decoder *_el_new_decoder( int id , int width, int height, float fps, int pixe
{
veejay_msg(VEEJAY_MSG_INFO,"Sub/Super sampling to output pixel format");
d->sampler = subsample_init( width );
#ifdef SUPPORT_READ_DV2
if( id == CODEC_ID_DVVIDEO )
{
dv_decoder_ = vj_dv_decoder_init( 1, width, height, pixel_format );
}
#endif
}
d->tmp_buffer = (uint8_t*) vj_malloc(sizeof(uint8_t) * width * height * 4 );
@@ -450,19 +429,6 @@ vj_decoder *_el_new_decoder( int id , int width, int height, float fps, int pixe
memset( d->deinterlace_buffer[2], 0, width * height );
int i;
/* for(i = 0;i < 2 ; i ++ )
{
if(d->codec[i] != NULL)
{
if ( avcodec_open( d->context[i], d->codec[i] ) < 0 )
{
veejay_msg(VEEJAY_MSG_ERROR, "Error initializing decoder %d",id);
//@@!!
return NULL;
}
}
}*/
d->ref = 1;
return d;
}