Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
1b05ac22
Commit
1b05ac22
authored
Dec 31, 2013
by
Nicolas George
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavf: add write_uncoded_frame() API.
parent
6c12b1de
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
4 deletions
+138
-4
avformat.h
libavformat/avformat.h
+49
-0
internal.h
libavformat/internal.h
+14
-0
mux.c
libavformat/mux.c
+75
-4
No files found.
libavformat/avformat.h
View file @
1b05ac22
...
...
@@ -512,6 +512,17 @@ typedef struct AVOutputFormat {
*/
int
(
*
control_message
)(
struct
AVFormatContext
*
s
,
int
type
,
void
*
data
,
size_t
data_size
);
/**
* Write an uncoded AVFrame.
*
* See av_write_uncoded_frame() for details.
*
* The library will free *frame afterwards, but the muxer can prevent it
* by setting the pointer to NULL.
*/
int
(
*
write_uncoded_frame
)(
struct
AVFormatContext
*
,
int
stream_index
,
AVFrame
**
frame
,
unsigned
flags
);
}
AVOutputFormat
;
/**
* @}
...
...
@@ -2092,6 +2103,44 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt);
*/
int
av_interleaved_write_frame
(
AVFormatContext
*
s
,
AVPacket
*
pkt
);
/**
* Write a uncoded frame to an output media file.
*
* The frame must be correctly interleaved according to the container
* specification; if not, then av_interleaved_write_frame() must be used.
*
* See av_interleaved_write_frame() for details.
*/
int
av_write_uncoded_frame
(
AVFormatContext
*
s
,
int
stream_index
,
AVFrame
*
frame
);
/**
* Write a uncoded frame to an output media file.
*
* If the muxer supports it, this function allows to write an AVFrame
* structure directly, without encoding it into a packet.
* It is mostly useful for devices and similar special muxers that use raw
* video or PCM data and will not serialize it into a byte stream.
*
* To test whether it is possible to use it with a given muxer and stream,
* use av_write_uncoded_frame_query().
*
* The caller gives up ownership of the frame and must not access it
* afterwards.
*
* @return >=0 for success, a negative code on error
*/
int
av_interleaved_write_uncoded_frame
(
AVFormatContext
*
s
,
int
stream_index
,
AVFrame
*
frame
);
/**
* Test whether a muxer supports uncoded frame.
*
* @return >=0 if an uncoded frame can be written to that muxer and stream,
* <0 if not
*/
int
av_write_uncoded_frame_query
(
AVFormatContext
*
s
,
int
stream_index
);
/**
* Write the stream trailer to an output media file and free the
* file private data.
...
...
libavformat/internal.h
View file @
1b05ac22
...
...
@@ -398,4 +398,18 @@ int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t dts);
void
ff_rfps_calculate
(
AVFormatContext
*
ic
);
/**
* Flags for AVFormatContext.write_uncoded_frame()
*/
enum
AVWriteUncodedFrameFlags
{
/**
* Query whether the feature is possible on this stream.
* The frame argument is ignored.
*/
AV_WRITE_UNCODED_FRAME_QUERY
=
0x0001
,
};
#endif
/* AVFORMAT_INTERNAL_H */
libavformat/mux.c
View file @
1b05ac22
...
...
@@ -417,6 +417,15 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
return
0
;
}
#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
/* Note: using sizeof(AVFrame) from outside lavu is unsafe in general, but
it is only being used internally to this file as a consistency check.
The value is chosen to be very unlikely to appear on its own and to cause
immediate failure if used anywhere as a real size. */
#define UNCODED_FRAME_PACKET_SIZE (INT_MIN / 3 * 2 + (int)sizeof(AVFrame))
//FIXME merge with compute_pkt_fields
static
int
compute_pkt_fields2
(
AVFormatContext
*
s
,
AVStream
*
st
,
AVPacket
*
pkt
)
{
...
...
@@ -482,7 +491,9 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
/* update pts */
switch
(
st
->
codec
->
codec_type
)
{
case
AVMEDIA_TYPE_AUDIO
:
frame_size
=
ff_get_audio_frame_size
(
st
->
codec
,
pkt
->
size
,
1
);
frame_size
=
(
pkt
->
flags
&
AV_PKT_FLAG_UNCODED_FRAME
)
?
((
AVFrame
*
)
pkt
->
data
)
->
nb_samples
:
ff_get_audio_frame_size
(
st
->
codec
,
pkt
->
size
,
1
);
/* HACK/FIXME, we skip the initial 0 size packets as they are most
* likely equal to the encoder delay, but it would be better if we
...
...
@@ -549,7 +560,14 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
}
did_split
=
av_packet_split_side_data
(
pkt
);
ret
=
s
->
oformat
->
write_packet
(
s
,
pkt
);
if
((
pkt
->
flags
&
AV_PKT_FLAG_UNCODED_FRAME
))
{
AVFrame
*
frame
=
(
AVFrame
*
)
pkt
->
data
;
av_assert0
(
pkt
->
size
==
UNCODED_FRAME_PACKET_SIZE
);
ret
=
s
->
oformat
->
write_uncoded_frame
(
s
,
pkt
->
stream_index
,
&
frame
,
0
);
av_frame_free
(
&
frame
);
}
else
{
ret
=
s
->
oformat
->
write_packet
(
s
,
pkt
);
}
if
(
s
->
flush_packets
&&
s
->
pb
&&
ret
>=
0
&&
s
->
flags
&
AVFMT_FLAG_FLUSH_PACKETS
)
avio_flush
(
s
->
pb
);
...
...
@@ -632,8 +650,13 @@ FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt
->
buf
=
NULL
;
av_dup_packet
(
&
this_pktl
->
pkt
);
// duplicate the packet if it uses non-allocated memory
av_copy_packet_side_data
(
&
this_pktl
->
pkt
,
&
this_pktl
->
pkt
);
// copy side data
if
((
pkt
->
flags
&
AV_PKT_FLAG_UNCODED_FRAME
))
{
av_assert0
(
pkt
->
size
==
UNCODED_FRAME_PACKET_SIZE
);
av_assert0
(((
AVFrame
*
)
pkt
->
data
)
->
buf
);
}
else
{
av_dup_packet
(
&
this_pktl
->
pkt
);
// duplicate the packet if it uses non-allocated memory
av_copy_packet_side_data
(
&
this_pktl
->
pkt
,
&
this_pktl
->
pkt
);
// copy side data
}
if
(
s
->
streams
[
pkt
->
stream_index
]
->
last_in_packet_buffer
)
{
next_point
=
&
(
st
->
last_in_packet_buffer
->
next
);
...
...
@@ -932,3 +955,51 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
dst
->
streams
[
dst_stream
]
->
time_base
);
return
av_write_frame
(
dst
,
&
local_pkt
);
}
static
int
av_write_uncoded_frame_internal
(
AVFormatContext
*
s
,
int
stream_index
,
AVFrame
*
frame
,
int
interleaved
)
{
AVPacket
pkt
,
*
pktp
;
av_assert0
(
s
->
oformat
);
if
(
!
s
->
oformat
->
write_uncoded_frame
)
return
AVERROR
(
ENOSYS
);
if
(
!
frame
)
{
pktp
=
NULL
;
}
else
{
pktp
=
&
pkt
;
av_init_packet
(
&
pkt
);
pkt
.
data
=
(
void
*
)
frame
;
pkt
.
size
=
UNCODED_FRAME_PACKET_SIZE
;
pkt
.
pts
=
pkt
.
dts
=
frame
->
pts
;
pkt
.
duration
=
av_frame_get_pkt_duration
(
frame
);
pkt
.
stream_index
=
stream_index
;
pkt
.
flags
|=
AV_PKT_FLAG_UNCODED_FRAME
;
}
return
interleaved
?
av_interleaved_write_frame
(
s
,
pktp
)
:
av_write_frame
(
s
,
pktp
);
}
int
av_write_uncoded_frame
(
AVFormatContext
*
s
,
int
stream_index
,
AVFrame
*
frame
)
{
return
av_write_uncoded_frame_internal
(
s
,
stream_index
,
frame
,
0
);
}
int
av_interleaved_write_uncoded_frame
(
AVFormatContext
*
s
,
int
stream_index
,
AVFrame
*
frame
)
{
return
av_write_uncoded_frame_internal
(
s
,
stream_index
,
frame
,
1
);
}
int
av_write_uncoded_frame_query
(
AVFormatContext
*
s
,
int
stream_index
)
{
av_assert0
(
s
->
oformat
);
if
(
!
s
->
oformat
->
write_uncoded_frame
)
return
AVERROR
(
ENOSYS
);
return
s
->
oformat
->
write_uncoded_frame
(
s
,
stream_index
,
NULL
,
AV_WRITE_UNCODED_FRAME_QUERY
);
}
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