Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 07/04/16 14:23, Luca Barbato wrote: > From: Derek Buitenhuis > > Modifying global header extradata in encode_frame is an API violation > and only happens to work currently because mov writes its header > at the end of the file. > > Heavily based off of a patch from 2012 by Nicolas George. > > Signed-off-by: Derek Buitenhuis > Signed-off-by: Luca Barbato > --- > I'd push this if nobody has other comments. lu ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
[libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
From: Derek Buitenhuis Modifying global header extradata in encode_frame is an API violation and only happens to work currently because mov writes its header at the end of the file. Heavily based off of a patch from 2012 by Nicolas George. Signed-off-by: Derek Buitenhuis Signed-off-by: Luca Barbato --- Simplified using av_frame_get_buffer(). libavcodec/libxvid.c | 41 + 1 file changed, 41 insertions(+) diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index b352849..49952f5 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -85,6 +85,10 @@ struct xvid_ff_pass1 { struct xvid_context *context; /**< Pointer to private context */ }; +static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *picture, int *got_packet); + + /* * Xvid 2-Pass Kludge Section * @@ -677,6 +681,43 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->max_b_frames > 0 && !x->quicktime_format) xvid_enc_create.global |= XVID_GLOBAL_PACKED; +/* Encode a dummy frame to get the extradata immediately */ +if (x->quicktime_format) { +AVFrame *picture; +AVPacket packet; +int got_packet, ret; + +av_init_packet(&packet); + +picture = av_frame_alloc(); +if (!picture) +return AVERROR(ENOMEM); + +xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); +if (xerr) { +av_frame_free(&picture); +av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); +return AVERROR_UNKNOWN; +} +x->encoder_handle = xvid_enc_create.handle; + +picture->width = avctx->width; +picture->height = avctx->height; +picture->format = avctx->pix_fmt; + +if ((ret = av_frame_get_buffer(picture, 32)) < 0) { +xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); +av_frame_free(&picture); +return ret; +} + +ret = xvid_encode_frame(avctx, &packet, picture, &got_packet); +if (!ret && got_packet) +av_packet_unref(&packet); +av_frame_free(&picture); +xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); +} + /* Create encoder context */ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); if (xerr) { -- 2.6.1 ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 05/04/16 17:21, Derek Buitenhuis wrote: > +size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); > +picture->data[0] = av_malloc(size + size / 2); > +if (!picture->data[0]) { > +av_frame_free(&picture); > +return AVERROR(ENOMEM); > +} > +picture->data[1] = picture->data[0] + size; > +picture->data[2] = picture->data[1] + size / 4; > +memset(picture->data[0], 0, size); > +memset(picture->data[1], 128, size / 2); av_frame_get_buffer isn't safer? lu ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 4/6/2016 4:12 AM, Tim W. wrote: > It is ugly, but AFAICT that's libxvid's fault; other solution I can imagine > would be to create fake extradata like Anton did for QSV/HEVC/VPS, which is > a lot more work for little benefit. Definitely not worth it for this. Because SO many people encode xvid to not-AVI. -Derek ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On Tue, Apr 5, 2016 at 5:21 PM, Derek Buitenhuis wrote: > Modifying global header extradata in encode_frame is an API violation > and only happens to work currently because mov writes its header > at the end of the file. > > Heavily based off of a patch from 2012 by Nicolas George. > > Signed-off-by: Derek Buitenhuis > --- > Fixes encoding xvid to mov. > --- > libavcodec/libxvid.c | 41 + > 1 file changed, 41 insertions(+) LGTM except cosmetics already mentioned by Luca. It is ugly, but AFAICT that's libxvid's fault; other solution I can imagine would be to create fake extradata like Anton did for QSV/HEVC/VPS, which is a lot more work for little benefit. Tim ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 05/04/16 18:37, Derek Buitenhuis wrote: > On 4/5/2016 5:18 PM, Luca Barbato wrote: >>> +xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); >>> +if( xerr ) { >> >> Meh, I'll fix it for you if nothing else crops up. > > You should really explain *what* you'll fix, otherwise the review > is useless and I learn nothing new. if (err) { > >> >>> +av_frame_free(&picture); >>> +av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder >>> reference\n"); >>> +return AVERROR_UNKNOWN; >>> +} >>> +x->encoder_handle = xvid_enc_create.handle; >>> +size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); >> >> Same > > Same. Actually that one is fine albeit sufficiently strange. > It's not needed unless there is a global header. Same as x264 and x265. Sure then. ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 4/5/2016 5:18 PM, Luca Barbato wrote: >> +xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); >> +if( xerr ) { > > Meh, I'll fix it for you if nothing else crops up. You should really explain *what* you'll fix, otherwise the review is useless and I learn nothing new. > >> +av_frame_free(&picture); >> +av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder >> reference\n"); >> +return AVERROR_UNKNOWN; >> +} >> +x->encoder_handle = xvid_enc_create.handle; >> +size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); > > Same Same. > I guess, as ugly as it could be, it is a solution. I wonder if it > shouldn't be called always though. It's not needed unless there is a global header. Same as x264 and x265. ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
On 05/04/16 17:21, Derek Buitenhuis wrote: > Modifying global header extradata in encode_frame is an API violation > and only happens to work currently because mov writes its header > at the end of the file. > > Heavily based off of a patch from 2012 by Nicolas George. > > Signed-off-by: Derek Buitenhuis > --- > Fixes encoding xvid to mov. > --- > libavcodec/libxvid.c | 41 + > 1 file changed, 41 insertions(+) > > diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c > index b352849..8ae18ae 100644 > --- a/libavcodec/libxvid.c > +++ b/libavcodec/libxvid.c > @@ -85,6 +85,10 @@ struct xvid_ff_pass1 { > struct xvid_context *context; /**< Pointer to private context */ > }; > > +static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, > + const AVFrame *picture, int *got_packet); > + > + > /* > * Xvid 2-Pass Kludge Section > * > @@ -677,6 +681,43 @@ FF_ENABLE_DEPRECATION_WARNINGS > if (avctx->max_b_frames > 0 && !x->quicktime_format) > xvid_enc_create.global |= XVID_GLOBAL_PACKED; > > +/* Encode a dummy frame to get the extradata immediately */ > +if (x->quicktime_format) { > +AVFrame *picture; > +AVPacket packet; > +int size, got_packet, ret; > + > +av_init_packet(&packet); > + > +picture = av_frame_alloc(); > +if (!picture) > +return AVERROR(ENOMEM); > + > +xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); > +if( xerr ) { Meh, I'll fix it for you if nothing else crops up. > +av_frame_free(&picture); > +av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder > reference\n"); > +return AVERROR_UNKNOWN; > +} > +x->encoder_handle = xvid_enc_create.handle; > +size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); Same > +picture->data[0] = av_malloc(size + size / 2); > +if (!picture->data[0]) { > +av_frame_free(&picture); > +return AVERROR(ENOMEM); > +} > +picture->data[1] = picture->data[0] + size; > +picture->data[2] = picture->data[1] + size / 4; > +memset(picture->data[0], 0, size); > +memset(picture->data[1], 128, size / 2); > +ret = xvid_encode_frame(avctx, &packet, picture, &got_packet); > +if (!ret && got_packet) > +av_packet_unref(&packet); > +av_free(picture->data[0]); > +av_frame_free(&picture); > +xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); > +} > + > /* Create encoder context */ > xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); > if (xerr) { > I guess, as ugly as it could be, it is a solution. I wonder if it shouldn't be called always though. lu ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
[libav-devel] [PATCH] libxvid: Create extradata in init using a dummy frame
Modifying global header extradata in encode_frame is an API violation and only happens to work currently because mov writes its header at the end of the file. Heavily based off of a patch from 2012 by Nicolas George. Signed-off-by: Derek Buitenhuis --- Fixes encoding xvid to mov. --- libavcodec/libxvid.c | 41 + 1 file changed, 41 insertions(+) diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index b352849..8ae18ae 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -85,6 +85,10 @@ struct xvid_ff_pass1 { struct xvid_context *context; /**< Pointer to private context */ }; +static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *picture, int *got_packet); + + /* * Xvid 2-Pass Kludge Section * @@ -677,6 +681,43 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->max_b_frames > 0 && !x->quicktime_format) xvid_enc_create.global |= XVID_GLOBAL_PACKED; +/* Encode a dummy frame to get the extradata immediately */ +if (x->quicktime_format) { +AVFrame *picture; +AVPacket packet; +int size, got_packet, ret; + +av_init_packet(&packet); + +picture = av_frame_alloc(); +if (!picture) +return AVERROR(ENOMEM); + +xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); +if( xerr ) { +av_frame_free(&picture); +av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); +return AVERROR_UNKNOWN; +} +x->encoder_handle = xvid_enc_create.handle; +size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); +picture->data[0] = av_malloc(size + size / 2); +if (!picture->data[0]) { +av_frame_free(&picture); +return AVERROR(ENOMEM); +} +picture->data[1] = picture->data[0] + size; +picture->data[2] = picture->data[1] + size / 4; +memset(picture->data[0], 0, size); +memset(picture->data[1], 128, size / 2); +ret = xvid_encode_frame(avctx, &packet, picture, &got_packet); +if (!ret && got_packet) +av_packet_unref(&packet); +av_free(picture->data[0]); +av_frame_free(&picture); +xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); +} + /* Create encoder context */ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); if (xerr) { -- 2.8.0.rc3 ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel