mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-14 20:00:01 +01:00
fixed a problem in negotiating image resolution and pixel format, fixed jpeg decoding
This commit is contained in:
@@ -118,7 +118,7 @@ typedef struct
|
|||||||
int frames_done[N_FRAMES];
|
int frames_done[N_FRAMES];
|
||||||
int frameidx;
|
int frameidx;
|
||||||
int frame_ready;
|
int frame_ready;
|
||||||
uint8_t *tmpbuf;
|
uint8_t *tmpbuf[3];
|
||||||
int is_streaming;
|
int is_streaming;
|
||||||
int pause_read;
|
int pause_read;
|
||||||
int pause_capture;
|
int pause_capture;
|
||||||
@@ -483,7 +483,7 @@ static void v4l2_enum_frame_sizes( v4l2info *v )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int v4l2_tryout_pixel_format( v4l2info *v, int pf, int w, int h )
|
static int v4l2_tryout_pixel_format( v4l2info *v, int pf, int w, int h, int *src_w, int *src_h, int *src_pf )
|
||||||
{
|
{
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
memset( &format, 0, sizeof(format));
|
memset( &format, 0, sizeof(format));
|
||||||
@@ -518,14 +518,18 @@ static int v4l2_tryout_pixel_format( v4l2info *v, int pf, int w, int h )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
veejay_msg(VEEJAY_MSG_INFO,"v4l2: Device supports capture in %4.4s (%dx%d)",
|
veejay_msg(VEEJAY_MSG_DEBUG,"v4l2: Query %dx%d in %d, device supports capture in %4.4s (%dx%d)",
|
||||||
|
w,h,pf,
|
||||||
(char*) &format.fmt.pix.pixelformat,
|
(char*) &format.fmt.pix.pixelformat,
|
||||||
format.fmt.pix.width,
|
format.fmt.pix.width,
|
||||||
format.fmt.pix.height
|
format.fmt.pix.height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
*src_w = format.fmt.pix.width;
|
||||||
|
*src_h = format.fmt.pix.height;
|
||||||
|
*src_pf = format.fmt.pix.pixelformat;
|
||||||
|
|
||||||
return 1;
|
return ( pf == format.fmt.pix.pixelformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v4l2_setup_jpeg_capture(v4l2info *v, int wid, int hei)
|
static void v4l2_setup_jpeg_capture(v4l2info *v, int wid, int hei)
|
||||||
@@ -535,7 +539,11 @@ static void v4l2_setup_jpeg_capture(v4l2info *v, int wid, int hei)
|
|||||||
jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DQT; // DQT
|
jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DQT; // DQT
|
||||||
ioctl(v->fd, VIDIOC_S_JPEGCOMP, &jpegcomp);
|
ioctl(v->fd, VIDIOC_S_JPEGCOMP, &jpegcomp);
|
||||||
v->is_jpeg = 1;
|
v->is_jpeg = 1;
|
||||||
v->tmpbuf = (uint8_t*) vj_malloc(sizeof(uint8_t) * wid * hei * 3 );
|
veejay_msg(VEEJAY_MSG_DEBUG, "v4l2: configure temporary buffer for jpeg decoding: %dx%d" , wid,hei );
|
||||||
|
|
||||||
|
v->tmpbuf[0] = (uint8_t*) vj_malloc(sizeof(uint8_t) * wid * hei * 3 );
|
||||||
|
v->tmpbuf[1] = v->tmpbuf[0] + (wid * hei);
|
||||||
|
v->tmpbuf[2] = v->tmpbuf[1] + (wid * hei);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int v4l2_setup_avcodec_capture( v4l2info *v, int wid, int hei, int codec_id )
|
static int v4l2_setup_avcodec_capture( v4l2info *v, int wid, int hei, int codec_id )
|
||||||
@@ -559,7 +567,10 @@ static int v4l2_setup_avcodec_capture( v4l2info *v, int wid, int hei, int codec_
|
|||||||
v->picture->data[0] = vj_malloc(wid * hei + wid);
|
v->picture->data[0] = vj_malloc(wid * hei + wid);
|
||||||
v->picture->data[1] = vj_malloc(wid * hei + wid);
|
v->picture->data[1] = vj_malloc(wid * hei + wid);
|
||||||
v->picture->data[2] = vj_malloc(wid * hei + wid);
|
v->picture->data[2] = vj_malloc(wid * hei + wid);
|
||||||
v->tmpbuf = (uint8_t*) vj_malloc(sizeof(uint8_t) * wid * hei * 3 );
|
v->tmpbuf[0] = (uint8_t*) vj_malloc(sizeof(uint8_t) * wid * hei * 3 );
|
||||||
|
v->tmpbuf[1] = v->tmpbuf[0] + (wid * hei);
|
||||||
|
v->tmpbuf[2] = v->tmpbuf[1] + (wid * hei);
|
||||||
|
|
||||||
if( v->codec->capabilities & CODEC_CAP_TRUNCATED)
|
if( v->codec->capabilities & CODEC_CAP_TRUNCATED)
|
||||||
v->c->flags |= CODEC_FLAG_TRUNCATED;
|
v->c->flags |= CODEC_FLAG_TRUNCATED;
|
||||||
|
|
||||||
@@ -571,66 +582,60 @@ static int v4l2_setup_avcodec_capture( v4l2info *v, int wid, int hei, int codec_
|
|||||||
free(v->picture->data[2]);
|
free(v->picture->data[2]);
|
||||||
free(v->picture);
|
free(v->picture);
|
||||||
av_free(v->c);
|
av_free(v->c);
|
||||||
free(v->tmpbuf);
|
free(v->tmpbuf[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int v4l2_negotiate_pixel_format( v4l2info *v, int host_fmt, int wid, int hei, uint32_t *candidate)
|
static int v4l2_negotiate_pixel_format( v4l2info *v, int host_fmt, int wid, int hei, uint32_t *candidate, uint32_t *dw, uint32_t *dh)
|
||||||
{
|
{
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
|
||||||
int native_pixel_format = v4l2_ffmpeg2v4l2( host_fmt );
|
int native_pixel_format = v4l2_ffmpeg2v4l2( host_fmt );
|
||||||
|
|
||||||
char *greycap = getenv( "VEEJAY_V4L2_GREYSCALE_ONLY" );
|
char *greycap = getenv( "VEEJAY_V4L2_GREYSCALE_ONLY" );
|
||||||
|
|
||||||
//@ does user want grey scale capture
|
//@ does user want grey scale capture
|
||||||
if( greycap ) {
|
if( greycap ) {
|
||||||
int gc = atoi(greycap);
|
int gc = atoi(greycap);
|
||||||
if( gc == 1 ) {
|
if( gc == 1 ) {
|
||||||
int have_gs = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_GREY, wid,hei );
|
int have_gs = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_GREY, wid,hei,dw,dh, candidate );
|
||||||
if( have_gs ) {
|
if( have_gs ) {
|
||||||
veejay_msg(VEEJAY_MSG_DEBUG, "v4l2: Setting grey scale (env)");
|
veejay_msg(VEEJAY_MSG_DEBUG, "v4l2: Setting grey scale (env)");
|
||||||
v->grey=1;
|
v->grey=1;
|
||||||
*candidate = V4L2_PIX_FMT_GREY;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ does capture card support our native format
|
//@ does capture card support our native format
|
||||||
|
int supported = v4l2_tryout_pixel_format( v, native_pixel_format, wid, hei,dw,dh,candidate );
|
||||||
|
if( supported ) {
|
||||||
|
veejay_msg(VEEJAY_MSG_DEBUG, "v4l2: Capture device supports native format" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int supported = v4l2_tryout_pixel_format( v, native_pixel_format, wid, hei );
|
|
||||||
if( supported ) {
|
|
||||||
*candidate = native_pixel_format;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@ does capture support YUYV or UYVU
|
//@ does capture support YUYV or UYVU
|
||||||
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_YUYV, wid, hei );
|
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_YUYV, wid, hei,dw,dh,candidate );
|
||||||
if( supported ) {
|
if( supported ) {
|
||||||
*candidate = V4L2_PIX_FMT_YUYV;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_UYVY, wid, hei );
|
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_UYVY, wid, hei,dw,dh,candidate );
|
||||||
if( supported ) {
|
if( supported ) {
|
||||||
*candidate = V4L2_PIX_FMT_UYVY;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ or RGB 24/32
|
//@ or RGB 24/32
|
||||||
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_RGB24, wid, hei );
|
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_RGB24, wid, hei ,dw,dh,candidate);
|
||||||
if( supported ) {
|
if( supported ) {
|
||||||
*candidate = V4L2_PIX_FMT_RGB24;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_RGB32, wid, hei );
|
supported = v4l2_tryout_pixel_format( v, V4L2_PIX_FMT_RGB32, wid, hei,dw,dh,candidate );
|
||||||
if( supported ) {
|
if( supported ) {
|
||||||
*candidate = V4L2_PIX_FMT_RGB32;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,14 +648,15 @@ static int v4l2_negotiate_pixel_format( v4l2info *v, int host_fmt, int wid, int
|
|||||||
|
|
||||||
if( v->supported_pixel_formats[k] == V4L2_PIX_FMT_JPEG ) {
|
if( v->supported_pixel_formats[k] == V4L2_PIX_FMT_JPEG ) {
|
||||||
v4l2_setup_jpeg_capture( v, wid,hei );
|
v4l2_setup_jpeg_capture( v, wid,hei );
|
||||||
*candidate = V4L2_PIX_FMT_YUV420;
|
*candidate = V4L2_PIX_FMT_JPEG;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( v->supported_pixel_formats[k] == V4L2_PIX_FMT_MJPEG) {
|
if( v->supported_pixel_formats[k] == V4L2_PIX_FMT_MJPEG) {
|
||||||
if( v4l2_setup_avcodec_capture( v, wid,hei, CODEC_ID_MJPEG ) == 0 )
|
if( v4l2_setup_avcodec_capture( v, wid,hei, CODEC_ID_MJPEG ) == 0 )
|
||||||
continue;
|
continue;
|
||||||
*candidate = V4L2_PIX_FMT_YUV420;
|
*candidate = v->supported_pixel_formats[k];
|
||||||
|
veejay_msg(VEEJAY_MSG_DEBUG, "v4l2: Using MJPEG decoder" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,10 +676,12 @@ static int v4l2_configure_format( v4l2info *v, int host_fmt, int wid, int hei )
|
|||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
|
||||||
uint32_t cap_pf = 0;
|
uint32_t cap_pf = 0;
|
||||||
|
uint32_t src_wid = 0;
|
||||||
|
uint32_t src_hei = 0;
|
||||||
|
|
||||||
memset( &format, 0, sizeof(format));
|
memset( &format, 0, sizeof(format));
|
||||||
|
|
||||||
int res = v4l2_negotiate_pixel_format(v, host_fmt, wid, hei, &cap_pf );
|
int res = v4l2_negotiate_pixel_format(v, host_fmt, wid, hei, &cap_pf, &src_wid, &src_hei );
|
||||||
|
|
||||||
if( res == 0 ) {
|
if( res == 0 ) {
|
||||||
veejay_msg(VEEJAY_MSG_ERROR, "v4l2: sorry but I don't know how to handle your capture device just yet!");
|
veejay_msg(VEEJAY_MSG_ERROR, "v4l2: sorry but I don't know how to handle your capture device just yet!");
|
||||||
@@ -682,18 +690,26 @@ static int v4l2_configure_format( v4l2info *v, int host_fmt, int wid, int hei )
|
|||||||
|
|
||||||
if( res == 1 ) {
|
if( res == 1 ) {
|
||||||
v->format.fmt.pix.pixelformat = cap_pf;
|
v->format.fmt.pix.pixelformat = cap_pf;
|
||||||
v->format.fmt.pix.width = wid;
|
v->format.fmt.pix.width = src_wid;
|
||||||
v->format.fmt.pix.height = hei;
|
v->format.fmt.pix.height = src_hei;
|
||||||
|
|
||||||
v->info = yuv_yuv_template( NULL,NULL,NULL,wid, hei,
|
v->info = yuv_yuv_template( NULL,NULL,NULL,src_wid, src_hei,
|
||||||
v4l2_pixelformat2ffmpeg( cap_pf ) );
|
v4l2_pixelformat2ffmpeg( cap_pf ) );
|
||||||
|
|
||||||
yuv_plane_sizes( v->info, &(v->planes[0]),&(v->planes[1]),&(v->planes[2]),&(v->planes[3]) );
|
yuv_plane_sizes( v->info, &(v->planes[0]),&(v->planes[1]),&(v->planes[2]),&(v->planes[3]) );
|
||||||
|
|
||||||
veejay_msg(VEEJAY_MSG_INFO, "v4l2: Final configuration is in %s (%dx%d)",
|
veejay_msg(VEEJAY_MSG_INFO, "v4l2: Using scaler, destination format is in %s (%dx%d), source is in %dx%d",
|
||||||
(char*) &cap_pf,
|
(char*) &cap_pf,
|
||||||
wid,
|
wid,
|
||||||
hei );
|
hei, src_wid,src_hei );
|
||||||
|
|
||||||
|
if( cap_pf == V4L2_PIX_FMT_JPEG ) {
|
||||||
|
v->info->data[0] = v->tmpbuf[0];
|
||||||
|
v->info->data[1] = v->tmpbuf[1];
|
||||||
|
v->info->data[2] = v->tmpbuf[2];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1141,52 +1157,45 @@ static int v4l2_pull_frame_intern( v4l2info *v )
|
|||||||
|
|
||||||
int got_picture = 0;
|
int got_picture = 0;
|
||||||
|
|
||||||
switch(v->is_jpeg) {
|
if(!v->is_jpeg)
|
||||||
case 1:
|
v4l2_set_output_pointers( v,src );
|
||||||
#ifdef HAVE_JPEG
|
|
||||||
v4l2_set_output_pointers(v,v->tmpbuf);
|
|
||||||
length = decode_jpeg_raw( src, n, 0,0, v->info->width,v->info->height,v->info->data[0],v->info->data[1],v->info->data[2] );
|
|
||||||
if( length == 0 ) { //@ success
|
|
||||||
length = 1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
veejay_msg(0, "v4l2: veejay was compiled without libjpeg");
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// length = avcodec_decode_video( v->c, v->picture, &got_picture, v->tmpbuf,src );
|
|
||||||
length = -1;
|
|
||||||
if( length == -1 ) {
|
|
||||||
veejay_msg(0,"v4l2: error while decoding frame");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
v->info->data[0] = v->picture->data[0];
|
|
||||||
v->info->data[1] = v->picture->data[1];
|
|
||||||
v->info->data[2] = v->picture->data[2];
|
|
||||||
|
|
||||||
break;
|
if( v->scaler == NULL )
|
||||||
default:
|
{
|
||||||
v4l2_set_output_pointers(v,src);
|
sws_template templ;
|
||||||
break;
|
memset(&templ,0,sizeof(sws_template));
|
||||||
|
templ.flags = yuv_which_scaler();
|
||||||
|
v->scaler = yuv_init_swscaler( v->info,v->frames[ 0 ], &templ, yuv_sws_get_cpu_flags() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( v->scaler == NULL )
|
if( v->is_jpeg == 1 ) {
|
||||||
{
|
length = decode_jpeg_raw( src, n, 0,0, v->info->width,v->info->height,v->info->data[0],v->info->data[1],v->info->data[2] );
|
||||||
sws_template templ;
|
if( length == 0 ) { //@ success
|
||||||
memset(&templ,0,sizeof(sws_template));
|
length = 1;
|
||||||
templ.flags = yuv_which_scaler();
|
|
||||||
v->scaler = yuv_init_swscaler( v->info,v->frames[ 0 ], &templ, yuv_sws_get_cpu_flags() );
|
|
||||||
}
|
}
|
||||||
|
} else if( v->is_jpeg == 2 ) {
|
||||||
yuv_convert_and_scale( v->scaler, v->info, v->frames[ v->frameidx ] );
|
AVPacket pkt;
|
||||||
|
veejay_memset( &pkt, 0, sizeof(AVPacket));
|
||||||
lock_(v->video_info);
|
pkt.data = src;
|
||||||
|
pkt.size = n;
|
||||||
|
|
||||||
|
length = avcodec_decode_video2( v->c, v->picture, &got_picture, &pkt );
|
||||||
|
if( length == -1 ) {
|
||||||
|
veejay_msg(0,"v4l2: error while decoding mjpeg frame");
|
||||||
|
}
|
||||||
|
v->info->data[0] = v->picture->data[0];
|
||||||
|
v->info->data[1] = v->picture->data[1];
|
||||||
|
v->info->data[2] = v->picture->data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
yuv_convert_and_scale( v->scaler, v->info, v->frames[ v->frameidx ] );
|
||||||
|
|
||||||
|
lock_(v->video_info);
|
||||||
v->frames_done[v->frameidx] = 1;
|
v->frames_done[v->frameidx] = 1;
|
||||||
v->frame_ready = v->frameidx;
|
v->frame_ready = v->frameidx;
|
||||||
v->frameidx = (v->frameidx + 1) % N_FRAMES;
|
v->frameidx = (v->frameidx + 1) % N_FRAMES;
|
||||||
unlock_(v->video_info);
|
unlock_(v->video_info);
|
||||||
signal_(v->video_info);
|
signal_(v->video_info);
|
||||||
|
|
||||||
if(!v->rw) {
|
if(!v->rw) {
|
||||||
if( -1 == vioctl( v->fd, VIDIOC_QBUF, &(v->buffer))) {
|
if( -1 == vioctl( v->fd, VIDIOC_QBUF, &(v->buffer))) {
|
||||||
@@ -1252,36 +1261,41 @@ int v4l2_pull_frame(void *vv,VJFrame *dst)
|
|||||||
|
|
||||||
int got_picture = 0;
|
int got_picture = 0;
|
||||||
|
|
||||||
switch(v->is_jpeg) {
|
if(!v->is_jpeg)
|
||||||
#ifdef HAVE_JPEG
|
v4l2_set_output_pointers( v,src );
|
||||||
case 1:
|
|
||||||
v4l2_set_output_pointers(v,v->tmpbuf);
|
|
||||||
length = decode_jpeg_raw( src, n, 0,0, v->info->width,v->info->height,v->info->data[0],v->info->data[1],v->info->data[2] );
|
|
||||||
if( length == 0 ) { //@ success
|
|
||||||
length = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 2:
|
|
||||||
//length = avcodec_decode_video( v->c, v->picture, &got_picture, v->tmpbuf,src );
|
|
||||||
length = -1;
|
|
||||||
if( length == -1 ) {
|
|
||||||
veejay_msg(0,"v4l2: error while decoding frame");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
v->info->data[0] = v->picture->data[0];
|
|
||||||
v->info->data[1] = v->picture->data[1];
|
|
||||||
v->info->data[2] = v->picture->data[2];
|
|
||||||
|
|
||||||
break;
|
if( v->scaler == NULL )
|
||||||
default:
|
{
|
||||||
v4l2_set_output_pointers(v,src);
|
sws_template templ;
|
||||||
break;
|
memset(&templ,0,sizeof(sws_template));
|
||||||
|
templ.flags = yuv_which_scaler();
|
||||||
|
v->scaler = yuv_init_swscaler( v->info,v->frames[ 0 ], &templ, yuv_sws_get_cpu_flags() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( v->is_jpeg == 1 ) {
|
||||||
|
length = decode_jpeg_raw( src, n, 0,0, v->info->width,v->info->height,v->info->data[0],v->info->data[1],v->info->data[2] );
|
||||||
|
if( length == 0 ) { //@ success
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
} else if( v->is_jpeg ==2 ) {
|
||||||
|
AVPacket pkt;
|
||||||
|
veejay_memset( &pkt, 0, sizeof(AVPacket));
|
||||||
|
pkt.data = src;
|
||||||
|
pkt.size = n;
|
||||||
|
|
||||||
|
length = avcodec_decode_video2( v->c, v->picture, &got_picture, &pkt );
|
||||||
|
if( length == -1 ) {
|
||||||
|
veejay_msg(0,"v4l2: error while decoding frame");
|
||||||
|
}
|
||||||
|
v->info->data[0] = v->picture->data[0];
|
||||||
|
v->info->data[1] = v->picture->data[1];
|
||||||
|
v->info->data[2] = v->picture->data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
yuv_convert_and_scale( v->scaler, v->info, v->frames[ v->frameidx ] );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( length > 0 ) {
|
|
||||||
yuv_convert_and_scale( v->scaler, v->info, dst );
|
|
||||||
}
|
|
||||||
if(!v->rw) {
|
if(!v->rw) {
|
||||||
if( -1 == vioctl( v->fd, VIDIOC_QBUF, &(v->buffer))) {
|
if( -1 == vioctl( v->fd, VIDIOC_QBUF, &(v->buffer))) {
|
||||||
veejay_msg(0, "v4l2: VIDIOC_QBUF failed with %s", strerror(errno));
|
veejay_msg(0, "v4l2: VIDIOC_QBUF failed with %s", strerror(errno));
|
||||||
@@ -1338,8 +1352,8 @@ void v4l2_close( void *d )
|
|||||||
if(v->c) {
|
if(v->c) {
|
||||||
av_free(v->c);
|
av_free(v->c);
|
||||||
}
|
}
|
||||||
if(v->tmpbuf) {
|
if(v->tmpbuf[0]) {
|
||||||
free(v->tmpbuf);
|
free(v->tmpbuf[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(v->codec) {
|
if(v->codec) {
|
||||||
|
|||||||
Reference in New Issue
Block a user