Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Suyu
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
many-archive
Suyu
Commits
8b8aa84e
There was an error fetching the commit references. Please try again later.
Commit
8b8aa84e
authored
1 year ago
by
Alessio
Committed by
Crimson Hawk
1 year ago
Browse files
Options
Downloads
Patches
Plain Diff
fix for amd video playback (green videos)
parent
95bd1120
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/video_core/host1x/ffmpeg/ffmpeg.cpp
+166
-4
166 additions, 4 deletions
src/video_core/host1x/ffmpeg/ffmpeg.cpp
with
166 additions
and
4 deletions
src/video_core/host1x/ffmpeg/ffmpeg.cpp
+
166
−
4
View file @
8b8aa84e
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
& 2024 suyu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include
"common/assert.h"
...
...
@@ -218,6 +218,165 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
return
true
;
}
// Nasty but allows linux builds to pass.
// Requires double checks when FFMPEG gets updated.
// Hopefully a future FFMPEG update will all and expose a solution in the public API.
namespace
{
typedef
struct
FFCodecDefault
{
const
char
*
key
;
const
char
*
value
;
}
FFCodecDefault
;
typedef
struct
FFCodec
{
/**
* The public AVCodec. See codec.h for it.
*/
AVCodec
p
;
/**
* Internal codec capabilities FF_CODEC_CAP_*.
*/
unsigned
caps_internal
:
29
;
/**
* This field determines the type of the codec (decoder/encoder)
* and also the exact callback cb implemented by the codec.
* cb_type uses enum FFCodecType values.
*/
unsigned
cb_type
:
3
;
int
priv_data_size
;
/**
* @name Frame-level threading support functions
* @{
*/
/**
* Copy necessary context variables from a previous thread context to the current one.
* If not defined, the next thread will start automatically; otherwise, the codec
* must call ff_thread_finish_setup().
*
* dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
*/
int
(
*
update_thread_context
)(
struct
AVCodecContext
*
dst
,
const
struct
AVCodecContext
*
src
);
/**
* Copy variables back to the user-facing context
*/
int
(
*
update_thread_context_for_user
)(
struct
AVCodecContext
*
dst
,
const
struct
AVCodecContext
*
src
);
/** @} */
/**
* Private codec-specific defaults.
*/
const
FFCodecDefault
*
defaults
;
/**
* Initialize codec static data, called from av_codec_iterate().
*
* This is not intended for time consuming operations as it is
* run for every codec regardless of that codec being used.
*/
void
(
*
init_static_data
)(
struct
FFCodec
*
codec
);
int
(
*
init
)(
struct
AVCodecContext
*
);
union
{
/**
* Decode to an AVFrame.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE.
*
* @param avctx codec context
* @param[out] frame AVFrame for output
* @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that
* a non-empty frame was returned in frame.
* @param[in] avpkt AVPacket containing the data to be decoded
* @return amount of bytes read from the packet on success,
* negative error code on failure
*/
int
(
*
decode
)(
struct
AVCodecContext
*
avctx
,
struct
AVFrame
*
frame
,
int
*
got_frame_ptr
,
struct
AVPacket
*
avpkt
);
/**
* Decode subtitle data to an AVSubtitle.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE_SUB.
*
* Apart from that this is like the decode callback.
*/
int
(
*
decode_sub
)(
struct
AVCodecContext
*
avctx
,
struct
AVSubtitle
*
sub
,
int
*
got_frame_ptr
,
const
struct
AVPacket
*
avpkt
);
/**
* Decode API with decoupled packet/frame dataflow.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_FRAME.
*
* This function is called to get one output frame. It should call
* ff_decode_get_packet() to obtain input data.
*/
int
(
*
receive_frame
)(
struct
AVCodecContext
*
avctx
,
struct
AVFrame
*
frame
);
/**
* Encode data to an AVPacket.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE
*
* @param avctx codec context
* @param[out] avpkt output AVPacket
* @param[in] frame AVFrame containing the input to be encoded
* @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
* non-empty packet was returned in avpkt.
* @return 0 on success, negative error code on failure
*/
int
(
*
encode
)(
struct
AVCodecContext
*
avctx
,
struct
AVPacket
*
avpkt
,
const
struct
AVFrame
*
frame
,
int
*
got_packet_ptr
);
/**
* Encode subtitles to a raw buffer.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE_SUB.
*/
int
(
*
encode_sub
)(
struct
AVCodecContext
*
avctx
,
uint8_t
*
buf
,
int
buf_size
,
const
struct
AVSubtitle
*
sub
);
/**
* Encode API with decoupled frame/packet dataflow.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_PACKET.
*
* This function is called to get one output packet.
* It should call ff_encode_get_frame() to obtain input data.
*/
int
(
*
receive_packet
)(
struct
AVCodecContext
*
avctx
,
struct
AVPacket
*
avpkt
);
}
cb
;
int
(
*
close
)(
struct
AVCodecContext
*
);
/**
* Flush buffers.
* Will be called when seeking
*/
void
(
*
flush
)(
struct
AVCodecContext
*
);
/**
* Decoding only, a comma-separated list of bitstream filters to apply to
* packets before decoding.
*/
const
char
*
bsfs
;
/**
* Array of pointers to hardware configurations supported by the codec,
* or NULL if no hardware supported. The array is terminated by a NULL
* pointer.
*
* The user can only access this field via avcodec_get_hw_config().
*/
const
struct
AVCodecHWConfigInternal
*
const
*
hw_configs
;
/**
* List of supported codec_tags, terminated by FF_CODEC_TAGS_END.
*/
const
uint32_t
*
codec_tags
;
}
FFCodec
;
static
av_always_inline
const
FFCodec
*
ffcodec
(
const
AVCodec
*
codec
)
{
return
(
const
FFCodec
*
)
codec
;
}
}
// namespace
bool
DecoderContext
::
SendPacket
(
const
Packet
&
packet
)
{
m_temp_frame
=
std
::
make_shared
<
Frame
>
();
m_got_frame
=
0
;
...
...
@@ -227,8 +386,10 @@ bool DecoderContext::SendPacket(const Packet& packet) {
#ifndef ANDROID
if
(
!
m_codec_context
->
hw_device_ctx
&&
m_codec_context
->
codec_id
==
AV_CODEC_ID_H264
)
{
m_decode_order
=
true
;
const
int
ret
=
avcodec_send_frame
(
m_codec_context
,
m_temp_frame
->
GetFrame
());
if
(
ret
<
0
)
{
auto
*
codec
{
ffcodec
(
m_decoder
.
GetCodec
())};
if
(
const
int
ret
=
codec
->
cb
.
decode
(
m_codec_context
,
m_temp_frame
->
GetFrame
(),
&
m_got_frame
,
packet
.
GetPacket
());
ret
<
0
)
{
LOG_DEBUG
(
Service_NVDRV
,
"avcodec_send_packet error {}"
,
AVError
(
ret
));
return
false
;
}
...
...
@@ -250,6 +411,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
#ifndef ANDROID
if
(
!
m_codec_context
->
hw_device_ctx
&&
m_codec_context
->
codec_id
==
AV_CODEC_ID_H264
)
{
m_decode_order
=
true
;
auto
*
codec
{
ffcodec
(
m_decoder
.
GetCodec
())};
int
ret
{
0
};
if
(
m_got_frame
==
0
)
{
...
...
@@ -257,7 +419,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto
*
pkt
=
packet
.
GetPacket
();
pkt
->
data
=
nullptr
;
pkt
->
size
=
0
;
ret
=
av
codec
_receive_packet
(
m_codec_context
,
pkt
);
ret
=
codec
->
cb
.
decode
(
m_codec_context
,
m_temp_frame
->
GetFrame
(),
&
m_got_frame
,
pkt
);
m_codec_context
->
has_b_frames
=
0
;
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment