Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
external
ffmpeg
Commits
d55c2e05
Commit
d55c2e05
authored
May 30, 2012
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avtools: move buffer management code from avconv to cmdutils.
It will be used by avplay.
parent
3ffa2335
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
172 additions
and
142 deletions
+172
-142
avconv.c
avconv.c
+0
-142
cmdutils.c
cmdutils.c
+130
-0
cmdutils.h
cmdutils.h
+42
-0
No files found.
avconv.c
View file @
d55c2e05
...
...
@@ -171,19 +171,6 @@ typedef struct FilterGraph {
int
nb_outputs
;
}
FilterGraph
;
typedef
struct
FrameBuffer
{
uint8_t
*
base
[
4
];
uint8_t
*
data
[
4
];
int
linesize
[
4
];
int
h
,
w
;
enum
PixelFormat
pix_fmt
;
int
refcount
;
struct
FrameBuffer
**
pool
;
///< head of the buffer pool
struct
FrameBuffer
*
next
;
}
FrameBuffer
;
typedef
struct
InputStream
{
int
file_index
;
AVStream
*
st
;
...
...
@@ -449,135 +436,6 @@ static void reset_options(OptionsContext *o)
init_opts
();
}
static
int
alloc_buffer
(
FrameBuffer
**
pool
,
AVCodecContext
*
s
,
FrameBuffer
**
pbuf
)
{
FrameBuffer
*
buf
=
av_mallocz
(
sizeof
(
*
buf
));
int
i
,
ret
;
const
int
pixel_size
=
av_pix_fmt_descriptors
[
s
->
pix_fmt
].
comp
[
0
].
step_minus1
+
1
;
int
h_chroma_shift
,
v_chroma_shift
;
int
edge
=
32
;
// XXX should be avcodec_get_edge_width(), but that fails on svq1
int
w
=
s
->
width
,
h
=
s
->
height
;
if
(
!
buf
)
return
AVERROR
(
ENOMEM
);
if
(
!
(
s
->
flags
&
CODEC_FLAG_EMU_EDGE
))
{
w
+=
2
*
edge
;
h
+=
2
*
edge
;
}
avcodec_align_dimensions
(
s
,
&
w
,
&
h
);
if
((
ret
=
av_image_alloc
(
buf
->
base
,
buf
->
linesize
,
w
,
h
,
s
->
pix_fmt
,
32
))
<
0
)
{
av_freep
(
&
buf
);
return
ret
;
}
/* XXX this shouldn't be needed, but some tests break without this line
* those decoders are buggy and need to be fixed.
* the following tests fail:
* cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
*/
memset
(
buf
->
base
[
0
],
128
,
ret
);
avcodec_get_chroma_sub_sample
(
s
->
pix_fmt
,
&
h_chroma_shift
,
&
v_chroma_shift
);
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
buf
->
data
);
i
++
)
{
const
int
h_shift
=
i
==
0
?
0
:
h_chroma_shift
;
const
int
v_shift
=
i
==
0
?
0
:
v_chroma_shift
;
if
(
s
->
flags
&
CODEC_FLAG_EMU_EDGE
)
buf
->
data
[
i
]
=
buf
->
base
[
i
];
else
buf
->
data
[
i
]
=
buf
->
base
[
i
]
+
FFALIGN
((
buf
->
linesize
[
i
]
*
edge
>>
v_shift
)
+
(
pixel_size
*
edge
>>
h_shift
),
32
);
}
buf
->
w
=
s
->
width
;
buf
->
h
=
s
->
height
;
buf
->
pix_fmt
=
s
->
pix_fmt
;
buf
->
pool
=
pool
;
*
pbuf
=
buf
;
return
0
;
}
static
void
free_buffer_pool
(
FrameBuffer
**
pool
)
{
FrameBuffer
*
buf
=
*
pool
;
while
(
buf
)
{
*
pool
=
buf
->
next
;
av_freep
(
&
buf
->
base
[
0
]);
av_free
(
buf
);
buf
=
*
pool
;
}
}
static
void
unref_buffer
(
FrameBuffer
*
buf
)
{
FrameBuffer
**
pool
=
buf
->
pool
;
av_assert0
(
buf
->
refcount
);
buf
->
refcount
--
;
if
(
!
buf
->
refcount
)
{
buf
->
next
=
*
pool
;
*
pool
=
buf
;
}
}
static
int
codec_get_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
)
{
FrameBuffer
**
pool
=
s
->
opaque
;
FrameBuffer
*
buf
;
int
ret
,
i
;
if
(
!*
pool
&&
(
ret
=
alloc_buffer
(
pool
,
s
,
pool
))
<
0
)
return
ret
;
buf
=
*
pool
;
*
pool
=
buf
->
next
;
buf
->
next
=
NULL
;
if
(
buf
->
w
!=
s
->
width
||
buf
->
h
!=
s
->
height
||
buf
->
pix_fmt
!=
s
->
pix_fmt
)
{
av_freep
(
&
buf
->
base
[
0
]);
av_free
(
buf
);
if
((
ret
=
alloc_buffer
(
pool
,
s
,
&
buf
))
<
0
)
return
ret
;
}
buf
->
refcount
++
;
frame
->
opaque
=
buf
;
frame
->
type
=
FF_BUFFER_TYPE_USER
;
frame
->
extended_data
=
frame
->
data
;
frame
->
pkt_pts
=
s
->
pkt
?
s
->
pkt
->
pts
:
AV_NOPTS_VALUE
;
frame
->
width
=
buf
->
w
;
frame
->
height
=
buf
->
h
;
frame
->
format
=
buf
->
pix_fmt
;
frame
->
sample_aspect_ratio
=
s
->
sample_aspect_ratio
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
buf
->
data
);
i
++
)
{
frame
->
base
[
i
]
=
buf
->
base
[
i
];
// XXX h264.c uses base though it shouldn't
frame
->
data
[
i
]
=
buf
->
data
[
i
];
frame
->
linesize
[
i
]
=
buf
->
linesize
[
i
];
}
return
0
;
}
static
void
codec_release_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
)
{
FrameBuffer
*
buf
=
frame
->
opaque
;
int
i
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
frame
->
data
);
i
++
)
frame
->
data
[
i
]
=
NULL
;
unref_buffer
(
buf
);
}
static
void
filter_release_buffer
(
AVFilterBuffer
*
fb
)
{
FrameBuffer
*
buf
=
fb
->
priv
;
av_free
(
fb
);
unref_buffer
(
buf
);
}
/**
* Define a function for building a string containing a list of
* allowed formats,
...
...
cmdutils.c
View file @
d55c2e05
...
...
@@ -37,6 +37,7 @@
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
#include "libavutil/imgutils.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
...
...
@@ -1041,3 +1042,132 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
}
return
array
;
}
static
int
alloc_buffer
(
FrameBuffer
**
pool
,
AVCodecContext
*
s
,
FrameBuffer
**
pbuf
)
{
FrameBuffer
*
buf
=
av_mallocz
(
sizeof
(
*
buf
));
int
i
,
ret
;
const
int
pixel_size
=
av_pix_fmt_descriptors
[
s
->
pix_fmt
].
comp
[
0
].
step_minus1
+
1
;
int
h_chroma_shift
,
v_chroma_shift
;
int
edge
=
32
;
// XXX should be avcodec_get_edge_width(), but that fails on svq1
int
w
=
s
->
width
,
h
=
s
->
height
;
if
(
!
buf
)
return
AVERROR
(
ENOMEM
);
if
(
!
(
s
->
flags
&
CODEC_FLAG_EMU_EDGE
))
{
w
+=
2
*
edge
;
h
+=
2
*
edge
;
}
avcodec_align_dimensions
(
s
,
&
w
,
&
h
);
if
((
ret
=
av_image_alloc
(
buf
->
base
,
buf
->
linesize
,
w
,
h
,
s
->
pix_fmt
,
32
))
<
0
)
{
av_freep
(
&
buf
);
return
ret
;
}
/* XXX this shouldn't be needed, but some tests break without this line
* those decoders are buggy and need to be fixed.
* the following tests fail:
* cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
*/
memset
(
buf
->
base
[
0
],
128
,
ret
);
avcodec_get_chroma_sub_sample
(
s
->
pix_fmt
,
&
h_chroma_shift
,
&
v_chroma_shift
);
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
buf
->
data
);
i
++
)
{
const
int
h_shift
=
i
==
0
?
0
:
h_chroma_shift
;
const
int
v_shift
=
i
==
0
?
0
:
v_chroma_shift
;
if
(
s
->
flags
&
CODEC_FLAG_EMU_EDGE
)
buf
->
data
[
i
]
=
buf
->
base
[
i
];
else
buf
->
data
[
i
]
=
buf
->
base
[
i
]
+
FFALIGN
((
buf
->
linesize
[
i
]
*
edge
>>
v_shift
)
+
(
pixel_size
*
edge
>>
h_shift
),
32
);
}
buf
->
w
=
s
->
width
;
buf
->
h
=
s
->
height
;
buf
->
pix_fmt
=
s
->
pix_fmt
;
buf
->
pool
=
pool
;
*
pbuf
=
buf
;
return
0
;
}
int
codec_get_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
)
{
FrameBuffer
**
pool
=
s
->
opaque
;
FrameBuffer
*
buf
;
int
ret
,
i
;
if
(
!*
pool
&&
(
ret
=
alloc_buffer
(
pool
,
s
,
pool
))
<
0
)
return
ret
;
buf
=
*
pool
;
*
pool
=
buf
->
next
;
buf
->
next
=
NULL
;
if
(
buf
->
w
!=
s
->
width
||
buf
->
h
!=
s
->
height
||
buf
->
pix_fmt
!=
s
->
pix_fmt
)
{
av_freep
(
&
buf
->
base
[
0
]);
av_free
(
buf
);
if
((
ret
=
alloc_buffer
(
pool
,
s
,
&
buf
))
<
0
)
return
ret
;
}
buf
->
refcount
++
;
frame
->
opaque
=
buf
;
frame
->
type
=
FF_BUFFER_TYPE_USER
;
frame
->
extended_data
=
frame
->
data
;
frame
->
pkt_pts
=
s
->
pkt
?
s
->
pkt
->
pts
:
AV_NOPTS_VALUE
;
frame
->
width
=
buf
->
w
;
frame
->
height
=
buf
->
h
;
frame
->
format
=
buf
->
pix_fmt
;
frame
->
sample_aspect_ratio
=
s
->
sample_aspect_ratio
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
buf
->
data
);
i
++
)
{
frame
->
base
[
i
]
=
buf
->
base
[
i
];
// XXX h264.c uses base though it shouldn't
frame
->
data
[
i
]
=
buf
->
data
[
i
];
frame
->
linesize
[
i
]
=
buf
->
linesize
[
i
];
}
return
0
;
}
static
void
unref_buffer
(
FrameBuffer
*
buf
)
{
FrameBuffer
**
pool
=
buf
->
pool
;
av_assert0
(
buf
->
refcount
);
buf
->
refcount
--
;
if
(
!
buf
->
refcount
)
{
buf
->
next
=
*
pool
;
*
pool
=
buf
;
}
}
void
codec_release_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
)
{
FrameBuffer
*
buf
=
frame
->
opaque
;
int
i
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
frame
->
data
);
i
++
)
frame
->
data
[
i
]
=
NULL
;
unref_buffer
(
buf
);
}
void
filter_release_buffer
(
AVFilterBuffer
*
fb
)
{
FrameBuffer
*
buf
=
fb
->
priv
;
av_free
(
fb
);
unref_buffer
(
buf
);
}
void
free_buffer_pool
(
FrameBuffer
**
pool
)
{
FrameBuffer
*
buf
=
*
pool
;
while
(
buf
)
{
*
pool
=
buf
->
next
;
av_freep
(
&
buf
->
base
[
0
]);
av_free
(
buf
);
buf
=
*
pool
;
}
}
cmdutils.h
View file @
d55c2e05
...
...
@@ -383,4 +383,46 @@ void exit_program(int ret);
*/
void
*
grow_array
(
void
*
array
,
int
elem_size
,
int
*
size
,
int
new_size
);
typedef
struct
FrameBuffer
{
uint8_t
*
base
[
4
];
uint8_t
*
data
[
4
];
int
linesize
[
4
];
int
h
,
w
;
enum
PixelFormat
pix_fmt
;
int
refcount
;
struct
FrameBuffer
**
pool
;
///< head of the buffer pool
struct
FrameBuffer
*
next
;
}
FrameBuffer
;
/**
* Get a frame from the pool. This is intended to be used as a callback for
* AVCodecContext.get_buffer.
*
* @param s codec context. s->opaque must be a pointer to the head of the
* buffer pool.
* @param frame frame->opaque will be set to point to the FrameBuffer
* containing the frame data.
*/
int
codec_get_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
);
/**
* A callback to be used for AVCodecContext.release_buffer along with
* codec_get_buffer().
*/
void
codec_release_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
);
/**
* A callback to be used for AVFilterBuffer.free.
* @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer
* containing the buffer data.
*/
void
filter_release_buffer
(
AVFilterBuffer
*
fb
);
/**
* Free all the buffers in the pool. This must be called after all the
* buffers have been released.
*/
void
free_buffer_pool
(
FrameBuffer
**
pool
);
#endif
/* LIBAV_CMDUTILS_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment