Something went wrong. Try again.
🎥 Command line media player
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211#include <libavutil/frame.h>
#include "audio/aframe.h"#include "common/av_common.h"#include "demux/packet.h"#include "video/mp_image.h"
#include "frame.h"
struct frame_handler { const char *name; bool is_data; bool is_signaling; void *(*new_ref)(void *data); double (*get_pts)(void *data); void (*set_pts)(void *data, double pts); int (*approx_size)(void *data); AVFrame *(*new_av_ref)(void *data); void *(*from_av_ref)(AVFrame *data); void (*free)(void *data);};
static void *video_ref(void *data){ return mp_image_new_ref(data);}
static double video_get_pts(void *data){ return ((struct mp_image *)data)->pts;}
static void video_set_pts(void *data, double pts){ ((struct mp_image *)data)->pts = pts;}
static int video_approx_size(void *data){ return mp_image_approx_byte_size(data);}
static AVFrame *video_new_av_ref(void *data){ return mp_image_to_av_frame(data);}
static void *video_from_av_ref(AVFrame *data){ return mp_image_from_av_frame(data);}
static void *audio_ref(void *data){ return mp_aframe_new_ref(data);}
static double audio_get_pts(void *data){ return mp_aframe_get_pts(data);}
static void audio_set_pts(void *data, double pts){ mp_aframe_set_pts(data, pts);}
static int audio_approx_size(void *data){ return mp_aframe_approx_byte_size(data);}
static AVFrame *audio_new_av_ref(void *data){ return mp_aframe_to_avframe(data);}
static void *audio_from_av_ref(AVFrame *data){ return mp_aframe_from_avframe(data);}
static void *packet_ref(void *data){ return demux_copy_packet(NULL, data);}
static const struct frame_handler frame_handlers[] = { [MP_FRAME_NONE] = { .name = "none", }, [MP_FRAME_EOF] = { .name = "eof", .is_signaling = true, }, [MP_FRAME_VIDEO] = { .name = "video", .is_data = true, .new_ref = video_ref, .get_pts = video_get_pts, .set_pts = video_set_pts, .approx_size = video_approx_size, .new_av_ref = video_new_av_ref, .from_av_ref = video_from_av_ref, .free = talloc_free, }, [MP_FRAME_AUDIO] = { .name = "audio", .is_data = true, .new_ref = audio_ref, .get_pts = audio_get_pts, .set_pts = audio_set_pts, .approx_size = audio_approx_size, .new_av_ref = audio_new_av_ref, .from_av_ref = audio_from_av_ref, .free = talloc_free, }, [MP_FRAME_PACKET] = { .name = "packet", .is_data = true, .new_ref = packet_ref, .free = talloc_free, },};
const char *mp_frame_type_str(enum mp_frame_type t){ return frame_handlers[t].name;}
bool mp_frame_is_data(struct mp_frame frame){ return frame_handlers[frame.type].is_data;}
bool mp_frame_is_signaling(struct mp_frame frame){ return frame_handlers[frame.type].is_signaling;}
void mp_frame_unref(struct mp_frame *frame){ if (!frame) return;
if (frame_handlers[frame->type].free) frame_handlers[frame->type].free(frame->data);
*frame = (struct mp_frame){0};}
struct mp_frame mp_frame_ref(struct mp_frame frame){ if (frame_handlers[frame.type].new_ref) { assert(frame.data); frame.data = frame_handlers[frame.type].new_ref(frame.data); if (!frame.data) frame.type = MP_FRAME_NONE; } return frame;}
double mp_frame_get_pts(struct mp_frame frame){ if (frame_handlers[frame.type].get_pts) return frame_handlers[frame.type].get_pts(frame.data); return MP_NOPTS_VALUE;}
void mp_frame_set_pts(struct mp_frame frame, double pts){ if (frame_handlers[frame.type].get_pts) frame_handlers[frame.type].set_pts(frame.data, pts);}
int mp_frame_approx_size(struct mp_frame frame){ if (frame_handlers[frame.type].approx_size) return frame_handlers[frame.type].approx_size(frame.data); return 0;}
AVFrame *mp_frame_to_av(struct mp_frame frame, struct AVRational *tb){ if (!frame_handlers[frame.type].new_av_ref) return NULL;
AVFrame *res = frame_handlers[frame.type].new_av_ref(frame.data); if (!res) return NULL;
res->pts = mp_pts_to_av(mp_frame_get_pts(frame), tb); return res;}
struct mp_frame mp_frame_from_av(enum mp_frame_type type, struct AVFrame *frame, struct AVRational *tb){ struct mp_frame res = {type};
if (!frame_handlers[res.type].from_av_ref) return MP_NO_FRAME;
res.data = frame_handlers[res.type].from_av_ref(frame); if (!res.data) return MP_NO_FRAME;
mp_frame_set_pts(res, mp_pts_from_av(frame->pts, tb)); return res;}