diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index ae97b44..30130c8 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -8,13 +8,10 @@ AM_CPPFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS AM_CPPFLAGS += -ggdb libeplayer3_la_SOURCES = \ - container/container_ffmpeg.cpp \ - manager/manager.cpp output/output.cpp \ - playback/playback.cpp output/writer/writer.cpp output/writer/wmv.cpp \ - output/writer/ac3.cpp output/writer/divx.cpp output/writer/pes.cpp \ - output/writer/dts.cpp output/writer/mpeg2.cpp output/writer/mp3.cpp output/writer/misc.cpp \ - output/writer/h264.cpp output/writer/h263.cpp output/writer/vc1.cpp \ - output/writer/flac.cpp output/writer/pcm.cpp + input.cpp output.cpp manager.cpp player.cpp \ + writer/writer.cpp writer/wmv.cpp writer/ac3.cpp writer/divx.cpp writer/pes.cpp \ + writer/dts.cpp writer/mpeg2.cpp writer/mp3.cpp writer/misc.cpp writer/h264.cpp \ + writer/h263.cpp writer/vc1.cpp writer/flac.cpp writer/pcm.cpp LIBEPLAYER3_LIBS = libeplayer3.la -lpthread -lavformat -lavcodec -lavutil -lswresample -lm diff --git a/libeplayer3/include/input.h b/libeplayer3/include/input.h index 7352ecf..dc13eec 100644 --- a/libeplayer3/include/input.h +++ b/libeplayer3/include/input.h @@ -58,7 +58,6 @@ class Input bool SwitchVideo(Track *track); bool GetMetadata(std::vector &keys, std::vector &values); bool GetReadCount(uint64_t &readcount); - }; #endif diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index b67a486..0e3476a 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -26,9 +26,9 @@ extern "C" { struct Chapter { - std::string title; - double start; - double end; + std::string title; + double start; + double end; }; class Player { diff --git a/libeplayer3/include/writer.h b/libeplayer3/include/writer.h index dca081a..de4596d 100644 --- a/libeplayer3/include/writer.h +++ b/libeplayer3/include/writer.h @@ -1,5 +1,5 @@ -#ifndef WRITER_H_ -#define WRITER_H_ +#ifndef __WRITER_H__ +#define __WRITER_H__ #include #include diff --git a/libeplayer3/input.cpp b/libeplayer3/input.cpp index 7ba8d8a..dfac82e 100644 --- a/libeplayer3/input.cpp +++ b/libeplayer3/input.cpp @@ -19,10 +19,6 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include @@ -65,22 +61,22 @@ Input::~Input() int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts) { - if (!avfc || !stream) { - fprintf(stderr, "player / stream null\n"); - return INVALID_PTS_VALUE; - } + if (!avfc || !stream) { + fprintf(stderr, "player / stream null\n"); + return INVALID_PTS_VALUE; + } - if (pts == AV_NOPTS_VALUE) - pts = INVALID_PTS_VALUE; - else if (avfc->start_time == AV_NOPTS_VALUE) - pts = 90000.0 * (double) pts * av_q2d(stream->time_base); - else - pts = 90000.0 * (double) pts * av_q2d(stream->time_base) - 90000.0 * avfc->start_time / AV_TIME_BASE; + if (pts == AV_NOPTS_VALUE) + pts = INVALID_PTS_VALUE; + else if (avfc->start_time == AV_NOPTS_VALUE) + pts = 90000.0 * (double) pts * av_q2d(stream->time_base); + else + pts = 90000.0 * (double) pts * av_q2d(stream->time_base) - 90000.0 * avfc->start_time / AV_TIME_BASE; - if (pts & 0x8000000000000000ull) - pts = INVALID_PTS_VALUE; + if (pts & 0x8000000000000000ull) + pts = INVALID_PTS_VALUE; - return pts; + return pts; } // from neutrino-mp/lib/libdvbsubtitle/dvbsub.cpp @@ -92,200 +88,194 @@ extern "C" void teletext_write(int pid, uint8_t *data, int size); bool Input::Play() { - char threadname[17]; - strncpy(threadname, __func__, sizeof(threadname)); - threadname[16] = 0; - prctl(PR_SET_NAME, (unsigned long) &threadname); + char threadname[17]; + strncpy(threadname, __func__, sizeof(threadname)); + threadname[16] = 0; + prctl(PR_SET_NAME, (unsigned long) &threadname); - hasPlayThreadStarted = 1; + hasPlayThreadStarted = 1; - int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0; + int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0; + bool restart_audio_resampling = false; - while (player->isCreationPhase) { - fprintf(stderr, "Thread waiting for end of init phase...\n"); - usleep(1000); - } - fprintf(stderr, "Running!\n"); - - bool restart_audio_resampling = false; - - while (player->isPlaying && !player->abortRequested) { - - //IF MOVIE IS PAUSED, WAIT - if (player->isPaused) { - fprintf(stderr, "paused\n"); - - usleep(100000); - continue; + while (player->isCreationPhase) { + fprintf(stderr, "Thread waiting for end of init phase...\n"); + usleep(1000); } + fprintf(stderr, "Running!\n"); - int seek_target_flag = 0; - int64_t seek_target = INT64_MIN; - if (seek_sec_rel != 0.0) { - if (avfc->iformat->flags & AVFMT_TS_DISCONT) { - float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; - seek_target_flag = AVSEEK_FLAG_BYTE; - seek_target = avio_tell(avfc->pb) + seek_sec_rel * br; - } else { - seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + seek_sec_rel) * AV_TIME_BASE; - } - seek_sec_rel = 0.0; - } else if (seek_sec_abs >= 0.0) { - if (avfc->iformat->flags & AVFMT_TS_DISCONT) { - float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; - seek_target_flag = AVSEEK_FLAG_BYTE; - seek_target = seek_sec_abs * br; - } else { - seek_target = seek_sec_abs * AV_TIME_BASE; - } - seek_sec_abs = -1.0; - } else if (player->isBackWard && av_gettime() >= showtime) { - player->output.ClearVideo(); + while (player->isPlaying && !player->abortRequested) { - if (bofcount == 1) { - showtime = av_gettime(); - usleep(100000); - continue; - } - - if (avfc->iformat->flags & AVFMT_TS_DISCONT) { - off_t pos = avio_tell(avfc->pb); - - if (pos > 0) { - float br; - if (avfc->bit_rate) - br = avfc->bit_rate / 8.0; - else - br = 180000.0; - seek_target = pos + player->Speed * 8 * br; - seek_target_flag = AVSEEK_FLAG_BYTE; + //IF MOVIE IS PAUSED, WAIT + if (player->isPaused) { + fprintf(stderr, "paused\n"); + usleep(100000); + continue; } - } else { - seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + player->Speed * 8) * AV_TIME_BASE;; - } - showtime = av_gettime() + 300000; //jump back every 300ms - } else { - bofcount = 0; - } - if (seek_target > INT64_MIN) { - int res; - if (seek_target < 0) - seek_target = 0; - res = avformat_seek_file(avfc, -1, INT64_MIN, seek_target, INT64_MAX, seek_target_flag); + int seek_target_flag = 0; + int64_t seek_target = INT64_MIN; - if (res < 0 && player->isBackWard) - bofcount = 1; - seek_target = INT64_MIN; - restart_audio_resampling = true; + if (seek_sec_rel != 0.0) { + if (avfc->iformat->flags & AVFMT_TS_DISCONT) { + float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; + seek_target_flag = AVSEEK_FLAG_BYTE; + seek_target = avio_tell(avfc->pb) + seek_sec_rel * br; + } else { + seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + seek_sec_rel) * AV_TIME_BASE; + } + seek_sec_rel = 0.0; + } else if (seek_sec_abs >= 0.0) { + if (avfc->iformat->flags & AVFMT_TS_DISCONT) { + float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; + seek_target_flag = AVSEEK_FLAG_BYTE; + seek_target = seek_sec_abs * br; + } else { + seek_target = seek_sec_abs * AV_TIME_BASE; + } + seek_sec_abs = -1.0; + } else if (player->isBackWard && av_gettime() >= showtime) { + player->output.ClearVideo(); - // flush streams - unsigned int i; - for (i = 0; i < avfc->nb_streams; i++) - if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec) - avcodec_flush_buffers(avfc->streams[i]->codec); - } + if (bofcount == 1) { + showtime = av_gettime(); + usleep(100000); + continue; + } - AVPacket packet; - av_init_packet(&packet); + if (avfc->iformat->flags & AVFMT_TS_DISCONT) { + off_t pos = avio_tell(avfc->pb); - int av_res = av_read_frame(avfc, &packet); - if (av_res == AVERROR(EAGAIN)) { - av_free_packet(&packet); - continue; - } - if (av_res) { // av_read_frame failed - fprintf(stderr, "no data ->end of file reached ?\n"); - av_free_packet(&packet); - break; // while - } - long long int pts; - - player->readCount += packet.size; - - int pid = avfc->streams[packet.stream_index]->id; - - -Track *_videoTrack = videoTrack; -Track *_audioTrack = audioTrack; -Track *_subtitleTrack = subtitleTrack; -Track *_teletextTrack = teletextTrack; - - - if (_videoTrack && (_videoTrack->pid == pid)) { - currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts); - - if (!player->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts)) - ;//fprintf(stderr, "writing data to video device failed\n"); - } else if (_audioTrack && (_audioTrack->pid == pid)) { - if (restart_audio_resampling) { - restart_audio_resampling = false; - player->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts); - } - if (!player->isBackWard) { - currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts); - if (!player->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts)) - ;//fprintf(stderr, "writing data to audio device failed\n"); - } - } else if (_subtitleTrack && (_subtitleTrack->pid == pid)) { - float duration = 3.0; - - pts = calcPts(avfc, _subtitleTrack->stream, packet.pts); - - if (duration > 0.0) { - /* is there a decoder ? */ - if (((AVStream *) _subtitleTrack->stream)->codec->codec) { - AVSubtitle sub; - memset(&sub, 0, sizeof(sub)); - int got_sub_ptr; - - if (avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) { - fprintf(stderr, "error decoding subtitle\n"); - } - - if (got_sub_ptr && sub.num_rects > 0) { - switch (sub.rects[0]->type) { - case SUBTITLE_TEXT: // FIXME? - case SUBTITLE_ASS: - dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid); - break; - case SUBTITLE_BITMAP: - dvbsub_write(&sub, pts); - // avsubtitle_free() will be called by handler - break; - default: - break; - } - } + if (pos > 0) { + float br; + if (avfc->bit_rate) + br = avfc->bit_rate / 8.0; + else + br = 180000.0; + seek_target = pos + player->Speed * 8 * br; + seek_target_flag = AVSEEK_FLAG_BYTE; + } + } else { + seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + player->Speed * 8) * AV_TIME_BASE;; + } + showtime = av_gettime() + 300000; //jump back every 300ms + } else { + bofcount = 0; } - } /* duration */ - } else if (_teletextTrack && (_teletextTrack->pid == pid)) { - teletext_write(pid, packet.data, packet.size); - } - av_free_packet(&packet); - } /* while */ + if (seek_target > INT64_MIN) { + int res; + if (seek_target < 0) + seek_target = 0; + res = avformat_seek_file(avfc, -1, INT64_MIN, seek_target, INT64_MAX, seek_target_flag); - if (player && player->abortRequested) - player->output.Clear(); + if (res < 0 && player->isBackWard) + bofcount = 1; + seek_target = INT64_MIN; + restart_audio_resampling = true; - dvbsub_ass_clear(); + // flush streams + unsigned int i; + for (i = 0; i < avfc->nb_streams; i++) + if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec) + avcodec_flush_buffers(avfc->streams[i]->codec); + } + AVPacket packet; + av_init_packet(&packet); + + int av_res = av_read_frame(avfc, &packet); + if (av_res == AVERROR(EAGAIN)) { + av_free_packet(&packet); + continue; + } + if (av_res) { // av_read_frame failed + fprintf(stderr, "no data ->end of file reached ?\n"); + av_free_packet(&packet); + break; // while + } + int64_t pts; + + player->readCount += packet.size; + + int pid = avfc->streams[packet.stream_index]->id; + + + Track *_videoTrack = videoTrack; + Track *_audioTrack = audioTrack; + Track *_subtitleTrack = subtitleTrack; + Track *_teletextTrack = teletextTrack; + + + if (_videoTrack && (_videoTrack->pid == pid)) { + currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts); + + if (!player->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts)) + fprintf(stderr, "writing data to video device failed\n"); + } else if (_audioTrack && (_audioTrack->pid == pid)) { + if (restart_audio_resampling) { + restart_audio_resampling = false; + player->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts); + } + if (!player->isBackWard) { + currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts); + if (!player->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts)) + fprintf(stderr, "writing data to audio device failed\n"); + } + } else if (_subtitleTrack && (_subtitleTrack->pid == pid)) { + float duration = 3.0; + + pts = calcPts(avfc, _subtitleTrack->stream, packet.pts); + + if (duration > 0.0) { + /* is there a decoder ? */ + if (((AVStream *) _subtitleTrack->stream)->codec->codec) { + AVSubtitle sub; + memset(&sub, 0, sizeof(sub)); + int got_sub_ptr; + + if (avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) { + fprintf(stderr, "error decoding subtitle\n"); + } + + if (got_sub_ptr && sub.num_rects > 0) { + switch (sub.rects[0]->type) { + case SUBTITLE_TEXT: // FIXME? + case SUBTITLE_ASS: + dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid); + break; + case SUBTITLE_BITMAP: + dvbsub_write(&sub, pts); + // avsubtitle_free() will be called by handler + break; + default: + break; + } + } + } + } /* duration */ + } else if (_teletextTrack && (_teletextTrack->pid == pid)) { + teletext_write(pid, packet.data, packet.size); + } + + av_free_packet(&packet); + } /* while */ + + if (player && player->abortRequested) + player->output.Clear(); + + dvbsub_ass_clear(); player->abortPlayback = 1; - hasPlayThreadStarted = 0; + hasPlayThreadStarted = 0; return true; } -/* **************************** */ -/* Container part for ffmpeg */ -/* **************************** */ - /*static*/ int interrupt_cb(void *arg) { - Player *player = (Player *) arg; - return player->abortPlayback | player->abortRequested; + Player *player = (Player *) arg; + return player->abortPlayback | player->abortRequested; } static void log_callback(void *ptr __attribute__ ((unused)), int lvl __attribute__ ((unused)), const char *format, va_list ap) @@ -305,45 +295,45 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) AVFormatContext *subavfc = avformat_alloc_context(); if (avformat_open_input(&subavfc, subfile, av_find_input_format(format), 0)) { - avformat_free_context(subavfc); + avformat_free_context(subavfc); return false; - } - avformat_find_stream_info(subavfc, NULL); + } + avformat_find_stream_info(subavfc, NULL); if (subavfc->nb_streams != 1) { - avformat_free_context(subavfc); + avformat_free_context(subavfc); return false; } - AVCodecContext *c = subavfc->streams[0]->codec; - AVCodec *codec = avcodec_find_decoder(c->codec_id); + AVCodecContext *c = subavfc->streams[0]->codec; + AVCodec *codec = avcodec_find_decoder(c->codec_id); if (!codec) { - avformat_free_context(subavfc); + avformat_free_context(subavfc); return false; } - // fprintf(stderr, "codec=%s\n", avcodec_get_name(c->codec_id)); - if (avcodec_open2(c, codec, NULL) < 0) { + // fprintf(stderr, "codec=%s\n", avcodec_get_name(c->codec_id)); + if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "%s %d: avcodec_open\n", __FILE__, __LINE__); - avformat_free_context(subavfc); + avformat_free_context(subavfc); return false; } - AVPacket avpkt; - av_init_packet(&avpkt); + AVPacket avpkt; + av_init_packet(&avpkt); - if (c->subtitle_header) - fprintf(stderr, "%s\n", c->subtitle_header); + if (c->subtitle_header) + fprintf(stderr, "%s\n", c->subtitle_header); - while (av_read_frame(subavfc, &avpkt) > -1) { + while (av_read_frame(subavfc, &avpkt) > -1) { AVSubtitle sub; - memset(&sub, 0, sizeof(sub)); - int got_sub = 0; - avcodec_decode_subtitle2(c, &sub, &got_sub, &avpkt); - if (got_sub) + memset(&sub, 0, sizeof(sub)); + int got_sub = 0; + avcodec_decode_subtitle2(c, &sub, &got_sub, &avpkt); + if (got_sub) dvbsub_ass_write(c, &sub, pid); - av_free_packet(&avpkt); - } - avformat_close_input(&subavfc); - avformat_free_context(subavfc); + av_free_packet(&avpkt); + } + avformat_close_input(&subavfc); + avformat_free_context(subavfc); Track track; track.Name = format; @@ -366,92 +356,92 @@ bool Input::ReadSubtitles(const char *filename) { bool Input::Init(const char *filename) { - int err; + int err; - av_log_set_callback(log_callback); + av_log_set_callback(log_callback); - if (filename == NULL) { - fprintf(stderr, "filename NULL\n"); + if (filename == NULL) { + fprintf(stderr, "filename NULL\n"); + return false; + } - return false; - } + if (isContainerRunning) { + fprintf(stderr, "ups already running?\n"); + return false; + } + isContainerRunning = true; - if (isContainerRunning) { - fprintf(stderr, "ups already running?\n"); - return false; - } - isContainerRunning = true; + /* initialize ffmpeg */ + avcodec_register_all(); + av_register_all(); - /* initialize ffmpeg */ - avcodec_register_all(); - av_register_all(); + avformat_network_init(); - avformat_network_init(); + player->abortRequested = 0; + player->abortPlayback = 0; + videoTrack = NULL; + audioTrack = NULL; + subtitleTrack = NULL; + teletextTrack = NULL; + avfc = avformat_alloc_context(); + avfc->interrupt_callback.callback = interrupt_cb; + avfc->interrupt_callback.opaque = (void *) &player; - player->abortRequested = 0; - player->abortPlayback = 0; - videoTrack = NULL; - audioTrack = NULL; - subtitleTrack = NULL; - teletextTrack = NULL; - avfc = avformat_alloc_context(); - avfc->interrupt_callback.callback = interrupt_cb; - avfc->interrupt_callback.opaque = (void *) &player; + if ((err = avformat_open_input(&avfc, filename, NULL, 0)) != 0) { + char error[512]; - if ((err = avformat_open_input(&avfc, filename, NULL, 0)) != 0) { - char error[512]; + fprintf(stderr, "avformat_open_input failed %d (%s)\n", err, filename); + av_strerror(err, error, 512); + fprintf(stderr, "Cause: %s\n", error); - fprintf(stderr, "avformat_open_input failed %d (%s)\n", err, filename); - av_strerror(err, error, 512); - fprintf(stderr, "Cause: %s\n", error); + isContainerRunning = false; + return false; + } - isContainerRunning = false; - return false; - } + avfc->iformat->flags |= AVFMT_SEEK_TO_PTS; + avfc->flags = AVFMT_FLAG_GENPTS; + if (player->noprobe) { + avfc->max_analyze_duration = 1; + avfc->probesize = 8192; + } - avfc->iformat->flags |= AVFMT_SEEK_TO_PTS; - avfc->flags = AVFMT_FLAG_GENPTS; - if (player->noprobe) { - avfc->max_analyze_duration = 1; - avfc->probesize = 8192; - } - - if (avformat_find_stream_info(avfc, NULL) < 0) { - fprintf(stderr, "Error avformat_find_stream_info\n"); + if (avformat_find_stream_info(avfc, NULL) < 0) { + fprintf(stderr, "Error avformat_find_stream_info\n"); #ifdef this_is_ok - /* crow reports that sometimes this returns an error - * but the file is played back well. so remove this - * until other works are done and we can prove this. - */ - avformat_close_input(&avfc); - isContainerRunning = false; - return false; + /* crow reports that sometimes this returns an error + * but the file is played back well. so remove this + * until other works are done and we can prove this. + */ + avformat_close_input(&avfc); + isContainerRunning = false; + return false; #endif - } + } - terminating = false; - int res = UpdateTracks(); + terminating = false; - if (!videoTrack && !audioTrack) { - avformat_close_input(&avfc); - isContainerRunning = false; - return false; - } + bool res = UpdateTracks(); - if (videoTrack) - player->output.SwitchVideo(videoTrack->stream); - if (audioTrack) - player->output.SwitchAudio(audioTrack->stream); - - ReadSubtitles(filename); + if (!videoTrack && !audioTrack) { + avformat_close_input(&avfc); + isContainerRunning = false; + return false; + } - return res; + if (videoTrack) + player->output.SwitchVideo(videoTrack->stream); + if (audioTrack) + player->output.SwitchAudio(audioTrack->stream); + + ReadSubtitles(filename); + + return res; } bool Input::UpdateTracks() { - if (terminating) - return true; + if (terminating) + return true; std::vector chapters; for (unsigned int i = 0; i < avfc->nb_chapters; i++) { @@ -462,139 +452,110 @@ bool Input::UpdateTracks() if (!ch) continue; Chapter chapter; - chapter.title = title ? title->value : "unknown"; + chapter.title = title ? title->value : "?"; chapter.start = (double) ch->start * av_q2d(ch->time_base) * 1000.0; chapter.end = (double) ch->end * av_q2d(ch->time_base) * 1000.0; chapters.push_back(chapter); } player->SetChapters(chapters); - player->manager.initTrackUpdate(); + player->manager.initTrackUpdate(); - av_dump_format(avfc, 0, player->url.c_str(), 0); + av_dump_format(avfc, 0, player->url.c_str(), 0); - unsigned int n; + for (unsigned int n = 0; n < avfc->nb_streams; n++) { + AVStream *stream = avfc->streams[n]; - for (n = 0; n < avfc->nb_streams; n++) { - Track track; - AVStream *stream = avfc->streams[n]; + if (!stream->id) + stream->id = n + 1; - if (!stream->id) - stream->id = n + 1; - - track.avfc = avfc; - track.stream = stream; - - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - track.Name = "und"; + Track track; track.avfc = avfc; + track.stream = stream; + AVDictionaryEntry *lang = av_dict_get(stream->metadata, "language", NULL, 0); + track.Name = lang ? lang->value : "?"; track.pid = stream->id; + if (stream->duration == AV_NOPTS_VALUE) + track.duration = (double) avfc->duration / 1000.0; + else + track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; - if (stream->duration == AV_NOPTS_VALUE) { - track.duration = (double) avfc->duration / 1000.0; - } else { - track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; - } - player->manager.addVideoTrack(track); - if (!videoTrack) - videoTrack = player->manager.getVideoTrack(track.pid); - break; - case AVMEDIA_TYPE_AUDIO: - AVDictionaryEntry *lang; - - lang = av_dict_get(stream->metadata, "language", NULL, 0); - - track.Name = lang ? lang->value : "und"; - - track.pid = stream->id; - track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; - - if (stream->duration == AV_NOPTS_VALUE) { - track.duration = (double) avfc->duration / 1000.0; - } else { - track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; - } - - switch(stream->codec->codec_id) { - case AUDIO_ENCODING_MPEG2: - track.ac3flags = 9; + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: { + player->manager.addVideoTrack(track); + if (!videoTrack) + videoTrack = player->manager.getVideoTrack(track.pid); break; - case AV_CODEC_ID_MP3: - track.ac3flags = 4; - break; - case AV_CODEC_ID_AC3: - track.ac3flags = 1; - break; - case AV_CODEC_ID_EAC3: - track.ac3flags = 7; - break; - case AV_CODEC_ID_DTS: - track.ac3flags = 6; - break; - case AV_CODEC_ID_AAC: - track.ac3flags = 5; - break; - default: - track.ac3flags = 0; - } - player->manager.addAudioTrack(track); - if (!audioTrack) - audioTrack = player->manager.getAudioTrack(track.pid); - - break; - case AVMEDIA_TYPE_SUBTITLE: - { - AVDictionaryEntry *lang; - - lang = av_dict_get(stream->metadata, "language", NULL, 0); - - track.Name = lang ? lang->value : "und"; - - track.pid = stream->id; - track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; - - if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) { - int i = 0; - AVDictionaryEntry *t = NULL; - do { - char tmp[30]; - snprintf(tmp, sizeof(tmp), "teletext_%d", i); - t = av_dict_get(stream->metadata, tmp, NULL, 0); - if (t) { - char lang[strlen(t->value)]; - if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) { - track.Name = lang; - player->manager.addTeletextTrack(track); - } } - i++; - } while (t); - } else { - if (!stream->codec->codec) { - stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id); - if (!stream->codec->codec) - fprintf(stderr, "avcodec_find_decoder failed for subtitle track %d\n", n); - else if (avcodec_open2(stream->codec, stream->codec->codec, NULL)) { - fprintf(stderr, "avcodec_open2 failed for subtitle track %d\n", n); - stream->codec->codec = NULL; + case AVMEDIA_TYPE_AUDIO: { + switch(stream->codec->codec_id) { + case AUDIO_ENCODING_MPEG2: + track.ac3flags = 9; + break; + case AV_CODEC_ID_MP3: + track.ac3flags = 4; + break; + case AV_CODEC_ID_AC3: + track.ac3flags = 1; + break; + case AV_CODEC_ID_EAC3: + track.ac3flags = 7; + break; + case AV_CODEC_ID_DTS: + track.ac3flags = 6; + break; + case AV_CODEC_ID_AAC: + track.ac3flags = 5; + break; + default: + track.ac3flags = 0; + } + player->manager.addAudioTrack(track); + if (!audioTrack) + audioTrack = player->manager.getAudioTrack(track.pid); + break; } - } - if (stream->codec->codec) - player->manager.addSubtitleTrack(track); - } + case AVMEDIA_TYPE_SUBTITLE: { + if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) { + int i = 0; + AVDictionaryEntry *t = NULL; + do { + char tmp[30]; + snprintf(tmp, sizeof(tmp), "teletext_%d", i); + t = av_dict_get(stream->metadata, tmp, NULL, 0); + if (t) { + char lang[strlen(t->value)]; + if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) { + track.Name = lang; + player->manager.addTeletextTrack(track); + } + } + i++; + } while (t); + } else { + if (!stream->codec->codec) { + stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id); + if (!stream->codec->codec) + fprintf(stderr, "avcodec_find_decoder failed for subtitle track %d\n", n); + else if (avcodec_open2(stream->codec, stream->codec->codec, NULL)) { + fprintf(stderr, "avcodec_open2 failed for subtitle track %d\n", n); + stream->codec->codec = NULL; + } + } + if (stream->codec->codec) + player->manager.addSubtitleTrack(track); + } + break; + } + default: + fprintf(stderr, "not handled or unknown codec_type %d\n", stream->codec->codec_type); + break; + } - break; - } - default: - fprintf(stderr, "not handled or unknown codec_type %d\n", stream->codec->codec_type); - break; } - } /* for */ - - return true; + return true; } bool Input::Stop() @@ -622,11 +583,11 @@ bool Input::Stop() bool Input::Seek(float sec, bool absolute) { - if (absolute) - seek_sec_abs = sec, seek_sec_rel = 0.0; - else - seek_sec_abs = -1.0, seek_sec_rel = sec; - return true; + if (absolute) + seek_sec_abs = sec, seek_sec_rel = 0.0; + else + seek_sec_abs = -1.0, seek_sec_rel = sec; + return true; } bool Input::GetDuration(double &duration) diff --git a/libeplayer3/manager.cpp b/libeplayer3/manager.cpp index 5f54bb2..0a2e758 100644 --- a/libeplayer3/manager.cpp +++ b/libeplayer3/manager.cpp @@ -17,10 +17,6 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include "manager.h" diff --git a/libeplayer3/output.cpp b/libeplayer3/output.cpp index 013928f..2ee1bb1 100644 --- a/libeplayer3/output.cpp +++ b/libeplayer3/output.cpp @@ -17,10 +17,6 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include @@ -59,7 +55,6 @@ Output::Output() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); videofd = audiofd = -1; videoWriter = audioWriter = NULL; videoStream = audioStream = NULL; @@ -67,13 +62,11 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); Output::~Output() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); Close(); } bool Output::Open() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock v_lock(videoMutex); OpenThreads::ScopedLock a_lock(audioMutex); @@ -106,7 +99,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Close() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); Stop(); OpenThreads::ScopedLock v_lock(videoMutex); @@ -126,7 +118,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Play() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool ret = true; OpenThreads::ScopedLock v_lock(videoMutex); @@ -151,7 +142,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Stop() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool ret = true; OpenThreads::ScopedLock v_lock(videoMutex); @@ -171,14 +161,13 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); dioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); if (dioctl(audiofd, AUDIO_STOP, NULL)) ret = false; - } + } return ret; } bool Output::Pause() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool ret = true; OpenThreads::ScopedLock v_lock(videoMutex); @@ -192,14 +181,13 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); if (audiofd > -1) { if (dioctl(audiofd, AUDIO_PAUSE, NULL)) ret = false; - } + } return ret; } bool Output::Continue() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool ret = true; OpenThreads::ScopedLock v_lock(videoMutex); @@ -213,14 +201,13 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); if (audiofd > -1) { if (dioctl(audiofd, AUDIO_CONTINUE, NULL)) ret = false; - } + } return ret; } bool Output::Mute(bool b) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock a_lock(audioMutex); //AUDIO_SET_MUTE has no effect with new player @@ -233,7 +220,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Flush() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool ret = true; OpenThreads::ScopedLock v_lock(videoMutex); @@ -250,7 +236,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::FastForward(int speed) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock v_lock(videoMutex); if (videofd > -1 && dioctl(videofd, VIDEO_FAST_FORWARD, speed)) @@ -261,7 +246,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::SlowMotion(int speed) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock v_lock(videoMutex); if (videofd > -1 && dioctl(videofd, VIDEO_SLOWMOTION, speed)) @@ -272,7 +256,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::AVSync(bool b) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock a_lock(audioMutex); if (audiofd > -1 && dioctl(audiofd, AUDIO_SET_AV_SYNC, b)) return false; @@ -282,7 +265,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::ClearAudio() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock a_lock(audioMutex); if (audiofd > -1 && dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL)) return false; @@ -292,7 +274,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::ClearVideo() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock v_lock(videoMutex); if (videofd > -1 && dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL)) return false; @@ -302,7 +283,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Clear() { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool aret = ClearAudio(); bool vret = ClearVideo(); return aret && vret; @@ -310,7 +290,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::GetPts(int64_t &pts) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); pts = 0; return ((videofd > -1 && !dioctl(videofd, VIDEO_GET_PTS, (void *) &pts)) || (audiofd > -1 && !dioctl(audiofd, AUDIO_GET_PTS, (void *) &pts))); @@ -318,7 +297,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::GetFrameCount(int64_t &framecount) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); dvb_play_info_t playInfo; if ((videofd > -1 && dioctl(videofd, VIDEO_GET_PLAY_INFO, (void *) &playInfo)) || @@ -331,7 +309,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::SwitchAudio(AVStream *stream) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock a_lock(audioMutex); if (stream == audioStream) return true; @@ -353,7 +330,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::SwitchVideo(AVStream *stream) { -fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); OpenThreads::ScopedLock v_lock(videoMutex); if (stream == videoStream) return true; @@ -375,7 +351,6 @@ fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); bool Output::Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts) { -//fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { OpenThreads::ScopedLock v_lock(videoMutex); diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index 95b8db0..eba06ae 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -3,10 +3,6 @@ * duckbox 2010 */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include @@ -29,9 +25,9 @@ static pthread_t supervisorThread; Player::Player() { - input.player = this; - output.player = this; - manager.player = this; + input.player = this; + output.player = this; + manager.player = this; hasThreadStarted = 0; } @@ -51,69 +47,69 @@ void *Player::SupervisorThread(void *arg) bool Player::Open(const char *Url) { - if (isPlaying) + if (isPlaying) Stop(); // shouldn't happen. Most definitely a bug - fprintf(stderr, "URL=%s\n", Url); + fprintf(stderr, "URL=%s\n", Url); - if (isPlaying) { // shouldn't happen - fprintf(stderr, "playback already running\n"); + if (isPlaying) { // shouldn't happen + fprintf(stderr, "playback already running\n"); return false; - } - - isHttp = 0; - - if (!strncmp("file://", Url, 7) || !strncmp("myts://", Url, 7)) { - if (!strncmp("myts://", Url, 7)) { - url = "file"; - url += (Url + 4); - noprobe = 1; - } else { - noprobe = 0; - url = Url; } - } else if (strstr(Url, "://")) { + + isHttp = 0; + + if (!strncmp("file://", Url, 7) || !strncmp("myts://", Url, 7)) { + if (!strncmp("myts://", Url, 7)) { + url = "file"; + url += (Url + 4); + noprobe = 1; + } else { + noprobe = 0; + url = Url; + } + } else if (strstr(Url, "://")) { isHttp = 1; if (!strncmp("mms://", Url, 6)) { - url = "mmst"; - url += (Url + 3); + url = "mmst"; + url += (Url + 3); } else - url = Url; - } else { - fprintf(stderr, "Unknown stream (%s)\n", Url); + url = Url; + } else { + fprintf(stderr, "Unknown stream (%s)\n", Url); return false; - } - manager.clearTracks(); + } + manager.clearTracks(); - if (!input.Init(url.c_str())) - return false; + if (!input.Init(url.c_str())) + return false; - fprintf(stderr, "exiting with value 0\n"); + fprintf(stderr, "exiting with value 0\n"); - return true; + return true; } bool Player::Close() { - bool ret = true; + bool ret = true; - isPaused = 0; - isPlaying = 0; - isForwarding = 0; - isBackWard = 0; - isSlowMotion = 0; - Speed = 0; - url.clear(); + isPaused = 0; + isPlaying = 0; + isForwarding = 0; + isBackWard = 0; + isSlowMotion = 0; + Speed = 0; + url.clear(); - return ret; + return ret; } bool Player::Play() { - pthread_attr_t attr; - bool ret = true; + pthread_attr_t attr; + bool ret = true; - if (!isPlaying) { + if (!isPlaying) { AVSync = 1; output.AVSync(true); @@ -121,55 +117,55 @@ bool Player::Play() ret = output.Play(); if (!ret) { - isCreationPhase = 0; // allow thread to go into next state + isCreationPhase = 0; // allow thread to go into next state } else { - isPlaying = 1; - isPaused = 0; - isForwarding = 0; - if (isBackWard) { + isPlaying = 1; + isPaused = 0; + isForwarding = 0; + if (isBackWard) { isBackWard = 0; output.Mute(false); - } - isSlowMotion = 0; - Speed = 1; - - if (hasThreadStarted == 0) { - int error; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, this))) { - fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error)); - - ret = false; - } else { - fprintf(stderr, "Created thread\n"); } - } + isSlowMotion = 0; + Speed = 1; - fprintf(stderr, "clearing isCreationPhase!\n"); + if (hasThreadStarted == 0) { + int error; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - isCreationPhase = 0; // allow thread to go into next state + if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, this))) { + fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error)); + + ret = false; + } else { + fprintf(stderr, "Created thread\n"); + } + } + + fprintf(stderr, "clearing isCreationPhase!\n"); + + isCreationPhase = 0; // allow thread to go into next state } - } else { - fprintf(stderr,"playback already running\n"); - ret = false; - } + } else { + fprintf(stderr,"playback already running\n"); + ret = false; + } - fprintf(stderr, "exiting with value %d\n", ret); + fprintf(stderr, "exiting with value %d\n", ret); - return ret; + return ret; } bool Player::Pause() { - bool ret = true; + bool ret = true; - if (isPlaying && !isPaused) { + if (isPlaying && !isPaused) { if (isSlowMotion) - output.Clear(); + output.Clear(); output.Pause(); @@ -177,63 +173,62 @@ bool Player::Pause() //isPlaying = 1; isForwarding = 0; if (isBackWard) { - isBackWard = 0; - output.Mute(false); + isBackWard = 0; + output.Mute(false); + } + isSlowMotion = 0; + Speed = 1; + } else { + fprintf(stderr,"playback not playing or already in pause mode\n"); + ret = false; } - isSlowMotion = 0; - Speed = 1; - } else { - fprintf(stderr,"playback not playing or already in pause mode\n"); - ret = false; - } - fprintf(stderr, "exiting with value %d\n", ret); + fprintf(stderr, "exiting with value %d\n", ret); - return ret; + return ret; } bool Player::Continue() { - int ret = true; + int ret = true; - if (isPlaying && (isPaused || isForwarding - || isBackWard || isSlowMotion)) { + if (isPlaying && (isPaused || isForwarding || isBackWard || isSlowMotion)) { - if (isSlowMotion) - output.Clear(); + if (isSlowMotion) + output.Clear(); - output.Continue(); + output.Continue(); - isPaused = 0; - //isPlaying = 1; - isForwarding = 0; - if (isBackWard) { - isBackWard = 0; - output.Mute(false); + isPaused = 0; + //isPlaying = 1; + isForwarding = 0; + if (isBackWard) { + isBackWard = 0; + output.Mute(false); + } + isSlowMotion = 0; + Speed = 1; + } else { + fprintf(stderr,"continue not possible\n"); + ret = false; } - isSlowMotion = 0; - Speed = 1; - } else { - fprintf(stderr,"continue not possible\n"); - ret = false; - } - return ret; + return ret; } bool Player::Stop() { - bool ret = true; - int wait_time = 20; + bool ret = true; + int wait_time = 20; - if (isPlaying) { + if (isPlaying) { isPaused = 0; isPlaying = 0; isForwarding = 0; if (isBackWard) { - isBackWard = 0; - output.Mute(false); + isBackWard = 0; + output.Mute(false); } isSlowMotion = 0; Speed = 0; @@ -241,40 +236,40 @@ bool Player::Stop() output.Stop(); input.Stop(); - } else { - fprintf(stderr,"stop not possible\n"); - ret = false; - } + } else { + fprintf(stderr,"stop not possible\n"); + ret = false; + } - while ((hasThreadStarted == 1) && (--wait_time) > 0) { - fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); + while ((hasThreadStarted == 1) && (--wait_time) > 0) { + fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); - usleep(100000); - } + usleep(100000); + } - if (wait_time == 0) { - fprintf(stderr,"Timeout waiting for thread!\n"); + if (wait_time == 0) { + fprintf(stderr,"Timeout waiting for thread!\n"); - ret = false; - } + ret = false; + } - fprintf(stderr, "exiting with value %d\n", ret); + fprintf(stderr, "exiting with value %d\n", ret); - return ret; + return ret; } // FIXME bool Player::Terminate() { - bool ret = true; - int wait_time = 20; + bool ret = true; + int wait_time = 20; - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); - if (isPlaying) { + if (isPlaying) { if (!abortRequested && !output.Flush()) { - fprintf(stderr,"failed to flush output.\n"); + fprintf(stderr,"failed to flush output.\n"); } ret = input.Stop(); @@ -285,93 +280,91 @@ bool Player::Terminate() isSlowMotion = 0; Speed = 0; - } else { + } else { /* fixme: konfetti: we should return an error here but this seems to be a condition which * can happen and is not a real error, which leads to a dead neutrino. should investigate * here later. */ - } + } - while ((hasThreadStarted == 1) && (--wait_time) > 0) { - fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); + while ((hasThreadStarted == 1) && (--wait_time) > 0) { + fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); - usleep(100000); - } + usleep(100000); + } - if (wait_time == 0) { - fprintf(stderr,"Timeout waiting for thread!\n"); + if (wait_time == 0) { + fprintf(stderr,"Timeout waiting for thread!\n"); - ret = false; - } + ret = false; + } - fprintf(stderr, "exiting with value %d\n", ret); + fprintf(stderr, "exiting with value %d\n", ret); - return ret; + return ret; } bool Player::FastForward(int speed) { - int ret = true; + int ret = true; - /* Audio only forwarding not supported */ - if (isVideo && !isHttp && !isBackWard - && (!isPaused || isPlaying)) { + /* Audio only forwarding not supported */ + if (isVideo && !isHttp && !isBackWard && (!isPaused || isPlaying)) { - if ((speed <= 0) || (speed > cMaxSpeed_ff)) { - fprintf(stderr, "speed %d out of range (1 - %d) \n", speed, cMaxSpeed_ff); - return false; + if ((speed <= 0) || (speed > cMaxSpeed_ff)) { + fprintf(stderr, "speed %d out of range (1 - %d) \n", speed, cMaxSpeed_ff); + return false; + } + + isForwarding = 1; + Speed = speed; + output.FastForward(speed); + } else { + fprintf(stderr,"fast forward not possible\n"); + ret = false; } - isForwarding = 1; - Speed = speed; - output.FastForward(speed); - } else { - fprintf(stderr,"fast forward not possible\n"); - ret = false; - } - - return ret; + return ret; } bool Player::FastBackward(int speed) { - bool ret = true; + bool ret = true; - /* Audio only reverse play not supported */ - if (isVideo && !isForwarding - && (!isPaused || isPlaying)) { + /* Audio only reverse play not supported */ + if (isVideo && !isForwarding && (!isPaused || isPlaying)) { if ((speed > 0) || (speed < cMaxSpeed_fr)) { - fprintf(stderr, "speed %d out of range (0 - %d) \n", speed, cMaxSpeed_fr); - return false; + fprintf(stderr, "speed %d out of range (0 - %d) \n", speed, cMaxSpeed_fr); + return false; } if (speed == 0) { - isBackWard = false; - Speed = false; /* reverse end */ + isBackWard = false; + Speed = false; /* reverse end */ } else { - Speed = speed; - isBackWard = true; + Speed = speed; + isBackWard = true; } output.Clear(); #if 0 if (output->Command(player, OUTPUT_REVERSE, NULL) < 0) { - fprintf(stderr,"OUTPUT_REVERSE failed\n"); - isBackWard = 0; - Speed = 1; - ret = false; + fprintf(stderr,"OUTPUT_REVERSE failed\n"); + isBackWard = 0; + Speed = 1; + ret = false; } #endif - } else { - fprintf(stderr,"fast backward not possible\n"); - ret = false; - } + } else { + fprintf(stderr,"fast backward not possible\n"); + ret = false; + } - if (isBackWard) - output.Mute(true); + if (isBackWard) + output.Mute(true); - return ret; + return ret; } bool Player::SlowMotion(int repeats) @@ -381,13 +374,13 @@ bool Player::SlowMotion(int repeats) Continue(); switch (repeats) { - case 2: - case 4: - case 8: - isSlowMotion = true; - break; - default: - repeats = 0; + case 2: + case 4: + case 8: + isSlowMotion = true; + break; + default: + repeats = 0; } output.SlowMotion(repeats); @@ -399,8 +392,8 @@ bool Player::SlowMotion(int repeats) bool Player::Seek(float pos, bool absolute) { - output.Clear(); - return input.Seek(pos, absolute); + output.Clear(); + return input.Seek(pos, absolute); } bool Player::GetPts(int64_t &pts) @@ -419,10 +412,10 @@ bool Player::GetFrameCount(int64_t &frameCount) bool Player::GetDuration(double &duration) { - duration = -1; - if (isPlaying) - return input.GetDuration(duration); - return false; + duration = -1; + if (isPlaying) + return input.GetDuration(duration); + return false; } bool Player::SwitchVideo(int pid) diff --git a/libeplayer3/writer/divx.cpp b/libeplayer3/writer/divx.cpp index 323dd27..5133e82 100644 --- a/libeplayer3/writer/divx.cpp +++ b/libeplayer3/writer/divx.cpp @@ -19,10 +19,6 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include @@ -64,51 +60,50 @@ bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A if (fd < 0 || !packet) return false; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers - unsigned int FakeHeaderLength; - unsigned char Version = 5; - unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; - unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */ - BitPacker_t ld = { FakeHeaders, 0, 32 }; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers + unsigned int FakeHeaderLength; + unsigned char Version = 5; + unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; + unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */ + BitPacker_t ld = { FakeHeaders, 0, 32 }; - usecPerFrame = 1000000 / av_q2d(stream->r_frame_rate); + usecPerFrame = 1000000 / av_q2d(stream->r_frame_rate); - memset(FakeHeaders, 0, sizeof(FakeHeaders)); + memset(FakeHeaders, 0, sizeof(FakeHeaders)); - /* Create info record for frame parser */ - /* divx4 & 5 - VOS - PutBits(&ld, 0x0, 8); - PutBits(&ld, 0x0, 8); - */ - PutBits(&ld, 0x1b0, 32); // startcode - PutBits(&ld, 0, 8); // profile = reserved - PutBits(&ld, 0x1b2, 32); // startcode (user data) - PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file - PutBits(&ld, usecPerFrame, 32); - // microseconds per frame - FlushBits(&ld); + /* Create info record for frame parser */ + /* divx4 & 5 + VOS + PutBits(&ld, 0x0, 8); + PutBits(&ld, 0x0, 8); + */ + PutBits(&ld, 0x1b0, 32); // startcode + PutBits(&ld, 0, 8); // profile = reserved + PutBits(&ld, 0x1b2, 32); // startcode (user data) + PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file + PutBits(&ld, usecPerFrame, 32); + // microseconds per frame + FlushBits(&ld); - FakeHeaderLength = (ld.Ptr - (FakeHeaders)); + FakeHeaderLength = (ld.Ptr - (FakeHeaders)); - struct iovec iov[4]; - int ic = 0; - iov[ic].iov_base = PesHeader; - iov[ic++].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); - iov[ic].iov_base = FakeHeaders; - iov[ic++].iov_len = FakeHeaderLength; + struct iovec iov[4]; + int ic = 0; + iov[ic].iov_base = PesHeader; + iov[ic++].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); + iov[ic].iov_base = FakeHeaders; + iov[ic++].iov_len = FakeHeaderLength; - if (initialHeader) { - iov[ic].iov_base = stream->codec->extradata; - iov[ic++].iov_len = stream->codec->extradata_size; + if (initialHeader) { + iov[ic].iov_base = stream->codec->extradata; + iov[ic++].iov_len = stream->codec->extradata_size; + initialHeader = false; + } + iov[ic].iov_base = packet->data; + iov[ic++].iov_len = packet->size; - initialHeader = false; - } - iov[ic].iov_base = packet->data; - iov[ic++].iov_len = packet->size; - - return writev(fd, iov, ic) > -1; + return writev(fd, iov, ic) > -1; } WriterDIVX::WriterDIVX() diff --git a/libeplayer3/writer/dts.cpp b/libeplayer3/writer/dts.cpp index 06d1aaa..aac6543 100644 --- a/libeplayer3/writer/dts.cpp +++ b/libeplayer3/writer/dts.cpp @@ -31,7 +31,7 @@ #include "writer.h" #define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size. -#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE) +#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE) class WriterDTS : public Writer { @@ -45,33 +45,33 @@ bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream if (fd < 0 || !packet) return false; - unsigned char PesHeader[PES_AUDIO_HEADER_SIZE]; + unsigned char PesHeader[PES_AUDIO_HEADER_SIZE]; // #define DO_BYTESWAP #ifdef DO_BYTESWAP - unsigned char Data[packet->size]; - memcpy(Data, packet->data, packet->size); + unsigned char Data[packet->size]; + memcpy(Data, packet->data, packet->size); - /* 16-bit byte swap all data before injecting it */ - for (i = 0; i < packet->size; i += 2) { - unsigned char Tmp = Data[i]; - Data[i] = Data[i + 1]; - Data[i + 1] = Tmp; - } + /* 16-bit byte swap all data before injecting it */ + for (i = 0; i < packet->size; i += 2) { + unsigned char Tmp = Data[i]; + Data[i] = Data[i + 1]; + Data[i + 1] = Tmp; + } #endif - struct iovec iov[2]; + struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE /*PRIVATE_STREAM_1_PES_START_CODE */ , pts, 0); + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE /*PRIVATE_STREAM_1_PES_START_CODE */ , pts, 0); #ifdef DO_BYTESPWAP - iov[1].iov_base = Data; + iov[1].iov_base = Data; #else - iov[1].iov_base = packet->data; + iov[1].iov_base = packet->data; #endif - iov[1].iov_len = packet->size; + iov[1].iov_len = packet->size; - return writev(fd, iov, 2) > -1; + return writev(fd, iov, 2) > -1; } WriterDTS::WriterDTS() diff --git a/libeplayer3/writer/flac.cpp b/libeplayer3/writer/flac.cpp index 1665c0d..f97b913 100644 --- a/libeplayer3/writer/flac.cpp +++ b/libeplayer3/writer/flac.cpp @@ -42,15 +42,15 @@ bool WriterFLAC::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* strea if (fd < 0 || !packet) return -1; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - struct iovec iov[2]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); - iov[1].iov_base = packet->data; - iov[1].iov_len = packet->size; + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; - return writev(fd, iov, 2) > -1; + return writev(fd, iov, 2) > -1; } WriterFLAC::WriterFLAC() diff --git a/libeplayer3/writer/h263.cpp b/libeplayer3/writer/h263.cpp index 469e054..bb7e60a 100644 --- a/libeplayer3/writer/h263.cpp +++ b/libeplayer3/writer/h263.cpp @@ -39,27 +39,27 @@ bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* strea { if (fd < 0 || !packet) return false; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int HeaderLength = InsertPesHeader(PesHeader, packet->size, H263_VIDEO_PES_START_CODE, pts, 0); + int HeaderLength = InsertPesHeader(PesHeader, packet->size, H263_VIDEO_PES_START_CODE, pts, 0); - int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); + int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); - int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; - PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; - PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; - PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; - PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; + PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; + PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; + PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; + PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; - HeaderLength += PrivateHeaderLength; + HeaderLength += PrivateHeaderLength; - struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = HeaderLength; - iov[1].iov_base = packet->data; - iov[1].iov_len = packet->size; - return writev(fd, iov, 2) > -1; + struct iovec iov[2]; + iov[0].iov_base = PesHeader; + iov[0].iov_len = HeaderLength; + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; + return writev(fd, iov, 2) > -1; } WriterH263::WriterH263() diff --git a/libeplayer3/writer/h264.cpp b/libeplayer3/writer/h264.cpp index 6e7001f..5f5f06f 100644 --- a/libeplayer3/writer/h264.cpp +++ b/libeplayer3/writer/h264.cpp @@ -31,17 +31,17 @@ #include "pes.h" #include "writer.h" -#define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24 -#define CONTAINER_PARAMETERS_VERSION 0x00 +#define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24 +#define CONTAINER_PARAMETERS_VERSION 0x00 typedef struct avcC_s { - unsigned char Version; /* configurationVersion */ - unsigned char Profile; /* AVCProfileIndication */ - unsigned char Compatibility; /* profile_compatibility */ - unsigned char Level; /* AVCLevelIndication */ - unsigned char NalLengthMinusOne; /* held in bottom two bits */ - unsigned char NumParamSets; /* held in bottom 5 bits */ - unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture */ + unsigned char Version; // configurationVersion + unsigned char Profile; // AVCProfileIndication + unsigned char Compatibility; // profile_compatibility + unsigned char Level; // AVCLevelIndication + unsigned char NalLengthMinusOne; // held in bottom two bits + unsigned char NumParamSets; // held in bottom 5 bits + unsigned char Params[1]; // {length,params}{length,params}...sequence then picture } avcC_t; const unsigned char Head[] = { 0, 0, 0, 1 }; @@ -68,204 +68,200 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A { if (fd < 0 || !packet) return false; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - unsigned long long int VideoPts; - unsigned int TimeDelta; - unsigned int TimeScale; - int len = 0; - int ic = 0; - struct iovec iov[128]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned long long int VideoPts; + unsigned int TimeDelta; + unsigned int TimeScale; + int len = 0; + int ic = 0; + struct iovec iov[128]; - TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */ - TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */ - VideoPts = pts; + TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */ + TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */ + VideoPts = pts; + + if ((packet->size > 3) + && ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01) + || (packet->data[0] == 0xff && packet->data[1] == 0xff && packet->data[2] == 0xff && packet->data[3] == 0xff))) { + unsigned int PacketLength = 0; + unsigned int FakeStartCode = /* (call->Version << 8) | */ PES_VERSION_FAKE_START_CODE; + iov[ic++].iov_base = PesHeader; + if (initialHeader) { + initialHeader = false; + iov[ic].iov_base = stream->codec->extradata; + iov[ic++].iov_len = stream->codec->extradata_size; + PacketLength += stream->codec->extradata_size; + } + iov[ic].iov_base = packet->data; + iov[ic++].iov_len = packet->size; + PacketLength += packet->size; + // Hellmaster1024: + // some packets will only be accepted by the player if we send one byte more than data is available. + // The content of this byte does not matter. It will be ignored by the player + iov[ic].iov_base = (void *) ""; + iov[ic++].iov_len = 1; + iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); + return writev(fd, iov, ic) > -1; + } - if ((packet->size > 3) - && ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01) - || (packet->data[0] == 0xff && packet->data[1] == 0xff && packet->data[2] == 0xff && packet->data[3] == 0xff))) { - unsigned int PacketLength = 0; - unsigned int FakeStartCode = /* (call->Version << 8) | */ PES_VERSION_FAKE_START_CODE; - iov[ic++].iov_base = PesHeader; if (initialHeader) { - initialHeader = false; - iov[ic].iov_base = stream->codec->extradata; - iov[ic++].iov_len = stream->codec->extradata_size; - PacketLength += stream->codec->extradata_size; - } - iov[ic].iov_base = packet->data; - iov[ic++].iov_len = packet->size; - PacketLength += packet->size; - /*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than - data is available. The content of this byte does not matter. It will be ignored - by the player */ - iov[ic].iov_base = (void *) ""; - iov[ic++].iov_len = 1; - iov[0].iov_len = - InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); - return writev(fd, iov, ic) > -1; - } + avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata; + unsigned int i; + unsigned int ParamSets; + unsigned int ParamOffset; + unsigned int InitialHeaderLength = 0; + unsigned int ParametersLength; - if (initialHeader) { - avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata; - unsigned int i; - unsigned int ParamSets; - unsigned int ParamOffset; - unsigned int InitialHeaderLength = 0; - unsigned int ParametersLength; + if (avcCHeader == NULL) { + fprintf(stderr, "stream->codec->extradata == NULL\n"); + return false; + } - if (avcCHeader == NULL) { - fprintf(stderr, "stream->codec->extradata == NULL\n"); - return false; + if (avcCHeader->Version != 1) + fprintf(stderr, "Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version); + + ParametersLength = 0; + + unsigned char HeaderData[19]; + HeaderData[ParametersLength++] = 0x00; // Start code + HeaderData[ParametersLength++] = 0x00; + HeaderData[ParametersLength++] = 0x01; + HeaderData[ParametersLength++] = NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS; + // Container message version - changes when/if we vary the format of the message + HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION; + HeaderData[ParametersLength++] = 0xff; // Field separator + + if (TimeDelta == 0xffffffff) + TimeDelta = (TimeScale > 1000) ? 1001 : 1; + + HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale + HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff; + HeaderData[ParametersLength++] = 0xff; + HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff; + HeaderData[ParametersLength++] = TimeScale & 0xff; + HeaderData[ParametersLength++] = 0xff; + + HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period + HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff; + HeaderData[ParametersLength++] = 0xff; + HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff; + HeaderData[ParametersLength++] = TimeDelta & 0xff; + HeaderData[ParametersLength++] = 0xff; + HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits + + assert(ParametersLength <= sizeof(HeaderData)); + + ic = 0; + iov[ic].iov_base = PesHeader; + iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + iov[ic].iov_base = HeaderData; + iov[ic++].iov_len = ParametersLength; + len = writev(fd, iov, ic); + if (len < 0) + return false; + + NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1; + ParamSets = avcCHeader->NumParamSets & 0x1f; + + ParamOffset = 0; + ic = 0; + iov[ic++].iov_base = PesHeader; + for (i = 0; i < ParamSets; i++) { + unsigned int PsLength = + (avcCHeader->Params[ParamOffset] << 8) + + avcCHeader->Params[ParamOffset + 1]; + + iov[ic].iov_base = (char *) Head; + iov[ic++].iov_len = sizeof(Head); + InitialHeaderLength += sizeof(Head); + iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2]; + iov[ic++].iov_len = PsLength; + InitialHeaderLength += PsLength; + ParamOffset += PsLength + 2; + } + + ParamSets = avcCHeader->Params[ParamOffset]; + + ParamOffset++; + for (i = 0; i < ParamSets; i++) { + unsigned int PsLength = + (avcCHeader->Params[ParamOffset] << 8) + + avcCHeader->Params[ParamOffset + 1]; + + iov[ic].iov_base = (char *) Head; + iov[ic++].iov_len = sizeof(Head); + InitialHeaderLength += sizeof(Head); + iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2]; + iov[ic++].iov_len = PsLength; + InitialHeaderLength += PsLength; + ParamOffset += PsLength + 2; + } + + iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + ssize_t l = writev(fd, iov, ic); + if (l < 0) + return false; + len += l; + + initialHeader = 0; } - if (avcCHeader->Version != 1) - fprintf(stderr, "Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version); + unsigned int SampleSize = packet->size; + unsigned int NalStart = 0; + unsigned int VideoPosition = 0; - ParametersLength = 0; + do { + unsigned int NalLength; + unsigned char NalData[4]; + int NalPresent = 1; - unsigned char HeaderData[19]; - HeaderData[ParametersLength++] = 0x00; // Start code - HeaderData[ParametersLength++] = 0x00; - HeaderData[ParametersLength++] = 0x01; - HeaderData[ParametersLength++] = - NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS; - // Container message version - changes when/if we vary the format of the message - HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION; - HeaderData[ParametersLength++] = 0xff; // Field separator + memcpy(NalData, packet->data + VideoPosition, NalLengthBytes); + VideoPosition += NalLengthBytes; + NalStart += NalLengthBytes; + switch (NalLengthBytes) { + case 1: + NalLength = (NalData[0]); + break; + case 2: + NalLength = (NalData[0] << 8) | (NalData[1]); + break; + case 3: + NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]); + break; + default: + NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); + break; + } - if (TimeDelta == 0xffffffff) - TimeDelta = (TimeScale > 1000) ? 1001 : 1; + if (NalStart + NalLength > SampleSize) { + fprintf(stderr, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart); + NalStart = SampleSize; + } else { + NalStart += NalLength; + ic = 0; + iov[ic++].iov_base = PesHeader; - HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale - HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff; - HeaderData[ParametersLength++] = 0xff; - HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff; - HeaderData[ParametersLength++] = TimeScale & 0xff; - HeaderData[ParametersLength++] = 0xff; + if (NalPresent) { + NalPresent = 0; + iov[ic].iov_base = (char *) Head; + iov[ic++].iov_len = sizeof(Head); + } - HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period - HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff; - HeaderData[ParametersLength++] = 0xff; - HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff; - HeaderData[ParametersLength++] = TimeDelta & 0xff; - HeaderData[ParametersLength++] = 0xff; - HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits + iov[ic].iov_base = packet->data + VideoPosition; + iov[ic++].iov_len = NalLength; + VideoPosition += NalLength; - assert(ParametersLength <= sizeof(HeaderData)); + iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); + ssize_t l = writev(fd, iov, ic); + if (l < 0) + return false; + len += l; - ic = 0; - iov[ic].iov_base = PesHeader; - iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); - iov[ic].iov_base = HeaderData; - iov[ic++].iov_len = ParametersLength; - len = writev(fd, iov, ic); - if (len < 0) - return false; + VideoPts = INVALID_PTS_VALUE; + } + } while (NalStart < SampleSize); - NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1; - ParamSets = avcCHeader->NumParamSets & 0x1f; - - ParamOffset = 0; - ic = 0; - iov[ic++].iov_base = PesHeader; - for (i = 0; i < ParamSets; i++) { - unsigned int PsLength = - (avcCHeader->Params[ParamOffset] << 8) + - avcCHeader->Params[ParamOffset + 1]; - - iov[ic].iov_base = (char *) Head; - iov[ic++].iov_len = sizeof(Head); - InitialHeaderLength += sizeof(Head); - iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2]; - iov[ic++].iov_len = PsLength; - InitialHeaderLength += PsLength; - ParamOffset += PsLength + 2; - } - - ParamSets = avcCHeader->Params[ParamOffset]; - - ParamOffset++; - for (i = 0; i < ParamSets; i++) { - unsigned int PsLength = - (avcCHeader->Params[ParamOffset] << 8) + - avcCHeader->Params[ParamOffset + 1]; - - iov[ic].iov_base = (char *) Head; - iov[ic++].iov_len = sizeof(Head); - InitialHeaderLength += sizeof(Head); - iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2]; - iov[ic++].iov_len = PsLength; - InitialHeaderLength += PsLength; - ParamOffset += PsLength + 2; - } - - iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); - ssize_t l = writev(fd, iov, ic); - if (l < 0) - return false; - len += l; - - initialHeader = 0; - } - - unsigned int SampleSize = packet->size; - unsigned int NalStart = 0; - unsigned int VideoPosition = 0; - - do { - unsigned int NalLength; - unsigned char NalData[4]; - int NalPresent = 1; - - memcpy(NalData, packet->data + VideoPosition, NalLengthBytes); - VideoPosition += NalLengthBytes; - NalStart += NalLengthBytes; - switch (NalLengthBytes) { - case 1: - NalLength = (NalData[0]); - break; - case 2: - NalLength = (NalData[0] << 8) | (NalData[1]); - break; - case 3: - NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]); - break; - default: - NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); - break; - } - - if (NalStart + NalLength > SampleSize) { - fprintf(stderr, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart); - NalStart = SampleSize; - } else { - NalStart += NalLength; - ic = 0; - iov[ic++].iov_base = PesHeader; - - if (NalPresent) { - NalPresent = 0; - iov[ic].iov_base = (char *) Head; - iov[ic++].iov_len = sizeof(Head); - } - - iov[ic].iov_base = packet->data + VideoPosition; - iov[ic++].iov_len = NalLength; - VideoPosition += NalLength; - - iov[0].iov_len = - InsertPesHeader(PesHeader, NalLength, - MPEG_VIDEO_PES_START_CODE, VideoPts, 0); - ssize_t l = writev(fd, iov, ic); - if (l < 0) - return false; - len += l; - - VideoPts = INVALID_PTS_VALUE; - } - } while (NalStart < SampleSize); - - return len > -1; + return len > -1; } WriterH264::WriterH264() diff --git a/libeplayer3/writer/misc.cpp b/libeplayer3/writer/misc.cpp index e90b4aa..68731d1 100644 --- a/libeplayer3/writer/misc.cpp +++ b/libeplayer3/writer/misc.cpp @@ -24,66 +24,65 @@ #include #include #include -#include #include #include "misc.h" void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length) { - unsigned int bit_buf; - unsigned int bit_left; + unsigned int bit_buf; + unsigned int bit_left; - bit_buf = ld->BitBuffer; - bit_left = ld->Remaining; + bit_buf = ld->BitBuffer; + bit_left = ld->Remaining; #ifdef DEBUG_PUTBITS - if (ld->debug) + if (ld->debug) dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n", code, length, bit_buf, bit_left); #endif /* DEBUG_PUTBITS */ - if (length < bit_left) { - /* fits into current buffer */ - bit_buf = (bit_buf << length) | code; - bit_left -= length; - } else { - /* doesn't fit */ - bit_buf <<= bit_left; - bit_buf |= code >> (length - bit_left); - ld->Ptr[0] = (char) (bit_buf >> 24); - ld->Ptr[1] = (char) (bit_buf >> 16); - ld->Ptr[2] = (char) (bit_buf >> 8); - ld->Ptr[3] = (char) bit_buf; - ld->Ptr += 4; - length -= bit_left; - bit_buf = code & ((1 << length) - 1); - bit_left = 32 - length; - bit_buf = code; - } + if (length < bit_left) { + /* fits into current buffer */ + bit_buf = (bit_buf << length) | code; + bit_left -= length; + } else { + /* doesn't fit */ + bit_buf <<= bit_left; + bit_buf |= code >> (length - bit_left); + ld->Ptr[0] = (char) (bit_buf >> 24); + ld->Ptr[1] = (char) (bit_buf >> 16); + ld->Ptr[2] = (char) (bit_buf >> 8); + ld->Ptr[3] = (char) bit_buf; + ld->Ptr += 4; + length -= bit_left; + bit_buf = code & ((1 << length) - 1); + bit_left = 32 - length; + bit_buf = code; + } #ifdef DEBUG_PUTBITS - if (ld->debug) - dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf); + if (ld->debug) + dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf); #endif /* DEBUG_PUTBITS */ - /* writeback */ - ld->BitBuffer = bit_buf; - ld->Remaining = bit_left; + /* writeback */ + ld->BitBuffer = bit_buf; + ld->Remaining = bit_left; } void FlushBits(BitPacker_t * ld) { - ld->BitBuffer <<= ld->Remaining; - while (ld->Remaining < 32) { + ld->BitBuffer <<= ld->Remaining; + while (ld->Remaining < 32) { #ifdef DEBUG_PUTBITS - if (ld->debug) - dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24); + if (ld->debug) + dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24); #endif /* DEBUG_PUTBITS */ - *ld->Ptr++ = ld->BitBuffer >> 24; - ld->BitBuffer <<= 8; - ld->Remaining += 8; - } - ld->Remaining = 32; - ld->BitBuffer = 0; + *ld->Ptr++ = ld->BitBuffer >> 24; + ld->BitBuffer <<= 8; + ld->Remaining += 8; + } + ld->Remaining = 32; + ld->BitBuffer = 0; } diff --git a/libeplayer3/writer/mp3.cpp b/libeplayer3/writer/mp3.cpp index cebd801..73525aa 100644 --- a/libeplayer3/writer/mp3.cpp +++ b/libeplayer3/writer/mp3.cpp @@ -42,15 +42,15 @@ bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream if (fd < 0 || !packet) return false; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - struct iovec iov[2]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); - iov[1].iov_base = packet->data; - iov[1].iov_len = packet->size; + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; - return writev(fd, iov, 2) > -1; + return writev(fd, iov, 2) > -1; } WriterMP3::WriterMP3() diff --git a/libeplayer3/writer/pcm.cpp b/libeplayer3/writer/pcm.cpp index f850a43..16f4c84 100644 --- a/libeplayer3/writer/pcm.cpp +++ b/libeplayer3/writer/pcm.cpp @@ -83,150 +83,149 @@ class WriterPCM : public Writer bool WriterPCM::prepareClipPlay() { - SubFrameLen = 0; - SubFramesPerPES = 0; - breakBufferFillSize = 0; + SubFrameLen = 0; + SubFramesPerPES = 0; + breakBufferFillSize = 0; - memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv)); + memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv)); - // figure out size of subframe and set up sample rate - switch (uSampleRate) { - case 48000: - SubFrameLen = 40; - break; - case 96000: - lpcm_prv[8] |= 0x10; - SubFrameLen = 80; - break; - case 192000: - lpcm_prv[8] |= 0x20; - SubFrameLen = 160; - break; - case 44100: - lpcm_prv[8] |= 0x80; - SubFrameLen = 40; - break; - case 88200: - lpcm_prv[8] |= 0x90; - SubFrameLen = 80; - break; - case 176400: - lpcm_prv[8] |= 0xA0; - SubFrameLen = 160; - break; - default: - break; - } + // figure out size of subframe and set up sample rate + switch (uSampleRate) { + case 48000: + SubFrameLen = 40; + break; + case 96000: + lpcm_prv[8] |= 0x10; + SubFrameLen = 80; + break; + case 192000: + lpcm_prv[8] |= 0x20; + SubFrameLen = 160; + break; + case 44100: + lpcm_prv[8] |= 0x80; + SubFrameLen = 40; + break; + case 88200: + lpcm_prv[8] |= 0x90; + SubFrameLen = 80; + break; + case 176400: + lpcm_prv[8] |= 0xA0; + SubFrameLen = 160; + break; + default: + break; + } - SubFrameLen *= uNoOfChannels; - SubFrameLen *= (uBitsPerSample / 8); + SubFrameLen *= uNoOfChannels; + SubFrameLen *= (uBitsPerSample / 8); - //rewrite PES size to have as many complete subframes per PES as we can - // FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14. - SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen; - SubFrameLen *= SubFramesPerPES; + //rewrite PES size to have as many complete subframes per PES as we can + // FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14. + SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen; + SubFrameLen *= SubFramesPerPES; - //set number of channels - lpcm_prv[10] = uNoOfChannels - 1; + //set number of channels + lpcm_prv[10] = uNoOfChannels - 1; - switch (uBitsPerSample) { - case 24: - lpcm_prv[7] |= 0x20; - case 16: - break; - default: - printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample); - return false; - } + switch (uBitsPerSample) { + case 24: + lpcm_prv[7] |= 0x20; + case 16: + break; + default: + printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample); + return false; + } - return true; + return true; } int WriterPCM::writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) { - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - if (initialHeader) { - initialHeader = false; - prepareClipPlay(); - } + if (initialHeader) { + initialHeader = false; + prepareClipPlay(); + } - unsigned int n; - unsigned char *injectBuffer = (unsigned char *) malloc(SubFrameLen); - unsigned int pos; + unsigned int n; + unsigned char *injectBuffer = (unsigned char *) malloc(SubFrameLen); + unsigned int pos; - for (pos = 0; pos < size;) { + for (pos = 0; pos < size;) { //printf("PCM %s - Position=%d\n", __FUNCTION__, pos); if ((size - pos) < SubFrameLen) { - breakBufferFillSize = size - pos; - memcpy(breakBuffer, &data[pos], - sizeof(unsigned char) * breakBufferFillSize); - //printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize); - break; - } - //get first PES's worth - if (breakBufferFillSize > 0) { - memcpy(injectBuffer, breakBuffer, sizeof(unsigned char) * breakBufferFillSize); - memcpy(&injectBuffer[breakBufferFillSize], &data[pos], sizeof(unsigned char) * (SubFrameLen - breakBufferFillSize)); - pos += (SubFrameLen - breakBufferFillSize); - breakBufferFillSize = 0; - } else { - memcpy(injectBuffer, &data[pos], sizeof(unsigned char) * SubFrameLen); - pos += SubFrameLen; + breakBufferFillSize = size - pos; + memcpy(breakBuffer, &data[pos], sizeof(unsigned char) * breakBufferFillSize); + //printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize); + break; + } + //get first PES's worth + if (breakBufferFillSize > 0) { + memcpy(injectBuffer, breakBuffer, sizeof(unsigned char) * breakBufferFillSize); + memcpy(&injectBuffer[breakBufferFillSize], &data[pos], sizeof(unsigned char) * (SubFrameLen - breakBufferFillSize)); + pos += (SubFrameLen - breakBufferFillSize); + breakBufferFillSize = 0; + } else { + memcpy(injectBuffer, &data[pos], sizeof(unsigned char) * SubFrameLen); + pos += SubFrameLen; + } + + struct iovec iov[3]; + iov[0].iov_base = PesHeader; + iov[1].iov_base = lpcm_prv; + iov[1].iov_len = sizeof(lpcm_prv); + + iov[2].iov_base = injectBuffer; + iov[2].iov_len = SubFrameLen; + + //write the PCM data + if (uBitsPerSample == 16) { + for (n = 0; n < SubFrameLen; n += 2) { + unsigned char tmp; + tmp = injectBuffer[n]; + injectBuffer[n] = injectBuffer[n + 1]; + injectBuffer[n + 1] = tmp; + } + } else { + // 0 1 2 3 4 5 6 7 8 9 10 11 + // A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a + // to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c + for (n = 0; n < SubFrameLen; n += 12) { + unsigned char t, *p = &injectBuffer[n]; + t = p[0]; + p[0] = p[2]; + p[2] = p[5]; + p[5] = p[7]; + p[7] = p[11]; + p[11] = p[9]; + p[9] = p[3]; + p[3] = p[4]; + p[4] = p[8]; + p[8] = t; + } + } + + //increment err... subframe count? + lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F); + + iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, Pts, 0); + int len = writev(fd, iov, 3); + if (len < 0) + break; } + free(injectBuffer); - struct iovec iov[3]; - iov[0].iov_base = PesHeader; - iov[1].iov_base = lpcm_prv; - iov[1].iov_len = sizeof(lpcm_prv); - - iov[2].iov_base = injectBuffer; - iov[2].iov_len = SubFrameLen; - - //write the PCM data - if (uBitsPerSample == 16) { - for (n = 0; n < SubFrameLen; n += 2) { - unsigned char tmp; - tmp = injectBuffer[n]; - injectBuffer[n] = injectBuffer[n + 1]; - injectBuffer[n + 1] = tmp; - } - } else { - // 0 1 2 3 4 5 6 7 8 9 10 11 - // A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a - // to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c - for (n = 0; n < SubFrameLen; n += 12) { - unsigned char t, *p = &injectBuffer[n]; - t = p[0]; - p[0] = p[2]; - p[2] = p[5]; - p[5] = p[7]; - p[7] = p[11]; - p[11] = p[9]; - p[9] = p[3]; - p[3] = p[4]; - p[4] = p[8]; - p[8] = t; - } - } - - //increment err... subframe count? - lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F); - - iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, Pts, 0); - int len = writev(fd, iov, 3); - if (len < 0) - break; - } - free(injectBuffer); - - return size; + return size; } void WriterPCM::Init() { - initialHeader = true; - restart_audio_resampling = true; + initialHeader = true; + restart_audio_resampling = true; } extern int64_t calcPts(AVFormatContext *, AVStream *, int64_t); @@ -237,7 +236,6 @@ bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket return false; if (!packet) { -fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); restart_audio_resampling = true; return true; } @@ -246,18 +244,13 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); unsigned int packet_size = packet->size; if (restart_audio_resampling) { -fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); restart_audio_resampling = false; initialHeader = true; - if (swr) { + if (swr) swr_free(&swr); - swr = NULL; //FIXME: Needed? - } - if (decoded_frame) { + if (decoded_frame) av_frame_free(&decoded_frame); - decoded_frame = NULL; //FIXME: Needed? - } AVCodec *codec = avcodec_find_decoder(c->codec_id); @@ -276,7 +269,6 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, packet); if (len < 0) { -fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); restart_audio_resampling = true; break; } @@ -317,12 +309,10 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); e = swr_init(swr); if (e < 0) { - fprintf(stderr, - "swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n", + fprintf(stderr, "swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n", -e, (int) c->channel_layout, (int) out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16); swr_free(&swr); - swr = NULL; } } @@ -365,7 +355,7 @@ WriterPCM::WriterPCM() out_channel_layout = AV_CH_LAYOUT_STEREO; restart_audio_resampling = true; - Register(this, AV_CODEC_ID_PCM_S16LE/*FIXME*/, AUDIO_ENCODING_LPCMA); + Register(this, AV_CODEC_ID_INJECTPCM, AUDIO_ENCODING_LPCMA); } static WriterPCM writer_pcm __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/pes.cpp b/libeplayer3/writer/pes.cpp index f496fef..f14ee53 100644 --- a/libeplayer3/writer/pes.cpp +++ b/libeplayer3/writer/pes.cpp @@ -27,44 +27,11 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include #include #include -#include -#include - -#include "player.h" -#include "output.h" #include "misc.h" #include "pes.h" -#include "writer.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -/* ***************************** */ -/* Types */ -/* ***************************** */ - - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size) { diff --git a/libeplayer3/writer/vc1.cpp b/libeplayer3/writer/vc1.cpp index f656225..d451725 100644 --- a/libeplayer3/writer/vc1.cpp +++ b/libeplayer3/writer/vc1.cpp @@ -65,7 +65,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket if (fd < 0 || !packet) return false; - if (initialHeader) { + if (initialHeader) { initialHeader = false; FrameHeaderSeen = false; @@ -74,15 +74,15 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket const unsigned char Metadata[] = { - 0x00, 0x00, 0x00, 0xc5, - 0x04, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ - 0x00, 0x00, 0x00, 0x00, /* Struct A */ - 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, /* Struct B */ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0xc5, + 0x04, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ + 0x00, 0x00, 0x00, 0x00, /* Struct A */ + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, /* Struct B */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; @@ -158,7 +158,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); HeaderLength += sizeof(Vc1FrameStartCode); } - insertSampleHeader = 0; + insertSampleHeader = 0; } struct iovec iov[2]; diff --git a/libeplayer3/writer/wmv.cpp b/libeplayer3/writer/wmv.cpp index fa283d6..8fb5fba 100644 --- a/libeplayer3/writer/wmv.cpp +++ b/libeplayer3/writer/wmv.cpp @@ -33,22 +33,22 @@ #include -#define WMV3_PRIVATE_DATA_LENGTH 4 +#define WMV3_PRIVATE_DATA_LENGTH 4 static const unsigned char Metadata[] = { - 0x00, 0x00, 0x00, 0xc5, - 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc5, + 0x04, 0x00, 0x00, 0x00, #define METADATA_STRUCT_C_START 8 - 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ + 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ #define METADATA_STRUCT_A_START 12 - 0x00, 0x00, 0x00, 0x00, /* Struct A */ - 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /* Struct A */ + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, #define METADATA_STRUCT_B_START 24 - 0x60, 0x00, 0x00, 0x00, /* Struct B */ - 0x00, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, /* Struct B */ + 0x00, 0x00, 0x00, 0x00, #define METADATA_STRUCT_B_FRAMERATE_START 32 - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00 }; class WriterWMV : public Writer @@ -63,7 +63,7 @@ class WriterWMV : public Writer void WriterWMV::Init() { - initialHeader = 1; + initialHeader = 1; } bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) @@ -71,92 +71,92 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV if (fd < 0 || !packet) return false; - if (initialHeader) { + if (initialHeader) { #define PES_MIN_HEADER_SIZE 9 - unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128]; - unsigned char *PesPtr; - unsigned int MetadataLength; - unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate))); + unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128]; + unsigned char *PesPtr; + unsigned int MetadataLength; + unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate))); - PesPtr = &PesPacket[PES_MIN_HEADER_SIZE]; + PesPtr = &PesPacket[PES_MIN_HEADER_SIZE]; - memcpy(PesPtr, Metadata, sizeof(Metadata)); - PesPtr += METADATA_STRUCT_C_START; + memcpy(PesPtr, Metadata, sizeof(Metadata)); + PesPtr += METADATA_STRUCT_C_START; - unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 }; - memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size); + unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 }; + memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size); - memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH); - PesPtr += WMV3_PRIVATE_DATA_LENGTH; + memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH); + PesPtr += WMV3_PRIVATE_DATA_LENGTH; - /* Metadata Header Struct A */ - *PesPtr++ = (stream->codec->height >> 0) & 0xff; - *PesPtr++ = (stream->codec->height >> 8) & 0xff; - *PesPtr++ = (stream->codec->height >> 16) & 0xff; - *PesPtr++ = stream->codec->height >> 24; - *PesPtr++ = (stream->codec->width >> 0) & 0xff; - *PesPtr++ = (stream->codec->width >> 8) & 0xff; - *PesPtr++ = (stream->codec->width >> 16) & 0xff; - *PesPtr++ = stream->codec->width >> 24; + /* Metadata Header Struct A */ + *PesPtr++ = (stream->codec->height >> 0) & 0xff; + *PesPtr++ = (stream->codec->height >> 8) & 0xff; + *PesPtr++ = (stream->codec->height >> 16) & 0xff; + *PesPtr++ = stream->codec->height >> 24; + *PesPtr++ = (stream->codec->width >> 0) & 0xff; + *PesPtr++ = (stream->codec->width >> 8) & 0xff; + *PesPtr++ = (stream->codec->width >> 16) & 0xff; + *PesPtr++ = stream->codec->width >> 24; - PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ + PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ - *PesPtr++ = (usecPerFrame >> 0) & 0xff; - *PesPtr++ = (usecPerFrame >> 8) & 0xff; - *PesPtr++ = (usecPerFrame >> 16) & 0xff; - *PesPtr++ = usecPerFrame >> 24; + *PesPtr++ = (usecPerFrame >> 0) & 0xff; + *PesPtr++ = (usecPerFrame >> 8) & 0xff; + *PesPtr++ = (usecPerFrame >> 16) & 0xff; + *PesPtr++ = usecPerFrame >> 24; - MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE]; + MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE]; - int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); - if (write(fd, PesPacket, HeaderLength + MetadataLength) < 0) - return false; + if (write(fd, PesPacket, HeaderLength + MetadataLength) < 0) + return false; - initialHeader = false; - } - - if (packet->size > 0 && packet->data) { - int Position = 0; - bool insertSampleHeader = true; - - uint64_t _pts = pts; - - while (Position < packet->size) { - - int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); - - unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 }; - int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); - - if (insertSampleHeader) { - unsigned int PesLength; - unsigned int PrivateHeaderLength; - - PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); - /* Update PesLength */ - PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; - PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; - PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; - PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; - PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; - - HeaderLength += PrivateHeaderLength; - insertSampleHeader = false; - } - - uint8_t PacketStart[packet->size + HeaderLength]; - memcpy(PacketStart, PesHeader, HeaderLength); - memcpy(PacketStart + HeaderLength, packet->data + Position, PacketLength); - if (write(fd, PacketStart, PacketLength + HeaderLength) < 0) - return false; - - Position += PacketLength; - _pts = INVALID_PTS_VALUE; + initialHeader = false; } - } - return true; + if (packet->size > 0 && packet->data) { + int Position = 0; + bool insertSampleHeader = true; + + uint64_t _pts = pts; + + while (Position < packet->size) { + + int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); + + unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 }; + int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); + + if (insertSampleHeader) { + unsigned int PesLength; + unsigned int PrivateHeaderLength; + + PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); + /* Update PesLength */ + PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; + PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; + PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; + PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; + + HeaderLength += PrivateHeaderLength; + insertSampleHeader = false; + } + + uint8_t PacketStart[packet->size + HeaderLength]; + memcpy(PacketStart, PesHeader, HeaderLength); + memcpy(PacketStart + HeaderLength, packet->data + Position, PacketLength); + if (write(fd, PacketStart, PacketLength + HeaderLength) < 0) + return false; + + Position += PacketLength; + _pts = INVALID_PTS_VALUE; + } + } + + return true; } WriterWMV::WriterWMV()