Example #1
0
// Select a decoder from the given list for the given codec. The selection
// can be influenced by the selection string, which can specify a priority
// list of preferred decoders.
// This returns a list of decoders to try, with the preferred decoders first.
// The selection string corresponds to --vd/--ad directly, and has the
// following syntax:
//   selection = [<entry> ("," <entry>)*]
//       entry = <family> ":" <decoder>         // prefer decoder
//       entry = <family> ":*"                  // prefer all decoders
//       entry = "+" <family> ":" <decoder>     // force a decoder
//       entry = "-" <family> ":" <decoder>     // exclude a decoder
//       entry = "-"                            // don't add fallback decoders
// Forcing a decoder means it's added even if the codec mismatches.
struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all,
                                           const char *codec,
                                           const char *selection)
{
    struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
    struct mp_decoder_list *remove = talloc_zero(NULL, struct mp_decoder_list);
    if (!codec)
        codec = "unknown";
    bool stop = false;
    bstr sel = bstr0(selection);
    while (sel.len) {
        bstr entry;
        bstr_split_tok(sel, ",", &entry, &sel);
        if (bstr_equals0(entry, "-")) {
            stop = true;
            break;
        }
        bool force = bstr_eatstart0(&entry, "+");
        bool exclude = !force && bstr_eatstart0(&entry, "-");
        struct mp_decoder_list *dest = exclude ? remove : list;
        bstr family, decoder;
        if (!bstr_split_tok(entry, ":", &family, &decoder)) {
            mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Decoders must be specified as "
                   "'family:decoder' for the --ad/--vd options.\n");
            break;
        }
        if (bstr_equals0(decoder, "*")) {
            for (int n = 0; n < all->num_entries; n++) {
                struct mp_decoder_entry *cur = &all->entries[n];
                if (bstr_equals0(family, cur->family))
                    add_new(dest, cur, codec);
            }
        } else {
            add_new(dest, find_decoder(all, family, decoder),
                    force ? NULL : codec);
        }
    }
    if (!stop) {
        // Add the remaining codecs which haven't been added yet
        for (int n = 0; n < all->num_entries; n++)
            add_new(list, &all->entries[n], codec);
    }
    for (int n = 0; n < remove->num_entries; n++) {
        struct mp_decoder_entry *ex = &remove->entries[n];
        struct mp_decoder_entry *del =
            find_decoder(list, bstr0(ex->family), bstr0(ex->decoder));
        if (del) {
            int index = del - &list->entries[0];
            MP_TARRAY_REMOVE_AT(list->entries, list->num_entries, index);
        }
    }
    talloc_free(remove);
    return list;
}
void Decoder::init_decoder(const int in_width, const int in_height,
		const int in_pix_fmt, const int codec_ID)
{
	/* Declarations */
	AVCodec *codec;

	/* Find the decoder */
	codec = find_decoder(codec_ID);
	if (!codec)
		throw std::runtime_error("Could not find codec.");

	/* Allocate codec context */
	codec_context_ = avcodec_alloc_context3(codec);
	if (!codec_context_)
		throw std::runtime_error("Could not allocate codec context.");

	/* Set codec configuration */
	codec_context_->pix_fmt = (enum AVPixelFormat) in_pix_fmt;
	codec_context_->coded_width = in_width;
	codec_context_->coded_height = in_height;

	/* Open the codec context */
	if (codec_open(codec_context_, codec, NULL) < 0)
		throw std::runtime_error("Could not open codec context.");

	/* Allocate Decoder AVFrame */
	frame_in_ = boost::make_shared<Frame>(in_width, in_height, in_pix_fmt);

	has_keyframe_ = false;
	previous_packet_ = 0;
}
Example #3
0
// Add entry, but only if it's not yet on the list, and if the codec matches.
// If codec == NULL, don't compare codecs.
static void add_new(struct mp_decoder_list *to, struct mp_decoder_entry *entry,
                    const char *codec)
{
    if (!entry || (codec && strcmp(entry->codec, codec) != 0))
        return;
    if (!find_decoder(to, bstr0(entry->family), bstr0(entry->decoder)))
        mp_add_decoder_entry(to, entry);
}
Example #4
0
static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
    IWICComponentFactory *iface, IStream *pIStream, const GUID *pguidVendor,
    WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
    HRESULT res;
    IWICBitmapDecoder *decoder = NULL;

    TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
        metadataOptions, ppIDecoder);

    if (pguidVendor)
        decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
    if (!decoder)
        decoder = find_decoder(pIStream, NULL, metadataOptions);

    if (decoder)
    {
        *ppIDecoder = decoder;
        return S_OK;
    }
    else
    {
        if (WARN_ON(wincodecs))
        {
            LARGE_INTEGER seek;
            BYTE data[4];
            ULONG bytesread;

            WARN("failed to load from a stream\n");

            seek.QuadPart = 0;
            res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
            if (SUCCEEDED(res))
                res = IStream_Read(pIStream, data, 4, &bytesread);
            if (SUCCEEDED(res))
                WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
        }
        *ppIDecoder = NULL;
        return WINCODEC_ERR_COMPONENTNOTFOUND;
    }
}
Example #5
0
struct song *read_songs(char *dirname) 
{
    /* bleught.  string manipulation in C.  I hate this part */

    struct dirent *de;
    DIR *dir=opendir(dirname);
    int buf_size=0;
    int nsongs=0;
    char *buf;
    struct song *songs,*song;

    while((de=readdir(dir))) {
	if(find_decoder(de->d_name)) {
	    nsongs++;
	    buf_size+=strlen(de->d_name)+1;
	} else {
	    printf("skipping %s\n",de->d_name);
	}
    }
    buf=calloc(buf_size,1);
    songs=calloc(nsongs,sizeof (struct song));
    song=&songs[0];
    rewinddir(dir);
    struct decoder *d;
    while(nsongs && (de=readdir(dir))) {
	if((d=find_decoder(de->d_name))) {
	    nsongs--;
	    strcpy(buf,de->d_name);
	    song->filename=buf;
	    printf("--%s\n",buf);
	    buf+=strlen(buf)+1;
	    d->read_metadata(song);
	    song->decoder=d;
	    song++;
	}
    }
    song->filename=(char *)0;
    n_songs=song-songs;
    return songs;
}
Example #6
0
/* Find the index in plugins table for the given file.
 * Return -1 if not found. */
static int find_type (const char *file)
{
    int result = -1;
    char *extn, *mime;

    extn = ext_pos (file);
    mime = NULL;

    result = find_decoder (extn, file, &mime);

    free (mime);
    return result;
}
int find_and_open_decoder
(
    AVCodecContext *ctx,
    enum AVCodecID  codec_id,
    const char    **preferred_decoder_names,
    int             threads
)
{
    AVCodec *codec = find_decoder( codec_id, preferred_decoder_names );
    if( !codec )
        return -1;
    ctx->thread_count = threads;
    return (open_decoder( ctx, codec ) < 0) ? -1 : 0;
}
Example #8
0
// selection is a ","-separated list of decoders, all in the given family.
struct mp_decoder_list *mp_select_decoder_list(struct mp_decoder_list *all,
                                               const char *codec,
                                               const char *family,
                                               const char *selection)
{
    struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
    bstr sel = bstr0(selection);
    while (sel.len) {
        bstr decoder;
        bstr_split_tok(sel, ",", &decoder, &sel);
        add_new(list, find_decoder(all, bstr0(family), decoder), codec);
    }
    return list;
}
Example #9
0
int main(int argc, char **argv)
{
    SDL_Event *event = av_mallocz(sizeof(SDL_Event));
    Content *content = av_mallocz(sizeof(Content));
    Media *video = av_mallocz(sizeof(Media));
    Media *audio = av_mallocz(sizeof(Media));
    State *state = av_mallocz(sizeof(State));
    SDL_Thread *video_decode_tid1;
    SDL_Thread *video_decode_tid2;
    SDL_Thread *read_pkt_tid;
    SDL_Thread *refresh_tid;
//    InitPool(2);
    state->content = content;
    state->video = video;
    state->audio = audio;
    init_video(video);
    if(argc < 2) {
	LOGE("Usage : play <content>");
	exit(1);
    }
    av_register_all();
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
	LOGE("fail to initialize SDL");
	exit(1);
    }
    av_strlcpy(content->name, argv[1], sizeof(content->name));
    LOGE("addr : %x", video->frame_buf);
    get_content_info(content);
    LOGI("finding streams");
    find_av_streams(content, video, audio);
    LOGI("finding decoder");
    find_decoder(video);
    video->get_info(video);
    LOGI("creating reading thread...");
    read_pkt_tid = SDL_CreateThread(queue_av_pkt, "read", state);
    LOGI("initing screen");
    init_screen(video);
//    LOGI("alloc frame");
    alloc_frame(video);
    LOGI("alloc all the frame");
//    alloc_all_frame(video);
    LOGI("creating decode thread1...");
    video_decode_tid1 = SDL_CreateThread(decode_video, "decode1", video);    
    refresh(state, 50);
    event_handle(event);
    return 0;
}
Example #10
0
/* Use the stream's MIME type to return a decoder for it, or NULL if no
 * applicable decoder was found. */
static struct decoder *get_decoder_by_mime_type (struct io_stream *stream)
{
    int i;
    char *mime;
    struct decoder *result;

    result = NULL;
    mime = xstrdup (io_get_mime_type (stream));
    if (mime) {
        i = find_decoder (NULL, NULL, &mime);
        if (i != -1) {
            logit ("Found decoder for MIME type %s: %s", mime, plugins[i].name);
            result = plugins[i].decoder;
        }
        free (mime);
    }
    else
        logit ("No MIME type.");

    return result;
}
Example #11
0
static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
{
	AVFormatContext *format_context = demuxer->format_context;
	unsigned int i;
	AVStream *audio_stream = NULL;
	AVStream *video_stream = NULL;
	int64_t start_time = INT64_MAX;

	for (i = 0; i < format_context->nb_streams; i++) {
		AVCodecContext *codec = format_context->streams[i]->codec;

		if (codec->codec_type == AVMEDIA_TYPE_VIDEO && !video_stream)
			video_stream = format_context->streams[i];

		if (codec->codec_type == AVMEDIA_TYPE_AUDIO && !audio_stream)
			audio_stream = format_context->streams[i];
	}

	int default_stream_index = av_find_default_stream_index(
			demuxer->format_context);

	if (default_stream_index >= 0) {
		AVStream *stream =
				format_context->streams[default_stream_index];

		if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
			demuxer->clock.sync_type = AV_SYNC_AUDIO_MASTER;
		else if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
			demuxer->clock.sync_type = AV_SYNC_VIDEO_MASTER;
	}

	if (video_stream != NULL)
		find_decoder(demuxer, video_stream);

	if (audio_stream != NULL)
		find_decoder(demuxer, audio_stream);

	if (demuxer->video_decoder == NULL && demuxer->audio_decoder == NULL) {
		return false;
	}

	if (!set_clock_sync_type(demuxer)) {
		return false;
	}

	for (i = 0; i < format_context->nb_streams; i++) {
		AVStream *st = format_context->streams[i];
		int64_t st_start_time;

		if (st->discard == AVDISCARD_ALL ||
		    st->start_time == AV_NOPTS_VALUE) {
			continue;
		}

		st_start_time = av_rescale_q(st->start_time, st->time_base,
				AV_TIME_BASE_Q);
		start_time = FFMIN(start_time, st_start_time);
	}

	if (format_context->start_time != AV_NOPTS_VALUE) {
		if (start_time > format_context->start_time ||
		    start_time == INT64_MAX) {
			start_time = format_context->start_time;
		}
	}

	if (start_time != INT64_MAX) {
		set_decoder_start_time(demuxer->video_decoder, start_time);
		set_decoder_start_time(demuxer->audio_decoder, start_time);
	}

	if (demuxer->audio_decoder != NULL) {
		if (ff_callbacks_initialize(&demuxer->audio_callbacks)) {
			ff_decoder_start(demuxer->audio_decoder);
		} else {
			ff_decoder_free(demuxer->audio_decoder);
			demuxer->audio_decoder = NULL;
			if (!set_clock_sync_type(demuxer))
				return false;
		}
	}

	if (demuxer->video_decoder != NULL) {
		if (ff_callbacks_initialize(&demuxer->video_callbacks)) {
			ff_decoder_start(demuxer->video_decoder);
		} else {
			ff_decoder_free(demuxer->video_decoder);
			demuxer->video_decoder = NULL;
			if (!set_clock_sync_type(demuxer))
				return false;
		}
	}

	return set_clock_sync_type(demuxer);
}
void lwlibav_update_configuration
(
    lwlibav_decode_handler_t *dhp,
    uint32_t                  frame_number,
    int                       extradata_index,
    int64_t                   rap_pos
)
{
    lwlibav_extradata_handler_t *exhp = &dhp->exh;
    if( exhp->entry_count == 0 || extradata_index < 0 )
    {
        /* No need to update the extradata. */
        exhp->current_index = extradata_index;
        lwlibav_flush_buffers( dhp );
        return;
    }
    AVCodecContext *ctx = dhp->format->streams[ dhp->stream_index ]->codec;
    void *app_specific = ctx->opaque;
    avcodec_close( ctx );
    if( ctx->extradata )
    {
        av_freep( &ctx->extradata );
        ctx->extradata_size = 0;
    }
    /* Find an appropriate decoder. */
    char error_string[96] = { 0 };
    lwlibav_extradata_t *entry = &exhp->entries[extradata_index];
    const AVCodec *codec = find_decoder( entry->codec_id, dhp->preferred_decoder_names );
    if( !codec )
    {
        strcpy( error_string, "Failed to find the decoder.\n" );
        goto fail;
    }
    /* Get decoder default settings. */
    int thread_count = ctx->thread_count;
    if( avcodec_get_context_defaults3( ctx, codec ) < 0 )
    {
        strcpy( error_string, "Failed to get CODEC default.\n" );
        goto fail;
    }
    /* Set up decoder basic settings. */
    if( ctx->codec_type == AVMEDIA_TYPE_VIDEO )
        set_video_basic_settings( dhp, frame_number );
    else
        set_audio_basic_settings( dhp, frame_number );
    /* Update extradata. */
    if( entry->extradata_size > 0 )
    {
        ctx->extradata = (uint8_t *)av_malloc( entry->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !ctx->extradata )
        {
            strcpy( error_string, "Failed to allocate extradata.\n" );
            goto fail;
        }
        ctx->extradata_size = entry->extradata_size;
        memcpy( ctx->extradata, entry->extradata, ctx->extradata_size );
        memset( ctx->extradata + ctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
    }
    /* AVCodecContext.codec_id is supposed to be set properly in avcodec_open2().
     * See lwlibav_flush_buffers(), why this is needed. */
    ctx->codec_id  = AV_CODEC_ID_NONE;
    /* This is needed by some CODECs such as UtVideo and raw video. */
    ctx->codec_tag = entry->codec_tag;
    /* Open an appropriate decoder.
     * Here, we force single threaded decoding since some decoder doesn't do its proper initialization with multi-threaded decoding. */
    ctx->thread_count = 1;
    if( open_decoder( ctx, codec ) < 0 )
    {
        strcpy( error_string, "Failed to open decoder.\n" );
        goto fail;
    }
    exhp->current_index = extradata_index;
    exhp->delay_count   = 0;
    /* Set up decoder basic settings by actual decoding. */
    if( ctx->codec_type == AVMEDIA_TYPE_VIDEO
      ? try_decode_video_frame( dhp, frame_number, rap_pos, error_string ) < 0
      : try_decode_audio_frame( dhp, frame_number, error_string ) < 0 )
        goto fail;
    /* Reopen/flush with the requested number of threads. */
    ctx->thread_count = thread_count;
    int width  = ctx->width;
    int height = ctx->height;
    lwlibav_flush_buffers( dhp );
    ctx->get_buffer2 = exhp->get_buffer ? exhp->get_buffer : avcodec_default_get_buffer2;
    ctx->opaque      = app_specific;
    /* avcodec_open2() may have changed resolution unexpectedly. */
    ctx->width       = width;
    ctx->height      = height;
    return;
fail:
    exhp->delay_count = 0;
    dhp->error = 1;
    lw_log_show( &dhp->lh, LW_LOG_FATAL,
                 "%sIt is recommended you reopen the file.", error_string );
}