summaryrefslogtreecommitdiffstats
path: root/video/decode/dec_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/decode/dec_video.c')
-rw-r--r--video/decode/dec_video.c224
1 files changed, 75 insertions, 149 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 8730703216..191a13d3fb 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -22,7 +22,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
-#include <unistd.h>
+#include <assert.h>
+
+#include "demux/codec_tags.h"
#include "core/mp_msg.h"
@@ -32,7 +34,7 @@
#include "stream/stream.h"
#include "demux/demux.h"
-#include "core/codec-cfg.h"
+#include "core/codecs.h"
#include "video/out/vo.h"
#include "video/csputils.h"
@@ -180,173 +182,97 @@ void uninit_video(sh_video_t *sh_video)
{
if (!sh_video->initialized)
return;
- mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Uninit video: %s\n", sh_video->codec->drv);
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Uninit video.\n");
sh_video->vd_driver->uninit(sh_video);
vf_uninit_filter_chain(sh_video->vfilter);
+ talloc_free(sh_video->gsh->decoder_desc);
+ sh_video->gsh->decoder_desc = NULL;
sh_video->initialized = 0;
}
-void vfm_help(void)
+static int init_video_codec(sh_video_t *sh_video, const char *decoder)
{
- int i;
- mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Available (compiled-in) video codec families/drivers:\n");
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n");
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n");
- for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++)
- mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n",
- mpcodecs_vd_drivers[i]->info->short_name,
- mpcodecs_vd_drivers[i]->info->name,
- mpcodecs_vd_drivers[i]->info->comment);
+ assert(!sh_video->vf_initialized);
+
+ if (!sh_video->vd_driver->init(sh_video, decoder)) {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Video decoder init failed.\n");
+ //uninit_video(sh_video);
+ return 0;
+ }
+
+ sh_video->initialized = 1;
+ sh_video->prev_codec_reordered_pts = MP_NOPTS_VALUE;
+ sh_video->prev_sorted_pts = MP_NOPTS_VALUE;
+ return 1;
}
-static int init_video(sh_video_t *sh_video, char *codecname, char *vfm,
- int status, stringset_t *selected)
+struct mp_decoder_list *mp_video_decoder_list(void)
{
- int force = 0;
- unsigned int orig_fourcc =
- sh_video->bih ? sh_video->bih->biCompression : 0;
- sh_video->codec = NULL;
- sh_video->vf_initialized = 0;
- if (codecname && codecname[0] == '+') {
- codecname = &codecname[1];
- force = 1;
- }
+ struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
+ for (int i = 0; mpcodecs_vd_drivers[i] != NULL; i++)
+ mpcodecs_vd_drivers[i]->add_decoders(list);
+ return list;
+}
- while (1) {
- int i;
- int orig_w, orig_h;
- // restore original fourcc:
- if (sh_video->bih)
- sh_video->bih->biCompression = orig_fourcc;
- if (!
- (sh_video->codec =
- find_video_codec(sh_video->format,
- sh_video->bih ? ((unsigned int *) &sh_video->
- bih->biCompression) : NULL,
- sh_video->codec, force)))
- break;
- // ok we found one codec
- if (stringset_test(selected, sh_video->codec->name))
- continue; // already tried & failed
- if (codecname && strcmp(sh_video->codec->name, codecname))
- continue; // -vc
- if (vfm && strcmp(sh_video->codec->drv, vfm))
- continue; // vfm doesn't match
- if (!force && sh_video->codec->status < status)
- continue; // too unstable
- stringset_add(selected, sh_video->codec->name); // tagging it
- // ok, it matches all rules, let's find the driver!
- for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++)
- if (!strcmp(mpcodecs_vd_drivers[i]->info->short_name,
- sh_video->codec->drv))
- break;
- sh_video->vd_driver = mpcodecs_vd_drivers[i];
- if (!sh_video->vd_driver) { // driver not available (==compiled in)
- mp_tmsg(MSGT_DECVIDEO, MSGL_WARN,
- _("Requested video codec family [%s] (vfm=%s) not available.\nEnable it at compilation.\n"),
- sh_video->codec->name, sh_video->codec->drv);
- continue;
- }
- orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w;
- orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h;
- sh_video->disp_w = orig_w;
- sh_video->disp_h = orig_h;
- if (sh_video->bih) {
- sh_video->bih->biWidth = sh_video->disp_w;
- sh_video->bih->biHeight = sh_video->disp_h;
- }
+static struct mp_decoder_list *mp_select_video_decoders(const char *codec,
+ char *selection)
+{
+ struct mp_decoder_list *list = mp_video_decoder_list();
+ struct mp_decoder_list *new = mp_select_decoders(list, codec, selection);
+ talloc_free(list);
+ return new;
+}
- // init()
- const struct vd_functions *vd = sh_video->vd_driver;
- mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Opening video decoder: [%s] %s\n",
- vd->info->short_name, vd->info->name);
- // clear vf init error, it is no longer relevant
- if (sh_video->vf_initialized < 0)
- sh_video->vf_initialized = 0;
- if (!vd->init(sh_video)) {
- mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Video decoder init failed for "
- "codecs.conf entry \"%s\".\n", sh_video->codec->name);
- sh_video->disp_w = orig_w;
- sh_video->disp_h = orig_h;
- if (sh_video->bih) {
- sh_video->bih->biWidth = sh_video->disp_w;
- sh_video->bih->biHeight = sh_video->disp_h;
- }
- continue; // try next...
- }
- // Yeah! We got it!
- sh_video->initialized = 1;
- sh_video->prev_codec_reordered_pts = MP_NOPTS_VALUE;
- sh_video->prev_sorted_pts = MP_NOPTS_VALUE;
- return 1;
+static const struct vd_functions *find_driver(const char *name)
+{
+ for (int i = 0; mpcodecs_vd_drivers[i] != NULL; i++) {
+ if (strcmp(mpcodecs_vd_drivers[i]->name, name) == 0)
+ return mpcodecs_vd_drivers[i];
}
- return 0;
+ return NULL;
}
-int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list,
- char **video_fm_list)
+int init_best_video_codec(sh_video_t *sh_video, char* video_decoders)
{
- char *vc_l_default[2] = { "", (char *) NULL };
- stringset_t selected;
- // hack:
- if (!video_codec_list)
- video_codec_list = vc_l_default;
- // Go through the codec.conf and find the best codec...
- sh_video->initialized = 0;
- stringset_init(&selected);
- while (!sh_video->initialized && *video_codec_list) {
- char *video_codec = *(video_codec_list++);
- if (video_codec[0]) {
- if (video_codec[0] == '-') {
- // disable this codec:
- stringset_add(&selected, video_codec + 1);
- } else {
- // forced codec by name:
- mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Forced video codec: %s\n",
- video_codec);
- init_video(sh_video, video_codec, NULL, -1, &selected);
- }
- } else {
- int status;
- // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING.
- if (video_fm_list) {
- char **fmlist = video_fm_list;
- // try first the preferred codec families:
- while (!sh_video->initialized && *fmlist) {
- char *video_fm = *(fmlist++);
- mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Trying to force video codec driver family %s...\n",
- video_fm);
- for (status = CODECS_STATUS__MAX;
- status >= CODECS_STATUS__MIN; --status)
- if (init_video
- (sh_video, NULL, video_fm, status, &selected))
- break;
- }
- }
- if (!sh_video->initialized)
- for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN;
- --status)
- if (init_video(sh_video, NULL, NULL, status, &selected))
- break;
+ assert(!sh_video->initialized);
+
+ struct mp_decoder_entry *decoder = NULL;
+ struct mp_decoder_list *list =
+ mp_select_video_decoders(sh_video->gsh->codec, video_decoders);
+
+ mp_print_decoders(MSGT_DECVIDEO, MSGL_V, "Codec list:", list);
+
+ for (int n = 0; n < list->num_entries; n++) {
+ struct mp_decoder_entry *sel = &list->entries[n];
+ const struct vd_functions *driver = find_driver(sel->family);
+ if (!driver)
+ continue;
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Opening video decoder %s:%s\n",
+ sel->family, sel->decoder);
+ sh_video->vd_driver = driver;
+ if (init_video_codec(sh_video, sel->decoder)) {
+ decoder = sel;
+ break;
}
+ sh_video->vd_driver = NULL;
+ mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Video decoder init failed for "
+ "%s:%s\n", sel->family, sel->decoder);
}
- stringset_free(&selected);
- if (!sh_video->initialized) {
- mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Cannot find codec matching selected -vo and video format 0x%X.\n",
- sh_video->format);
- return 0; // failed
+ if (sh_video->initialized) {
+ sh_video->gsh->decoder_desc =
+ talloc_asprintf(NULL, "%s [%s:%s]", decoder->desc, decoder->family,
+ decoder->decoder);
+ mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Selected video codec: %s\n",
+ sh_video->gsh->decoder_desc);
+ } else {
+ mp_msg(MSGT_DECVIDEO, MSGL_ERR,
+ "Failed to initialize a video decoder for codec '%s'.\n",
+ sh_video->gsh->codec ? sh_video->gsh->codec : "<unknown>");
}
- mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Selected video codec: %s [%s]\n",
- sh_video->codecname ? sh_video->codecname : sh_video->codec->info,
- sh_video->vd_driver->info->print_name ?
- sh_video->vd_driver->info->print_name :
- sh_video->vd_driver->info->short_name);
- mp_tmsg(MSGT_DECVIDEO, MSGL_V,
- "Video codecs.conf entry: %s (%s) vfm: %s\n",
- sh_video->codec->name, sh_video->codec->info, sh_video->codec->drv);
- return 1; // success
+ talloc_free(list);
+ return sh_video->initialized;
}
void *decode_video(sh_video_t *sh_video, struct demux_packet *packet,