diff --git a/ffmpeg.c b/ffmpeg.c index b9fb2b11..54b2ef6c 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -79,6 +79,64 @@ void my_frame_free(AVFrame *frame){ av_freep(&frame); #endif } +/*********************************************/ +int my_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height){ + int retcd = 0; +#if (LIBAVFORMAT_VERSION_MAJOR >= 57) + int align = 1; + retcd = av_image_get_buffer_size(pix_fmt, width, height, align); +#else + retcd = avpicture_get_size(pix_fmt, width, height); +#endif + return retcd; +} +/*********************************************/ +int my_image_copy_to_buffer(AVFrame *frame, uint8_t *buffer_ptr, enum AVPixelFormat pix_fmt,int width, int height,int dest_size){ + int retcd = 0; +#if (LIBAVFORMAT_VERSION_MAJOR >= 57) + int align = 1; + retcd = av_image_copy_to_buffer((uint8_t *)buffer_ptr,dest_size + ,(const uint8_t * const*)frame,frame->linesize,pix_fmt,width,height,align); +#else + retcd = avpicture_layout((const AVPicture*)frame,pix_fmt,width,height + ,(unsigned char *)buffer_ptr,dest_size); +#endif + return retcd; +} +/*********************************************/ +int my_image_fill_arrays(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height){ + int retcd = 0; +#if (LIBAVFORMAT_VERSION_MAJOR >= 57) + int align = 1; + retcd = av_image_fill_arrays( + frame->data + ,frame->linesize + ,buffer_ptr + ,pix_fmt + ,width + ,height + ,align + ); +#else + retcd = avpicture_fill( + (AVPicture *)frame + ,buffer_ptr + ,pix_fmt + ,width + ,height); +#endif + return retcd; +} +/*********************************************/ +void my_packet_unref(AVPacket pkt){ +#if (LIBAVFORMAT_VERSION_MAJOR >= 57) + av_packet_unref(&pkt); +#else + av_free_packet(&pkt); +#endif +} +/*********************************************/ + /**************************************************************************** **************************************************************************** ****************************************************************************/ @@ -219,7 +277,7 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename, AVCodecContext *c; AVCodec *codec; struct ffmpeg *ffmpeg; - int ret; + int retcd; char errstr[128]; AVDictionary *opts = 0; @@ -312,9 +370,9 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename, } pthread_mutex_lock(&global_lock); - ret = avcodec_open2(c, codec, &opts); + retcd = avcodec_open2(c, codec, &opts); pthread_mutex_unlock(&global_lock); - if (ret < 0) { + if (retcd < 0) { if (codec->supported_framerates) { const AVRational *fps = codec->supported_framerates; while (fps->num) { @@ -324,14 +382,14 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename, } int chkrate = 1; pthread_mutex_lock(&global_lock); - while ((chkrate < 36) && (ret != 0)) { + while ((chkrate < 36) && (retcd != 0)) { c->time_base.den = chkrate; - ret = avcodec_open2(c, codec, &opts); + retcd = avcodec_open2(c, codec, &opts); chkrate++; } pthread_mutex_unlock(&global_lock); - if (ret < 0){ - av_strerror(ret, errstr, sizeof(errstr)); + if (retcd < 0){ + av_strerror(retcd, errstr, sizeof(errstr)); MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: Could not open codec %s",errstr); av_dict_free(&opts); ffmpeg_cleanups(ffmpeg); @@ -399,7 +457,13 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename, * we write the data via standard file I/O so we close the * items here */ - avformat_write_header(ffmpeg->oc, NULL); + retcd = avformat_write_header(ffmpeg->oc, NULL); + if (retcd < 0){ + av_strerror(retcd, errstr, sizeof(errstr)); + MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: Could not write ffmpeg header %s",errstr); + ffmpeg_cleanups(ffmpeg); + return NULL; + } if (ffmpeg->tlapse == TIMELAPSE_APPEND) { av_write_trailer(ffmpeg->oc); avio_close(ffmpeg->oc->pb); @@ -573,7 +637,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){ } if (got_packet_ptr == 0){ //Buffered packet. Throw special return code - av_free_packet(&pkt); + my_packet_unref(pkt); return -2; } if (pkt.pts != AV_NOPTS_VALUE) @@ -590,7 +654,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){ } else { retcd = av_write_frame(ffmpeg->oc, &pkt); } - av_free_packet(&pkt); + my_packet_unref(pkt); if (retcd != 0) { MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error while writing video frame"); @@ -617,12 +681,12 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){ ffmpeg->video_outbuf_size, pic); if (retcd < 0 ){ MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error encoding video"); - av_free_packet(&pkt); + my_packet_unref(pkt); return -1; } if (retcd == 0 ){ // No bytes encoded => buffered=>special handling - av_free_packet(&pkt); + my_packet_unref(pkt); return -2; } @@ -637,7 +701,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){ } else { retcd = av_write_frame(ffmpeg->oc, &pkt); } - av_free_packet(&pkt); + my_packet_unref(pkt); if (retcd != 0) { MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error while writing video frame"); diff --git a/ffmpeg.h b/ffmpeg.h index c1e372fc..b93dfb95 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -10,6 +10,7 @@ #include #include +#include #include #if (LIBAVFORMAT_VERSION_MAJOR >= 56) @@ -91,6 +92,11 @@ int ffmpeg_put_frame(struct ffmpeg *, AVFrame *); void ffmpeg_cleanups(struct ffmpeg *); AVFrame *ffmpeg_prepare_frame(struct ffmpeg *, unsigned char *, unsigned char *, unsigned char *); +int my_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height); +int my_image_copy_to_buffer(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height,int dest_size); +int my_image_fill_arrays(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height); +void my_packet_unref(AVPacket pkt); + #endif #endif /* _INCLUDE_FFMPEG_H_ */ diff --git a/netcam_rtsp.c b/netcam_rtsp.c index 671a1a95..356517d2 100644 --- a/netcam_rtsp.c +++ b/netcam_rtsp.c @@ -133,10 +133,10 @@ static void netcam_buffsize_rtsp(netcam_buff_ptr buff, size_t numbytes){ static int decode_packet(AVPacket *packet, netcam_buff_ptr buffer, AVFrame *frame, AVCodecContext *cc){ int check = 0; int frame_size = 0; - int ret = 0; + int retcd = 0; - ret = avcodec_decode_video2(cc, frame, &check, packet); - if (ret < 0) { + retcd = avcodec_decode_video2(cc, frame, &check, packet); + if (retcd < 0) { MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error decoding video packet"); return 0; } @@ -145,12 +145,15 @@ static int decode_packet(AVPacket *packet, netcam_buff_ptr buffer, AVFrame *fram return 0; } - frame_size = avpicture_get_size(cc->pix_fmt, cc->width, cc->height); + frame_size = my_image_get_buffer_size(cc->pix_fmt, cc->width, cc->height); netcam_buffsize_rtsp(buffer, frame_size); - avpicture_layout((const AVPicture*)frame,cc->pix_fmt,cc->width,cc->height - ,(unsigned char *)buffer->ptr,frame_size ); + retcd = my_image_copy_to_buffer(frame, (uint8_t *)buffer->ptr,cc->pix_fmt,cc->width,cc->height, frame_size); + if (retcd < 0) { + MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error decoding video packet: Copying to buffer"); + return 0; + } buffer->used = frame_size; @@ -313,7 +316,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){ netcam->rtsp->readingframe = 1; while (size_decoded == 0 && av_read_frame(netcam->rtsp->format_context, &packet) >= 0) { if(packet.stream_index != netcam->rtsp->video_stream_index) { - av_free_packet(&packet); + my_packet_unref(packet); av_init_packet(&packet); packet.data = NULL; packet.size = 0; @@ -322,7 +325,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){ } size_decoded = decode_packet(&packet, buffer, netcam->rtsp->frame, netcam->rtsp->codec_context); - av_free_packet(&packet); + my_packet_unref(packet); av_init_packet(&packet); packet.data = NULL; packet.size = 0; @@ -330,7 +333,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){ netcam->rtsp->readingframe = 0; // at this point, we are finished with the packet - av_free_packet(&packet); + my_packet_unref(packet); if (size_decoded == 0) { // something went wrong, end of stream? Interupted? @@ -575,17 +578,17 @@ int netcam_rtsp_open_sws(netcam_context_ptr netcam){ return -1; } - netcam->rtsp->swsframe_size = avpicture_get_size( + netcam->rtsp->swsframe_size = my_image_get_buffer_size( MY_PIX_FMT_YUV420P ,netcam->width ,netcam->height); - if (netcam->rtsp->swsframe_size <= 0) { - if (netcam->rtsp->status == RTSP_NOTCONNECTED){ - MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error determining size of frame out"); - } - netcam_rtsp_close_context(netcam); - return -1; + if (netcam->rtsp->swsframe_size <= 0) { + if (netcam->rtsp->status == RTSP_NOTCONNECTED){ + MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error determining size of frame out"); } + netcam_rtsp_close_context(netcam); + return -1; + } return 0; @@ -611,8 +614,8 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){ char errstr[128]; uint8_t *buffer_out; - retcd = avpicture_fill( - (AVPicture*)netcam->rtsp->swsframe_in + retcd=my_image_fill_arrays( + netcam->rtsp->swsframe_in ,(uint8_t*)netcam->latest->ptr ,netcam->rtsp->codec_context->pix_fmt ,netcam->rtsp->codec_context->width @@ -629,8 +632,8 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){ buffer_out=(uint8_t *)av_malloc(netcam->rtsp->swsframe_size*sizeof(uint8_t)); - retcd = avpicture_fill( - (AVPicture*)netcam->rtsp->swsframe_out + retcd=my_image_fill_arrays( + netcam->rtsp->swsframe_out ,buffer_out ,MY_PIX_FMT_YUV420P ,netcam->width @@ -661,13 +664,13 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){ return -1; } - retcd = avpicture_layout( - (const AVPicture*)netcam->rtsp->swsframe_out + retcd=my_image_copy_to_buffer( + netcam->rtsp->swsframe_out + ,(uint8_t *)image ,MY_PIX_FMT_YUV420P ,netcam->width ,netcam->height - ,(unsigned char *)image - ,netcam->rtsp->swsframe_size ); + ,netcam->rtsp->swsframe_size); if (retcd < 0) { if (netcam->rtsp->status == RTSP_NOTCONNECTED){ av_strerror(retcd, errstr, sizeof(errstr)); @@ -874,7 +877,7 @@ int netcam_setup_rtsp(netcam_context_ptr netcam, struct url_t *url){ av_register_all(); avcodec_register_all(); pthread_mutex_unlock(&global_lock); - + /* * The RTSP context should be all ready to attempt a connection with * the server, so we try ....