mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-23 00:00:02 +01:00
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:
@@ -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)
|
||||
int pitches[3];
|
||||
if (!input_buf)
|
||||
return 0;
|
||||
|
||||
if (dv_parse_header(d->decoder, input_buf) < 0)
|
||||
if (dv_parse_header(d->decoder, input_buf) < 0)
|
||||
{
|
||||
veejay_msg(0, "Unable to read DV header");
|
||||
return 0;
|
||||
}
|
||||
if (!((d->decoder->num_dif_seqs == 10)
|
||||
|| (d->decoder->num_dif_seqs == 12)))
|
||||
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->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;
|
||||
}
|
||||
|
||||
if (d->decoder->sampling == e_dv_sample_411 || d->decoder->sampling == e_dv_sample_422)
|
||||
{
|
||||
pitches[0] = width * 2;
|
||||
pitches[1] = 0;
|
||||
@@ -220,52 +288,32 @@ 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 )
|
||||
{
|
||||
uint8_t *pixels[3];
|
||||
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 );
|
||||
|
||||
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);
|
||||
pixels[0] = d->dv_video;
|
||||
pixels[1] = d->dv_video + (width * height);
|
||||
pixels[2] = d->dv_video + (width * height * 5)/4;
|
||||
pitches[0] = width * 2;
|
||||
pitches[1] = 0;
|
||||
pitches[2] = 0;
|
||||
|
||||
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 );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,20 +429,7 @@ 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;
|
||||
d->ref = 1;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user