diff options
Diffstat (limited to 'src/dxr3')
-rw-r--r-- | src/dxr3/ffmpeg_encoder.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/dxr3/ffmpeg_encoder.c b/src/dxr3/ffmpeg_encoder.c index aba8ddbd4..1dd912dba 100644 --- a/src/dxr3/ffmpeg_encoder.c +++ b/src/dxr3/ffmpeg_encoder.c @@ -47,6 +47,13 @@ #include "../combined/ffmpeg/ffmpeg_compat.h" +#if AVENCVIDEO == 1 +/* buffer size for encoded mpeg1 stream; will hold one intra frame + * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ +#define DEFAULT_BUFFER_SIZE 512*1024 +#endif + + /* functions required by encoder api */ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); @@ -57,6 +64,9 @@ typedef struct lavc_data_s { encoder_data_t encoder_data; AVCodecContext *context; /* handle for encoding */ int width, height; /* width and height of the video frame */ +#if AVENCVIDEO == 1 + uint8_t *ffmpeg_buffer; /* lavc buffer */ +#endif AVFrame *picture; /* picture to be encoded */ uint8_t *out[3]; /* aligned buffer for YV12 data */ uint8_t *buf; /* base address of YV12 buffer */ @@ -217,13 +227,27 @@ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) } lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); +#if AVENCVIDEO == 1 + if (!this->ffmpeg_buffer) + this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */ + if (!this->ffmpeg_buffer) { + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); + return 0; + } +#endif + return 1; } static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) { +#if AVENCVIDEO == 1 + int size; +#else /* 2 */ AVPacket pkt = { 0 }; int ret, got_output; +#endif lavc_data_t* this = (lavc_data_t *)drv->enc; ssize_t written; @@ -239,28 +263,53 @@ static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) lavc_prepare_frame(this, drv, frame); /* do the encoding */ +#if AVENCVIDEO == 1 + size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture); +#else /* 2 */ ret = avcodec_encode_video2(this->context, &pkt, this->picture, &got_output); +#endif frame->vo_frame.free(&frame->vo_frame); - if (ret < 0) { +#if AVENCVIDEO == 1 + if (size < 0) +#else /* 2 */ + if (ret < 0) +#endif + { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: encoding failed\n"); return 0; - } else if (!got_output) + } +#if AVENCVIDEO == 2 + else if (!got_output) return 1; +#endif +#if AVENCVIDEO == 1 + written = write(drv->fd_video, this->ffmpeg_buffer, size); +#else written = write(drv->fd_video, pkt.data, pkt.size); +#endif + if (written < 0) { +#if AVENCVIDEO == 2 av_packet_unref(&pkt); +#endif xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); return 0; } +#if AVENCVIDEO == 1 + if (written != size) + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, size); +#else /* 2 */ if (written != pkt.size) xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, pkt.size); av_packet_unref(&pkt); +#endif return 1; } |