mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-23 08:09:58 +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,
|
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)
|
uint8_t * Cb, uint8_t * Cr, int width, int height, int fmt)
|
||||||
{
|
{
|
||||||
|
|
||||||
int pitches[3];
|
int pitches[3];
|
||||||
|
|
||||||
if (!input_buf)
|
if (!input_buf)
|
||||||
return 0;
|
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;
|
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)
|
if (!((d->decoder->num_dif_seqs == 10)
|
||||||
|| (d->decoder->num_dif_seqs == 12)))
|
|| (d->decoder->num_dif_seqs == 12)))
|
||||||
|
{
|
||||||
|
veejay_msg(0, "Dont know how to handle %d dif seqs",
|
||||||
|
d->decoder->num_dif_seqs );
|
||||||
return 0;
|
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)
|
||||||
if (d->decoder->sampling == e_dv_sample_411 ||
|
|
||||||
d->decoder->sampling == e_dv_sample_422 ||
|
|
||||||
d->decoder->sampling == e_dv_sample_420)
|
|
||||||
{
|
{
|
||||||
pitches[0] = width * 2;
|
pitches[0] = width * 2;
|
||||||
pitches[1] = 0;
|
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,
|
dv_decode_full_frame(d->decoder, input_buf,
|
||||||
e_dv_color_yuv, pixels, pitches);
|
e_dv_color_yuv, pixels, pitches);
|
||||||
|
|
||||||
if(fmt == FMT_420)
|
frame_YUV422_to_planar( pixels, pixels[0], width, height, fmt );
|
||||||
yuy2toyv12(Y, Cb, Cr, d->dv_video, width, height);
|
|
||||||
else
|
|
||||||
yuy2toyv16(Y, Cb, Cr, d->dv_video, width, height);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
pitches[0] = width * 2;
|
|
||||||
pitches[1] = 0;
|
|
||||||
pitches[2] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if( d->decoder->sampling == e_dv_sample_420 )
|
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[0] = d->dv_video;
|
||||||
pixels[1] = d->dv_video + (width * height);
|
pixels[1] = d->dv_video + (width * height);
|
||||||
pixels[2] = d->dv_video + (width * height * 5)/4;
|
pixels[2] = d->dv_video + (width * height * 5)/4;
|
||||||
dv_decode_full_frame( d->decoder, input_buf, e_dv_color_yuv,
|
pitches[0] = width * 2;
|
||||||
pixels,pitches);
|
pitches[1] = 0;
|
||||||
if(fmt==FMT_422)
|
pitches[2] = 0;
|
||||||
yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height );
|
|
||||||
else
|
|
||||||
yuy2toyv12( Y,Cb,Cr, d->dv_video, width, height );
|
|
||||||
|
|
||||||
return 1;
|
dv_decode_full_frame( d->decoder, input_buf, e_dv_color_yuv, pixels,pitches);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if(fmt==FMT_422)
|
if(fmt==FMT_422)
|
||||||
yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height );
|
yuy2toyv16( Y,Cb,Cr, d->dv_video, width ,height );
|
||||||
else
|
else
|
||||||
yuy2toyv12( Y,Cb,Cr, d->dv_video, width, height );
|
yuy2toyv12( Y,Cb,Cr, d->dv_video, width, height );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ typedef struct
|
|||||||
dv_decoder_t *decoder;
|
dv_decoder_t *decoder;
|
||||||
uint8_t *dv_video;
|
uint8_t *dv_video;
|
||||||
int fmt;
|
int fmt;
|
||||||
|
int yuy2;
|
||||||
int audio;
|
int audio;
|
||||||
int16_t **audio_buffers;
|
int16_t **audio_buffers;
|
||||||
} vj_dv_decoder;
|
} vj_dv_decoder;
|
||||||
|
|||||||
@@ -349,47 +349,31 @@ vj_decoder *_el_new_decoder( int id , int width, int height, float fps, int pixe
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset( d, 0, sizeof(vj_decoder));
|
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",
|
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);
|
id,id,width,height,fps,pixel_format,out_fmt);
|
||||||
|
|
||||||
|
|
||||||
#ifdef SUPPORT_READ_DV2
|
#ifdef SUPPORT_READ_DV2
|
||||||
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420 && id != CODEC_ID_DVVIDEO)
|
if( id == CODEC_ID_DVVIDEO )
|
||||||
{
|
|
||||||
#else
|
|
||||||
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420)
|
|
||||||
{
|
{
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
|
if( id != CODEC_ID_YUV422 && id != CODEC_ID_YUV420 && !found)
|
||||||
|
{
|
||||||
int i;
|
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->codec = avcodec_find_decoder( id );
|
||||||
d->context = avcodec_alloc_context();
|
d->context = avcodec_alloc_context();
|
||||||
d->context->width = width;
|
d->context->width = width;
|
||||||
d->context->height = height;
|
d->context->height = height;
|
||||||
// d->context->time_base.den = fps;
|
|
||||||
// d->context->time_base.num = 1;
|
|
||||||
d->context->opaque = d;
|
d->context->opaque = d;
|
||||||
d->context->palctrl = NULL;
|
d->context->palctrl = NULL;
|
||||||
d->frame = avcodec_alloc_frame();
|
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");
|
veejay_msg(VEEJAY_MSG_INFO,"Sub/Super sampling to output pixel format");
|
||||||
d->sampler = subsample_init( width );
|
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 );
|
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 );
|
memset( d->deinterlace_buffer[2], 0, width * height );
|
||||||
|
|
||||||
int i;
|
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;
|
return d;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user