수색…
소개
인코딩 된 미디어 스트림에서 원본 비디오 / 오디오 가져 오기.
스트림 찾기
미디어 스트림 컨테이너에는 일반적으로 비디오 스트림 및 오디오 스트림과 같은 여러 스트림이 있습니다. 예를 들어, 다음을 사용하여 오디오 스트림을 가져올 수 있습니다.
// A Format Context - see Reading Data for more info
AVFormatContext *formatContext;
// Inspect packets of stream to determine properties
if (avformat_find_stream_info(formatContext, NULL) < 0){
// Error finding info
}
// Find the stream and its codec
AVCodec* audioCodec;
int audioStreamIndex = av_find_best_stream(
formatContext, // The media stream
AVMEDIA_TYPE_AUDIO, // The type of stream we are looking for - audio for example
-1, // Desired stream number, -1 for any
-1, // Number of related stream, -1 for none
&audioCodec, // Gets the codec associated with the stream, can be NULL
0 // Flags - not used currently
);
if(audioStreamIndex = AVERROR_STREAM_NOT_FOUND || !audioCodec){
// Error finding audio (ie. no audio stream?)
}
다른 유형의 스트림을 얻으려면 스트림 유형을 바꾸면됩니다. 유효한 유형은 다음과 같습니다.
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_SUBTITLE,
AVMEDIA_TYPE_DATA, // Usually continuous
AVMEDIA_TYPE_ATTACHMENT, // Usually sparse
코덱 컨텍스트 열기
스트림 포맷 컨텍스트와 해당 코덱이 있으면 다음 코드를 사용하여 디코딩 할 수 있습니다.
// The format context and codec, given - see Find a stream for how to get these
AVFormatContext *formatContext;
AVCodec* codec;
int streamIndex;
// Get the codec context
AVCodecContext *codecContext = avcodec_alloc_context3(codec);
if (!codecContext){
// Out of memory
avformat_close_input(&formatContext);
}
// Set the parameters of the codec context from the stream
int result = avcodec_parameters_to_context(
codecContext,
formatContext->streams[streamIndex]->codecpar
);
if(result < 0){
// Failed to set parameters
avformat_close_input(&formatContext);
avcodec_free_context(&codecContext);
}
// Ready to open stream based on previous parameters
// Third parameter (NULL) is optional dictionary settings
if (avcodec_open2(codecContext, codec, NULL) < 0){
// Cannot open the video codec
codecContext = nullptr;
}
// Do something with the opened codec context... (ie decode frames through the context)
프레임 디코딩
코덱 컨텍스트와 미디어 스트림에서 인코딩 된 패킷이 제공된 경우 미디어를 원시 프레임으로 디코딩 할 수 있습니다. 단일 프레임을 디코딩하려면 다음 코드를 사용할 수 있습니다.
// A codec context, and some encoded data packet from a stream/file, given.
AVCodecContext *codecContext; // See Open a codec context
AVPacket *packet; // See the Reading Media topic
// Send the data packet to the decoder
int sendPacketResult = avcodec_send_packet(codecContext, packet);
if (sendPacketResult == AVERROR(EAGAIN)){
// Decoder can't take packets right now. Make sure you are draining it.
}else if (sendPacketResult < 0){
// Failed to send the packet to the decoder
}
// Get decoded frame from decoder
AVFrame *frame = av_frame_alloc();
int decodeFrame = avcodec_receive_frame(codecContext, frame);
if (decodeFrame == AVERROR(EAGAIN)){
// The decoder doesn't have enough data to produce a frame
// Not an error unless we reached the end of the stream
// Just pass more packets until it has enough to produce a frame
av_frame_unref(frame);
av_freep(frame);
}else if (decodeFrame < 0){
// Failed to get a frame from the decoder
av_frame_unref(frame);
av_freep(frame);
}
// Use the frame (ie. display it)
모든 프레임을 디코드하려면 이전 코드를 루프에 넣고 연속 패킷을 보내면됩니다.
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow