mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Fix avcodec_align_dimensions to return values suitably aligned for FLV decoding
with SSE and add a avcodec_align_dimensions2 taht returns the stride alignment requirements independently from doing the width/height padding. Originally committed as revision 22095 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
1d53620311
commit
eb285cfe8e
@ -1367,7 +1367,7 @@ typedef struct AVCodecContext {
|
||||
/**
|
||||
* Called at the beginning of each frame to get a buffer for it.
|
||||
* If pic.reference is set then the frame will be read later by libavcodec.
|
||||
* avcodec_align_dimensions() should be used to find the required width and
|
||||
* avcodec_align_dimensions2() should be used to find the required width and
|
||||
* height, as they normally need to be rounded up to the next multiple of 16.
|
||||
* if CODEC_CAP_DR1 is not set then get_buffer() must call
|
||||
* avcodec_default_get_buffer() instead of providing buffers allocated by
|
||||
@ -3226,7 +3226,19 @@ AVFrame *avcodec_alloc_frame(void);
|
||||
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
|
||||
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
|
||||
int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
|
||||
/**
|
||||
* Modifies width and height values so that they will result in a memory
|
||||
* buffer that is acceptable for the codec if you do not use any horizontal
|
||||
* padding.
|
||||
*/
|
||||
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
|
||||
/**
|
||||
* Modifies width and height values so that they will result in a memory
|
||||
* buffer that is acceptable for the codec if you also ensure that all
|
||||
* line sizes are a multiple of the respective linesize_align[i].
|
||||
*/
|
||||
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
|
||||
int linesize_align[4]);
|
||||
|
||||
/**
|
||||
* Checks if the given dimension of a picture is valid, meaning that all
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/integer.h"
|
||||
#include "libavutil/crc.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "opt.h"
|
||||
@ -117,7 +118,7 @@ typedef struct InternalBuffer{
|
||||
|
||||
#define INTERNAL_BUFFER_SIZE 32
|
||||
|
||||
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
|
||||
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){
|
||||
int w_align= 1;
|
||||
int h_align= 1;
|
||||
|
||||
@ -180,6 +181,36 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
|
||||
*height= FFALIGN(*height, h_align);
|
||||
if(s->codec_id == CODEC_ID_H264)
|
||||
*height+=2; // some of the optimized chroma MC reads one line too much
|
||||
|
||||
linesize_align[0] =
|
||||
linesize_align[1] =
|
||||
linesize_align[2] =
|
||||
linesize_align[3] = STRIDE_ALIGN;
|
||||
//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes
|
||||
//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the
|
||||
//picture size unneccessarily in some cases. The solution here is not
|
||||
//pretty and better ideas are welcome!
|
||||
#if HAVE_MMX
|
||||
if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||
|
||||
s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||
|
||||
s->codec_id == CODEC_ID_VP6A) {
|
||||
linesize_align[0] =
|
||||
linesize_align[1] =
|
||||
linesize_align[2] = 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
|
||||
int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w;
|
||||
int linesize_align[4];
|
||||
int align;
|
||||
avcodec_align_dimensions2(s, width, height, linesize_align);
|
||||
align = FFMAX(linesize_align[0], linesize_align[3]);
|
||||
linesize_align[1] <<= chroma_shift;
|
||||
linesize_align[2] <<= chroma_shift;
|
||||
align = FFMAX3(align, linesize_align[1], linesize_align[2]);
|
||||
*width=FFALIGN(*width, align);
|
||||
}
|
||||
|
||||
int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){
|
||||
@ -244,7 +275,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
|
||||
|
||||
avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
|
||||
|
||||
avcodec_align_dimensions(s, &w, &h);
|
||||
avcodec_align_dimensions2(s, &w, &h, stride_align);
|
||||
|
||||
if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
|
||||
w+= EDGE_WIDTH*2;
|
||||
@ -260,18 +291,6 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
|
||||
|
||||
unaligned = 0;
|
||||
for (i=0; i<4; i++){
|
||||
//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes
|
||||
//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the
|
||||
//picture size unneccessarily in some cases. The solution here is not
|
||||
//pretty and better ideas are welcome!
|
||||
#if HAVE_MMX
|
||||
if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||
|
||||
s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||
|
||||
s->codec_id == CODEC_ID_VP6A)
|
||||
stride_align[i]= 16;
|
||||
else
|
||||
#endif
|
||||
stride_align[i] = STRIDE_ALIGN;
|
||||
unaligned |= picture.linesize[i] % stride_align[i];
|
||||
}
|
||||
} while (unaligned);
|
||||
|
Loading…
Reference in New Issue
Block a user