Skip to content

Commit

Permalink
1. 为generic_demux添加mutex, 使得数据访问同步.
Browse files Browse the repository at this point in the history
2. 添加audio_codec和video_codec到media_base_info.
3. 修改打开解码器方式.

Signed-off-by: Jack <[email protected]>
  • Loading branch information
Jackarain committed Mar 14, 2013
1 parent 27f2ffa commit afc8e58
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 26 deletions.
51 changes: 38 additions & 13 deletions demux/generic_demux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ generic_demux::generic_demux(void)
, m_source_ctx(NULL)
, m_io_buffer(NULL)
, m_abort(false)
{}
{
memset(&m_base_info, 0, sizeof(m_base_info));
}

generic_demux::~generic_demux(void)
{}
Expand Down Expand Up @@ -224,22 +226,25 @@ bool generic_demux::open(boost::any ctx)
// 如果有音频, 获得音频的一些基本信息.
if (m_base_info.has_audio >= 0)
{
avrational_copy(m_format_ctx->streams[m_base_info.has_audio]->r_frame_rate, m_base_info.audio_frame_rate);
avrational_copy(m_format_ctx->streams[m_base_info.has_audio]->time_base, m_base_info.audio_time_base);
m_base_info.audio_start_time = m_format_ctx->streams[m_base_info.has_audio]->start_time;
m_base_info.sample_rate = m_format_ctx->streams[m_base_info.has_audio]->codec->sample_rate;
m_base_info.channels = m_format_ctx->streams[m_base_info.has_audio]->codec->channels;
AVStream *streams = m_format_ctx->streams[m_base_info.has_audio];
avrational_copy(streams->r_frame_rate, m_base_info.audio_frame_rate);
avrational_copy(streams->time_base, m_base_info.audio_time_base);
m_base_info.audio_start_time = streams->start_time;
m_base_info.sample_rate = streams->codec->sample_rate;
m_base_info.channels = streams->codec->channels;
m_base_info.audio_codec = streams->codec;
}

// 如果有视频, 获得视频的一些基本信息.
if (m_base_info.has_video >= 0)
{
avrational_copy(m_format_ctx->streams[m_base_info.has_video]->r_frame_rate, m_base_info.video_frame_rate);
avrational_copy(m_format_ctx->streams[m_base_info.has_video]->time_base, m_base_info.video_time_base);
m_base_info.video_start_time = m_format_ctx->streams[m_base_info.has_video]->start_time;

m_base_info.width = m_format_ctx->streams[m_base_info.has_video]->codec->width;
m_base_info.height = m_format_ctx->streams[m_base_info.has_video]->codec->height;
AVStream *streams = m_format_ctx->streams[m_base_info.has_video];
avrational_copy(streams->r_frame_rate, m_base_info.video_frame_rate);
avrational_copy(streams->time_base, m_base_info.video_time_base);
m_base_info.video_start_time = streams->start_time;
m_base_info.width = streams->codec->width;
m_base_info.height = streams->codec->height;
m_base_info.video_codec = streams->codec;
}

m_base_info.start_time = m_format_ctx->start_time;
Expand Down Expand Up @@ -267,6 +272,9 @@ bool generic_demux::open(boost::any ctx)

bool generic_demux::read_packet(AVPacket *pkt)
{
boost::mutex::scoped_lock l(m_mutex);
if (!m_format_ctx)
return false;
int ret = av_read_frame(m_format_ctx, pkt);
if (ret < 0)
return false;
Expand All @@ -275,6 +283,9 @@ bool generic_demux::read_packet(AVPacket *pkt)

bool generic_demux::seek_packet(int64_t timestamp)
{
boost::mutex::scoped_lock l(m_mutex);
if (!m_format_ctx)
return false;
int64_t seek_min = INT64_MIN;
int64_t seek_max = INT64_MAX;
int seek_flags = 0 & (~AVSEEK_FLAG_BYTE);
Expand All @@ -286,6 +297,11 @@ bool generic_demux::seek_packet(int64_t timestamp)

bool generic_demux::stream_index(enum AVMediaType type, int &index)
{
boost::mutex::scoped_lock l(m_mutex);

if (!m_format_ctx)
return false;

index = -1;

for (unsigned int i = 0; (unsigned int) i < m_format_ctx->nb_streams; i++)
Expand All @@ -302,6 +318,8 @@ bool generic_demux::stream_index(enum AVMediaType type, int &index)

bool generic_demux::query_avcodec_id(int index, enum AVCodecID &codec_id)
{
boost::mutex::scoped_lock l(m_mutex);

if (index >= 0 && index < m_format_ctx->nb_streams)
{
codec_id = m_format_ctx->streams[index]->codec->codec_id;
Expand All @@ -312,29 +330,36 @@ bool generic_demux::query_avcodec_id(int index, enum AVCodecID &codec_id)

void generic_demux::close()
{
boost::mutex::scoped_lock l(m_mutex);

if (m_format_ctx)
{
avformat_close_input(&m_format_ctx);
m_format_ctx = NULL;
}

if (m_avio_ctx)
{
av_free(m_avio_ctx);
av_freep(&m_avio_ctx);
}
}

int generic_demux::read_pause()
{
boost::mutex::scoped_lock l(m_mutex);
return av_read_pause(m_format_ctx);
}

int generic_demux::read_play()
{
boost::mutex::scoped_lock l(m_mutex);
return av_read_play(m_format_ctx);
}

int generic_demux::query_index(enum AVMediaType type, AVFormatContext *ctx)
{
boost::mutex::scoped_lock l(m_mutex);

unsigned int i;

for (i = 0; (unsigned int) i < ctx->nb_streams; i++)
Expand Down
3 changes: 3 additions & 0 deletions demux/generic_demux.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class generic_demux : public demuxer
// 数据缓冲.
unsigned char *m_io_buffer;

// 同步访问.
mutable boost::mutex m_mutex;

// 是否中止.
bool m_abort;
};
Expand Down
1 change: 1 addition & 0 deletions demux/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern "C"

#include <boost/any.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread/mutex.hpp>

namespace fs = boost::filesystem;

Expand Down
33 changes: 20 additions & 13 deletions libav/avplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,21 @@ int open_decoder2(AVCodecContext **context, enum AVCodecID codec_id)
if (!codec)
return -1;

/* 打开解码器. */
/*
*context = avcodec_alloc_context3(codec);
if (avcodec_get_context_defaults3(*context, codec) < 0)
return -1;
*/

/* 打开解码器. */
if (avcodec_open2(*context, codec, NULL) < 0)
{
avcodec_close(*context);
av_free(*context);
*context = NULL;
return -1;
}

return 0;
}

Expand Down Expand Up @@ -512,17 +518,9 @@ int initialize(avplay *play, const char *file_name, int source_type, demux_conte
play->m_demux_context = dc;

/* 设置source type. */
if (source_type == MEDIA_TYPE_YK)
{
dc->type = source_type_flv;
dc->info.flv.unused = 0;
}
else
{
play->m_generic_info = &dc->info.generic;
dc->type = generic_source_type;
strcpy(play->m_generic_info->file_name, file_name); /* 保存文件名到generic_info.file_name, 以便其在初始化demux时使用. */
}
play->m_generic_info = &dc->info.generic;
dc->type = source_type;
strcpy(play->m_generic_info->file_name, file_name); /* 保存文件名到generic_info.file_name, 以便其在初始化demux时使用. */

/* 初始化demux的source. */
if (dc->init_demux(dc) == -1)
Expand All @@ -542,11 +540,21 @@ int initialize(avplay *play, const char *file_name, int source_type, demux_conte
/* 打开解码器. */
if (play->m_audio_index != -1)
{
AVCodec *codec = NULL;
/* 查找解码器. */
codec = avcodec_find_decoder(play->m_base_info->audio_codec->codec_id);
play->m_audio_ctx = avcodec_alloc_context3(codec);
avcodec_copy_context(play->m_audio_ctx, play->m_base_info->audio_codec);
if (open_decoder2(&play->m_audio_ctx, dc->query_avcodec_id(dc, play->m_audio_index)) != 0)
goto FAILED_FLG;
}
if (play->m_video_index != -1)
{
AVCodec *codec = NULL;
/* 查找解码器. */
codec = avcodec_find_decoder(play->m_base_info->video_codec->codec_id);
play->m_video_ctx = avcodec_alloc_context3(codec);
avcodec_copy_context(play->m_video_ctx, play->m_base_info->video_codec);
if (open_decoder2(&play->m_video_ctx, dc->query_avcodec_id(dc, play->m_video_index)) != 0)
goto FAILED_FLG;
}
Expand Down Expand Up @@ -1191,7 +1199,6 @@ void* read_pkt_thrd(void *param)

/* Return 0 if OK, < 0 on error or end of file. */
ret = dc->read_packet(dc, &packet);
/* ret = av_read_frame(play->m_format_ctx, &packet); */
if (ret < 0)
{
if (play->m_video_q.m_size == 0 && play->m_audio_q.m_size == 0 &&
Expand Down
3 changes: 3 additions & 0 deletions libav/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ typedef struct media_base_info
int width; /* 视频宽. */
int height; /* 视频高. */

AVCodecContext *audio_codec;
AVCodecContext *video_codec;

int sample_rate; /* 音频采样率. */
int channels; /* 音频声道. */

Expand Down

0 comments on commit afc8e58

Please sign in to comment.